mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 08:39:18 +02:00
network fixes and improvements, code refactoring
This commit is contained in:
@@ -74,4 +74,8 @@ enum class TCommandType
|
|||||||
using material_handle = int;
|
using material_handle = int;
|
||||||
using texture_handle = int;
|
using texture_handle = int;
|
||||||
|
|
||||||
|
struct invalid_scenery_exception : std::runtime_error {
|
||||||
|
invalid_scenery_exception() : std::runtime_error("cannot load scenery") {}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1772,11 +1772,10 @@ void TController::Activation()
|
|||||||
}
|
}
|
||||||
if (pVehicle != old)
|
if (pVehicle != old)
|
||||||
{ // jeśli zmieniony został pojazd prowadzony
|
{ // jeśli zmieniony został pojazd prowadzony
|
||||||
if( ( simulation::Train )
|
// ewentualna zmiana kabiny TTrain
|
||||||
&& ( simulation::Train->Dynamic() == old ) ) {
|
TTrain *train = simulation::Trains.find(old->name());
|
||||||
// ewentualna zmiana kabiny użytkownikowi
|
if (train)
|
||||||
Global.changeDynObj = pVehicle; // uruchomienie protezy
|
train->MoveToVehicle(pVehicle);
|
||||||
}
|
|
||||||
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu (może się zmienić) -
|
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu (może się zmienić) -
|
||||||
// silnikowy dla EZT
|
// silnikowy dla EZT
|
||||||
}
|
}
|
||||||
|
|||||||
11
DynObj.cpp
11
DynObj.cpp
@@ -2330,17 +2330,6 @@ TDynamicObject::create_controller( std::string const Type, bool const Trainset )
|
|||||||
|
|
||||||
if( Type == "" ) { return; }
|
if( Type == "" ) { return; }
|
||||||
|
|
||||||
if( asName == Global.asHumanCtrlVehicle ) {
|
|
||||||
// jeśli pojazd wybrany do prowadzenia
|
|
||||||
if( MoverParameters->EngineType != TEngineType::Dumb ) {
|
|
||||||
// wsadzamy tam sterującego
|
|
||||||
Controller = Humandriver;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// w przeciwnym razie trzeba włączyć pokazywanie kabiny
|
|
||||||
bDisplayCab = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// McZapkie-151102: rozkład jazdy czytany z pliku *.txt z katalogu w którym jest sceneria
|
// McZapkie-151102: rozkład jazdy czytany z pliku *.txt z katalogu w którym jest sceneria
|
||||||
if( ( Type == "1" )
|
if( ( Type == "1" )
|
||||||
|| ( Type == "2" ) ) {
|
|| ( Type == "2" ) ) {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
{
|
{
|
||||||
|
|
||||||
Parser.getTokens();
|
Parser.getTokens();
|
||||||
Parser >> asHumanCtrlVehicle;
|
Parser >> local_start_vehicle;
|
||||||
}
|
}
|
||||||
else if( token == "fieldofview" ) {
|
else if( token == "fieldofview" ) {
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ struct global_settings {
|
|||||||
std::mt19937 local_random_engine;
|
std::mt19937 local_random_engine;
|
||||||
bool ready_to_load { false };
|
bool ready_to_load { false };
|
||||||
uint32_t random_seed;
|
uint32_t random_seed;
|
||||||
TDynamicObject *changeDynObj{ nullptr };// info o zmianie pojazdu
|
|
||||||
TCamera pCamera; // parametry kamery
|
TCamera pCamera; // parametry kamery
|
||||||
TCamera pDebugCamera;
|
TCamera pDebugCamera;
|
||||||
std::array<Math3D::vector3, 10> FreeCameraInit; // pozycje kamery
|
std::array<Math3D::vector3, 10> FreeCameraInit; // pozycje kamery
|
||||||
@@ -61,7 +60,7 @@ struct global_settings {
|
|||||||
std::string szTexturesDDS{ ".dds" }; // lista tekstur od DDS
|
std::string szTexturesDDS{ ".dds" }; // lista tekstur od DDS
|
||||||
std::string szDefaultExt{ szTexturesDDS };
|
std::string szDefaultExt{ szTexturesDDS };
|
||||||
std::string SceneryFile{ "td.scn" };
|
std::string SceneryFile{ "td.scn" };
|
||||||
std::string asHumanCtrlVehicle{ "EU07-424" };
|
std::string local_start_vehicle{ "EU07-424" };
|
||||||
int iConvertModels{ 0 }; // tworzenie plików binarnych
|
int iConvertModels{ 0 }; // tworzenie plików binarnych
|
||||||
// logs
|
// logs
|
||||||
int iWriteLogEnabled{ 3 }; // maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów
|
int iWriteLogEnabled{ 3 }; // maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów
|
||||||
|
|||||||
5
Logs.cpp
5
Logs.cpp
@@ -46,12 +46,13 @@ std::string filename_date() {
|
|||||||
std::snprintf(
|
std::snprintf(
|
||||||
logbuffer,
|
logbuffer,
|
||||||
sizeof(logbuffer),
|
sizeof(logbuffer),
|
||||||
"%d%02d%02d_%02d%02d",
|
"%d%02d%02d_%02d%02d%03d",
|
||||||
st.wYear,
|
st.wYear,
|
||||||
st.wMonth,
|
st.wMonth,
|
||||||
st.wDay,
|
st.wDay,
|
||||||
st.wHour,
|
st.wHour,
|
||||||
st.wMinute );
|
st.wMinute,
|
||||||
|
st.wMilliseconds);
|
||||||
|
|
||||||
return std::string( logbuffer );
|
return std::string( logbuffer );
|
||||||
}
|
}
|
||||||
|
|||||||
10
Names.h
10
Names.h
@@ -46,8 +46,16 @@ public:
|
|||||||
auto lookup = m_itemmap.find( Name );
|
auto lookup = m_itemmap.find( Name );
|
||||||
if (lookup == m_itemmap.end())
|
if (lookup == m_itemmap.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
delete m_items[lookup->second];
|
delete m_items[lookup->second];
|
||||||
|
|
||||||
|
detach(Name);
|
||||||
|
}
|
||||||
|
void detach (std::string const &Name)
|
||||||
|
{
|
||||||
|
auto lookup = m_itemmap.find( Name );
|
||||||
|
if (lookup == m_itemmap.end())
|
||||||
|
return;
|
||||||
|
|
||||||
m_items[lookup->second] = nullptr;
|
m_items[lookup->second] = nullptr;
|
||||||
// TBD, TODO: remove from m_items?
|
// TBD, TODO: remove from m_items?
|
||||||
|
|
||||||
|
|||||||
62
Train.cpp
62
Train.cpp
@@ -4749,11 +4749,12 @@ void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Comm
|
|||||||
if( false == Train->CabChange( 1 ) ) {
|
if( false == Train->CabChange( 1 ) ) {
|
||||||
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ side::front ].CouplingFlag, coupling::gangway ) ) {
|
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ side::front ].CouplingFlag, coupling::gangway ) ) {
|
||||||
// przejscie do nastepnego pojazdu
|
// przejscie do nastepnego pojazdu
|
||||||
Global.changeDynObj = Train->DynamicObject->PrevConnected;
|
TDynamicObject *dynobj = Train->DynamicObject->PrevConnected;
|
||||||
Global.changeDynObj->MoverParameters->ActiveCab = (
|
dynobj->MoverParameters->ActiveCab = (
|
||||||
Train->DynamicObject->PrevConnectedNo ?
|
Train->DynamicObject->PrevConnectedNo ?
|
||||||
-1 :
|
-1 :
|
||||||
1 );
|
1 );
|
||||||
|
Train->MoveToVehicle(dynobj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4765,11 +4766,12 @@ void TTrain::OnCommand_cabchangebackward( TTrain *Train, command_data const &Com
|
|||||||
if( false == Train->CabChange( -1 ) ) {
|
if( false == Train->CabChange( -1 ) ) {
|
||||||
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ side::rear ].CouplingFlag, coupling::gangway ) ) {
|
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ side::rear ].CouplingFlag, coupling::gangway ) ) {
|
||||||
// przejscie do nastepnego pojazdu
|
// przejscie do nastepnego pojazdu
|
||||||
Global.changeDynObj = Train->DynamicObject->NextConnected;
|
TDynamicObject *dynobj = Train->DynamicObject->NextConnected;
|
||||||
Global.changeDynObj->MoverParameters->ActiveCab = (
|
dynobj->MoverParameters->ActiveCab = (
|
||||||
Train->DynamicObject->NextConnectedNo ?
|
Train->DynamicObject->NextConnectedNo ?
|
||||||
-1 :
|
-1 :
|
||||||
1 );
|
1 );
|
||||||
|
Train->MoveToVehicle(dynobj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6911,6 +6913,58 @@ void TTrain::DynamicSet(TDynamicObject *d)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
TTrain::MoveToVehicle(TDynamicObject *target) {
|
||||||
|
ErrorLog("MoveToVehicle");
|
||||||
|
// > Ra: to nie może być tak robione, to zbytnia proteza jest
|
||||||
|
// indeed, too much hacks...
|
||||||
|
|
||||||
|
simulation::Trains.detach(Dynamic()->name());
|
||||||
|
|
||||||
|
if( Dynamic()->Mechanik ) {
|
||||||
|
// AI może sobie samo pójść
|
||||||
|
if( false == Dynamic()->Mechanik->AIControllFlag ) {
|
||||||
|
// tylko jeśli ręcznie prowadzony
|
||||||
|
// jeśli prowadzi AI, to mu nie robimy dywersji!
|
||||||
|
Occupied()->CabDeactivisation();
|
||||||
|
Occupied()->ActiveCab = 0;
|
||||||
|
Occupied()->BrakeLevelSet( Occupied()->Handle->GetPos( bh_NP ) ); //rozwala sterowanie hamulcem GF 04-2016
|
||||||
|
Dynamic()->MechInside = false;
|
||||||
|
Dynamic()->Controller = AIdriver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dynamic()->bDisplayCab = false;
|
||||||
|
Dynamic()->ABuSetModelShake( {} );
|
||||||
|
|
||||||
|
if( Dynamic()->Mechanik ) // AI może sobie samo pójść
|
||||||
|
if( false == Dynamic()->Mechanik->AIControllFlag ) {
|
||||||
|
// tylko jeśli ręcznie prowadzony
|
||||||
|
// przsunięcie obiektu zarządzającego
|
||||||
|
Dynamic()->Mechanik->MoveTo( target );
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicSet( target );
|
||||||
|
|
||||||
|
if( Dynamic()->Mechanik ) // AI może sobie samo pójść
|
||||||
|
if( false == Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
|
||||||
|
{
|
||||||
|
Occupied()->LimPipePress = Occupied()->PipePress;
|
||||||
|
Occupied()->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
|
||||||
|
Dynamic()->MechInside = true;
|
||||||
|
Dynamic()->Controller = Humandriver;
|
||||||
|
}
|
||||||
|
InitializeCab(
|
||||||
|
Occupied()->CabNo,
|
||||||
|
Dynamic()->asBaseDir + Occupied()->TypeName + ".mmd" );
|
||||||
|
if( false == FreeFlyModeFlag ) {
|
||||||
|
Dynamic()->bDisplayCab = true;
|
||||||
|
Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
|
||||||
|
}
|
||||||
|
|
||||||
|
simulation::Trains.insert(this, Dynamic()->name());
|
||||||
|
}
|
||||||
|
|
||||||
// checks whether specified point is within boundaries of the active cab
|
// checks whether specified point is within boundaries of the active cab
|
||||||
bool
|
bool
|
||||||
TTrain::point_inside( Math3D::vector3 const Point ) const {
|
TTrain::point_inside( Math3D::vector3 const Point ) const {
|
||||||
|
|||||||
1
Train.h
1
Train.h
@@ -670,6 +670,7 @@ private:
|
|||||||
inline TMoverParameters *Occupied() { return mvOccupied; };
|
inline TMoverParameters *Occupied() { return mvOccupied; };
|
||||||
inline TMoverParameters const *Occupied() const { return mvOccupied; };
|
inline TMoverParameters const *Occupied() const { return mvOccupied; };
|
||||||
void DynamicSet(TDynamicObject *d);
|
void DynamicSet(TDynamicObject *d);
|
||||||
|
void MoveToVehicle(TDynamicObject *target);
|
||||||
// checks whether specified point is within boundaries of the active cab
|
// checks whether specified point is within boundaries of the active cab
|
||||||
bool point_inside( Math3D::vector3 const Point ) const;
|
bool point_inside( Math3D::vector3 const Point ) const;
|
||||||
Math3D::vector3 clamp_inside( Math3D::vector3 const &Point ) const;
|
Math3D::vector3 clamp_inside( Math3D::vector3 const &Point ) const;
|
||||||
|
|||||||
160
application.cpp
160
application.cpp
@@ -9,9 +9,9 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "scenarioloadermode.h"
|
|
||||||
#include "drivermode.h"
|
#include "drivermode.h"
|
||||||
#include "editormode.h"
|
#include "editormode.h"
|
||||||
|
#include "scenarioloadermode.h"
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
@@ -104,20 +104,20 @@ eu07_application::init( int Argc, char *Argv[] ) {
|
|||||||
|
|
||||||
int result { 0 };
|
int result { 0 };
|
||||||
|
|
||||||
WriteLog( "Starting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")" );
|
|
||||||
WriteLog( "For online documentation and additional files refer to: http://eu07.pl" );
|
|
||||||
WriteLog( "Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, "
|
|
||||||
"ShaXbee, Oli_EU, youBy, KURS90, Ra, hunter, szociu, Stele, Q, firleju and others\n" );
|
|
||||||
|
|
||||||
init_debug();
|
init_debug();
|
||||||
init_files();
|
init_files();
|
||||||
if( ( result = init_settings( Argc, Argv ) ) != 0 ) {
|
if( ( result = init_settings( Argc, Argv ) ) != 0 ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WriteLog( "Starting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")" );
|
||||||
|
WriteLog( "For online documentation and additional files refer to: http://eu07.pl" );
|
||||||
|
WriteLog( "Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, "
|
||||||
|
"ShaXbee, Oli_EU, youBy, KURS90, Ra, hunter, szociu, Stele, Q, firleju and others\n" );
|
||||||
|
|
||||||
if( ( result = init_locale() ) != 0 ) {
|
if( ( result = init_locale() ) != 0 ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( result = init_glfw() ) != 0 ) {
|
if( ( result = init_glfw() ) != 0 ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -171,81 +171,94 @@ eu07_application::run() {
|
|||||||
|
|
||||||
double frameStartTime = Timer::GetTime();
|
double frameStartTime = Timer::GetTime();
|
||||||
|
|
||||||
bool nextloop = true;
|
if (m_modes[m_modestack.top()]->is_command_processor()) {
|
||||||
while (nextloop)
|
// active mode is doing real calculations (e.g. drivermode)
|
||||||
{
|
|
||||||
command_queue::commands_map commands_to_exec;
|
|
||||||
command_queue::commands_map local_commands = simulation::Commands.pop_intercept_queue();
|
|
||||||
double slave_sync;
|
|
||||||
|
|
||||||
// if we're the server
|
bool nextloop = true;
|
||||||
if (m_network && m_network->servers)
|
while (nextloop)
|
||||||
{
|
{
|
||||||
// fetch from network layer command requests received from clients
|
command_queue::commands_map commands_to_exec;
|
||||||
command_queue::commands_map remote_commands = m_network->servers->pop_commands();
|
command_queue::commands_map local_commands = simulation::Commands.pop_intercept_queue();
|
||||||
|
double slave_sync;
|
||||||
|
|
||||||
// push these into local queue
|
// if we're the server
|
||||||
add_to_dequemap(local_commands, remote_commands);
|
if (m_network && m_network->servers)
|
||||||
}
|
{
|
||||||
|
// fetch from network layer command requests received from clients
|
||||||
|
command_queue::commands_map remote_commands = m_network->servers->pop_commands();
|
||||||
|
|
||||||
// if we're slave
|
// push these into local queue
|
||||||
if (m_network && m_network->client)
|
add_to_dequemap(local_commands, remote_commands);
|
||||||
{
|
}
|
||||||
// fetch frame info from network layer,
|
|
||||||
auto frame_info = m_network->client->get_next_delta();
|
|
||||||
|
|
||||||
// use delta and commands received from master
|
// if we're slave
|
||||||
double delta = std::get<0>(frame_info);
|
if (m_network && m_network->client)
|
||||||
Timer::set_delta_override(delta);
|
{
|
||||||
slave_sync = std::get<1>(frame_info);
|
// fetch frame info from network layer,
|
||||||
add_to_dequemap(commands_to_exec, std::get<2>(frame_info));
|
auto frame_info = m_network->client->get_next_delta();
|
||||||
|
|
||||||
// and send our local commands to master
|
// use delta and commands received from master
|
||||||
m_network->client->send_commands(local_commands);
|
double delta = std::get<0>(frame_info);
|
||||||
|
Timer::set_delta_override(delta);
|
||||||
|
slave_sync = std::get<1>(frame_info);
|
||||||
|
add_to_dequemap(commands_to_exec, std::get<2>(frame_info));
|
||||||
|
|
||||||
|
// and send our local commands to master
|
||||||
|
m_network->client->send_commands(local_commands);
|
||||||
|
|
||||||
|
if (delta == 0.0)
|
||||||
|
nextloop = false;
|
||||||
|
}
|
||||||
|
// if we're master
|
||||||
|
else {
|
||||||
|
// just push local commands to execution
|
||||||
|
add_to_dequemap(commands_to_exec, local_commands);
|
||||||
|
|
||||||
if (delta == 0.0)
|
|
||||||
nextloop = false;
|
nextloop = false;
|
||||||
}
|
}
|
||||||
// if we're master
|
|
||||||
else {
|
|
||||||
// just push local commands to execution
|
|
||||||
add_to_dequemap(commands_to_exec, local_commands);
|
|
||||||
|
|
||||||
nextloop = false;
|
// send commands to command queue
|
||||||
}
|
simulation::Commands.push_commands(commands_to_exec);
|
||||||
|
|
||||||
// send commands to command queue
|
// do actual frame processing
|
||||||
simulation::Commands.push_commands(commands_to_exec);
|
if (!m_modes[ m_modestack.top() ]->update())
|
||||||
|
goto die;
|
||||||
|
|
||||||
|
// update continuous commands
|
||||||
|
simulation::Commands.update();
|
||||||
|
|
||||||
|
double sync = generate_sync();
|
||||||
|
|
||||||
|
// if we're the server
|
||||||
|
if (m_network && m_network->servers)
|
||||||
|
{
|
||||||
|
// send delta, sync, and commands we just executed to clients
|
||||||
|
double delta = Timer::GetDeltaTime();
|
||||||
|
m_network->servers->push_delta(delta, sync, commands_to_exec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we're slave
|
||||||
|
if (m_network && m_network->client)
|
||||||
|
{
|
||||||
|
// verify sync
|
||||||
|
if (sync != slave_sync) {
|
||||||
|
WriteLog("net: DESYNC!", logtype::net);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set total delta for rendering code
|
||||||
|
double totalDelta = Timer::GetTime() - frameStartTime;
|
||||||
|
Timer::set_delta_override(totalDelta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// active mode is loader
|
||||||
|
|
||||||
|
// clear local command queue
|
||||||
|
simulation::Commands.pop_intercept_queue();
|
||||||
|
|
||||||
// do actual frame processing
|
// do actual frame processing
|
||||||
if (!m_modes[ m_modestack.top() ]->update())
|
if (!m_modes[ m_modestack.top() ]->update())
|
||||||
goto die;
|
goto die;
|
||||||
|
|
||||||
// update continuous commands
|
|
||||||
simulation::Commands.update();
|
|
||||||
|
|
||||||
double sync = generate_sync();
|
|
||||||
|
|
||||||
// if we're the server
|
|
||||||
if (m_network && m_network->servers)
|
|
||||||
{
|
|
||||||
// send delta, sync, and commands we just executed to clients
|
|
||||||
double delta = Timer::GetDeltaTime();
|
|
||||||
m_network->servers->push_delta(delta, sync, commands_to_exec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we're slave
|
|
||||||
if (m_network && m_network->client)
|
|
||||||
{
|
|
||||||
// verify sync
|
|
||||||
if (sync != slave_sync) {
|
|
||||||
WriteLog("net: DESYNC!", logtype::net);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set total delta for rendering code
|
|
||||||
double totalDelta = Timer::GetTime() - frameStartTime;
|
|
||||||
Timer::set_delta_override(totalDelta);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
@@ -269,7 +282,7 @@ eu07_application::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_network)
|
if (m_network)
|
||||||
m_network->poll();
|
m_network->update();
|
||||||
|
|
||||||
auto frametime = Timer::subsystem.mainloop_total.stop();
|
auto frametime = Timer::subsystem.mainloop_total.stop();
|
||||||
if (Global.minframetime.count() != 0.0f && (Global.minframetime - frametime).count() > 0.0f)
|
if (Global.minframetime.count() != 0.0f && (Global.minframetime - frametime).count() > 0.0f)
|
||||||
@@ -490,7 +503,7 @@ eu07_application::init_files() {
|
|||||||
#elif __linux__
|
#elif __linux__
|
||||||
unlink("log.txt");
|
unlink("log.txt");
|
||||||
unlink("errors.txt");
|
unlink("errors.txt");
|
||||||
mkdir("logs", 0664);
|
mkdir("logs", 0755);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,7 +532,7 @@ eu07_application::init_settings( int Argc, char *Argv[] ) {
|
|||||||
}
|
}
|
||||||
else if( token == "-v" ) {
|
else if( token == "-v" ) {
|
||||||
if( i + 1 < Argc ) {
|
if( i + 1 < Argc ) {
|
||||||
Global.asHumanCtrlVehicle = ToLower( Argv[ ++i ] );
|
Global.local_start_vehicle = ToLower( Argv[ ++i ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -709,6 +722,11 @@ bool eu07_application::init_network() {
|
|||||||
if (Global.network_conf.is_client) {
|
if (Global.network_conf.is_client) {
|
||||||
m_network->connect(Global.network_conf.client_host, Global.network_conf.client_port);
|
m_network->connect(Global.network_conf.client_host, Global.network_conf.client_port);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Global.random_seed = std::random_device{}();
|
||||||
|
Global.random_engine.seed(Global.random_seed);
|
||||||
|
Global.ready_to_load = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ public:
|
|||||||
virtual
|
virtual
|
||||||
void
|
void
|
||||||
on_event_poll() = 0;
|
on_event_poll() = 0;
|
||||||
|
virtual
|
||||||
|
bool
|
||||||
|
is_command_processor() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// members
|
// members
|
||||||
|
|||||||
@@ -197,9 +197,9 @@ driver_mode::update() {
|
|||||||
InOutKey();
|
InOutKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Global.changeDynObj ) {
|
if (!FreeFlyModeFlag && simulation::Train->Dynamic() != Camera.m_owner) {
|
||||||
// ABu zmiana pojazdu - przejście do innego
|
// fixup camera after vehicle switch
|
||||||
ChangeDynamic();
|
CabView();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( simulation::Train != nullptr )
|
if( simulation::Train != nullptr )
|
||||||
@@ -264,8 +264,8 @@ void
|
|||||||
driver_mode::enter() {
|
driver_mode::enter() {
|
||||||
|
|
||||||
TDynamicObject *nPlayerTrain { (
|
TDynamicObject *nPlayerTrain { (
|
||||||
( Global.asHumanCtrlVehicle != "ghostview" ) ?
|
( Global.local_start_vehicle != "ghostview" ) ?
|
||||||
simulation::Vehicles.find( Global.asHumanCtrlVehicle ) :
|
simulation::Vehicles.find( Global.local_start_vehicle ) :
|
||||||
nullptr ) };
|
nullptr ) };
|
||||||
|
|
||||||
Camera.Init(Global.FreeCameraInit[0], Global.FreeCameraInitAngle[0], nullptr );
|
Camera.Init(Global.FreeCameraInit[0], Global.FreeCameraInitAngle[0], nullptr );
|
||||||
@@ -277,14 +277,14 @@ driver_mode::enter() {
|
|||||||
|
|
||||||
if (nPlayerTrain)
|
if (nPlayerTrain)
|
||||||
{
|
{
|
||||||
WriteLog( "Trying to enter player train, \"" + Global.asHumanCtrlVehicle + "\"" );
|
WriteLog( "Trying to enter player train, \"" + Global.local_start_vehicle + "\"" );
|
||||||
|
|
||||||
m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0, nPlayerTrain->GetPosition());
|
m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0, nPlayerTrain->GetPosition());
|
||||||
change_train = nPlayerTrain->name();
|
change_train = nPlayerTrain->name();
|
||||||
}
|
}
|
||||||
else if (Global.asHumanCtrlVehicle != "ghostview")
|
else if (Global.local_start_vehicle != "ghostview")
|
||||||
{
|
{
|
||||||
Error("Bad scenario: failed to locate player train, \"" + Global.asHumanCtrlVehicle + "\"" );
|
Error("Bad scenario: failed to locate player train, \"" + Global.local_start_vehicle + "\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!Global.bMultiplayer) //na razie włączone
|
// if (!Global.bMultiplayer) //na razie włączone
|
||||||
@@ -301,7 +301,7 @@ driver_mode::enter() {
|
|||||||
KeyEvents[ 9 ] = simulation::Events.FindEvent( "keyctrl09" );
|
KeyEvents[ 9 ] = simulation::Events.FindEvent( "keyctrl09" );
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer::ResetTimers();
|
Timer::ResetTimers();
|
||||||
|
|
||||||
set_picking( Global.ControlPicking );
|
set_picking( Global.ControlPicking );
|
||||||
}
|
}
|
||||||
@@ -377,6 +377,12 @@ driver_mode::on_event_poll() {
|
|||||||
m_input.poll();
|
m_input.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
driver_mode::is_command_processor() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
driver_mode::update_camera( double const Deltatime ) {
|
driver_mode::update_camera( double const Deltatime ) {
|
||||||
|
|
||||||
@@ -946,65 +952,6 @@ driver_mode::CabView() {
|
|||||||
train->pMechOffset = Camera.m_owneroffset;
|
train->pMechOffset = Camera.m_owneroffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
driver_mode::ChangeDynamic() {
|
|
||||||
|
|
||||||
auto *train { simulation::Train };
|
|
||||||
if( train == nullptr ) { return; }
|
|
||||||
|
|
||||||
auto *vehicle { train->Dynamic() };
|
|
||||||
auto *occupied { train->Occupied() };
|
|
||||||
auto *driver { vehicle->Mechanik };
|
|
||||||
// Ra: to nie może być tak robione, to zbytnia proteza jest
|
|
||||||
if( driver ) {
|
|
||||||
// AI może sobie samo pójść
|
|
||||||
if( false == driver->AIControllFlag ) {
|
|
||||||
// tylko jeśli ręcznie prowadzony
|
|
||||||
// jeśli prowadzi AI, to mu nie robimy dywersji!
|
|
||||||
occupied->CabDeactivisation();
|
|
||||||
occupied->ActiveCab = 0;
|
|
||||||
occupied->BrakeLevelSet( occupied->Handle->GetPos( bh_NP ) ); //rozwala sterowanie hamulcem GF 04-2016
|
|
||||||
vehicle->MechInside = false;
|
|
||||||
vehicle->Controller = AIdriver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TDynamicObject *temp = Global.changeDynObj;
|
|
||||||
vehicle->bDisplayCab = false;
|
|
||||||
vehicle->ABuSetModelShake( {} );
|
|
||||||
|
|
||||||
if( driver ) // AI może sobie samo pójść
|
|
||||||
if( false == driver->AIControllFlag ) {
|
|
||||||
// tylko jeśli ręcznie prowadzony
|
|
||||||
// przsunięcie obiektu zarządzającego
|
|
||||||
driver->MoveTo( temp );
|
|
||||||
}
|
|
||||||
|
|
||||||
train->DynamicSet( temp );
|
|
||||||
// update helpers
|
|
||||||
train = simulation::Train;
|
|
||||||
vehicle = train->Dynamic();
|
|
||||||
occupied = train->Occupied();
|
|
||||||
driver = vehicle->Mechanik;
|
|
||||||
Global.asHumanCtrlVehicle = vehicle->name();
|
|
||||||
if( driver ) // AI może sobie samo pójść
|
|
||||||
if( false == driver->AIControllFlag ) // tylko jeśli ręcznie prowadzony
|
|
||||||
{
|
|
||||||
occupied->LimPipePress = occupied->PipePress;
|
|
||||||
occupied->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
|
|
||||||
vehicle->MechInside = true;
|
|
||||||
vehicle->Controller = Humandriver;
|
|
||||||
}
|
|
||||||
train->InitializeCab(
|
|
||||||
occupied->CabNo,
|
|
||||||
vehicle->asBaseDir + occupied->TypeName + ".mmd" );
|
|
||||||
if( false == FreeFlyModeFlag ) {
|
|
||||||
vehicle->bDisplayCab = true;
|
|
||||||
vehicle->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
|
|
||||||
CabView(); // na pozycję mecha
|
|
||||||
}
|
|
||||||
Global.changeDynObj = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
driver_mode::InOutKey()
|
driver_mode::InOutKey()
|
||||||
{ // przełączenie widoku z kabiny na zewnętrzny i odwrotnie
|
{ // przełączenie widoku z kabiny na zewnętrzny i odwrotnie
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public:
|
|||||||
on_scroll( double const Xoffset, double const Yoffset ) override;
|
on_scroll( double const Xoffset, double const Yoffset ) override;
|
||||||
void
|
void
|
||||||
on_event_poll() override;
|
on_event_poll() override;
|
||||||
|
bool
|
||||||
|
is_command_processor() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
@@ -86,7 +88,7 @@ private:
|
|||||||
void update_camera( const double Deltatime );
|
void update_camera( const double Deltatime );
|
||||||
// handles vehicle change flag
|
// handles vehicle change flag
|
||||||
void OnKeyDown( int cKey );
|
void OnKeyDown( int cKey );
|
||||||
void ChangeDynamic();
|
|
||||||
void InOutKey();
|
void InOutKey();
|
||||||
void CabView();
|
void CabView();
|
||||||
void ExternalView();
|
void ExternalView();
|
||||||
@@ -99,7 +101,7 @@ private:
|
|||||||
TCamera Camera;
|
TCamera Camera;
|
||||||
TCamera DebugCamera;
|
TCamera DebugCamera;
|
||||||
int m_externalviewmode { view::consistfront }; // selected external view mode
|
int m_externalviewmode { view::consistfront }; // selected external view mode
|
||||||
bool m_externalview { false };
|
bool m_externalview { true };
|
||||||
std::array<view_config, view::count_> m_externalviewconfigs;
|
std::array<view_config, view::count_> m_externalviewconfigs;
|
||||||
TDynamicObject *pDynamicNearest { nullptr }; // vehicle nearest to the active camera. TODO: move to camera
|
TDynamicObject *pDynamicNearest { nullptr }; // vehicle nearest to the active camera. TODO: move to camera
|
||||||
double fTime50Hz { 0.0 }; // bufor czasu dla komunikacji z PoKeys
|
double fTime50Hz { 0.0 }; // bufor czasu dla komunikacji z PoKeys
|
||||||
|
|||||||
@@ -262,6 +262,11 @@ editor_mode::on_event_poll() {
|
|||||||
m_input.poll();
|
m_input.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool editor_mode::is_command_processor() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
editor_mode::mode_translation() const {
|
editor_mode::mode_translation() const {
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ public:
|
|||||||
on_scroll( double const Xoffset, double const Yoffset ) override { ; }
|
on_scroll( double const Xoffset, double const Yoffset ) override { ; }
|
||||||
void
|
void
|
||||||
on_event_poll() override;
|
on_event_poll() override;
|
||||||
|
bool
|
||||||
|
is_command_processor() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
|||||||
// jeśli długość nazwy jest niezerowa szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #7
|
// jeśli długość nazwy jest niezerowa szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #7
|
||||||
auto *vehicle = (
|
auto *vehicle = (
|
||||||
pRozkaz->cString[ 1 ] == '*' ?
|
pRozkaz->cString[ 1 ] == '*' ?
|
||||||
simulation::Vehicles.find( Global.asHumanCtrlVehicle ) :
|
simulation::Train->Dynamic() :
|
||||||
simulation::Vehicles.find( std::string{ pRozkaz->cString + 1, (unsigned)pRozkaz->cString[ 0 ] } ) );
|
simulation::Vehicles.find( std::string{ pRozkaz->cString + 1, (unsigned)pRozkaz->cString[ 0 ] } ) );
|
||||||
if( vehicle != nullptr ) {
|
if( vehicle != nullptr ) {
|
||||||
WyslijNamiary( vehicle ); // wysłanie informacji o pojeździe
|
WyslijNamiary( vehicle ); // wysłanie informacji o pojeździe
|
||||||
@@ -181,7 +181,7 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
|||||||
{ // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #13
|
{ // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #13
|
||||||
auto *lookup = (
|
auto *lookup = (
|
||||||
pRozkaz->cString[ 2 ] == '*' ?
|
pRozkaz->cString[ 2 ] == '*' ?
|
||||||
simulation::Vehicles.find( Global.asHumanCtrlVehicle ) : // nazwa pojazdu użytkownika
|
simulation::Train->Dynamic() : // nazwa pojazdu użytkownika
|
||||||
simulation::Vehicles.find( std::string( pRozkaz->cString + 2, (unsigned)pRozkaz->cString[ 1 ] ) ) ); // nazwa pojazdu
|
simulation::Vehicles.find( std::string( pRozkaz->cString + 2, (unsigned)pRozkaz->cString[ 1 ] ) ) ); // nazwa pojazdu
|
||||||
if( lookup == nullptr ) { break; } // nothing found, nothing to do
|
if( lookup == nullptr ) { break; } // nothing found, nothing to do
|
||||||
auto *d { lookup };
|
auto *d { lookup };
|
||||||
|
|||||||
@@ -9,10 +9,14 @@ network::tcp::connection::connection(asio::io_context &io_ctx, bool client, size
|
|||||||
m_header_buffer.resize(8);
|
m_header_buffer.resize(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
network::tcp::connection::~connection()
|
||||||
|
{
|
||||||
|
m_socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
void network::tcp::connection::disconnect()
|
void network::tcp::connection::disconnect()
|
||||||
{
|
{
|
||||||
network::connection::disconnect();
|
network::connection::disconnect();
|
||||||
m_socket.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::tcp::connection::send_data(std::shared_ptr<std::string> buffer)
|
void network::tcp::connection::send_data(std::shared_ptr<std::string> buffer)
|
||||||
@@ -176,8 +180,6 @@ void network::tcp::client::connect()
|
|||||||
if (this->conn)
|
if (this->conn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::cout << "create sock" << std::endl;
|
|
||||||
|
|
||||||
std::shared_ptr<connection> conn = std::make_shared<connection>(io_ctx, true, resume_frame_counter);
|
std::shared_ptr<connection> conn = std::make_shared<connection>(io_ctx, true, resume_frame_counter);
|
||||||
conn->set_handler(std::bind(&client::handle_message, this, conn, std::placeholders::_1));
|
conn->set_handler(std::bind(&client::handle_message, this, conn, std::placeholders::_1));
|
||||||
|
|
||||||
@@ -187,7 +189,6 @@ void network::tcp::client::connect()
|
|||||||
conn->m_socket.set_option(asio::ip::tcp::no_delay(true));
|
conn->m_socket.set_option(asio::ip::tcp::no_delay(true));
|
||||||
conn->m_socket.async_connect(endpoint,
|
conn->m_socket.async_connect(endpoint,
|
||||||
std::bind(&client::handle_accept, this, std::placeholders::_1));
|
std::bind(&client::handle_accept, this, std::placeholders::_1));
|
||||||
std::cout << "connect start" <<std::endl;
|
|
||||||
|
|
||||||
this->conn = conn;
|
this->conn = conn;
|
||||||
|
|
||||||
@@ -195,7 +196,6 @@ void network::tcp::client::connect()
|
|||||||
|
|
||||||
void network::tcp::client::handle_accept(const asio::error_code &err)
|
void network::tcp::client::handle_accept(const asio::error_code &err)
|
||||||
{
|
{
|
||||||
std::cout << "connect handl" <<std::endl;
|
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
conn->connected();
|
conn->connected();
|
||||||
@@ -203,6 +203,6 @@ void network::tcp::client::handle_accept(const asio::error_code &err)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteLog(std::string("net: failed to connect: " + err.message()), logtype::net);
|
WriteLog(std::string("net: failed to connect: " + err.message()), logtype::net);
|
||||||
conn->state = connection::DEAD;
|
conn->disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace network::tcp
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
connection(asio::io_context &io_ctx, bool client = false, size_t counter = 0);
|
connection(asio::io_context &io_ctx, bool client = false, size_t counter = 0);
|
||||||
|
~connection();
|
||||||
|
|
||||||
virtual void connected() override;
|
virtual void connected() override;
|
||||||
virtual void disconnect() override;
|
virtual void disconnect() override;
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ void network::server_manager::push_delta(double dt, double sync, const command_q
|
|||||||
if (dt == 0.0 && commands.empty())
|
if (dt == 0.0 && commands.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto srv : servers)
|
|
||||||
srv->push_delta(dt, sync, commands);
|
|
||||||
|
|
||||||
frame_info msg;
|
frame_info msg;
|
||||||
msg.dt = dt;
|
msg.dt = dt;
|
||||||
msg.sync = sync;
|
msg.sync = sync;
|
||||||
msg.commands = commands;
|
msg.commands = commands;
|
||||||
|
|
||||||
|
for (auto srv : servers)
|
||||||
|
srv->push_delta(msg);
|
||||||
|
|
||||||
serialize_message(msg, *backbuffer.get());
|
serialize_message(msg, *backbuffer.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +42,13 @@ network::manager::manager()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::manager::poll()
|
void network::manager::update()
|
||||||
{
|
{
|
||||||
io_context.restart();
|
io_context.restart();
|
||||||
io_context.poll();
|
io_context.poll();
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
client->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::manager::create_server(const std::string &host, uint32_t port)
|
void network::manager::create_server(const std::string &host, uint32_t port)
|
||||||
|
|||||||
@@ -32,6 +32,6 @@ namespace network
|
|||||||
|
|
||||||
void create_server(const std::string &host, uint32_t port);
|
void create_server(const std::string &host, uint32_t port);
|
||||||
void connect(const std::string &host, uint32_t port);
|
void connect(const std::string &host, uint32_t port);
|
||||||
void poll();
|
void update();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,27 +40,29 @@ void network::connection::catch_up()
|
|||||||
|
|
||||||
std::vector<std::shared_ptr<message>> messages;
|
std::vector<std::shared_ptr<message>> messages;
|
||||||
|
|
||||||
for (size_t i = 0; i < CATCHUP_PACKETS; i++) {
|
for (int i = 0; i < CATCHUP_PACKETS; i++) {
|
||||||
if (backbuffer->peek() == EOF) {
|
if (backbuffer->peek() == EOF) {
|
||||||
send_messages(messages);
|
send_messages(messages);
|
||||||
backbuffer->seekg(0, std::ios_base::end);
|
|
||||||
state = ACTIVE;
|
state = ACTIVE;
|
||||||
|
backbuffer->seekg(0, std::ios_base::end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto msg = deserialize_message(*backbuffer.get());
|
||||||
|
|
||||||
if (packet_counter) {
|
if (packet_counter) {
|
||||||
packet_counter--;
|
packet_counter--;
|
||||||
|
i--; // TODO: it would be better to skip frames in chunks
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
messages.push_back(deserialize_message(*backbuffer.get()));
|
messages.push_back(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_messages(messages);
|
|
||||||
|
|
||||||
backbuffer_pos = backbuffer->tellg();
|
backbuffer_pos = backbuffer->tellg();
|
||||||
|
|
||||||
backbuffer->seekg(0, std::ios_base::end);
|
backbuffer->seekg(0, std::ios_base::end);
|
||||||
|
|
||||||
|
send_messages(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::connection::send_complete(std::shared_ptr<std::string> buf)
|
void network::connection::send_complete(std::shared_ptr<std::string> buf)
|
||||||
@@ -108,13 +110,8 @@ network::server::server(std::shared_ptr<std::istream> buf) : backbuffer(buf)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::server::push_delta(double dt, double sync, const command_queue::commands_map &commands)
|
void network::server::push_delta(const frame_info &msg)
|
||||||
{
|
{
|
||||||
frame_info msg;
|
|
||||||
msg.dt = dt;
|
|
||||||
msg.sync = sync;
|
|
||||||
msg.commands = commands;
|
|
||||||
|
|
||||||
for (auto it = clients.begin(); it != clients.end(); ) {
|
for (auto it = clients.begin(); it != clients.end(); ) {
|
||||||
if ((*it)->state == connection::DEAD) {
|
if ((*it)->state == connection::DEAD) {
|
||||||
it = clients.erase(it);
|
it = clients.erase(it);
|
||||||
@@ -146,6 +143,11 @@ void network::server::handle_message(std::shared_ptr<connection> conn, const mes
|
|||||||
if (msg.type == message::CLIENT_HELLO) {
|
if (msg.type == message::CLIENT_HELLO) {
|
||||||
auto cmd = dynamic_cast<const client_hello&>(msg);
|
auto cmd = dynamic_cast<const client_hello&>(msg);
|
||||||
|
|
||||||
|
if (cmd.version != 1) {
|
||||||
|
conn->disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
server_hello reply;
|
server_hello reply;
|
||||||
reply.seed = Global.random_seed;
|
reply.seed = Global.random_seed;
|
||||||
conn->state = connection::CATCHING_UP;
|
conn->state = connection::CATCHING_UP;
|
||||||
@@ -167,20 +169,24 @@ void network::server::handle_message(std::shared_ptr<connection> conn, const mes
|
|||||||
|
|
||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
// client
|
void network::client::update()
|
||||||
int zzz = 20;
|
|
||||||
std::tuple<double, double, command_queue::commands_map> network::client::get_next_delta()
|
|
||||||
{
|
{
|
||||||
if (conn && conn->state == connection::DEAD) {
|
if (conn && conn->state == connection::DEAD) {
|
||||||
conn.reset();
|
conn.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
zzz--;
|
if (!reconnect_delay) {
|
||||||
if (zzz < 0)
|
|
||||||
connect();
|
connect();
|
||||||
|
reconnect_delay = RECONNECT_DELAY_FRAMES;
|
||||||
|
}
|
||||||
|
reconnect_delay--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// client
|
||||||
|
std::tuple<double, double, command_queue::commands_map> network::client::get_next_delta()
|
||||||
|
{
|
||||||
if (delta_queue.empty()) {
|
if (delta_queue.empty()) {
|
||||||
return std::tuple<double, double,
|
return std::tuple<double, double,
|
||||||
command_queue::commands_map>(0.0, 0.0, command_queue::commands_map());
|
command_queue::commands_map>(0.0, 0.0, command_queue::commands_map());
|
||||||
@@ -189,6 +195,7 @@ std::tuple<double, double, command_queue::commands_map> network::client::get_nex
|
|||||||
auto entry = delta_queue.front();
|
auto entry = delta_queue.front();
|
||||||
delta_queue.pop();
|
delta_queue.pop();
|
||||||
|
|
||||||
|
auto &delta = entry.second;
|
||||||
return std::make_tuple(entry.second.dt, entry.second.sync, entry.second.commands);
|
return std::make_tuple(entry.second.dt, entry.second.sync, entry.second.commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,9 +223,11 @@ void network::client::handle_message(std::shared_ptr<connection> conn, const mes
|
|||||||
auto cmd = dynamic_cast<const server_hello&>(msg);
|
auto cmd = dynamic_cast<const server_hello&>(msg);
|
||||||
conn->state = connection::ACTIVE;
|
conn->state = connection::ACTIVE;
|
||||||
|
|
||||||
Global.random_seed = cmd.seed;
|
if (!Global.ready_to_load) {
|
||||||
Global.random_engine.seed(Global.random_seed);
|
Global.random_seed = cmd.seed;
|
||||||
Global.ready_to_load = true;
|
Global.random_engine.seed(Global.random_seed);
|
||||||
|
Global.ready_to_load = true;
|
||||||
|
}
|
||||||
|
|
||||||
WriteLog("net: accept received", logtype::net);
|
WriteLog("net: accept received", logtype::net);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace network
|
|||||||
friend class client;
|
friend class client;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const size_t CATCHUP_PACKETS = 100;
|
const int CATCHUP_PACKETS = 100;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
std::queue<
|
std::queue<
|
||||||
@@ -74,7 +74,7 @@ namespace network
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
server(std::shared_ptr<std::istream> buf);
|
server(std::shared_ptr<std::istream> buf);
|
||||||
void push_delta(double dt, double sync, const command_queue::commands_map &commands);
|
void push_delta(const frame_info &msg);
|
||||||
command_queue::commands_map pop_commands();
|
command_queue::commands_map pop_commands();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -85,12 +85,16 @@ namespace network
|
|||||||
void handle_message(std::shared_ptr<connection> conn, const message &msg);
|
void handle_message(std::shared_ptr<connection> conn, const message &msg);
|
||||||
std::shared_ptr<connection> conn;
|
std::shared_ptr<connection> conn;
|
||||||
size_t resume_frame_counter = 0;
|
size_t resume_frame_counter = 0;
|
||||||
|
size_t reconnect_delay = 0;
|
||||||
|
|
||||||
|
const size_t RECONNECT_DELAY_FRAMES = 60;
|
||||||
|
|
||||||
std::queue<
|
std::queue<
|
||||||
std::pair<std::chrono::high_resolution_clock::time_point,
|
std::pair<std::chrono::high_resolution_clock::time_point,
|
||||||
frame_info>> delta_queue;
|
frame_info>> delta_queue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void update();
|
||||||
std::tuple<double, double, command_queue::commands_map> get_next_delta();
|
std::tuple<double, double, command_queue::commands_map> get_next_delta();
|
||||||
void send_commands(command_queue::commands_map commands);
|
void send_commands(command_queue::commands_map commands);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2114,9 +2114,6 @@ bool opengl_renderer::Render(TDynamicObject *Dynamic)
|
|||||||
m_sunlight.apply_intensity(Dynamic->fShade);
|
m_sunlight.apply_intensity(Dynamic->fShade);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calc_motion = true;
|
|
||||||
// std::cout << glm::to_string(glm::vec3(Dynamic->get_velocity_vec())) << std::endl;
|
|
||||||
|
|
||||||
// render
|
// render
|
||||||
if (Dynamic->mdLowPolyInt)
|
if (Dynamic->mdLowPolyInt)
|
||||||
Render(Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance);
|
Render(Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance);
|
||||||
@@ -2128,7 +2125,6 @@ bool opengl_renderer::Render(TDynamicObject *Dynamic)
|
|||||||
Render(Dynamic->mdLoad, Dynamic->Material(), squaredistance, {0.f, Dynamic->LoadOffset, 0.f}, {});
|
Render(Dynamic->mdLoad, Dynamic->Material(), squaredistance, {0.f, Dynamic->LoadOffset, 0.f}, {});
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
// calc_motion = false;
|
|
||||||
|
|
||||||
if (Dynamic->fShade > 0.0f)
|
if (Dynamic->fShade > 0.0f)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,27 +35,40 @@ scenarioloader_mode::init() {
|
|||||||
// mode-specific update of simulation data. returns: false on error, true otherwise
|
// mode-specific update of simulation data. returns: false on error, true otherwise
|
||||||
bool
|
bool
|
||||||
scenarioloader_mode::update() {
|
scenarioloader_mode::update() {
|
||||||
|
if (!Global.ready_to_load)
|
||||||
|
// waiting for network connection
|
||||||
|
return true;
|
||||||
|
|
||||||
WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." );
|
if (!state) {
|
||||||
|
WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." );
|
||||||
|
|
||||||
auto timestart = std::chrono::system_clock::now();
|
timestart = std::chrono::system_clock::now();
|
||||||
|
state = simulation::State.deserialize_begin(Global.SceneryFile);
|
||||||
|
}
|
||||||
|
|
||||||
if( true == simulation::State.deserialize( Global.SceneryFile ) ) {
|
try {
|
||||||
WriteLog( "Scenario loading time: " + std::to_string( std::chrono::duration_cast<std::chrono::seconds>( ( std::chrono::system_clock::now() - timestart ) ).count() ) + " seconds" );
|
if (simulation::State.deserialize_continue(state))
|
||||||
// TODO: implement and use next mode cue
|
return true;
|
||||||
Global.random_seed = std::random_device{}();
|
}
|
||||||
Global.random_engine.seed(Global.random_seed);
|
catch (invalid_scenery_exception &e) {
|
||||||
Application.pop_mode();
|
ErrorLog( "Bad init: scenario loading failed" );
|
||||||
Application.push_mode( eu07_application::mode::driver );
|
Application.pop_mode();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
ErrorLog( "Bad init: scenario loading failed" );
|
WriteLog( "Scenario loading time: " + std::to_string( std::chrono::duration_cast<std::chrono::seconds>( ( std::chrono::system_clock::now() - timestart ) ).count() ) + " seconds" );
|
||||||
Application.pop_mode();
|
// TODO: implement and use next mode cue
|
||||||
}
|
|
||||||
|
Application.pop_mode();
|
||||||
|
Application.push_mode( eu07_application::mode::driver );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
scenarioloader_mode::is_command_processor() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// maintenance method, called when the mode is activated
|
// maintenance method, called when the mode is activated
|
||||||
void
|
void
|
||||||
scenarioloader_mode::enter() {
|
scenarioloader_mode::enter() {
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "applicationmode.h"
|
#include "applicationmode.h"
|
||||||
|
#include "simulation.h"
|
||||||
|
|
||||||
class scenarioloader_mode : public application_mode {
|
class scenarioloader_mode : public application_mode {
|
||||||
|
std::shared_ptr<simulation::deserializer_state> state;
|
||||||
|
std::chrono::system_clock::time_point timestart;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
@@ -40,4 +43,6 @@ public:
|
|||||||
on_scroll( double const Xoffset, double const Yoffset ) override { ; }
|
on_scroll( double const Xoffset, double const Yoffset ) override { ; }
|
||||||
void
|
void
|
||||||
on_event_poll() override { ; }
|
on_event_poll() override { ; }
|
||||||
|
bool
|
||||||
|
is_command_processor() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,10 +45,16 @@ TTrain *Train { nullptr };
|
|||||||
uint16_t prev_train_id { 0 };
|
uint16_t prev_train_id { 0 };
|
||||||
bool is_ready { false };
|
bool is_ready { false };
|
||||||
|
|
||||||
bool
|
std::shared_ptr<deserializer_state>
|
||||||
state_manager::deserialize( std::string const &Scenariofile ) {
|
state_manager::deserialize_begin(std::string const &Scenariofile) {
|
||||||
|
|
||||||
return m_serializer.deserialize( Scenariofile );
|
return m_serializer.deserialize_begin( Scenariofile );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
state_manager::deserialize_continue(std::shared_ptr<deserializer_state> state) {
|
||||||
|
|
||||||
|
return m_serializer.deserialize_continue(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stores class data in specified file, in legacy (text) format
|
// stores class data in specified file, in legacy (text) format
|
||||||
|
|||||||
11
simulation.h
11
simulation.h
@@ -26,9 +26,12 @@ public:
|
|||||||
update( double Deltatime, int Iterationcount );
|
update( double Deltatime, int Iterationcount );
|
||||||
void
|
void
|
||||||
update_clocks();
|
update_clocks();
|
||||||
// restores simulation data from specified file. returns: true on success, false otherwise
|
// starts deserialization from specified file, returns context pointer on success, throws otherwise
|
||||||
bool
|
std::shared_ptr<deserializer_state>
|
||||||
deserialize( std::string const &Scenariofile );
|
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
|
// stores class data in specified file, in legacy (text) format
|
||||||
void
|
void
|
||||||
export_as_text( std::string const &Scenariofile ) const;
|
export_as_text( std::string const &Scenariofile ) const;
|
||||||
@@ -63,6 +66,8 @@ extern TTrain *Train;
|
|||||||
extern uint16_t prev_train_id;
|
extern uint16_t prev_train_id;
|
||||||
extern bool is_ready;
|
extern bool is_ready;
|
||||||
|
|
||||||
|
class deserializer_state;
|
||||||
|
|
||||||
} // simulation
|
} // simulation
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -25,98 +25,87 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
namespace simulation {
|
namespace simulation {
|
||||||
|
|
||||||
bool
|
std::shared_ptr<deserializer_state>
|
||||||
state_serializer::deserialize( std::string const &Scenariofile ) {
|
state_serializer::deserialize_begin( std::string const &Scenariofile ) {
|
||||||
|
|
||||||
// TODO: move initialization to separate routine so we can reuse it
|
// TODO: move initialization to separate routine so we can reuse it
|
||||||
SafeDelete( Region );
|
SafeDelete( Region );
|
||||||
Region = new scene::basic_region();
|
Region = new scene::basic_region();
|
||||||
|
|
||||||
|
// NOTE: for the time being import from text format is a given, since we don't have full binary serialization
|
||||||
|
std::shared_ptr<deserializer_state> state =
|
||||||
|
std::make_shared<deserializer_state>(Scenariofile, cParser::buffer_FILE, Global.asCurrentSceneryPath, Global.bLoadTraction);
|
||||||
|
|
||||||
// TODO: check first for presence of serialized binary files
|
// TODO: check first for presence of serialized binary files
|
||||||
// if this fails, fall back on the legacy text format
|
// if this fails, fall back on the legacy text format
|
||||||
scene::scratch_data importscratchpad;
|
state->scratchpad.name = Scenariofile;
|
||||||
importscratchpad.name = Scenariofile;
|
|
||||||
if( Scenariofile != "$.scn" ) {
|
if( Scenariofile != "$.scn" ) {
|
||||||
// compilation to binary file isn't supported for rainsted-created overrides
|
// compilation to binary file isn't supported for rainsted-created overrides
|
||||||
// NOTE: we postpone actual loading of the scene until we process time, season and weather data
|
// NOTE: we postpone actual loading of the scene until we process time, season and weather data
|
||||||
importscratchpad.binary.terrain = Region->is_scene( Scenariofile ) ;
|
state->scratchpad.binary.terrain = Region->is_scene( Scenariofile ) ;
|
||||||
}
|
}
|
||||||
// NOTE: for the time being import from text format is a given, since we don't have full binary serialization
|
|
||||||
cParser scenarioparser( Scenariofile, cParser::buffer_FILE, Global.asCurrentSceneryPath, Global.bLoadTraction );
|
|
||||||
|
|
||||||
if( false == scenarioparser.ok() ) { return false; }
|
if( false == state->input.ok() )
|
||||||
|
throw invalid_scenery_exception();
|
||||||
|
|
||||||
deserialize( scenarioparser, importscratchpad );
|
// prepare deserialization function table
|
||||||
if( ( false == importscratchpad.binary.terrain )
|
// since all methods use the same objects, we can have simple, hard-coded binds or lambdas for the task
|
||||||
&& ( Scenariofile != "$.scn" ) ) {
|
using deserializefunction = void( state_serializer::*)(cParser &, scene::scratch_data &);
|
||||||
// if we didn't find usable binary version of the scenario files, create them now for future use
|
std::vector<
|
||||||
// as long as the scenario file wasn't rainsted-created base file override
|
std::pair<
|
||||||
Region->serialize( Scenariofile );
|
std::string,
|
||||||
}
|
deserializefunction> > functionlist = {
|
||||||
return true;
|
{ "area", &state_serializer::deserialize_area },
|
||||||
|
{ "atmo", &state_serializer::deserialize_atmo },
|
||||||
|
{ "camera", &state_serializer::deserialize_camera },
|
||||||
|
{ "config", &state_serializer::deserialize_config },
|
||||||
|
{ "description", &state_serializer::deserialize_description },
|
||||||
|
{ "event", &state_serializer::deserialize_event },
|
||||||
|
{ "lua", &state_serializer::deserialize_lua },
|
||||||
|
{ "firstinit", &state_serializer::deserialize_firstinit },
|
||||||
|
{ "group", &state_serializer::deserialize_group },
|
||||||
|
{ "endgroup", &state_serializer::deserialize_endgroup },
|
||||||
|
{ "light", &state_serializer::deserialize_light },
|
||||||
|
{ "node", &state_serializer::deserialize_node },
|
||||||
|
{ "origin", &state_serializer::deserialize_origin },
|
||||||
|
{ "endorigin", &state_serializer::deserialize_endorigin },
|
||||||
|
{ "rotate", &state_serializer::deserialize_rotate },
|
||||||
|
{ "sky", &state_serializer::deserialize_sky },
|
||||||
|
{ "test", &state_serializer::deserialize_test },
|
||||||
|
{ "time", &state_serializer::deserialize_time },
|
||||||
|
{ "trainset", &state_serializer::deserialize_trainset },
|
||||||
|
{ "endtrainset", &state_serializer::deserialize_endtrainset } };
|
||||||
|
|
||||||
|
for( auto &function : functionlist ) {
|
||||||
|
state->functionmap.emplace( function.first, std::bind( function.second, this, std::ref( state->input ), std::ref( state->scratchpad ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// restores class data from provided stream
|
// continues deserialization for given context, amount limited by time, returns true if needs to be called again
|
||||||
void
|
bool
|
||||||
state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_continue(std::shared_ptr<deserializer_state> state) {
|
||||||
|
cParser &Input = state->input;
|
||||||
// prepare deserialization function table
|
scene::scratch_data &Scratchpad = state->scratchpad;
|
||||||
// since all methods use the same objects, we can have simple, hard-coded binds or lambdas for the task
|
|
||||||
using deserializefunction = void( state_serializer::*)(cParser &, scene::scratch_data &);
|
|
||||||
std::vector<
|
|
||||||
std::pair<
|
|
||||||
std::string,
|
|
||||||
deserializefunction> > functionlist = {
|
|
||||||
{ "area", &state_serializer::deserialize_area },
|
|
||||||
{ "atmo", &state_serializer::deserialize_atmo },
|
|
||||||
{ "camera", &state_serializer::deserialize_camera },
|
|
||||||
{ "config", &state_serializer::deserialize_config },
|
|
||||||
{ "description", &state_serializer::deserialize_description },
|
|
||||||
{ "event", &state_serializer::deserialize_event },
|
|
||||||
{ "lua", &state_serializer::deserialize_lua },
|
|
||||||
{ "firstinit", &state_serializer::deserialize_firstinit },
|
|
||||||
{ "group", &state_serializer::deserialize_group },
|
|
||||||
{ "endgroup", &state_serializer::deserialize_endgroup },
|
|
||||||
{ "light", &state_serializer::deserialize_light },
|
|
||||||
{ "node", &state_serializer::deserialize_node },
|
|
||||||
{ "origin", &state_serializer::deserialize_origin },
|
|
||||||
{ "endorigin", &state_serializer::deserialize_endorigin },
|
|
||||||
{ "rotate", &state_serializer::deserialize_rotate },
|
|
||||||
{ "sky", &state_serializer::deserialize_sky },
|
|
||||||
{ "test", &state_serializer::deserialize_test },
|
|
||||||
{ "time", &state_serializer::deserialize_time },
|
|
||||||
{ "trainset", &state_serializer::deserialize_trainset },
|
|
||||||
{ "endtrainset", &state_serializer::deserialize_endtrainset } };
|
|
||||||
using deserializefunctionbind = std::function<void()>;
|
|
||||||
std::unordered_map<
|
|
||||||
std::string,
|
|
||||||
deserializefunctionbind> functionmap;
|
|
||||||
for( auto &function : functionlist ) {
|
|
||||||
functionmap.emplace( function.first, std::bind( function.second, this, std::ref( Input ), std::ref( Scratchpad ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// deserialize content from the provided input
|
// deserialize content from the provided input
|
||||||
auto
|
auto timelast { std::chrono::steady_clock::now() };
|
||||||
timelast { std::chrono::steady_clock::now() },
|
|
||||||
timenow { timelast };
|
|
||||||
std::string token { Input.getToken<std::string>() };
|
std::string token { Input.getToken<std::string>() };
|
||||||
while( false == token.empty() ) {
|
while( false == token.empty() ) {
|
||||||
|
|
||||||
auto lookup = functionmap.find( token );
|
auto lookup = state->functionmap.find( token );
|
||||||
if( lookup != functionmap.end() ) {
|
if( lookup != state->functionmap.end() ) {
|
||||||
lookup->second();
|
lookup->second();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad scenario: unexpected token \"" + token + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
|
ErrorLog( "Bad scenario: unexpected token \"" + token + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
|
||||||
}
|
}
|
||||||
|
|
||||||
timenow = std::chrono::steady_clock::now();
|
auto timenow = std::chrono::steady_clock::now();
|
||||||
if( std::chrono::duration_cast<std::chrono::milliseconds>( timenow - timelast ).count() >= 200 ) {
|
if( std::chrono::duration_cast<std::chrono::milliseconds>( timenow - timelast ).count() >= 200 ) {
|
||||||
timelast = timenow;
|
|
||||||
glfwPollEvents();
|
|
||||||
Application.set_progress( Input.getProgress(), Input.getFullProgress() );
|
Application.set_progress( Input.getProgress(), Input.getFullProgress() );
|
||||||
GfxRenderer.Render();
|
return true;
|
||||||
GfxRenderer.SwapBuffers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token = Input.getToken<std::string>();
|
token = Input.getToken<std::string>();
|
||||||
@@ -129,6 +118,15 @@ state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad )
|
|||||||
|
|
||||||
if (Global.map_enabled)
|
if (Global.map_enabled)
|
||||||
Region->create_map_geometry();
|
Region->create_map_geometry();
|
||||||
|
|
||||||
|
if( ( false == state->scratchpad.binary.terrain )
|
||||||
|
&& ( state->scenariofile != "$.scn" ) ) {
|
||||||
|
// if we didn't find usable binary version of the scenario files, create them now for future use
|
||||||
|
// as long as the scenario file wasn't rainsted-created base file override
|
||||||
|
Region->serialize( state->scenariofile );
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -14,21 +14,37 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
namespace simulation {
|
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;
|
||||||
|
|
||||||
|
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 {
|
class state_serializer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
// restores simulation data from specified file. returns: true on success, false otherwise
|
// starts deserialization from specified file, returns context pointer on success, throws otherwise
|
||||||
bool
|
std::shared_ptr<deserializer_state>
|
||||||
deserialize( std::string const &Scenariofile );
|
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
|
// stores class data in specified file, in legacy (text) format
|
||||||
void
|
void
|
||||||
export_as_text( std::string const &Scenariofile ) const;
|
export_as_text( std::string const &Scenariofile ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// methods
|
// methods
|
||||||
// restores class data from provided stream
|
// restores class data from provided stream
|
||||||
void deserialize( cParser &Input, scene::scratch_data &Scratchpad );
|
|
||||||
void deserialize_area( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_area( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_atmo( 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_camera( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
|
|||||||
Reference in New Issue
Block a user