diff --git a/DynObj.cpp b/DynObj.cpp index 9a6c7e7f..dbdbb31e 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -7333,8 +7333,11 @@ vehicle_table::erase_disabled() { && ( simulation::Train->Dynamic() == vehicle ) ) { // clear potential train binding // TBD, TODO: kill vehicle sounds - SafeDelete( simulation::Train ); + simulation::Train = nullptr; } + + simulation::Trains.purge(vehicle->name()); + // remove potential entries in the light array simulation::Lights.remove( vehicle ); /* diff --git a/Event.cpp b/Event.cpp index b1bd3429..a32a8af6 100644 --- a/Event.cpp +++ b/Event.cpp @@ -2032,17 +2032,32 @@ event_manager::insert( basic_event *Event ) { return true; } +basic_event * event_manager::FindEventById(uint32_t id) +{ + if (id < m_eventmap.size()) + return m_events[id]; + else + return nullptr; +} + +uint32_t event_manager::GetEventId(const basic_event *ev) { + return GetEventId(ev->m_name); +} + +uint32_t event_manager::GetEventId(const std::string &Name) +{ + if (Name.empty()) + return -1; + + auto const lookup = m_eventmap.find(Name); + return lookup != m_eventmap.end() ? lookup->second : -1; +} + // legacy method, returns pointer to specified event, or null basic_event * -event_manager::FindEvent( std::string const &Name ) { - - if( Name.empty() ) { return nullptr; } - - auto const lookup = m_eventmap.find( Name ); - return ( - lookup != m_eventmap.end() ? - m_events[ lookup->second ] : - nullptr ); +event_manager::FindEvent( std::string const &Name ) +{ + return FindEventById(GetEventId(Name)); } // legacy method, inserts specified event in the event query diff --git a/Event.h b/Event.h index ae7cacfd..199e54af 100644 --- a/Event.h +++ b/Event.h @@ -590,6 +590,12 @@ public: basic_event * begin() { return QueryRootEvent; } + + basic_event* + FindEventById(uint32_t id); + uint32_t GetEventId(const basic_event *ev); + uint32_t GetEventId(std::string const &Name); + // legacy method, returns pointer to specified event, or null basic_event * FindEvent( std::string const &Name ); diff --git a/Globals.cpp b/Globals.cpp index 638e47d1..138b6a98 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -778,20 +778,25 @@ global_settings::ConfigParse(cParser &Parser) { Parser.getTokens(1); Parser >> python_mipmaps; } - else if (token == "network.enabled") - { - Parser.getTokens(1); - Parser >> network_conf.enabled; - } else if (token == "network.server") { Parser.getTokens(1); Parser >> network_conf.is_server; + if (network_conf.is_server) { + Parser.getTokens(2); + Parser >> network_conf.server_host; + Parser >> network_conf.server_port; + } } else if (token == "network.client") { Parser.getTokens(1); Parser >> network_conf.is_client; + if (network_conf.is_client) { + Parser.getTokens(2); + Parser >> network_conf.client_host; + Parser >> network_conf.client_port; + } } } while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile) // na koniec trochę zależności diff --git a/Globals.h b/Globals.h index 4844ec38..00aa629b 100644 --- a/Globals.h +++ b/Globals.h @@ -197,9 +197,13 @@ struct global_settings { bool gfx_usegles = false; struct network_conf_t { - bool enabled = false; bool is_server = false; + std::string server_host; + uint32_t server_port; + bool is_client = false; + std::string client_host; + uint32_t client_port; } network_conf; // methods diff --git a/Names.h b/Names.h index ff76d833..23eae828 100644 --- a/Names.h +++ b/Names.h @@ -41,6 +41,18 @@ public: { return insert(Item, Item->name()); } + void purge (std::string const &Name) + { + auto lookup = m_itemmap.find( Name ); + if (lookup == m_itemmap.end()) + return; + + delete m_items[lookup->second]; + m_items[lookup->second] = nullptr; + // TBD, TODO: remove from m_items? + + m_itemmap.erase(lookup); + } // locates item with specified name. returns pointer to the item, or nullptr Type_ * find( std::string const &Name ) const { diff --git a/Train.cpp b/Train.cpp index 3956d5c9..a44dafa7 100644 --- a/Train.cpp +++ b/Train.cpp @@ -8050,10 +8050,9 @@ int TTrain::get_drive_direction() } uint16_t TTrain::id() { - static uint16_t i = 0; // todo: do something better if (vid == 0) { - vid = ++i; - WriteLog("assigning id " + std::to_string(vid) + " to vehicle " + Dynamic()->name()); + vid = ++simulation::prev_train_id; + WriteLog("net: assigning id " + std::to_string(vid) + " to vehicle " + Dynamic()->name(), logtype::net); } return vid; } @@ -8061,6 +8060,8 @@ uint16_t TTrain::id() { void train_table::update(double dt) { for (TTrain *train : m_items) { + if (!train) + continue; train->Update(dt); } } diff --git a/Train.h b/Train.h index 80a29bb0..774fc40c 100644 --- a/Train.h +++ b/Train.h @@ -653,7 +653,7 @@ private: float m_mastercontrollerreturndelay { 0.f }; int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego std::vector>> m_screens; - uint16_t vid = 0; + uint16_t vid { 0 }; public: float fPress[20][3]; // cisnienia dla wszystkich czlonow diff --git a/application.cpp b/application.cpp index 3878caeb..1526e45b 100644 --- a/application.cpp +++ b/application.cpp @@ -144,29 +144,6 @@ eu07_application::init( int Argc, char *Argv[] ) { return result; } -void eu07_application::request_train(std::string name) { - m_network->request_train(name); -} - -void eu07_application::spawn_train(std::string name) { - TTrain *train = simulation::Trains.find(name); - if (train) - return; - - TDynamicObject *dynobj = simulation::Vehicles.find(name); - if (!dynobj) - return; - - train = new TTrain(); - if (train->Init(dynobj)) { - simulation::Trains.insert(train, name); - } - else { - delete train; - train = nullptr; - } -} - double eu07_application::generate_sync() { if (Timer::GetDeltaTime() == 0.0) return 0.0; @@ -709,7 +686,7 @@ eu07_application::init_modes() { } bool eu07_application::init_network() { - if (Global.network_conf.enabled) { + if (Global.network_conf.is_server || Global.network_conf.is_client) { m_network.emplace(); if (Global.network_conf.is_server) { m_network->create_server(); diff --git a/application.h b/application.h index af1d38ac..2da6655a 100644 --- a/application.h +++ b/application.h @@ -76,8 +76,6 @@ public: GLFWwindow * window( int const Windowindex = 0 ); - void request_train(std::string name); - void spawn_train(std::string name); double generate_sync(); private: diff --git a/command.cpp b/command.cpp index 86c1c7f7..c5d9bd74 100644 --- a/command.cpp +++ b/command.cpp @@ -227,6 +227,9 @@ commanddescription_sequence Commands_descriptions = { { "vehiclemovebackwards", command_target::vehicle, command_mode::oneoff }, { "vehicleboost", command_target::vehicle, command_mode::oneoff }, { "debugtoggle", command_target::simulation, command_mode::oneoff }, + { "pausetoggle", command_target::simulation, command_mode::oneoff }, + { "entervehicle", command_target::simulation, command_mode::oneoff }, + { "queueevent", command_target::simulation, command_mode::oneoff }, }; } // simulation diff --git a/command.h b/command.h index 53723dc5..61b10e26 100644 --- a/command.h +++ b/command.h @@ -221,6 +221,9 @@ enum class user_command { vehiclemovebackwards, vehicleboost, debugtoggle, + pausetoggle, + entervehicle, + queueevent, none = -1 }; diff --git a/driverkeyboardinput.cpp b/driverkeyboardinput.cpp index 78f3bd8b..372de817 100644 --- a/driverkeyboardinput.cpp +++ b/driverkeyboardinput.cpp @@ -228,6 +228,7 @@ driverkeyboard_input::default_bindings() { { user_command::vehiclemovebackwards, GLFW_KEY_RIGHT_BRACKET | keymodifier::control }, { user_command::vehicleboost, GLFW_KEY_TAB | keymodifier::control }, { user_command::debugtoggle, GLFW_KEY_F12 | keymodifier::control | keymodifier::shift }, + { user_command::pausetoggle, GLFW_KEY_ESCAPE } }; } diff --git a/drivermode.cpp b/drivermode.cpp index 9790c220..e7f49d34 100644 --- a/drivermode.cpp +++ b/drivermode.cpp @@ -206,6 +206,7 @@ driver_mode::update() { // render time routines follow: auto const deltarealtime = Timer::GetDeltaRenderTime(); // nie uwzględnia pauzowania ani mnożenia czasu + simulation::State.process_commands(); // fixed step render time routines @@ -248,27 +249,6 @@ driver_mode::update() { return true; } -TTrain* driver_mode::request_train(TDynamicObject *dynamic) { - TTrain *train = simulation::Trains.find(dynamic->name()); - if (train) - return train; - - if (!Global.network_conf.enabled) { - train = new TTrain(); - if (train->Init(dynamic)) { - simulation::Trains.insert(train, dynamic->name()); - } - else { - delete train; - train = nullptr; - } - return train; - } else { - Application.request_train(dynamic->name()); - } - return train; -} - // maintenance method, called when the mode is activated void driver_mode::enter() { @@ -280,27 +260,21 @@ driver_mode::enter() { Camera.Init(Global.FreeCameraInit[0], Global.FreeCameraInitAngle[0], nPlayerTrain ); Global.pCamera = Camera; - Global.pDebugCamera = DebugCamera; + Global.pDebugCamera = DebugCamera; if (nPlayerTrain) { + // M7TODO: restore + /* WriteLog( "Initializing player train, \"" + Global.asHumanCtrlVehicle + "\"" ); - TTrain *train = request_train(nPlayerTrain); - if (train->Init(nPlayerTrain)) { - simulation::Train = train; + Global.pCamera.Pos = nPlayerTrain->GetPosition(); + m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0); + */ - WriteLog("Player train initialization OK"); - Application.set_title( Global.AppName + " (" + simulation::Train->Controlled()->Name + " @ " + Global.SceneryFile + ")" ); - CabView(); - } - else { - delete train; - - Error("Bad init: player train initialization failed"); - FreeFlyModeFlag = true; // Ra: automatycznie włączone latanie - Camera.m_owner = nullptr; - } + FreeFlyModeFlag = true; + Camera.m_owner = nullptr; + DebugCamera = Camera; } else { @@ -327,8 +301,6 @@ driver_mode::enter() { KeyEvents[ 9 ] = simulation::Events.FindEvent( "keyctrl09" ); } - //ui_log->enabled = false; - Timer::ResetTimers(); set_picking( Global.ControlPicking ); @@ -666,7 +638,7 @@ driver_mode::OnKeyDown(int cKey) { // z [Shift] uruchomienie eventu if( ( false == Global.iPause ) // podczas pauzy klawisze nie działają && ( KeyEvents[ i ] != nullptr ) ) { - simulation::Events.AddToQuery( KeyEvents[ i ], NULL ); + m_relay.post(user_command::queueevent, (double)simulation::Events.GetEventId(KeyEvents[i]), 0.0, GLFW_PRESS, 0); } } else if( Global.ctrlState ) { @@ -708,33 +680,20 @@ driver_mode::OnKeyDown(int cKey) { break; } case GLFW_KEY_F5: { - // przesiadka do innego pojazdu - if( false == FreeFlyModeFlag ) { - // only available in free fly mode - break; - } + // przesiadka do innego pojazdu + if (!FreeFlyModeFlag) + // only available in free fly mode + break; - TDynamicObject *tmp = std::get( simulation::Region->find_vehicle( Global.pCamera.Pos, 50, true, false ) ); + TDynamicObject *dynamic = std::get( simulation::Region->find_vehicle( Global.pCamera.Pos, 50, true, false ) ); + TTrain *train = simulation::Trains.find(dynamic->name()); + if (train) { + simulation::Train = train; + InOutKey(); + } else { + m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0); + } - if( tmp != nullptr ) { - - if( ( true == DebugModeFlag ) - || ( tmp->MoverParameters->Vel <= 5.0 ) ) { - TTrain *train = request_train(tmp); - if (train != nullptr) { - /* - if( simulation::Train ) {// jeśli mielismy pojazd - if( simulation::Train->Dynamic()->Mechanik ) { // na skutek jakiegoś błędu może czasem zniknąć - simulation::Train->Dynamic()->Mechanik->TakeControl( true ); // oddajemy dotychczasowy AI - } - } - train->Dynamic()->Mechanik->TakeControl( false ); - */ - simulation::Train = train; - InOutKey(); - } - } - } break; } case GLFW_KEY_F6: { diff --git a/drivermode.h b/drivermode.h index c2b6779f..734df796 100644 --- a/drivermode.h +++ b/drivermode.h @@ -91,8 +91,7 @@ private: void CabView(); void ExternalView(); void DistantView( bool const Near = false ); - void set_picking( bool const Picking ); - TTrain* request_train(TDynamicObject *dynamic); + void set_picking( bool const Picking ); // members drivermode_input m_input; @@ -109,4 +108,5 @@ private: double m_primaryupdateaccumulator { m_secondaryupdaterate }; // keeps track of elapsed simulation time, for core fixed step routines double m_secondaryupdateaccumulator { m_secondaryupdaterate }; // keeps track of elapsed simulation time, for less important fixed step routines int iPause { 0 }; // wykrywanie zmian w zapauzowaniu + command_relay m_relay; }; diff --git a/driveruilayer.cpp b/driveruilayer.cpp index 27a60176..29a6c937 100644 --- a/driveruilayer.cpp +++ b/driveruilayer.cpp @@ -60,22 +60,6 @@ driver_ui::on_key( int const Key, int const Action ) { if (ui_layer::on_key(Key, Action)) return true; - if( Key == GLFW_KEY_ESCAPE ) { - // toggle pause - if( Action != GLFW_PRESS ) { return true; } // recognized, but ignored - - if( Global.iPause & 1 ) { - // jeśli pauza startowa - // odpauzowanie, gdy po wczytaniu miało nie startować - Global.iPause ^= 1; - } - else if( ( Global.iMultiplayer & 2 ) == 0 ) { - // w multiplayerze pauza nie ma sensu - Global.iPause ^= 2; // zmiana stanu zapauzowania - } - return true; - } - switch( Key ) { case GLFW_KEY_F1: @@ -219,8 +203,7 @@ driver_ui::render_() { if( ImGui::BeginPopupModal( popupheader, &m_pause_modal_opened, ImGuiWindowFlags_AlwaysAutoResize ) ) { auto const popupwidth{ locale::strings[ locale::string::driver_pause_header ].size() * 7 }; if( ImGui::Button( locale::strings[ locale::string::driver_pause_resume ].c_str(), ImVec2( popupwidth, 0 ) ) ) { - auto const pausemask { 1 | 2 }; - Global.iPause &= ~pausemask; + m_relay.post(user_command::pausetoggle, 0.0, 0.0, GLFW_PRESS, 0); } if( ImGui::Button( locale::strings[ locale::string::driver_pause_quit ].c_str(), ImVec2( popupwidth, 0 ) ) ) { glfwSetWindowShouldClose( m_window, 1 ); diff --git a/driveruilayer.h b/driveruilayer.h index ff3f6cfd..a7a34ade 100644 --- a/driveruilayer.h +++ b/driveruilayer.h @@ -53,5 +53,6 @@ private: bool m_paused { false }; bool m_pause_modal_opened { false }; + command_relay m_relay; ui::vehiclelist_panel m_vehiclelist; }; diff --git a/keyboardinput.cpp b/keyboardinput.cpp index d496b22d..e3663b61 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -63,7 +63,7 @@ keyboard_input::recall_bindings() { // misc { "f1", GLFW_KEY_F1 }, { "f2", GLFW_KEY_F2 }, { "f3", GLFW_KEY_F3 }, { "f4", GLFW_KEY_F4 }, { "f5", GLFW_KEY_F5 }, { "f6", GLFW_KEY_F6 }, { "f7", GLFW_KEY_F7 }, { "f8", GLFW_KEY_F8 }, { "f9", GLFW_KEY_F9 }, { "f10", GLFW_KEY_F10 }, - { "f11", GLFW_KEY_F11 }, { "f12", GLFW_KEY_F12 }, { "tab", GLFW_KEY_TAB } + { "f11", GLFW_KEY_F11 }, { "f12", GLFW_KEY_F12 }, { "tab", GLFW_KEY_TAB }, { "esc", GLFW_KEY_ESCAPE } }; // NOTE: to simplify things we expect one entry per line, and whole entry in one line diff --git a/messaging.cpp b/messaging.cpp index 8d97166b..01a457a6 100644 --- a/messaging.cpp +++ b/messaging.cpp @@ -68,7 +68,8 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz) || ( typeid( *event ) == typeid( lights_event ) ) || ( event->m_sibling != 0 ) ) { // tylko jawne albo niejawne Multiple - simulation::Events.AddToQuery( event, nullptr ); // drugi parametr to dynamic wywołujący - tu brak + command_relay relay; + relay.post(user_command::queueevent, (double)simulation::Events.GetEventId(event), 0.0, GLFW_PRESS, 0); } } } diff --git a/network/manager.cpp b/network/manager.cpp index 292f6df7..2295ad6d 100644 --- a/network/manager.cpp +++ b/network/manager.cpp @@ -40,29 +40,3 @@ void network::manager::send_commands(command_queue::commands_map commands) { client->send_commands(commands); } - -void network::manager::request_train(std::string name) -{ - if (server) { - TTrain *train = simulation::Trains.find(name); - if (train) - return; - - TDynamicObject *dynobj = simulation::Vehicles.find(name); - if (!dynobj) - return; - - train = new TTrain(); - if (train->Init(dynobj)) { - simulation::Trains.insert(train, name); - server->notify_train(name); - } - else { - delete train; - train = nullptr; - } - } - if (client) { - client->request_train(name); - } -} diff --git a/network/manager.h b/network/manager.h index 3127556a..e0f8ec9d 100644 --- a/network/manager.h +++ b/network/manager.h @@ -24,6 +24,5 @@ namespace network void push_delta(double delta, double sync, command_queue::commands_map commands); command_queue::commands_map pop_commands(); void send_commands(command_queue::commands_map commands); - void request_train(std::string name); }; } diff --git a/network/message.cpp b/network/message.cpp index 2893a813..f03be69b 100644 --- a/network/message.cpp +++ b/network/message.cpp @@ -144,12 +144,6 @@ std::shared_ptr network::deserialize_message(std::istream &str m->deserialize(stream); msg = m; } - else if (type == message::REQUEST_SPAWN_TRAIN || type == message::SPAWN_TRAIN) { - auto m = std::make_shared(type); - m->type = type; - m->deserialize(stream); - msg = m; - } else { msg = std::make_shared(type); } diff --git a/network/message.h b/network/message.h index f483e46d..13a215da 100644 --- a/network/message.h +++ b/network/message.h @@ -13,8 +13,6 @@ namespace network CONNECT_ACCEPT, STEP_INFO, CLIENT_COMMAND, - REQUEST_SPAWN_TRAIN, - SPAWN_TRAIN, TYPE_MAX }; diff --git a/network/network.cpp b/network/network.cpp index fc946e82..78c505a2 100644 --- a/network/network.cpp +++ b/network/network.cpp @@ -5,11 +5,15 @@ #include "Timer.h" #include "application.h" +network::connection::connection(bool client) { + is_client = client; +} + void network::connection::connected() { WriteLog("net: socket connected", logtype::net); - if (!Global.network_conf.is_server) { + if (is_client) { std::shared_ptr hello = std::make_shared(message::CONNECT_REQUEST); send_message(hello); } @@ -52,16 +56,6 @@ void network::connection::message_received(std::shared_ptr &msg) auto now = std::chrono::high_resolution_clock::now(); delta_queue.push(std::make_pair(now, delta)); } - else if (msg->type == message::REQUEST_SPAWN_TRAIN) - { - auto req = std::dynamic_pointer_cast(msg); - Application.request_train(req->name); - } - else if (msg->type == message::SPAWN_TRAIN) - { - auto req = std::dynamic_pointer_cast(msg); - Application.spawn_train(req->name); - } } std::tuple network::connection::get_next_delta() @@ -125,6 +119,9 @@ network::server::server() void network::server::push_delta(double dt, double sync, command_queue::commands_map commands) { + if (dt == 0.0 && commands.empty()) + return; + std::shared_ptr msg = std::make_shared(); msg->dt = dt; msg->sync = sync; @@ -140,15 +137,6 @@ void network::server::push_delta(double dt, double sync, command_queue::commands c->send_message(msg); } -void network::server::notify_train(std::string name) -{ - std::shared_ptr msg = std::make_shared(message::SPAWN_TRAIN); - msg->name = name; - - for (auto c : clients) - c->send_message(msg); -} - command_queue::commands_map network::server::pop_commands() { command_queue::commands_map map; @@ -178,11 +166,3 @@ void network::client::send_commands(command_queue::commands_map commands) conn->send_message(msg); } - -void network::client::request_train(std::string name) -{ - std::shared_ptr msg = std::make_shared(message::REQUEST_SPAWN_TRAIN); - msg->name = name; - - conn->send_message(msg); -} diff --git a/network/network.h b/network/network.h index bac8de22..f69ef61c 100644 --- a/network/network.h +++ b/network/network.h @@ -19,6 +19,7 @@ namespace network std::shared_ptr>> delta_queue; command_queue::commands_map client_commands_queue; + bool is_client; //std::chrono::high_resolution_clock::time_point last_time; //double accum = -1.0; @@ -30,6 +31,7 @@ namespace network void data_received(std::string &buffer); public: + connection(bool client = false); void send_message(std::shared_ptr msg); virtual void connected(); @@ -47,7 +49,6 @@ namespace network server(); void push_delta(double dt, double sync, command_queue::commands_map commands); command_queue::commands_map pop_commands(); - void notify_train(std::string name); }; class client @@ -58,6 +59,5 @@ namespace network public: std::tuple get_next_delta(); void send_commands(command_queue::commands_map commands); - void request_train(std::string name); }; } diff --git a/network/tcp.cpp b/network/tcp.cpp index 03ddac58..b8ec9be6 100644 --- a/network/tcp.cpp +++ b/network/tcp.cpp @@ -1,9 +1,10 @@ #include "network/tcp.h" #include "Logs.h" #include "sn_utils.h" +#include "Globals.h" -network::tcp_conn::tcp_conn(asio::io_context &io_ctx) - : m_socket(io_ctx) +network::tcp_conn::tcp_conn(asio::io_context &io_ctx, bool client) + : connection(client), m_socket(io_ctx) { m_header_buffer.resize(8); } @@ -82,10 +83,9 @@ asio::ip::tcp::socket& network::tcp_conn::socket() network::tcp_server::tcp_server(asio::io_context &io_ctx) : m_acceptor(io_ctx) { - auto endpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v6(), 7424); + auto endpoint = asio::ip::tcp::endpoint(asio::ip::address::from_string(Global.network_conf.server_host), Global.network_conf.server_port); m_acceptor.open(endpoint.protocol()); m_acceptor.set_option(asio::socket_base::reuse_address(true)); - m_acceptor.set_option(asio::ip::v6_only(false)); m_acceptor.set_option(asio::ip::tcp::no_delay(true)); m_acceptor.bind(endpoint); m_acceptor.listen(10); @@ -117,11 +117,11 @@ void network::tcp_server::handle_accept(std::shared_ptr conn, const as network::tcp_client::tcp_client(asio::io_context &io_ctx) { - conn = std::make_shared(io_ctx); + conn = std::make_shared(io_ctx, true); auto tcpconn = std::static_pointer_cast(conn); asio::ip::tcp::endpoint endpoint( - asio::ip::address::from_string("192.168.0.20"), 7424); + asio::ip::address::from_string(Global.network_conf.client_host), Global.network_conf.client_port); tcpconn->socket().open(endpoint.protocol()); tcpconn->socket().set_option(asio::ip::tcp::no_delay(true)); tcpconn->socket().async_connect(endpoint, diff --git a/network/tcp.h b/network/tcp.h index cf6ae0ed..bf741dd9 100644 --- a/network/tcp.h +++ b/network/tcp.h @@ -26,7 +26,7 @@ namespace network void send_data(std::shared_ptr buffer) override; public: - tcp_conn(asio::io_context &io_ctx); + tcp_conn(asio::io_context &io_ctx, bool client = false); asio::ip::tcp::socket& socket(); void connected() override; diff --git a/simulation.cpp b/simulation.cpp index 518ef152..505be766 100644 --- a/simulation.cpp +++ b/simulation.cpp @@ -42,6 +42,7 @@ lua Lua; scene::basic_region *Region { nullptr }; TTrain *Train { nullptr }; +uint16_t prev_train_id { 0 }; bool is_ready { false }; bool @@ -60,13 +61,6 @@ state_manager::export_as_text( std::string const &Scenariofile ) const { // legacy method, calculates changes in simulation state over specified time void state_manager::update( double const Deltatime, int Iterationcount ) { - // aktualizacja animacji krokiem FPS: dt=krok czasu [s], dt*iter=czas od ostatnich przeliczeń - if (Deltatime == 0.0) { - return; - } - - process_commands(); - auto const totaltime { Deltatime * Iterationcount }; // NOTE: we perform animations first, as they can determine factors like contact with powergrid TAnimModel::AnimUpdate( totaltime ); // wykonanie zakolejkowanych animacji @@ -84,6 +78,51 @@ void state_manager::process_commands() { if (commanddata.command == user_command::debugtoggle) DebugModeFlag = !DebugModeFlag; + if (commanddata.command == user_command::pausetoggle) { + if( Global.iPause & 1 ) { + // jeśli pauza startowa + // odpauzowanie, gdy po wczytaniu miało nie startować + Global.iPause ^= 1; + } + else { + Global.iPause ^= 2; // zmiana stanu zapauzowania + } + } + + if (commanddata.command == user_command::entervehicle) { + // przesiadka do innego pojazdu + if (!commanddata.freefly) + // only available in free fly mode + continue; + + TDynamicObject *dynamic = std::get( simulation::Region->find_vehicle( commanddata.location, 50, true, false ) ); + + if (!dynamic) + continue; + + TTrain *train = simulation::Trains.find(dynamic->name()); + if (train) + continue; + + if( ( true == DebugModeFlag ) + || ( dynamic->MoverParameters->Vel <= 5.0 ) ) { + train = new TTrain(); + if (train->Init(dynamic)) { + simulation::Trains.insert(train, dynamic->name()); + } + else { + delete train; + train = nullptr; + } + } + } + + if (commanddata.command == user_command::queueevent) { + uint32_t id = std::round(commanddata.param1); + basic_event *ev = Events.FindEventById(id); + Events.AddToQuery(ev, nullptr); + } + if (DebugModeFlag) { if (commanddata.command == user_command::timejump) { Time.update(commanddata.param1); diff --git a/simulation.h b/simulation.h index 1520374a..5b144dad 100644 --- a/simulation.h +++ b/simulation.h @@ -32,12 +32,13 @@ public: // stores class data in specified file, in legacy (text) format void export_as_text( std::string const &Scenariofile ) const; + // process input commands + void + process_commands(); private: // members state_serializer m_serializer; - - void process_commands(); }; // passes specified sound to all vehicles within range as a radio message broadcasted on specified channel @@ -59,6 +60,7 @@ extern lua Lua; extern scene::basic_region *Region; extern TTrain *Train; +extern uint16_t prev_train_id; extern bool is_ready; } // simulation diff --git a/widgets/vehiclelist.cpp b/widgets/vehiclelist.cpp index 916c3ecb..7c3d2dc6 100644 --- a/widgets/vehiclelist.cpp +++ b/widgets/vehiclelist.cpp @@ -4,7 +4,7 @@ #include "Driver.h" void ui::vehiclelist_panel::render_contents() { - for (const TDynamicObject* vehicle : simulation::Vehicles.sequence()) { + for (TDynamicObject* vehicle : simulation::Vehicles.sequence()) { if (vehicle->Prev()) continue;