mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 08:39:18 +02:00
work
This commit is contained in:
@@ -22,7 +22,8 @@ file(GLOB HEADERS "*.h"
|
|||||||
"Console/*.h"
|
"Console/*.h"
|
||||||
"McZapkie/*.h"
|
"McZapkie/*.h"
|
||||||
"gl/*.h"
|
"gl/*.h"
|
||||||
"network/*.h")
|
"network/*.h"
|
||||||
|
"widgets/*.h")
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
"Texture.cpp"
|
"Texture.cpp"
|
||||||
@@ -118,6 +119,8 @@ set(SOURCES
|
|||||||
"network/tcp.cpp"
|
"network/tcp.cpp"
|
||||||
"network/manager.cpp"
|
"network/manager.cpp"
|
||||||
|
|
||||||
|
"widgets/vehiclelist.cpp"
|
||||||
|
|
||||||
"ref/glad/src/glad.c"
|
"ref/glad/src/glad.c"
|
||||||
|
|
||||||
"gl/shader.cpp"
|
"gl/shader.cpp"
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ void TCamera::Update()
|
|||||||
command_data command;
|
command_data command;
|
||||||
// NOTE: currently we're only storing commands for local entity and there's no id system in place,
|
// NOTE: currently we're only storing commands for local entity and there's no id system in place,
|
||||||
// so we're supplying 'default' entity id of 0
|
// so we're supplying 'default' entity id of 0
|
||||||
while( simulation::Commands.pop( command, static_cast<std::size_t>( command_target::entity ) | 0 ) ) {
|
while( simulation::Commands->pop( command, static_cast<std::size_t>( command_target::entity ) | 0 ) ) {
|
||||||
|
|
||||||
OnCommand( command );
|
OnCommand( command );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3856,7 +3856,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
IsLineBreakerClosed = ( mvOccupied->Power > 0.01 ? mvOccupied->Mains : true );
|
IsLineBreakerClosed = ( mvOccupied->Power > 0.01 ? mvOccupied->Mains : true );
|
||||||
p = pVehicle;
|
p = pVehicle;
|
||||||
while( ( true == IsLineBreakerClosed )
|
while( ( true == IsLineBreakerClosed )
|
||||||
&& ( ( p = p->PrevC( coupling::control) ) != nullptr ) ) {
|
&& ( ( p = p->Prev( coupling::control) ) != nullptr ) ) {
|
||||||
auto const *vehicle { p->MoverParameters };
|
auto const *vehicle { p->MoverParameters };
|
||||||
if( vehicle->Power > 0.01 ) {
|
if( vehicle->Power > 0.01 ) {
|
||||||
IsLineBreakerClosed = ( IsLineBreakerClosed && vehicle->Mains );
|
IsLineBreakerClosed = ( IsLineBreakerClosed && vehicle->Mains );
|
||||||
@@ -3864,7 +3864,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
}
|
}
|
||||||
p = pVehicle;
|
p = pVehicle;
|
||||||
while( ( true == IsLineBreakerClosed )
|
while( ( true == IsLineBreakerClosed )
|
||||||
&& ( ( p = p->NextC( coupling::control ) ) != nullptr ) ) {
|
&& ( ( p = p->Next( coupling::control ) ) != nullptr ) ) {
|
||||||
auto const *vehicle { p->MoverParameters };
|
auto const *vehicle { p->MoverParameters };
|
||||||
if( vehicle->Power > 0.01 ) {
|
if( vehicle->Power > 0.01 ) {
|
||||||
IsLineBreakerClosed = ( IsLineBreakerClosed && vehicle->Mains );
|
IsLineBreakerClosed = ( IsLineBreakerClosed && vehicle->Mains );
|
||||||
|
|||||||
34
DynObj.cpp
34
DynObj.cpp
@@ -3002,7 +3002,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
// 2. ustal mozliwa do realizacji sile hamowania ED
|
// 2. ustal mozliwa do realizacji sile hamowania ED
|
||||||
// - w szczegolnosci powinien brac pod uwage rozne sily hamowania
|
// - w szczegolnosci powinien brac pod uwage rozne sily hamowania
|
||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||||||
(kier ? p = p->NextC(4) : p = p->PrevC(4)))
|
(kier ? p = p->Next(4) : p = p->Prev(4)))
|
||||||
{
|
{
|
||||||
++np;
|
++np;
|
||||||
masamax +=
|
masamax +=
|
||||||
@@ -3122,7 +3122,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
// 1. najpierw daj kazdemu tyle samo
|
// 1. najpierw daj kazdemu tyle samo
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||||||
p = (kier == true ? p->NextC(4) : p->PrevC(4)) )
|
p = (kier == true ? p->Next(4) : p->Prev(4)) )
|
||||||
{
|
{
|
||||||
auto const Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
auto const Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
||||||
p->MoverParameters->BrakeCylSpring) *
|
p->MoverParameters->BrakeCylSpring) *
|
||||||
@@ -3150,7 +3150,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
i = 0;
|
i = 0;
|
||||||
float przek = 0;
|
float przek = 0;
|
||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||||||
p = (kier == true ? p->NextC(4) : p->PrevC(4)) )
|
p = (kier == true ? p->Next(4) : p->Prev(4)) )
|
||||||
{
|
{
|
||||||
if ((FzEP[i] > 0.01) &&
|
if ((FzEP[i] > 0.01) &&
|
||||||
(FzEP[i] >
|
(FzEP[i] >
|
||||||
@@ -3176,7 +3176,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
i = 0;
|
i = 0;
|
||||||
przek = przek / (np - nPrzekrF);
|
przek = przek / (np - nPrzekrF);
|
||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||||||
(true == kier ? p = p->NextC(4) : p = p->PrevC(4)))
|
(true == kier ? p = p->Next(4) : p = p->Prev(4)))
|
||||||
{
|
{
|
||||||
if (!PrzekrF[i])
|
if (!PrzekrF[i])
|
||||||
{
|
{
|
||||||
@@ -3187,7 +3187,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||||||
(true == kier ? p = p->NextC(4) : p = p->PrevC(4)))
|
(true == kier ? p = p->Next(4) : p = p->Prev(4)))
|
||||||
{
|
{
|
||||||
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
||||||
p->MoverParameters->BrakeCylSpring) *
|
p->MoverParameters->BrakeCylSpring) *
|
||||||
@@ -3235,7 +3235,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
MEDLogFile << MEDLogTime << "\t" << MoverParameters->Vel << "\t" << masa*0.001 << "\t" << osie << "\t" << FmaxPN*0.001 << "\t" << FmaxED*0.001 << "\t"
|
MEDLogFile << MEDLogTime << "\t" << MoverParameters->Vel << "\t" << masa*0.001 << "\t" << osie << "\t" << FmaxPN*0.001 << "\t" << FmaxED*0.001 << "\t"
|
||||||
<< FfulED*0.001 << "\t" << FrED*0.001 << "\t" << Fzad*0.001 << "\t" << FzadED*0.001 << "\t" << FzadPN*0.001;
|
<< FfulED*0.001 << "\t" << FrED*0.001 << "\t" << Fzad*0.001 << "\t" << FzadED*0.001 << "\t" << FzadPN*0.001;
|
||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||||||
(true == kier ? p = p->NextC(4) : p = p->PrevC(4)))
|
(true == kier ? p = p->Next(4) : p = p->Prev(4)))
|
||||||
{
|
{
|
||||||
MEDLogFile << "\t" << p->MoverParameters->BrakePress;
|
MEDLogFile << "\t" << p->MoverParameters->BrakePress;
|
||||||
}
|
}
|
||||||
@@ -6278,35 +6278,23 @@ int TDynamicObject::DirectionSet(int d)
|
|||||||
// następnego
|
// następnego
|
||||||
};
|
};
|
||||||
|
|
||||||
TDynamicObject * TDynamicObject::PrevAny()
|
TDynamicObject * TDynamicObject::PrevAny() const
|
||||||
{ // wskaźnik na poprzedni,
|
{ // wskaźnik na poprzedni,
|
||||||
// nawet wirtualny
|
// nawet wirtualny
|
||||||
return iDirection ? PrevConnected : NextConnected;
|
return iDirection ? PrevConnected : NextConnected;
|
||||||
};
|
};
|
||||||
TDynamicObject * TDynamicObject::Prev()
|
TDynamicObject * TDynamicObject::Prev(int C) const
|
||||||
{
|
{
|
||||||
if (MoverParameters->Couplers[iDirection ^ 1].CouplingFlag)
|
if (MoverParameters->Couplers[iDirection ^ 1].CouplingFlag & C)
|
||||||
return iDirection ? PrevConnected : NextConnected;
|
return iDirection ? PrevConnected : NextConnected;
|
||||||
return NULL; // gdy sprzęg wirtualny, to jakby nic nie było
|
return NULL; // gdy sprzęg wirtualny, to jakby nic nie było
|
||||||
};
|
};
|
||||||
TDynamicObject * TDynamicObject::Next()
|
TDynamicObject * TDynamicObject::Next(int C) const
|
||||||
{
|
{
|
||||||
if (MoverParameters->Couplers[iDirection].CouplingFlag)
|
if (MoverParameters->Couplers[iDirection].CouplingFlag & C)
|
||||||
return iDirection ? NextConnected : PrevConnected;
|
return iDirection ? NextConnected : PrevConnected;
|
||||||
return NULL; // gdy sprzęg wirtualny, to jakby nic nie było
|
return NULL; // gdy sprzęg wirtualny, to jakby nic nie było
|
||||||
};
|
};
|
||||||
TDynamicObject * TDynamicObject::PrevC(int C)
|
|
||||||
{
|
|
||||||
if (MoverParameters->Couplers[iDirection ^ 1].CouplingFlag & C)
|
|
||||||
return iDirection ? PrevConnected : NextConnected;
|
|
||||||
return NULL; // gdy sprzęg wirtualny, to jakby nic nie było
|
|
||||||
};
|
|
||||||
TDynamicObject * TDynamicObject::NextC(int C)
|
|
||||||
{
|
|
||||||
if (MoverParameters->Couplers[iDirection].CouplingFlag & C)
|
|
||||||
return iDirection ? NextConnected : PrevConnected;
|
|
||||||
return NULL; // gdy sprzęg inny, to jakby nic nie było
|
|
||||||
};
|
|
||||||
double TDynamicObject::NextDistance(double d)
|
double TDynamicObject::NextDistance(double d)
|
||||||
{ // ustalenie odległości do
|
{ // ustalenie odległości do
|
||||||
// następnego pojazdu, potrzebne
|
// następnego pojazdu, potrzebne
|
||||||
|
|||||||
8
DynObj.h
8
DynObj.h
@@ -473,11 +473,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
int *iLights; // wskaźnik na bity zapalonych świateł (własne albo innego członu)
|
int *iLights; // wskaźnik na bity zapalonych świateł (własne albo innego członu)
|
||||||
bool DimHeadlights{ false }; // status of the headlight dimming toggle. NOTE: single toggle for all lights is a simplification. TODO: separate per-light switches
|
bool DimHeadlights{ false }; // status of the headlight dimming toggle. NOTE: single toggle for all lights is a simplification. TODO: separate per-light switches
|
||||||
TDynamicObject * PrevAny();
|
TDynamicObject * PrevAny() const;
|
||||||
TDynamicObject * Prev();
|
TDynamicObject * Prev(int C = -1) const;
|
||||||
TDynamicObject * Next();
|
TDynamicObject * Next(int C = -1) const;
|
||||||
TDynamicObject * PrevC(int C);
|
|
||||||
TDynamicObject * NextC(int C);
|
|
||||||
double NextDistance(double d = -1.0);
|
double NextDistance(double d = -1.0);
|
||||||
void SetdMoveLen(double dMoveLen) {
|
void SetdMoveLen(double dMoveLen) {
|
||||||
MoverParameters->dMoveLen = dMoveLen; }
|
MoverParameters->dMoveLen = dMoveLen; }
|
||||||
|
|||||||
14
Train.cpp
14
Train.cpp
@@ -4909,7 +4909,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
// eventually commands are going to be retrieved directly by the vehicle, filtered through active control stand
|
// eventually commands are going to be retrieved directly by the vehicle, filtered through active control stand
|
||||||
// and ultimately executed, provided the stand allows it.
|
// and ultimately executed, provided the stand allows it.
|
||||||
command_data commanddata;
|
command_data commanddata;
|
||||||
while( simulation::Commands.pop( commanddata, (uint32_t)command_target::vehicle | id() )) {
|
while( simulation::Commands->pop( commanddata, (uint32_t)command_target::vehicle | id() )) {
|
||||||
|
|
||||||
auto lookup = m_commandhandlers.find( commanddata.command );
|
auto lookup = m_commandhandlers.find( commanddata.command );
|
||||||
if( lookup != m_commandhandlers.end() ) {
|
if( lookup != m_commandhandlers.end() ) {
|
||||||
@@ -5076,9 +5076,9 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
iPowerNo = in;
|
iPowerNo = in;
|
||||||
}
|
}
|
||||||
// p = p->NextC(4); //prev
|
// p = p->NextC(4); //prev
|
||||||
if ((kier ? p->NextC(128) : p->PrevC(128)) != (kier ? p->NextC(4) : p->PrevC(4)))
|
if ((kier ? p->Next(128) : p->Prev(128)) != (kier ? p->Next(4) : p->Prev(4)))
|
||||||
iUnitNo++;
|
iUnitNo++;
|
||||||
p = (kier ? p->NextC(4) : p->PrevC(4));
|
p = (kier ? p->Next(4) : p->Prev(4));
|
||||||
iCarNo = i + 1;
|
iCarNo = i + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -6954,14 +6954,14 @@ void TTrain::SetLights()
|
|||||||
TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->ActiveCab < 0 ? 1 : 0, 4);
|
TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->ActiveCab < 0 ? 1 : 0, 4);
|
||||||
bool kier = (DynamicObject->DirectionGet() * mvOccupied->ActiveCab > 0);
|
bool kier = (DynamicObject->DirectionGet() * mvOccupied->ActiveCab > 0);
|
||||||
int xs = (kier ? 0 : 1);
|
int xs = (kier ? 0 : 1);
|
||||||
if (kier ? p->NextC(1) : p->PrevC(1)) // jesli jest nastepny, to tylko przod
|
if (kier ? p->Next(1) : p->Prev(1)) // jesli jest nastepny, to tylko przod
|
||||||
{
|
{
|
||||||
p->RaLightsSet(mvOccupied->Lights[xs][mvOccupied->LightsPos - 1] * (1 - xs),
|
p->RaLightsSet(mvOccupied->Lights[xs][mvOccupied->LightsPos - 1] * (1 - xs),
|
||||||
mvOccupied->Lights[1 - xs][mvOccupied->LightsPos - 1] * xs);
|
mvOccupied->Lights[1 - xs][mvOccupied->LightsPos - 1] * xs);
|
||||||
p = (kier ? p->NextC(4) : p->PrevC(4));
|
p = (kier ? p->Next(4) : p->Prev(4));
|
||||||
while (p)
|
while (p)
|
||||||
{
|
{
|
||||||
if (kier ? p->NextC(1) : p->PrevC(1))
|
if (kier ? p->Next(1) : p->Prev(1))
|
||||||
{
|
{
|
||||||
p->RaLightsSet(0, 0);
|
p->RaLightsSet(0, 0);
|
||||||
}
|
}
|
||||||
@@ -6970,7 +6970,7 @@ void TTrain::SetLights()
|
|||||||
p->RaLightsSet(mvOccupied->Lights[xs][mvOccupied->LightsPos - 1] * xs,
|
p->RaLightsSet(mvOccupied->Lights[xs][mvOccupied->LightsPos - 1] * xs,
|
||||||
mvOccupied->Lights[1 - xs][mvOccupied->LightsPos - 1] * (1 - xs));
|
mvOccupied->Lights[1 - xs][mvOccupied->LightsPos - 1] * (1 - xs));
|
||||||
}
|
}
|
||||||
p = (kier ? p->NextC(4) : p->PrevC(4));
|
p = (kier ? p->Next(4) : p->Prev(4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // calosc
|
else // calosc
|
||||||
|
|||||||
@@ -144,6 +144,29 @@ eu07_application::init( int Argc, char *Argv[] ) {
|
|||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
eu07_application::run() {
|
eu07_application::run() {
|
||||||
|
|
||||||
@@ -159,23 +182,26 @@ eu07_application::run() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!Global.network_conf.is_server) {
|
else if (!Global.network_conf.is_server) {
|
||||||
|
command_queue_client *queue = dynamic_cast<command_queue_client*>(simulation::Commands.get());
|
||||||
double delta;
|
double delta;
|
||||||
do {
|
do {
|
||||||
auto tup = m_network->get_next_delta();
|
auto tup = m_network->get_next_delta();
|
||||||
delta = std::get<0>(tup);
|
delta = std::get<0>(tup);
|
||||||
simulation::Commands.merge_command_sequences(std::get<1>(tup));
|
queue->push_server_commands(std::get<1>(tup));
|
||||||
Timer::set_delta_override(delta);
|
m_network->send_commands(queue->pop_queued_commands());
|
||||||
|
Timer::set_delta_override(delta);
|
||||||
|
|
||||||
simulation::Commands.update();
|
|
||||||
if (!m_modes[ m_modestack.top() ]->update())
|
if (!m_modes[ m_modestack.top() ]->update())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (delta != 0.0);
|
while (delta != 0.0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto commands = simulation::Commands.peek_command_sequences();
|
command_queue_server *queue = dynamic_cast<command_queue_server*>(simulation::Commands.get());
|
||||||
|
auto commands = queue->pop_queued_commands();
|
||||||
|
|
||||||
simulation::Commands.update();
|
queue->push_client_commands(m_network->pop_commands());
|
||||||
|
queue->update();
|
||||||
if (!m_modes[ m_modestack.top() ]->update())
|
if (!m_modes[ m_modestack.top() ]->update())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -619,14 +645,19 @@ eu07_application::init_modes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool eu07_application::init_network() {
|
bool eu07_application::init_network() {
|
||||||
if (!Global.network_conf.enabled)
|
if (Global.network_conf.enabled) {
|
||||||
return true;
|
m_network.emplace();
|
||||||
|
if (Global.network_conf.is_server) {
|
||||||
m_network.emplace();
|
m_network->create_server();
|
||||||
if (Global.network_conf.is_server)
|
simulation::Commands = std::make_unique<command_queue_server>();
|
||||||
m_network->create_server();
|
}
|
||||||
|
else {
|
||||||
|
m_network->connect();
|
||||||
|
simulation::Commands = std::make_unique<command_queue_client>();
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_network->connect();
|
simulation::Commands = std::make_unique<command_queue>();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ public:
|
|||||||
GLFWwindow *
|
GLFWwindow *
|
||||||
window( int const Windowindex = 0 );
|
window( int const Windowindex = 0 );
|
||||||
|
|
||||||
|
void request_train(std::string name);
|
||||||
|
void spawn_train(std::string name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
using modeptr_array = std::array<std::shared_ptr<application_mode>, static_cast<std::size_t>( mode::count_ )>;
|
using modeptr_array = std::array<std::shared_ptr<application_mode>, static_cast<std::size_t>( mode::count_ )>;
|
||||||
|
|||||||
124
command.cpp
124
command.cpp
@@ -18,7 +18,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
namespace simulation {
|
namespace simulation {
|
||||||
|
|
||||||
command_queue Commands;
|
std::unique_ptr<command_queue> Commands;
|
||||||
commanddescription_sequence Commands_descriptions = {
|
commanddescription_sequence Commands_descriptions = {
|
||||||
|
|
||||||
{ "aidriverenable", command_target::vehicle, command_mode::oneoff },
|
{ "aidriverenable", command_target::vehicle, command_mode::oneoff },
|
||||||
@@ -230,22 +230,25 @@ commanddescription_sequence Commands_descriptions = {
|
|||||||
|
|
||||||
} // simulation
|
} // simulation
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// command_queue
|
||||||
|
|
||||||
void command_queue::update()
|
void command_queue::update()
|
||||||
{
|
{
|
||||||
double delta = Timer::GetDeltaTime();
|
double delta = Timer::GetDeltaTime();
|
||||||
for (auto c : m_active_continuous)
|
for (auto c : m_active_continuous)
|
||||||
{
|
{
|
||||||
auto lookup = m_commands.emplace(c.second, commanddata_sequence() );
|
|
||||||
|
|
||||||
command_data data({c.first, GLFW_REPEAT, 0.0, 0.0, delta});
|
command_data data({c.first, GLFW_REPEAT, 0.0, 0.0, delta});
|
||||||
lookup.first->second.emplace_back(data);
|
auto lookup = m_commands.emplace( c.second, commanddata_sequence() );
|
||||||
|
// recipient stack was either located or created, so we can add to it quite safely
|
||||||
|
lookup.first->second.emplace_back( data );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// posts specified command for specified recipient
|
// posts specified command for specified recipient
|
||||||
void
|
void
|
||||||
command_queue::push( command_data const &Command, std::size_t const Recipient ) {
|
command_queue::push( command_data const &Command, uint32_t const Recipient ) {
|
||||||
auto const &desc = simulation::Commands_descriptions[ static_cast<std::size_t>( Command.command ) ];
|
auto const &desc = simulation::Commands_descriptions[ static_cast<std::size_t>( Command.command ) ];
|
||||||
if (desc.mode == command_mode::continuous)
|
if (desc.mode == command_mode::continuous)
|
||||||
{
|
{
|
||||||
if (Command.action == GLFW_PRESS)
|
if (Command.action == GLFW_PRESS)
|
||||||
@@ -256,14 +259,14 @@ command_queue::push( command_data const &Command, std::size_t const Recipient )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lookup = m_commands.emplace( Recipient, commanddata_sequence() );
|
auto lookup = m_commands.emplace( Recipient, commanddata_sequence() );
|
||||||
// recipient stack was either located or created, so we can add to it quite safely
|
// recipient stack was either located or created, so we can add to it quite safely
|
||||||
lookup.first->second.emplace_back( Command );
|
lookup.first->second.emplace_back( Command );
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieves oldest posted command for specified recipient, if any. returns: true on retrieval, false if there's nothing to retrieve
|
// retrieves oldest posted command for specified recipient, if any. returns: true on retrieval, false if there's nothing to retrieve
|
||||||
bool
|
bool
|
||||||
command_queue::pop( command_data &Command, std::size_t const Recipient ) {
|
command_queue::pop( command_data &Command, uint32_t const Recipient ) {
|
||||||
|
|
||||||
auto lookup = m_commands.find( Recipient );
|
auto lookup = m_commands.find( Recipient );
|
||||||
if( lookup == m_commands.end() ) {
|
if( lookup == m_commands.end() ) {
|
||||||
@@ -282,6 +285,65 @@ command_queue::pop( command_data &Command, std::size_t const Recipient ) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool command_queue::is_network_target(uint32_t const Recipient) {
|
||||||
|
const command_target target = (command_target)(Recipient & ~0xffff);
|
||||||
|
|
||||||
|
if (target == command_target::entity)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// command_queue_server
|
||||||
|
|
||||||
|
void command_queue_server::push(const command_data &Command, const uint32_t Recipient) {
|
||||||
|
if (is_network_target(Recipient)) {
|
||||||
|
auto lookup = network_queue.emplace(Recipient, commanddata_sequence());
|
||||||
|
lookup.first->second.emplace_back(Command);
|
||||||
|
}
|
||||||
|
command_queue::push(Command, Recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
command_queue_server::commands_map command_queue_server::pop_queued_commands() {
|
||||||
|
commands_map map(network_queue);
|
||||||
|
network_queue.clear();
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_queue_server::push_client_commands(const commands_map &commands) {
|
||||||
|
for (auto const &kv : commands)
|
||||||
|
for (command_data const &data : kv.second)
|
||||||
|
push(data, kv.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// command_queue_client
|
||||||
|
|
||||||
|
void command_queue_client::push(const command_data &Command, const uint32_t Recipient) {
|
||||||
|
if (is_network_target(Recipient)) {
|
||||||
|
auto lookup = network_queue.emplace(Recipient, commanddata_sequence());
|
||||||
|
lookup.first->second.emplace_back(Command);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
command_queue::push(Command, Recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
command_queue_client::commands_map command_queue_client::pop_queued_commands() {
|
||||||
|
commands_map map(network_queue);
|
||||||
|
network_queue.clear();
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_queue_client::push_server_commands(const commands_map &commands) {
|
||||||
|
for (auto const &kv : commands)
|
||||||
|
for (command_data const &data : kv.second)
|
||||||
|
command_queue::push(data, kv.first);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
|
||||||
void
|
void
|
||||||
command_relay::post( user_command const Command, double const Param1, double const Param2,
|
command_relay::post( user_command const Command, double const Param1, double const Param2,
|
||||||
int const Action, uint16_t Recipient) const {
|
int const Action, uint16_t Recipient) const {
|
||||||
@@ -303,44 +365,8 @@ command_relay::post( user_command const Command, double const Param1, double con
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
simulation::Commands.push(
|
uint32_t combined_recipient = static_cast<uint32_t>( command.target ) | Recipient;
|
||||||
command_data{
|
command_data commanddata({Command, Action, Param1, Param2, Timer::GetDeltaTime() });
|
||||||
Command,
|
|
||||||
Action,
|
|
||||||
Param1,
|
|
||||||
Param2,
|
|
||||||
Timer::GetDeltaTime()},
|
|
||||||
static_cast<std::size_t>( command.target ) | Recipient );
|
|
||||||
/*
|
|
||||||
#ifdef _DEBUG
|
|
||||||
if( Action != GLFW_RELEASE ) {
|
|
||||||
// key was pressed or is still held
|
|
||||||
if( false == command.name.empty() ) {
|
|
||||||
if( false == (
|
|
||||||
( Command == user_command::moveleft )
|
|
||||||
|| ( Command == user_command::moveleftfast )
|
|
||||||
|| ( Command == user_command::moveright )
|
|
||||||
|| ( Command == user_command::moverightfast )
|
|
||||||
|| ( Command == user_command::moveforward )
|
|
||||||
|| ( Command == user_command::moveforwardfast )
|
|
||||||
|| ( Command == user_command::moveback )
|
|
||||||
|| ( Command == user_command::movebackfast )
|
|
||||||
|| ( Command == user_command::moveup )
|
|
||||||
|| ( Command == user_command::moveupfast )
|
|
||||||
|| ( Command == user_command::movedown )
|
|
||||||
|| ( Command == user_command::movedownfast )
|
|
||||||
|| ( Command == user_command::movevector )
|
|
||||||
|| ( Command == user_command::viewturn ) ) ) {
|
|
||||||
WriteLog( "Command issued: " + command.name );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// key was released (but we don't log this)
|
|
||||||
WriteLog( "Key released: " + command.name );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
simulation::Commands->push(commanddata, combined_recipient);
|
||||||
|
}
|
||||||
|
|||||||
62
command.h
62
command.h
@@ -236,7 +236,7 @@ enum class command_target {
|
|||||||
signal = 0x20000,
|
signal = 0x20000,
|
||||||
entity = 0x40000,
|
entity = 0x40000,
|
||||||
|
|
||||||
simulation = 0x8000,
|
simulation = 0x80000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class command_mode {
|
enum class command_mode {
|
||||||
@@ -268,53 +268,65 @@ class command_queue {
|
|||||||
public:
|
public:
|
||||||
// types
|
// types
|
||||||
typedef std::deque<command_data> commanddata_sequence;
|
typedef std::deque<command_data> commanddata_sequence;
|
||||||
typedef std::unordered_map<std::size_t, commanddata_sequence> commanddatasequence_map;
|
typedef std::unordered_map<uint32_t, commanddata_sequence> commands_map;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
// posts specified command for specified recipient
|
// posts specified command for specified recipient
|
||||||
void
|
virtual void
|
||||||
push( command_data const &Command, std::size_t const Recipient );
|
push( command_data const &Command, uint32_t const Recipient );
|
||||||
// retrieves oldest posted command for specified recipient, if any. returns: true on retrieval, false if there's nothing to retrieve
|
// retrieves oldest posted command for specified recipient, if any. returns: true on retrieval, false if there's nothing to retrieve
|
||||||
bool
|
bool
|
||||||
pop( command_data &Command, std::size_t const Recipient );
|
pop( command_data &Command, uint32_t const Recipient );
|
||||||
void update();
|
void update();
|
||||||
|
bool is_network_target(const uint32_t Recipient);
|
||||||
commanddatasequence_map peek_command_sequences() const {
|
|
||||||
commanddatasequence_map map(m_commands);
|
|
||||||
for (auto &kv : map) {
|
|
||||||
if (kv.first & 0)
|
|
||||||
kv.second.clear();
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
void merge_command_sequences(commanddatasequence_map map) {
|
|
||||||
for (auto const &kv : map)
|
|
||||||
for (command_data const &data : kv.second)
|
|
||||||
push(data, kv.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
|
||||||
// members
|
// members
|
||||||
commanddatasequence_map m_commands;
|
// main command queue
|
||||||
|
commands_map m_commands;
|
||||||
|
|
||||||
|
// hash operator for m_active_continuous
|
||||||
struct command_set_hash {
|
struct command_set_hash {
|
||||||
uint64_t operator() (const std::pair<user_command, uint32_t> &pair) const {
|
uint64_t operator() (const std::pair<user_command, uint32_t> &pair) const {
|
||||||
return ((uint64_t)pair.first << 32) | ((uint64_t) pair.second);
|
return ((uint64_t)pair.first << 32) | ((uint64_t) pair.second);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// currently pressed continuous commands
|
||||||
std::unordered_set<std::pair<user_command, uint32_t>, command_set_hash> m_active_continuous;
|
std::unordered_set<std::pair<user_command, uint32_t>, command_set_hash> m_active_continuous;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class command_queue_server : public command_queue {
|
||||||
|
public:
|
||||||
|
void push( command_data const &Command, uint32_t const Recipient ) override;
|
||||||
|
|
||||||
|
commands_map pop_queued_commands();
|
||||||
|
void push_client_commands(const commands_map &commands);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// contains copies of commands to be sent to clients
|
||||||
|
commands_map network_queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class command_queue_client : public command_queue {
|
||||||
|
public:
|
||||||
|
void push( command_data const &Command, uint32_t const Recipient ) override;
|
||||||
|
|
||||||
|
commands_map pop_queued_commands();
|
||||||
|
void push_server_commands(const commands_map &commands);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// contains intercepted commands to be sent for execution to server
|
||||||
|
commands_map network_queue;
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: simulation should be a (light) wrapper rather than namespace so we could potentially instance it,
|
// NOTE: simulation should be a (light) wrapper rather than namespace so we could potentially instance it,
|
||||||
// but realistically it's not like we're going to run more than one simulation at a time
|
// but realistically it's not like we're going to run more than one simulation at a time
|
||||||
namespace simulation {
|
namespace simulation {
|
||||||
|
|
||||||
typedef std::vector<command_description> commanddescription_sequence;
|
typedef std::vector<command_description> commanddescription_sequence;
|
||||||
|
|
||||||
extern command_queue Commands;
|
extern std::unique_ptr<command_queue> Commands;
|
||||||
// TODO: add name to command map, and wrap these two into helper object
|
// TODO: add name to command map, and wrap these two into helper object
|
||||||
extern commanddescription_sequence Commands_descriptions;
|
extern commanddescription_sequence Commands_descriptions;
|
||||||
|
|
||||||
@@ -325,15 +337,11 @@ extern commanddescription_sequence Commands_descriptions;
|
|||||||
class command_relay {
|
class command_relay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
|
||||||
// methods
|
// methods
|
||||||
// posts specified command for the specified recipient
|
// posts specified command for the specified recipient
|
||||||
void
|
void
|
||||||
post(user_command const Command, double const Param1, double const Param2,
|
post(user_command const Command, double const Param1, double const Param2,
|
||||||
int const Action, uint16_t Recipient ) const;
|
int const Action, uint16_t Recipient ) const;
|
||||||
private:
|
|
||||||
// types
|
|
||||||
// members
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -248,6 +248,27 @@ driver_mode::update() {
|
|||||||
return true;
|
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
|
// maintenance method, called when the mode is activated
|
||||||
void
|
void
|
||||||
driver_mode::enter() {
|
driver_mode::enter() {
|
||||||
@@ -265,9 +286,8 @@ driver_mode::enter() {
|
|||||||
{
|
{
|
||||||
WriteLog( "Initializing player train, \"" + Global.asHumanCtrlVehicle + "\"" );
|
WriteLog( "Initializing player train, \"" + Global.asHumanCtrlVehicle + "\"" );
|
||||||
|
|
||||||
TTrain *train = new TTrain();
|
TTrain *train = request_train(nPlayerTrain);
|
||||||
if (train->Init(nPlayerTrain)) {
|
if (train->Init(nPlayerTrain)) {
|
||||||
simulation::Trains.insert(train, nPlayerTrain->name());
|
|
||||||
simulation::Train = train;
|
simulation::Train = train;
|
||||||
|
|
||||||
WriteLog("Player train initialization OK");
|
WriteLog("Player train initialization OK");
|
||||||
@@ -698,26 +718,15 @@ driver_mode::OnKeyDown(int cKey) {
|
|||||||
|
|
||||||
if( tmp != nullptr ) {
|
if( tmp != 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( true == DebugModeFlag )
|
if( ( true == DebugModeFlag )
|
||||||
|| ( tmp->MoverParameters->Vel <= 5.0 ) ) {
|
|| ( tmp->MoverParameters->Vel <= 5.0 ) ) {
|
||||||
TTrain *train = simulation::Trains.find(tmp->name());
|
TTrain *train = request_train(tmp);
|
||||||
if (train == nullptr) {
|
|
||||||
train = new TTrain();
|
|
||||||
if (train->Init(tmp)) {
|
|
||||||
simulation::Trains.insert(train, tmp->name());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delete train;
|
|
||||||
train = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (train != nullptr) {
|
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 );
|
train->Dynamic()->Mechanik->TakeControl( false );
|
||||||
simulation::Train = train;
|
simulation::Train = train;
|
||||||
InOutKey();
|
InOutKey();
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ private:
|
|||||||
void ExternalView();
|
void ExternalView();
|
||||||
void DistantView( bool const Near = false );
|
void DistantView( bool const Near = false );
|
||||||
void set_picking( bool const Picking );
|
void set_picking( bool const Picking );
|
||||||
|
TTrain* request_train(TDynamicObject *dynamic);
|
||||||
|
|
||||||
// members
|
// members
|
||||||
drivermode_input m_input;
|
drivermode_input m_input;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ driver_ui::driver_ui() {
|
|||||||
push_back( &m_debugpanel );
|
push_back( &m_debugpanel );
|
||||||
push_back( &m_transcriptspanel );
|
push_back( &m_transcriptspanel );
|
||||||
|
|
||||||
|
push_back( &m_vehiclelist );
|
||||||
push_back( &m_logpanel );
|
push_back( &m_logpanel );
|
||||||
m_logpanel.is_open = false;
|
m_logpanel.is_open = false;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "uilayer.h"
|
#include "uilayer.h"
|
||||||
#include "driveruipanels.h"
|
#include "driveruipanels.h"
|
||||||
|
|
||||||
|
#include "widgets/vehiclelist.h"
|
||||||
|
|
||||||
class driver_ui : public ui_layer {
|
class driver_ui : public ui_layer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -50,4 +52,6 @@ private:
|
|||||||
transcripts_panel m_transcriptspanel { "Transcripts", true }; // voice transcripts
|
transcripts_panel m_transcriptspanel { "Transcripts", true }; // voice transcripts
|
||||||
bool m_paused { false };
|
bool m_paused { false };
|
||||||
bool m_pause_modal_opened { false };
|
bool m_pause_modal_opened { false };
|
||||||
|
|
||||||
|
ui::vehiclelist_panel m_vehiclelist;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "network/manager.h"
|
#include "network/manager.h"
|
||||||
#include "network/tcp.h"
|
#include "network/tcp.h"
|
||||||
|
#include "simulation.h"
|
||||||
|
|
||||||
network::manager::manager()
|
network::manager::manager()
|
||||||
{
|
{
|
||||||
@@ -20,12 +21,48 @@ void network::manager::connect()
|
|||||||
client = std::make_shared<tcp_client>(io_context);
|
client = std::make_shared<tcp_client>(io_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<double, command_queue::commanddatasequence_map> network::manager::get_next_delta()
|
std::tuple<double, command_queue::commands_map> network::manager::get_next_delta()
|
||||||
{
|
{
|
||||||
return client->get_next_delta();
|
return client->get_next_delta();
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::manager::push_delta(double delta, command_queue::commanddatasequence_map commands)
|
void network::manager::push_delta(double delta, command_queue::commands_map commands)
|
||||||
{
|
{
|
||||||
server->push_delta(delta, commands);
|
server->push_delta(delta, commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
command_queue::commands_map network::manager::pop_commands()
|
||||||
|
{
|
||||||
|
return server->pop_commands();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ namespace network
|
|||||||
void connect();
|
void connect();
|
||||||
void poll();
|
void poll();
|
||||||
|
|
||||||
std::tuple<double, command_queue::commanddatasequence_map> get_next_delta();
|
std::tuple<double, command_queue::commands_map> get_next_delta();
|
||||||
void push_delta(double delta, command_queue::commanddatasequence_map commands);
|
void push_delta(double delta, 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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,8 @@ void network::message::deserialize(std::istream &stream)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void::network::delta_message::serialize(std::ostream &stream)
|
void::network::command_message::serialize(std::ostream &stream)
|
||||||
{
|
{
|
||||||
sn_utils::ls_float64(stream, dt);
|
|
||||||
|
|
||||||
sn_utils::ls_uint32(stream, commands.size());
|
sn_utils::ls_uint32(stream, commands.size());
|
||||||
for (auto const &kv : commands) {
|
for (auto const &kv : commands) {
|
||||||
sn_utils::ls_uint32(stream, kv.first);
|
sn_utils::ls_uint32(stream, kv.first);
|
||||||
@@ -29,10 +27,8 @@ void::network::delta_message::serialize(std::ostream &stream)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::delta_message::deserialize(std::istream &stream)
|
void network::command_message::deserialize(std::istream &stream)
|
||||||
{
|
{
|
||||||
dt = sn_utils::ld_float64(stream);
|
|
||||||
|
|
||||||
uint32_t commands_size = sn_utils::ld_uint32(stream);
|
uint32_t commands_size = sn_utils::ld_uint32(stream);
|
||||||
for (uint32_t i = 0; i < commands_size; i++) {
|
for (uint32_t i = 0; i < commands_size; i++) {
|
||||||
uint32_t recipient = sn_utils::ld_uint32(stream);
|
uint32_t recipient = sn_utils::ld_uint32(stream);
|
||||||
@@ -54,7 +50,7 @@ void network::delta_message::deserialize(std::istream &stream)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t network::delta_message::get_size()
|
size_t network::command_message::get_size()
|
||||||
{
|
{
|
||||||
size_t cmd_size = 4;
|
size_t cmd_size = 4;
|
||||||
|
|
||||||
@@ -65,7 +61,41 @@ size_t network::delta_message::get_size()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return message::get_size() + cmd_size + 8;
|
return message::get_size() + cmd_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t network::delta_message::get_size()
|
||||||
|
{
|
||||||
|
return command_message::get_size() + 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network::delta_message::serialize(std::ostream &stream)
|
||||||
|
{
|
||||||
|
sn_utils::ls_float64(stream, dt);
|
||||||
|
|
||||||
|
command_message::serialize(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network::delta_message::deserialize(std::istream &stream)
|
||||||
|
{
|
||||||
|
dt = sn_utils::ld_float64(stream);
|
||||||
|
|
||||||
|
command_message::deserialize(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network::string_message::serialize(std::ostream &stream)
|
||||||
|
{
|
||||||
|
sn_utils::s_str(stream, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network::string_message::deserialize(std::istream &stream)
|
||||||
|
{
|
||||||
|
name = sn_utils::d_str(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t network::string_message::get_size()
|
||||||
|
{
|
||||||
|
return message::get_size() + name.size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<network::message> network::deserialize_message(std::istream &stream)
|
std::shared_ptr<network::message> network::deserialize_message(std::istream &stream)
|
||||||
@@ -79,6 +109,18 @@ std::shared_ptr<network::message> network::deserialize_message(std::istream &str
|
|||||||
m->deserialize(stream);
|
m->deserialize(stream);
|
||||||
msg = m;
|
msg = m;
|
||||||
}
|
}
|
||||||
|
else if (type == message::CLIENT_COMMAND) {
|
||||||
|
auto m = std::make_shared<command_message>();
|
||||||
|
m->type = type;
|
||||||
|
m->deserialize(stream);
|
||||||
|
msg = m;
|
||||||
|
}
|
||||||
|
else if (type == message::REQUEST_SPAWN_TRAIN || type == message::SPAWN_TRAIN) {
|
||||||
|
auto m = std::make_shared<string_message>(type);
|
||||||
|
m->type = type;
|
||||||
|
m->deserialize(stream);
|
||||||
|
msg = m;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
msg = std::make_shared<message>(type);
|
msg = std::make_shared<message>(type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ namespace network
|
|||||||
CONNECT_REQUEST = 0,
|
CONNECT_REQUEST = 0,
|
||||||
CONNECT_ACCEPT,
|
CONNECT_ACCEPT,
|
||||||
STEP_INFO,
|
STEP_INFO,
|
||||||
VEHICLE_COMMAND,
|
CLIENT_COMMAND,
|
||||||
|
REQUEST_SPAWN_TRAIN,
|
||||||
|
SPAWN_TRAIN,
|
||||||
TYPE_MAX
|
TYPE_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -24,12 +26,34 @@ namespace network
|
|||||||
virtual size_t get_size() { return 2; }
|
virtual size_t get_size() { return 2; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct delta_message : public message
|
struct command_message : public message
|
||||||
{
|
{
|
||||||
delta_message() : message(STEP_INFO) {}
|
command_message() : message(CLIENT_COMMAND) {}
|
||||||
|
command_message(type_e type) : message(type) {}
|
||||||
|
|
||||||
|
command_queue::commands_map commands;
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &stream) override;
|
||||||
|
virtual void deserialize(std::istream &stream) override;
|
||||||
|
virtual size_t get_size() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct delta_message : public command_message
|
||||||
|
{
|
||||||
|
delta_message() : command_message(STEP_INFO) {}
|
||||||
|
|
||||||
double dt;
|
double dt;
|
||||||
command_queue::commanddatasequence_map commands;
|
|
||||||
|
virtual void serialize(std::ostream &stream) override;
|
||||||
|
virtual void deserialize(std::istream &stream) override;
|
||||||
|
virtual size_t get_size() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct string_message : public message
|
||||||
|
{
|
||||||
|
string_message(type_e type) : message(type) {}
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
|
||||||
virtual void serialize(std::ostream &stream) override;
|
virtual void serialize(std::ostream &stream) override;
|
||||||
virtual void deserialize(std::istream &stream) override;
|
virtual void deserialize(std::istream &stream) override;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "sn_utils.h"
|
#include "sn_utils.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
void network::connection::connected()
|
void network::connection::connected()
|
||||||
{
|
{
|
||||||
@@ -32,19 +33,35 @@ void network::connection::message_received(std::shared_ptr<message> &msg)
|
|||||||
{
|
{
|
||||||
WriteLog("accept received", logtype::net);
|
WriteLog("accept received", logtype::net);
|
||||||
}
|
}
|
||||||
|
else if (msg->type == message::CLIENT_COMMAND)
|
||||||
|
{
|
||||||
|
auto cmd = std::dynamic_pointer_cast<command_message>(msg);
|
||||||
|
for (auto const &kv : cmd->commands)
|
||||||
|
client_commands_queue.emplace(kv);
|
||||||
|
}
|
||||||
else if (msg->type == message::STEP_INFO)
|
else if (msg->type == message::STEP_INFO)
|
||||||
{
|
{
|
||||||
auto delta = std::dynamic_pointer_cast<delta_message>(msg);
|
auto delta = std::dynamic_pointer_cast<delta_message>(msg);
|
||||||
auto now = std::chrono::high_resolution_clock::now();
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
delta_queue.push(std::make_pair(now, delta));
|
delta_queue.push(std::make_pair(now, delta));
|
||||||
}
|
}
|
||||||
|
else if (msg->type == message::REQUEST_SPAWN_TRAIN)
|
||||||
|
{
|
||||||
|
auto req = std::dynamic_pointer_cast<string_message>(msg);
|
||||||
|
Application.request_train(req->name);
|
||||||
|
}
|
||||||
|
else if (msg->type == message::SPAWN_TRAIN)
|
||||||
|
{
|
||||||
|
auto req = std::dynamic_pointer_cast<string_message>(msg);
|
||||||
|
Application.spawn_train(req->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<double, command_queue::commanddatasequence_map> network::connection::get_next_delta()
|
std::tuple<double, command_queue::commands_map> network::connection::get_next_delta()
|
||||||
{
|
{
|
||||||
if (delta_queue.empty()) {
|
if (delta_queue.empty()) {
|
||||||
return std::tuple<double,
|
return std::tuple<double,
|
||||||
command_queue::commanddatasequence_map>(0.0, command_queue::commanddatasequence_map());
|
command_queue::commands_map>(0.0, command_queue::commands_map());
|
||||||
}
|
}
|
||||||
|
|
||||||
///auto now = std::chrono::high_resolution_clock::now();
|
///auto now = std::chrono::high_resolution_clock::now();
|
||||||
@@ -66,6 +83,13 @@ std::tuple<double, command_queue::commanddatasequence_map> network::connection::
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
command_queue::commands_map network::connection::pop_commands()
|
||||||
|
{
|
||||||
|
command_queue::commands_map map(client_commands_queue);
|
||||||
|
client_commands_queue.clear();
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
void network::connection::data_received(std::string &buffer)
|
void network::connection::data_received(std::string &buffer)
|
||||||
{
|
{
|
||||||
std::istringstream body(buffer);
|
std::istringstream body(buffer);
|
||||||
@@ -87,7 +111,7 @@ void network::connection::send_message(std::shared_ptr<message> msg)
|
|||||||
send_data(buf);
|
send_data(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::server::push_delta(double dt, command_queue::commanddatasequence_map commands)
|
void network::server::push_delta(double dt, command_queue::commands_map commands)
|
||||||
{
|
{
|
||||||
std::shared_ptr<delta_message> msg = std::make_shared<delta_message>();
|
std::shared_ptr<delta_message> msg = std::make_shared<delta_message>();
|
||||||
msg->dt = dt;
|
msg->dt = dt;
|
||||||
@@ -97,7 +121,46 @@ void network::server::push_delta(double dt, command_queue::commanddatasequence_m
|
|||||||
c->send_message(msg);
|
c->send_message(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<double, command_queue::commanddatasequence_map> network::client::get_next_delta()
|
void network::server::notify_train(std::string name)
|
||||||
|
{
|
||||||
|
std::shared_ptr<string_message> msg = std::make_shared<string_message>(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;
|
||||||
|
for (auto c : clients) {
|
||||||
|
command_queue::commands_map cmap = c->pop_commands();
|
||||||
|
for (auto const &kv : cmap) {
|
||||||
|
auto lookup = map.emplace(kv.first, command_queue::commanddata_sequence());
|
||||||
|
for (command_data const &data : kv.second)
|
||||||
|
lookup.first->second.emplace_back(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<double, command_queue::commands_map> network::client::get_next_delta()
|
||||||
{
|
{
|
||||||
return conn->get_next_delta();
|
return conn->get_next_delta();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void network::client::send_commands(command_queue::commands_map commands)
|
||||||
|
{
|
||||||
|
std::shared_ptr<command_message> msg = std::make_shared<command_message>();
|
||||||
|
msg->commands = commands;
|
||||||
|
|
||||||
|
conn->send_message(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network::client::request_train(std::string name)
|
||||||
|
{
|
||||||
|
std::shared_ptr<string_message> msg = std::make_shared<string_message>(message::REQUEST_SPAWN_TRAIN);
|
||||||
|
msg->name = name;
|
||||||
|
|
||||||
|
conn->send_message(msg);
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ namespace network
|
|||||||
std::pair<std::chrono::high_resolution_clock::time_point,
|
std::pair<std::chrono::high_resolution_clock::time_point,
|
||||||
std::shared_ptr<delta_message>>> delta_queue;
|
std::shared_ptr<delta_message>>> delta_queue;
|
||||||
|
|
||||||
|
command_queue::commands_map client_commands_queue;
|
||||||
|
|
||||||
//std::chrono::high_resolution_clock::time_point last_time;
|
//std::chrono::high_resolution_clock::time_point last_time;
|
||||||
//double accum = -1.0;
|
//double accum = -1.0;
|
||||||
|
|
||||||
@@ -31,7 +33,8 @@ namespace network
|
|||||||
void send_message(std::shared_ptr<message> msg);
|
void send_message(std::shared_ptr<message> msg);
|
||||||
virtual void connected();
|
virtual void connected();
|
||||||
|
|
||||||
std::tuple<double, command_queue::commanddatasequence_map> get_next_delta();
|
std::tuple<double, command_queue::commands_map> get_next_delta();
|
||||||
|
command_queue::commands_map pop_commands();
|
||||||
};
|
};
|
||||||
|
|
||||||
class server
|
class server
|
||||||
@@ -40,7 +43,9 @@ namespace network
|
|||||||
std::vector<std::shared_ptr<connection>> clients;
|
std::vector<std::shared_ptr<connection>> clients;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void push_delta(double dt, command_queue::commanddatasequence_map commands);
|
void push_delta(double dt, command_queue::commands_map commands);
|
||||||
|
command_queue::commands_map pop_commands();
|
||||||
|
void notify_train(std::string name);
|
||||||
};
|
};
|
||||||
|
|
||||||
class client
|
class client
|
||||||
@@ -49,6 +54,8 @@ namespace network
|
|||||||
std::shared_ptr<connection> conn;
|
std::shared_ptr<connection> conn;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::tuple<double, command_queue::commanddatasequence_map> get_next_delta();
|
std::tuple<double, command_queue::commands_map> get_next_delta();
|
||||||
|
void send_commands(command_queue::commands_map commands);
|
||||||
|
void request_train(std::string name);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ state_manager::update( double const Deltatime, int Iterationcount ) {
|
|||||||
|
|
||||||
void state_manager::process_commands() {
|
void state_manager::process_commands() {
|
||||||
command_data commanddata;
|
command_data commanddata;
|
||||||
while( Commands.pop( commanddata, (uint32_t)command_target::simulation )) {
|
while( Commands->pop( commanddata, (uint32_t)command_target::simulation )) {
|
||||||
if (commanddata.action == GLFW_RELEASE)
|
if (commanddata.action == GLFW_RELEASE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ bool ui_layer::init(GLFWwindow *Window)
|
|||||||
if (Global.map_enabled)
|
if (Global.map_enabled)
|
||||||
m_map = std::make_unique<map>();
|
m_map = std::make_unique<map>();
|
||||||
|
|
||||||
ImGui::StyleColorsClassic();
|
ImGui::StyleColorsDark();
|
||||||
ImGui_ImplGlfw_InitForOpenGL(m_window);
|
ImGui_ImplGlfw_InitForOpenGL(m_window);
|
||||||
#ifdef EU07_USEIMGUIIMPLOPENGL2
|
#ifdef EU07_USEIMGUIIMPLOPENGL2
|
||||||
ImGui_ImplOpenGL2_Init();
|
ImGui_ImplOpenGL2_Init();
|
||||||
|
|||||||
31
widgets/vehiclelist.cpp
Normal file
31
widgets/vehiclelist.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include "widgets/vehiclelist.h"
|
||||||
|
#include "simulation.h"
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
#include "Driver.h"
|
||||||
|
|
||||||
|
void ui::vehiclelist_panel::render_contents() {
|
||||||
|
for (const TDynamicObject* vehicle : simulation::Vehicles.sequence()) {
|
||||||
|
if (vehicle->Prev())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string name = vehicle->name();
|
||||||
|
double speed = vehicle->GetVelocity();
|
||||||
|
std::string timetable;
|
||||||
|
if (vehicle->Mechanik)
|
||||||
|
timetable = vehicle->Mechanik->TrainName() + ", ";
|
||||||
|
|
||||||
|
std::string label = std::string(name + ", " + timetable + std::to_string(speed) + " km/h");
|
||||||
|
if (!vehicle->Next())
|
||||||
|
ImGui::TextUnformatted(label.c_str());
|
||||||
|
else if (ImGui::TreeNode(vehicle, label.c_str())) {
|
||||||
|
vehicle = vehicle->Next();
|
||||||
|
while (vehicle) {
|
||||||
|
ImGui::TextUnformatted(vehicle->name().c_str());
|
||||||
|
vehicle = vehicle->Next();
|
||||||
|
}
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::ShowDemoWindow();
|
||||||
|
}
|
||||||
10
widgets/vehiclelist.h
Normal file
10
widgets/vehiclelist.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include "uilayer.h"
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
class vehiclelist_panel : public ui_panel {
|
||||||
|
public:
|
||||||
|
vehiclelist_panel() : ui_panel("Vehicle list", true) {}
|
||||||
|
|
||||||
|
void render_contents() override;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user