16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 23:49:19 +02:00
Files
maszyna/simulation/simulationstateserializer.h
maj00r 512595234f Stream visual scenery in the driver (play starts after infrastructure pass)
Splits the progressive load across modes: the loader runs only the first
(infrastructure) pass and then hands off to the driver, so play begins as soon
as tracks/traction/events/signals/the player train are ready. The deferred
visual nodes (3d models, terrain shapes/lines) then stream in from the driver,
a small budget per frame, so the world fills in without a long up-front wait.

- state_serializer: the infrastructure pass now returns to the caller (instead of
  chaining the visual pass), restarting the twin for the visual pass; the visual
  pass uses a small ~8 ms/frame budget and marks the load done at the end. A
  text/compile load (no twin) stays single-pass and finishes as before.
- state_manager: retains the load state across the loader->driver hand-off and
  exposes loading_visuals()/continue_loading_visuals().
- driver_mode::update(): advances the deferred visual load each frame.

Verified on td.scn (playable in ~2 s, visuals complete a few seconds later, no
duplicate objects) and on the large tomaszewo scenery (flora/terrain/models
deferred while infrastructure loads). Inserts run on the main thread before the
render step, so progressive loading needs no locking.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:23:36 +02:00

101 lines
5.3 KiB
C++

/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "utilities/parser.h"
#include "scene/scene.h"
namespace simulation {
struct deserializer_state {
std::string scenariofile;
cParser input;
scene::scratch_data scratchpad;
using deserializefunctionbind = std::function<void()>;
std::unordered_map<
std::string,
deserializefunctionbind> functionmap;
// progressive (two-pass) load over a binary twin: first pass loads infrastructure,
// second pass loads visual nodes. false while in the first (infrastructure) pass.
bool visualphase { false };
// set once the whole load (both passes / single text pass) has fully finished
bool done { false };
deserializer_state(std::string const &File, cParser::buffertype const Type, const std::string &Path, bool const Loadtraction)
: scenariofile(File), input(File, Type, Path, Loadtraction) { }
};
class state_serializer {
public:
// methods
// starts deserialization from specified file, returns context pointer on success, throws otherwise
std::shared_ptr<deserializer_state>
deserialize_begin(std::string const &Scenariofile);
// continues deserialization for given context, amount limited by time, returns true if needs to be called again
bool
deserialize_continue(std::shared_ptr<deserializer_state> state);
// stores class data in specified file, in legacy (text) format
void
export_as_text( std::string const &Scenariofile ) const;
// create new model from node stirng
TAnimModel * create_model(std::string const &src, std::string const &name, const glm::dvec3 &position);
// create new eventlauncher from node stirng
TEventLauncher * create_eventlauncher(std::string const &src, std::string const &name, const glm::dvec3 &position);
private:
// methods
// restores class data from provided stream
void deserialize_area( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_isolated( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_assignment( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_config( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_description( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_event( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_lua( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_firstinit( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_group( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_endgroup( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_light( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_node( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_origin( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_scale( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_endscale( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_rotate( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_sky( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_test( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_time( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_trainset( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_terrain( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_endtrainset( cParser &Input, scene::scratch_data &Scratchpad );
TTrack * deserialize_path( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
TTraction * deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
TTractionPowerSource * deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
TMemCell * deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
TEventLauncher * deserialize_eventlauncher( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
void init_time();
// skips content of stream until specified token
void skip_until( cParser &Input, std::string const &Token );
// transforms provided location by specifed rotation and offset
glm::dvec3 transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad );
void export_nodes_to_stream( std::ostream &, bool Dirty ) const;
};
} // simulation
//---------------------------------------------------------------------------