16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 01:59:19 +02:00

Add two-pass progressive scenery load (sequential; infra then visuals)

When replaying a binary twin, load in two passes over the same data: the first
pass loads infrastructure (tracks/traction/events/memcells/sounds + directives),
the second pass loads the visual nodes (3d models, terrain shapes/lines) that the
reader skipped via the v6 node-class markers.

- cParser: setReplayPass() selects the served node class (propagated to include
  children); restartReplay() rewinds the twin for the second pass.
- state_serializer: first pass uses the infrastructure pass; on completion it
  restarts the twin for the visual pass. Stateful directives (trainset, event,
  camera, light, sky, time, ...) are skipped on the visual pass so their side
  effects do not duplicate; transform/group directives re-run so deferred visual
  nodes get correct placement. A text/compile load (no twin) stays single-pass.

Verified: td.scn replays through both passes with no duplicate vehicles/events
and reaches the normal load endpoint. This is the sequential foundation; moving
the visual pass into the driver (so play starts after the infrastructure pass) is
the next step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
maj00r
2026-06-22 23:10:06 +02:00
parent c337866c58
commit fd8bfdbcf3
4 changed files with 77 additions and 0 deletions

View File

@@ -641,6 +641,9 @@ void cParser::startIncludeDirect(std::string includefile, std::vector<std::strin
);
mIncludeParser->allowRandomIncludes = allowRandomIncludes;
mIncludeParser->autoclear(m_autoclear);
// the child inherits the current load pass so the whole include tree is filtered
// consistently (e.g. visuals-only on the second pass)
mIncludeParser->setReplayPass(m_replaypass);
// a binary-twin replay child reports mSize 0 but is still valid
if (mIncludeParser->mSize <= 0 && (false == mIncludeParser->m_replay)) {
@@ -648,6 +651,29 @@ void cParser::startIncludeDirect(std::string includefile, std::vector<std::strin
}
}
void cParser::setReplayPass(scene::scenery_load_pass Pass)
{
m_replaypass = Pass;
if (m_reader)
{
m_reader->set_pass(Pass);
}
}
bool cParser::restartReplay(scene::scenery_load_pass Pass)
{
if ((false == m_replay) || (false == static_cast<bool>(m_reader)))
{
return false;
}
m_reader->open(m_twinbuf);
m_reader->set_pass(Pass);
m_replaypass = Pass;
m_replayexhausted = false;
mIncludeParser = nullptr;
return true;
}
bool cParser::handleIncludeIfPresent(std::string& token, bool ToLower, const char* Break) {
// token-mode include: token == "include". NOTE: we only process the directive here
// and report it; readToken loops to fetch the next token. fetching it here (the old