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

maintenance: event code refactoring

This commit is contained in:
tmj-fstate
2018-09-18 03:57:32 +02:00
parent 4da8b300e8
commit 40afc461fa
23 changed files with 2451 additions and 1644 deletions

View File

@@ -403,7 +403,7 @@ bool TAnimContainer::InMovement()
return (fRotateSpeed != 0.0) || (fTranslateSpeed != 0.0);
}
void TAnimContainer::EventAssign(TEvent *ev)
void TAnimContainer::EventAssign(basic_event *ev)
{ // przypisanie eventu wykonywanego po zakończeniu animacji
evDone = ev;
};

View File

@@ -43,7 +43,7 @@ class TAnimVocaloidFrame
char cBezier[64]; // krzywe Béziera do interpolacji dla x,y,z i obrotu
};
class TEvent;
class basic_event;
class TAnimContainer
{ // opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista
@@ -73,7 +73,7 @@ class TAnimContainer
{ // mogą być animacje klatkowe różnego typu, wskaźniki używa AnimModel
TAnimVocaloidFrame *pMovementData; // wskaźnik do klatki
};
TEvent *evDone; // ewent wykonywany po zakończeniu animacji, np. zapór, obrotnicy
basic_event *evDone; // ewent wykonywany po zakończeniu animacji, np. zapór, obrotnicy
public:
TAnimContainer *pNext;
TAnimContainer *acAnimNext; // lista animacji z eventem, które muszą być przeliczane również bez
@@ -101,9 +101,9 @@ class TAnimContainer
void WillBeAnimated() {
if (pSubModel)
pSubModel->WillBeAnimated(); };
void EventAssign(TEvent *ev);
void EventAssign(basic_event *ev);
inline
TEvent * Event() {
basic_event * Event() {
return evDone; };
};

View File

@@ -14,7 +14,7 @@ http://mozilla.org/MPL/2.0/.
//---------------------------------------------------------------------------
class opengl_renderer;
class TTrack; // odcinek trajektorii
class TEvent;
class basic_event;
class TTrain; // pojazd sterowany
class TDynamicObject; // pojazd w scenerii
struct material_data;

View File

@@ -39,22 +39,22 @@ http://mozilla.org/MPL/2.0/.
// finds point of specified track nearest to specified event. returns: distance to that point from the specified end of the track
// TODO: move this to file with all generic routines, too easy to forget it's here and it may come useful
double
ProjectEventOnTrack( TEvent const *Event, TTrack const *Track, double const Direction ) {
ProjectEventOnTrack( basic_event const *Event, TTrack const *Track, double const Direction ) {
auto const segment = Track->CurrentSegment();
auto const nearestpoint = segment->find_nearest_point( Event->PositionGet() );
auto const nearestpoint = segment->find_nearest_point( Event->input_location() );
return (
Direction > 0 ?
nearestpoint * segment->GetLength() : // measure from point1
( 1.0 - nearestpoint ) * segment->GetLength() ); // measure from point2
};
double GetDistanceToEvent(TTrack const *track, TEvent const *event, double scan_dir, double start_dist, int iter = 0, bool back = false)
double GetDistanceToEvent(TTrack const *track, basic_event const *event, double scan_dir, double start_dist, int iter = 0, bool back = false)
{
if( track == nullptr ) { return start_dist; }
auto const segment = track->CurrentSegment();
auto const pos_event = event->PositionGet();
auto const pos_event = event->input_location();
double len1, len2;
double sd = scan_dir;
double seg_len = scan_dir > 0 ? 0.0 : 1.0;
@@ -181,7 +181,7 @@ TSpeedPos::TSpeedPos(TTrack *track, double dist, int flag)
Set(track, dist, flag);
};
TSpeedPos::TSpeedPos(TEvent *event, double dist, TOrders order)
TSpeedPos::TSpeedPos(basic_event *event, double dist, TOrders order)
{
Set(event, dist, order);
};
@@ -198,9 +198,9 @@ void TSpeedPos::Clear()
void TSpeedPos::CommandCheck()
{ // sprawdzenie typu komendy w evencie i określenie prędkości
TCommandType command = evEvent->Command();
double value1 = evEvent->ValueGet(1);
double value2 = evEvent->ValueGet(2);
TCommandType command = evEvent->input_command();
double value1 = evEvent->input_value(1);
double value2 = evEvent->input_value(2);
switch (command)
{
case TCommandType::cm_ShuntVelocity:
@@ -326,7 +326,7 @@ std::string TSpeedPos::GetName() const
if (iFlags & spTrack) // jeśli tor
return trTrack->name();
else if( iFlags & spEvent ) // jeśli event
return evEvent->asName;
return evEvent->m_name;
else
return "";
}
@@ -358,12 +358,12 @@ bool TSpeedPos::IsProperSemaphor(TOrders order)
return false; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej
}
bool TSpeedPos::Set(TEvent *event, double dist, TOrders order)
bool TSpeedPos::Set(basic_event *event, double dist, TOrders order)
{ // zapamiętanie zdarzenia
fDist = dist;
iFlags = spEnabled | spEvent; // event+istotny
evEvent = event;
vPos = event->PositionGet(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
vPos = event->input_location(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
// zależnie od trybu sprawdzenie czy jest tutaj gdzieś semafor lub tarcza manewrowa
// jeśli wskazuje stop wtedy wystawiamy true jako koniec sprawdzania
@@ -421,13 +421,13 @@ void TController::TableClear()
eSignSkip = nullptr; // nic nie pomijamy
};
std::vector<TEvent *> TController::CheckTrackEvent( TTrack *Track, double const fDirection ) const
std::vector<basic_event *> TController::CheckTrackEvent( TTrack *Track, double const fDirection ) const
{ // sprawdzanie eventów na podanym torze do podstawowego skanowania
std::vector<TEvent *> events;
std::vector<basic_event *> events;
auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) };
for( auto const &event : eventsequence ) {
if( ( event.second != nullptr )
&& ( false == event.second->bEnabled ) ) {
&& ( event.second->m_passive ) ) {
events.emplace_back( event.second );
}
}
@@ -441,7 +441,7 @@ bool TController::TableAddNew()
return true; // false gdy się nałoży
};
bool TController::TableNotFound(TEvent const *Event) const
bool TController::TableNotFound(basic_event const *Event) const
{ // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy)
auto lookup =
std::find_if(
@@ -453,7 +453,7 @@ bool TController::TableNotFound(TEvent const *Event) const
if( ( Global.iWriteLogEnabled & 8 )
&& ( lookup != sSpeedTable.end() ) ) {
WriteLog( "Speed table for " + OwnerName() + " already contains event " + lookup->evEvent->asName );
WriteLog( "Speed table for " + OwnerName() + " already contains event " + lookup->evEvent->m_name );
}
return lookup == sSpeedTable.end();
@@ -558,7 +558,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
TableAddNew(); // zawsze jest true
if (Global.iWriteLogEnabled & 8) {
WriteLog("Speed table for " + OwnerName() + " found new event, " + pEvent->asName);
WriteLog("Speed table for " + OwnerName() + " found new event, " + pEvent->m_name);
}
auto &newspeedpoint = sSpeedTable[iLast];
/*
@@ -788,7 +788,7 @@ void TController::TableCheck(double fDistance)
else if (sSpeedTable[i].iFlags & spEvent) // jeśli event
{
if (sSpeedTable[i].fDist < (
sSpeedTable[i].evEvent->Type == tp_PutValues ?
typeid( *(sSpeedTable[i].evEvent) ) == typeid( putvalues_event ) ?
-fLength :
0)) // jeśli jest z tyłu
if ((mvOccupied->CategoryFlag & 1) ? false :
@@ -840,13 +840,13 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// stop points are irrelevant when not in one of the basic modes
if( ( OrderCurrentGet() & ( Obey_train | Shunt ) ) == 0 ) { continue; }
// first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them
if ( ToLower(sSpeedTable[i].evEvent->CommandGet()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 )
if ( ToLower(sSpeedTable[i].evEvent->input_text()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 )
{ // jeśli nazwa nie jest zgodna
if (sSpeedTable[i].fDist < 300.0 && sSpeedTable[i].fDist > 0) // tylko jeśli W4 jest blisko, przy dwóch może zaczać szaleć
{
// porównuje do następnej stacji, więc trzeba przewinąć do poprzedniej
// nastepnie ustawić następną na aktualną tak żeby prawidłowo ją obsłużył w następnym kroku
if( true == TrainParams->RewindTimeTable( sSpeedTable[ i ].evEvent->CommandGet() ) ) {
if( true == TrainParams->RewindTimeTable( sSpeedTable[ i ].evEvent->input_text() ) ) {
asNextStop = TrainParams->NextStop();
iStationStart = TrainParams->StationIndex;
}
@@ -895,8 +895,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
Drugi paramer dodatni - długość peronu (W4).
*/
auto L = 0.0;
auto Par1 = sSpeedTable[i].evEvent->ValueGet(1);
auto Par2 = sSpeedTable[i].evEvent->ValueGet(2);
auto Par1 = sSpeedTable[i].evEvent->input_value(1);
auto Par2 = sSpeedTable[i].evEvent->input_value(2);
if ((Par2 >= 0) || (fLength < -Par2)) { //użyj tego W4
if (Par1 < 0) {
L = -Par1;
@@ -922,7 +922,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
&& ( ( iDrivigFlags & moveStopCloser ) != 0 ?
sSpeedTable[ i ].fDist + fLength <=
std::max(
std::abs( sSpeedTable[ i ].evEvent->ValueGet( 2 ) ),
std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ),
2.0 * fMaxProximityDist + fLength ) : // fmaxproximitydist typically equals ~50 m
sSpeedTable[ i ].fDist < d_to_next_sem ) );
@@ -943,7 +943,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
if( ( iDrivigFlags & moveDoorOpened ) == 0 ) {
// drzwi otwierać jednorazowo
iDrivigFlags |= moveDoorOpened; // nie wykonywać drugi raz
Doors( true, static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->ValueGet( 2 ) ) ) ) % 10 );
Doors( true, static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10 );
}
if (TrainParams->UpdateMTable( simulation::Time, asNextStop) ) {
@@ -955,7 +955,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
// perform loading/unloading
auto const platformside = static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->ValueGet( 2 ) ) ) ) % 10;
auto const platformside = static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10;
auto const exchangetime = simulation::Station.update_load( pVehicles[ 0 ], *TrainParams, platformside );
WaitingSet( std::max( -fStopTime, exchangetime ) ); // na końcu rozkładu się ustawia 60s i tu by było skrócenie
@@ -1024,7 +1024,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// NOTE: this calculation is expected to run after completing loading/unloading
AutoRewident(); // nastawianie hamulca do jazdy pociągowej
if( static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->ValueGet( 1 ) ) ) ) % 2 ) {
if( static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 1 ) ) ) ) % 2 ) {
// nie podjeżdżać do semafora, jeśli droga nie jest wolna
iDrivigFlags |= moveStopHere;
}
@@ -1162,12 +1162,12 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// ostrożnie interpretować sygnały - semafor może zezwalać na jazdę pociągu z przodu!
iDrivigFlags |= moveVisibility;
// store the ordered restricted speed and don't exceed it until the flag is cleared
VelRestricted = sSpeedTable[ i ].evEvent->ValueGet( 2 );
VelRestricted = sSpeedTable[ i ].evEvent->input_value( 2 );
}
}
if( eSignSkip != sSpeedTable[ i ].evEvent ) {
// jeśli ten SBL nie jest do pominięcia to ma 0 odczytywać
v = sSpeedTable[ i ].evEvent->ValueGet( 1 );
v = sSpeedTable[ i ].evEvent->input_value( 1 );
// TODO sprawdzić do której zmiennej jest przypisywane v i zmienić to tutaj
}
}
@@ -1197,7 +1197,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
if (sSpeedTable[i].fSectionVelocityDist == 0.0)
{
if (Global.iWriteLogEnabled & 8)
WriteLog("TableUpdate: Event is behind. SVD = 0: " + sSpeedTable[i].evEvent->asName);
WriteLog("TableUpdate: Event is behind. SVD = 0: " + sSpeedTable[i].evEvent->m_name);
sSpeedTable[i].iFlags = 0; // jeśli punktowy to kasujemy i nie dajemy ograniczenia na stałe
}
else if (sSpeedTable[i].fSectionVelocityDist < 0.0)
@@ -1211,7 +1211,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
{ // jeśli większe to musi wyjechać za poprzednie
VelLimitLast = sSpeedTable[i].fVelNext;
if (Global.iWriteLogEnabled & 8)
WriteLog("TableUpdate: Event is behind. SVD < 0: " + sSpeedTable[i].evEvent->asName);
WriteLog("TableUpdate: Event is behind. SVD < 0: " + sSpeedTable[i].evEvent->m_name);
sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować
}
}
@@ -1230,7 +1230,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
{ //
VelLimitLast = -1.0;
if (Global.iWriteLogEnabled & 8)
WriteLog("TableUpdate: Event is behind. SVD > 0: " + sSpeedTable[i].evEvent->asName);
WriteLog("TableUpdate: Event is behind. SVD > 0: " + sSpeedTable[i].evEvent->m_name);
sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować
}
}
@@ -1313,7 +1313,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
sSpeedTable[ i ].iFlags = 0;
}
}
else if( sSpeedTable[ i ].evEvent->StopCommand() ) {
else if( sSpeedTable[ i ].evEvent->is_command() ) {
// jeśli prędkość jest zerowa, a komórka zawiera komendę
eSignNext = sSpeedTable[ i ].evEvent; // dla informacji
if( true == TestFlag( iDrivigFlags, moveStopHere ) ) {
@@ -4623,8 +4623,11 @@ TController::UpdateSituation(double dt) {
// jedzie w dowolnym trybie albo Wait_for_orders
if( mvOccupied->Vel < 0.1 ) {
// dopiero jak stanie
PutCommand( eSignNext->CommandGet(), eSignNext->ValueGet( 1 ), eSignNext->ValueGet( 2 ), nullptr );
/*
PutCommand( eSignNext->text(), eSignNext->value( 1 ), eSignNext->value( 2 ), nullptr );
eSignNext->StopCommandSent(); // się wykonało już
*/ // replacement of the above
eSignNext->send_command( *this );
}
}
break;
@@ -5744,22 +5747,22 @@ bool TController::BackwardTrackBusy(TTrack *Track)
return false; // wolny
};
TEvent * TController::CheckTrackEventBackward(double fDirection, TTrack *Track)
basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Track)
{ // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu
// NOTE: this method returns only one event which meets the conditions, due to limitations in the caller
// TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal
auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) };
for( auto const &event : eventsequence ) {
if( ( event.second != nullptr )
&& ( false == event.second->bEnabled )
&& ( event.second->Type == tp_GetValues ) ) {
&& ( event.second->m_passive )
&& ( typeid(*(event.second)) == typeid( getvalues_event ) ) ) {
return event.second;
}
}
return nullptr;
};
TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event)
TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event)
{ // szukanie sygnalizatora w kierunku przeciwnym jazdy (eventu odczytu komórki pamięci)
TTrack *pTrackChVel = Track; // tor ze zmianą prędkości
TTrack *pTrackFrom; // odcinek poprzedni, do znajdywania końca dróg
@@ -5873,7 +5876,7 @@ TCommandType TController::BackwardScan()
// Ra: przy wstecznym skanowaniu prędkość nie ma znaczenia
double scanmax = 1000; // 1000m do tyłu, żeby widział przeciwny koniec stacji
double scandist = scanmax; // zmodyfikuje na rzeczywiście przeskanowane
TEvent *e = NULL; // event potencjalnie od semafora
basic_event *e = NULL; // event potencjalnie od semafora
// opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru wg drugiej osi w kierunku ruchu
TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[0]->RaTrackGet(), e);
auto const dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania
@@ -5896,12 +5899,12 @@ TCommandType TController::BackwardScan()
#endif
// najpierw sprawdzamy, czy semafor czy inny znak został przejechany
auto pos = pVehicles[1]->RearPosition(); // pozycja tyłu
if (e->Type == tp_GetValues)
if( typeid( *e ) == typeid( getvalues_event ) )
{ // przesłać info o zbliżającym się semaforze
#if LOGBACKSCAN
edir += "(" + ( e->asNodeName ) + ")";
#endif
auto sl = e->PositionGet(); // położenie komórki pamięci
auto sl = e->input_location(); // położenie komórki pamięci
auto sem = sl - pos; // wektor do komórki pamięci od końca składu
if (dir.x * sem.x + dir.z * sem.z < 0) {
// jeśli został minięty
@@ -5911,7 +5914,7 @@ TCommandType TController::BackwardScan()
#endif
return TCommandType::cm_Unknown; // nic
}
vmechmax = e->ValueGet(1); // prędkość przy tym semaforze
vmechmax = e->input_value(1); // prędkość przy tym semaforze
// przeliczamy odległość od semafora - potrzebne by były współrzędne początku składu
scandist = sem.Length() - 2; // 2m luzu przy manewrach wystarczy
if( scandist < 0 ) {
@@ -5919,7 +5922,7 @@ TCommandType TController::BackwardScan()
scandist = 0;
}
bool move = false; // czy AI w trybie manewerowym ma dociągnąć pod S1
if( e->Command() == TCommandType::cm_SetVelocity ) {
if( e->input_command() == TCommandType::cm_SetVelocity ) {
if( ( vmechmax == 0.0 ) ?
( OrderCurrentGet() & ( Shunt | Connect ) ) :
( OrderCurrentGet() & Connect ) ) { // przy podczepianiu ignorować wyjazd?
@@ -5963,7 +5966,7 @@ TCommandType TController::BackwardScan()
if (OrderCurrentGet() ? OrderCurrentGet() & (Shunt | Connect) :
true) // w Wait_for_orders też widzi tarcze
{ // reakcja AI w trybie manewrowym dodatkowo na sygnały manewrowe
if (move ? true : e->Command() == TCommandType::cm_ShuntVelocity)
if (move ? true : e->input_command() == TCommandType::cm_ShuntVelocity)
{ // jeśli powyżej było SetVelocity 0 0, to dociągamy pod S1
if ((scandist > fMinProximityDist) ?
(mvOccupied->Vel > 0.0) || (vmechmax == 0.0) :
@@ -5996,7 +5999,7 @@ TCommandType TController::BackwardScan()
WriteLog(
edir + " - [ShuntVelocity] ["
+ to_string( vmechmax, 2 ) + "] ["
+ to_string( e->ValueGet( 2 ), 2 ) + "]" );
+ to_string( e->value( 2 ), 2 ) + "]" );
#endif
return (
vmechmax > 0 ?
@@ -6017,8 +6020,8 @@ TCommandType TController::BackwardScan()
}
} // if (move?...
} // if (OrderCurrentGet()==Shunt)
if (!e->bEnabled) // jeśli skanowany
if (e->StopCommand()) // a podłączona komórka ma komendę
if (e->m_passive) // jeśli skanowany
if (e->is_command()) // a podłączona komórka ma komendę
return TCommandType::cm_Command; // to też się obrócić
} // if (e->Type==tp_GetValues)
} // if (e)

View File

@@ -140,13 +140,13 @@ class TSpeedPos
struct
{
TTrack *trTrack{ nullptr }; // wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica)
TEvent *evEvent{ nullptr }; // połączenie z eventem albo komórką pamięci
basic_event *evEvent{ nullptr }; // połączenie z eventem albo komórką pamięci
};
void CommandCheck();
public:
TSpeedPos(TTrack *track, double dist, int flag);
TSpeedPos(TEvent *event, double dist, TOrders order);
TSpeedPos(basic_event *event, double dist, TOrders order);
TSpeedPos() = default;
void Clear();
bool Update();
@@ -155,7 +155,7 @@ class TSpeedPos
void
UpdateDistance( double dist ) {
fDist -= dist; }
bool Set(TEvent *e, double d, TOrders order = Wait_for_orders);
bool Set(basic_event *e, double d, TOrders order = Wait_for_orders);
void Set(TTrack *t, double d, int f);
std::string TableText() const;
std::string GetName() const;
@@ -181,7 +181,7 @@ class TController {
std::vector<TSpeedPos> sSpeedTable;
double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze
TTrack *tLast = nullptr; // ostatni analizowany tor
TEvent *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
std::size_t SemNextIndex{ std::size_t(-1) };
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
@@ -190,7 +190,7 @@ class TController {
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
public:
double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji
TEvent *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu
int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu
// parametry sterowania pojazdem (stan, hamowanie)
@@ -362,9 +362,9 @@ private:
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
void Lights(int head, int rear);
// Ra: metody obsługujące skanowanie toru
std::vector<TEvent *> CheckTrackEvent(TTrack *Track, double const fDirection ) const;
std::vector<basic_event *> CheckTrackEvent(TTrack *Track, double const fDirection ) const;
bool TableAddNew();
bool TableNotFound(TEvent const *Event) const;
bool TableNotFound(basic_event const *Event) const;
void TableTraceRoute(double fDistance, TDynamicObject *pVehicle);
void TableCheck(double fDistance);
TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc);
@@ -387,8 +387,8 @@ private:
private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
bool BackwardTrackBusy(TTrack *Track);
TEvent *CheckTrackEventBackward(double fDirection, TTrack *Track);
TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event);
basic_event *CheckTrackEventBackward(double fDirection, TTrack *Track);
TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event);
void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos );
TCommandType BackwardScan();

View File

@@ -110,12 +110,12 @@ bool TEventLauncher::Load(cParser *parser)
*parser >> token;
szText = token;
if (token != "*") //*=nie brać command pod uwagę
iCheckMask |= conditional_memstring;
iCheckMask |= basic_event::flags::text;
parser->getTokens();
*parser >> token;
if (token != "*") //*=nie brać wartości 1. pod uwagę
{
iCheckMask |= conditional_memval1;
iCheckMask |= basic_event::flags::value_1;
fVal1 = atof(token.c_str());
}
else
@@ -124,7 +124,7 @@ bool TEventLauncher::Load(cParser *parser)
*parser >> token;
if (token.compare("*") != 0) //*=nie brać wartości 2. pod uwagę
{
iCheckMask |= conditional_memval2;
iCheckMask |= basic_event::flags::value_2;
fVal2 = atof(token.c_str());
}
else
@@ -280,8 +280,8 @@ TEventLauncher::export_as_text_( std::ostream &Output ) const {
<< "condition "
<< asMemCellName << ' '
<< szText << ' '
<< ( ( iCheckMask & conditional_memval1 ) != 0 ? to_string( fVal1 ) : "*" ) << ' '
<< ( ( iCheckMask & conditional_memval2 ) != 0 ? to_string( fVal2 ) : "*" ) << ' ';
<< ( ( iCheckMask & basic_event::flags::value_1 ) != 0 ? to_string( fVal1 ) : "*" ) << ' '
<< ( ( iCheckMask & basic_event::flags::value_2 ) != 0 ? to_string( fVal2 ) : "*" ) << ' ';
}
// footer
Output

View File

@@ -32,8 +32,8 @@ public:
std::string asEvent1Name;
std::string asEvent2Name;
std::string asMemCellName;
TEvent *Event1 { nullptr };
TEvent *Event2 { nullptr };
basic_event *Event1 { nullptr };
basic_event *Event2 { nullptr };
TMemCell *MemCell { nullptr };
int iCheckMask { 0 };
double dRadius { 0.0 };

3014
Event.cpp

File diff suppressed because it is too large Load Diff

663
Event.h
View File

@@ -10,97 +10,142 @@ http://mozilla.org/MPL/2.0/.
#pragma once
#include "classes.h"
#include "dumb3d.h"
#include "scene.h"
#include "names.h"
#include "evlaunch.h"
enum TEventType {
tp_Unknown,
tp_Sound,
tp_Animation,
tp_Lights,
tp_UpdateValues,
tp_GetValues,
tp_PutValues,
tp_Switch,
tp_TrackVel,
tp_Multiple,
tp_AddValues,
tp_CopyValues,
tp_WhoIs,
tp_LogValues,
tp_Visible,
tp_Voltage,
tp_Message,
tp_Friction
};
const int update_memstring = 0x0000001; // zmodyfikować tekst (UpdateValues)
const int update_memval1 = 0x0000002; // zmodyfikować pierwszą wartosć
const int update_memval2 = 0x0000004; // zmodyfikować drugą wartosć
const int update_memadd = 0x0000008; // dodać do poprzedniej zawartości
const int update_load = 0x0000010; // odczytać ładunek
const int conditional_memstring = 0x0000100; // porównanie tekstu
const int conditional_memval1 = 0x0000200; // porównanie pierwszej wartości liczbowej
const int conditional_memval2 = 0x0000400; // porównanie drugiej wartości
const int conditional_trackoccupied = 0x1000000; // jeśli tor zajęty
const int conditional_trackfree = 0x2000000; // jeśli tor wolny
const int conditional_propability = 0x4000000; // zależnie od generatora lizcb losowych
// zdarzenie
class TEvent {
// common event interface
class basic_event {
public:
// constructors
TEvent() = default;
// types
enum flags {
// shared values
text = 1 << 0,
value_1 = 1 << 1,
value_2 = 1 << 2,
// update values
load = 1 << 3,
mode_add = 1 << 4,
// condition values
track_busy = 1 << 3,
track_free = 1 << 4,
probability = 1 << 5
};
// constructor
basic_event() = default;
// destructor
~TEvent();
// metody
void Load(cParser *parser, Math3D::vector3 const &org);
// prepares event for use
virtual ~basic_event();
// methods
// restores event data from provided stream
virtual
void
init();
// legacy method, verifies event condition
bool
test_condition() const;
deserialize( cParser &Input, scene::scratch_data &Scratchpad );
// prepares event for use
virtual
void
init() = 0;
// executes event
virtual
void
run();
// sends basic content of the class in legacy (text) format to provided stream
virtual
void
export_as_text( std::ostream &Output ) const;
static void AddToQuery( TEvent *Event, TEvent *&Start );
std::string CommandGet() const;
TCommandType Command() const;
double ValueGet(int n) const;
glm::dvec3 PositionGet() const;
bool StopCommand() const;
void StopCommandSent();
void Append(TEvent *e);
// adds a sibling event executed together
void
group( scene::group_handle Group );
scene::group_handle
group() const;
append( basic_event *Event );
// returns: true if the event should be executed immediately
virtual
bool
is_instant() const;
// sends content of associated data cell to specified vehicle controller
virtual
void
send_command( TController &Controller );
// returns: true if associated data cell contains a command for vehicle controller
virtual
bool
is_command() const;
// input data access
virtual std::string input_text() const;
virtual TCommandType input_command() const;
virtual double input_value( int Index ) const;
virtual glm::dvec3 input_location() const;
void group( scene::group_handle Group );
scene::group_handle group() const;
// members
std::string asName;
TEventType Type = tp_Unknown;
TEvent *evNext = nullptr; // następny w kolejce
basic_event *m_next { nullptr }; // następny w kolejce // TODO: replace with event list in the manager
basic_event *m_sibling { nullptr }; // kolejny event z tą samą nazwą - od wersji 378
std::string m_name;
bool m_ignored { false }; // replacement for tp_ignored
bool bEnabled = false; // false gdy ma nie być dodawany do kolejki (skanowanie sygnałów)
int iQueued = 0; // ile razy dodany do kolejki
TDynamicObject const *Activator = nullptr;
double fStartTime = 0.0;
double fDelay = 0.0;
double fRandomDelay = 0.0; // zakres dodatkowego opóźnienia // standardowo nie będzie dodatkowego losowego opóźnienia
TEvent *evJoined = nullptr; // kolejny event z tą samą nazwą - od wersji 378
bool m_passive { false }; // false gdy ma nie być dodawany do kolejki (skanowanie sygnałów)
int m_inqueue { 0 }; // ile razy dodany do kolejki
TDynamicObject const *m_activator { nullptr };
double m_launchtime { 0.0 };
double m_delay { 0.0 };
double m_delayrandom { 0.0 }; // zakres dodatkowego opóźnienia // standardowo nie będzie dodatkowego losowego opóźnienia
protected:
// types
using basic_node = std::tuple<std::string, scene::basic_node *>;
using node_sequence = std::vector<basic_node>;
struct event_conditions {
unsigned int flags { 0 };
float probability { 0.0 }; // used by conditional_probability
double match_value_1 { 0.0 }; // used by conditional_memcompare
double match_value_2 { 0.0 }; // used by conditional_memcompare
std::string match_text; // used by conditional_memcompare
basic_event::node_sequence *cells; // used by conditional_memcompare
std::vector<TTrack *> tracks; // used by conditional_track
bool has_else { false };
void deserialize( cParser &Input );
void bind( basic_event::node_sequence *Nodes );
void init();
// verifies whether event meets execution condition(s)
bool test() const;
// sends basic content of the class in legacy (text) format to provided stream
void export_as_text( std::ostream &Output ) const;
};
// methods
template <class TableType_>
void init_targets( TableType_ &Repository, std::string const &Targettype, bool const Logerrors = true );
// returns true if provided token is a an event desription keyword, false otherwise
static bool is_keyword( std::string const &Token );
// members
node_sequence m_targets; // targets of operation performed when this event is executed
private:
// types
// wrapper for binding between editor-supplied name, event, and execution conditional flag
using conditional_event = std::tuple<std::string, TEvent *, bool>;
using basic_node = std::tuple<std::string, scene::basic_node *>;
using basic_sound = std::tuple<std::string, sound_source *>;
// methods
// event type string
virtual std::string type() const = 0;
// deserialization helper, converts provided string to a list of target nodes
virtual void deserialize_targets( std::string const &Input );
// deserialize() subclass details
virtual void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) = 0;
// run() subclass details
virtual void run_() = 0;
// export_as_text() subclass details
virtual void export_as_text_( std::ostream &Output ) const = 0;
// members
scene::group_handle m_group { null_handle }; // group this event belongs to, if any
};
struct update_data {
// specialized event, sends received input to its target(s)
// TBD: replace the generic module with specialized mixins
class input_event : public basic_event {
friend basic_event * make_event( cParser &Input, scene::scratch_data &Scratchpad );
protected:
// types
struct input_data {
unsigned int flags { 0 };
std::string data_text;
double data_value_1 { 0.0 };
@@ -112,80 +157,392 @@ private:
TMemCell const * data_cell() const;
TMemCell * data_cell();
};
struct condition_data {
unsigned int flags { 0 };
float probability { 0.0 }; // used by conditional_probability
double match_value_1 { 0.0 }; // used by conditional_memcompare
double match_value_2 { 0.0 }; // used by conditional_memcompare
std::string match_text; // used by conditional_memcompare
std::vector<TTrack *> tracks; // used by conditional_track
bool has_else { false };
void load( cParser &Input );
};
// methods
void
load_targets( std::string const &Input );
// sends basic content of the class in legacy (text) format to provided stream
template <class TableType_>
void
init_targets( TableType_ &Repository, std::string const &Targettype, bool const Logerrors = true );
void
init_conditions();
std::string
type_to_string() const;
// members
scene::group_handle m_group { null_handle }; // group this event belongs to, if any
update_data m_update;
condition_data m_condition;
std::vector<basic_node> m_targets; // targets of operation performed when this event is executed
input_data m_input;
};
class updatevalues_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
// returns: true if the event should be executed immediately
bool is_instant() const override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
event_conditions m_conditions;
};
class copyvalues_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class getvalues_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
// sends content of associated data cell to specified vehicle controller
void send_command( TController &Controller ) override;
// returns: true if associated data cell contains a command for vehicle controller
bool is_command() const override;
// input data access
std::string input_text() const override;
TCommandType input_command() const override;
double input_value( int Index ) const override;
glm::dvec3 input_location() const override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class putvalues_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
// input data access
std::string input_text() const override;
TCommandType input_command() const override;
double input_value( int Index ) const override;
glm::dvec3 input_location() const override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class whois_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class logvalues_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class multi_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// types
// wrapper for binding between editor-supplied name, event, and execution conditional flag
using conditional_event = std::tuple<std::string, basic_event *, bool>;
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
std::vector<conditional_event> m_children; // events which are placed in the query when this event is executed
// specialized fields
std::vector<float> m_lights; // for tp_lights
bool m_visible { true }; // for tp_visible
double m_velocity { 0.0 }; // for tp_trackvel
std::vector<basic_sound> m_sounds; // for tp_sound
event_conditions m_conditions;
};
class sound_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// types
// wrapper for binding between editor-supplied name and sound object
using basic_sound = std::tuple<std::string, sound_source *>;
// methods
// event type string
std::string type() const override;
// deserialization helper, converts provided string to a list of target nodes
void deserialize_targets( std::string const &Input ) override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
std::vector<basic_sound> m_sounds;
int m_soundmode{ 0 };
int m_soundradiochannel{ 0 };
int m_animationtype{ 0 }; // for tp_animation
};
class animation_event : public basic_event {
public:
// destuctor
~animation_event() override;
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
int m_animationtype{ 0 };
std::array<double, 4> m_animationparams{ 0.0 };
std::string m_animationsubmodel;
std::vector<TAnimContainer *> m_animationcontainers;
std::string m_animationfilename;
std::size_t m_animationfilesize{ 0 };
char *m_animationfiledata{ nullptr };
int m_switchstate{ 0 }; // for tp_switch
float m_switchmoverate{ -1.f };
float m_switchmovedelay{ -1.f };
float m_friction { -1.f }; // for tp_friction
float m_voltage{ -1.f }; // for tp_voltage
};
inline
void
TEvent::group( scene::group_handle Group ) {
m_group = Group;
}
class lights_event : public basic_event {
inline
scene::group_handle
TEvent::group() const {
return m_group;
}
public:
// methods
// prepares event for use
void init() override;
template <class TableType_>
void
TEvent::init_targets( TableType_ &Repository, std::string const &Targettype, bool const Logerrors ) {
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
std::vector<float> m_lights;
};
for( auto &target : m_targets ) {
std::get<scene::basic_node *>( target ) = Repository.find( std::get<std::string>( target ) );
if( std::get<scene::basic_node *>( target ) == nullptr ) {
m_ignored = true; // deaktywacja
if( Logerrors )
ErrorLog( "Bad event: " + type_to_string() + " event \"" + asName + "\" cannot find " + Targettype +" \"" + std::get<std::string>( target ) + "\"" );
}
}
}
class switch_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
int m_switchstate{ 0 };
float m_switchmoverate{ -1.f };
float m_switchmovedelay{ -1.f };
};
class track_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
float m_velocity{ 0.f };
};
class voltage_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
float m_voltage{ -1.f };
};
class visible_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
bool m_visible{ true };
};
class friction_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
float m_friction{ -1.f };
};
class message_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
std::string m_message;
};
basic_event *
make_event( cParser &Input, scene::scratch_data &Scratchpad );
@@ -206,20 +563,22 @@ public:
// adds provided event to the collection. returns: true on success
// TBD, TODO: return handle to the event
bool
insert( TEvent *Event );
insert( basic_event *Event );
inline
bool
insert( TEventLauncher *Launcher ) {
return m_launchers.insert( Launcher ); }
// returns first event in the queue
TEvent *
inline
basic_event *
begin() {
return QueryRootEvent; }
// legacy method, returns pointer to specified event, or null
TEvent *
basic_event *
FindEvent( std::string const &Name );
// legacy method, inserts specified event in the event query
bool
AddToQuery( TEvent *Event, TDynamicObject const *Owner );
AddToQuery( basic_event *Event, TDynamicObject const *Owner );
// legacy method, executes queued events
bool
CheckQuery();
@@ -235,7 +594,7 @@ public:
private:
// types
using event_sequence = std::deque<TEvent *>;
using event_sequence = std::deque<basic_event *>;
using event_map = std::unordered_map<std::string, std::size_t>;
using eventlauncher_sequence = std::vector<TEventLauncher *>;
// members
@@ -245,11 +604,39 @@ private:
event_sequence m_eventqueue;
*/
// legacy version of the above
TEvent *QueryRootEvent { nullptr };
TEvent *m_workevent { nullptr };
basic_event *QueryRootEvent { nullptr };
basic_event *m_workevent { nullptr };
event_map m_eventmap;
basic_table<TEventLauncher> m_launchers;
eventlauncher_sequence m_launcherqueue;
};
inline
void
basic_event::group( scene::group_handle Group ) {
m_group = Group;
}
inline
scene::group_handle
basic_event::group() const {
return m_group;
}
template <class TableType_>
void
basic_event::init_targets( TableType_ &Repository, std::string const &Targettype, bool const Logerrors ) {
for( auto &target : m_targets ) {
std::get<scene::basic_node *>( target ) = Repository.find( std::get<std::string>( target ) );
if( std::get<scene::basic_node *>( target ) == nullptr ) {
m_ignored = true; // deaktywacja
if( Logerrors )
ErrorLog( "Bad event: " + type() + " event \"" + m_name + "\" cannot find " + Targettype +" \"" + std::get<std::string>( target ) + "\"" );
}
}
}
//---------------------------------------------------------------------------

View File

@@ -410,14 +410,14 @@ struct TBoilerType {
};
/*rodzaj odbieraka pradu*/
struct TCurrentCollector {
long CollectorsNo{0}; //musi być tu, bo inaczej się kopie
double MinH{ 0.0 }; double MaxH{ 0.0 }; //zakres ruchu pantografu, nigdzie nie używany
double CSW{ 0.0 }; //szerokość części roboczej (styku) ślizgacza
double MinV{ 0.0 }; double MaxV{ 0.0 }; //minimalne i maksymalne akceptowane napięcie
bool OVP{ false }; //czy jest przekaznik nadnapieciowy
double InsetV{ 0.0 }; //minimalne napięcie wymagane do załączenia
double MinPress{ 0.0 }; //minimalne ciśnienie do załączenia WS
double MaxPress{ 0.0 }; //maksymalne ciśnienie za reduktorem
long CollectorsNo; //musi być tu, bo inaczej się kopie
double MinH; double MaxH; //zakres ruchu pantografu, nigdzie nie używany
double CSW; //szerokość części roboczej (styku) ślizgacza
double MinV; double MaxV; //minimalne i maksymalne akceptowane napięcie
bool OVP; //czy jest przekaznik nadnapieciowy
double InsetV; //minimalne napięcie wymagane do załączenia
double MinPress; //minimalne ciśnienie do załączenia WS
double MaxPress; //maksymalne ciśnienie za reduktorem
//inline TCurrentCollector() {
// CollectorsNo = 0;
// MinH, MaxH, CSW, MinV, MaxV = 0.0;

View File

@@ -8522,7 +8522,7 @@ void TMoverParameters::LoadFIZ_PowerParamsDecode( TPowerParameters &Powerparamet
auto &collectorparameters = Powerparameters.CollectorParameters;
collectorparameters = TCurrentCollector();
collectorparameters = TCurrentCollector { 0, 0, 0, 0, 0, 0, false, 0, 0, 0 };
extract_value( collectorparameters.CollectorsNo, "CollectorsNo", Line, "" );
extract_value( collectorparameters.MinH, "MinH", Line, "" );

View File

@@ -27,25 +27,25 @@ TMemCell::TMemCell( scene::node_data const &Nodedata ) : basic_node( Nodedata )
void TMemCell::UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask )
{
if (CheckMask & update_memadd)
if (CheckMask & basic_event::flags::mode_add)
{ // dodawanie wartości
if( TestFlag( CheckMask, update_memstring ) )
if( TestFlag( CheckMask, basic_event::flags::text ) )
szText += szNewText;
if (TestFlag(CheckMask, update_memval1))
if (TestFlag(CheckMask, basic_event::flags::value_1))
fValue1 += fNewValue1;
if (TestFlag(CheckMask, update_memval2))
if (TestFlag(CheckMask, basic_event::flags::value_2))
fValue2 += fNewValue2;
}
else
{
if( TestFlag( CheckMask, update_memstring ) )
if( TestFlag( CheckMask, basic_event::flags::text ) )
szText = szNewText;
if (TestFlag(CheckMask, update_memval1))
if (TestFlag(CheckMask, basic_event::flags::value_1))
fValue1 = fNewValue1;
if (TestFlag(CheckMask, update_memval2))
if (TestFlag(CheckMask, basic_event::flags::value_2))
fValue2 = fNewValue2;
}
if (TestFlag(CheckMask, update_memstring))
if (TestFlag(CheckMask, basic_event::flags::text))
CommandCheck(); // jeśli zmieniony tekst, próbujemy rozpoznać komendę
}
@@ -120,7 +120,7 @@ void TMemCell::PutCommand( TController *Mech, glm::dvec3 const *Loc ) const
bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1, double const fTestValue2, int const CheckMask ) const {
// porównanie zawartości komórki pamięci z podanymi wartościami
if( TestFlag( CheckMask, conditional_memstring ) ) {
if( TestFlag( CheckMask, basic_event::flags::text ) ) {
// porównać teksty
auto range = szTestText.find( '*' );
if( range != std::string::npos ) {
@@ -137,8 +137,8 @@ bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1,
}
}
// tekst zgodny, porównać resztę
return ( ( !TestFlag( CheckMask, conditional_memval1 ) || ( fValue1 == fTestValue1 ) )
&& ( !TestFlag( CheckMask, conditional_memval2 ) || ( fValue2 == fTestValue2 ) ) );
return ( ( !TestFlag( CheckMask, basic_event::flags::value_1 ) || ( fValue1 == fTestValue1 ) )
&& ( !TestFlag( CheckMask, basic_event::flags::value_2 ) || ( fValue2 == fTestValue2 ) ) );
};
bool TMemCell::IsVelocity() const
@@ -161,7 +161,7 @@ void TMemCell::StopCommandSent()
}
};
void TMemCell::AssignEvents(TEvent *e)
void TMemCell::AssignEvents(basic_event *e)
{ // powiązanie eventu
OnSent = e;
};

View File

@@ -45,7 +45,7 @@ public:
void StopCommandSent();
TCommandType CommandCheck();
bool IsVelocity() const;
void AssignEvents(TEvent *e);
void AssignEvents(basic_event *e);
// members
std::string asTrackName; // McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac
TTrack *Track { nullptr }; // resolved binding with the specified track
@@ -68,7 +68,7 @@ private:
// other
TCommandType eCommand { TCommandType::cm_Unknown };
bool bCommand { false }; // czy zawiera komendę dla zatrzymanego AI
TEvent *OnSent { nullptr }; // event dodawany do kolejki po wysłaniu komendy zatrzymującej skład
basic_event *OnSent { nullptr }; // event dodawany do kolejki po wysłaniu komendy zatrzymującej skład
};

View File

@@ -124,7 +124,7 @@ void TIsolated::Modify(int i, TDynamicObject *o)
multiplayer::WyslijString(asName, 10); // wysłanie pakietu o zwolnieniu
if (pMemCell) // w powiązanej komórce
pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) & ~0xFF,
update_memval2 ); //"zerujemy" ostatnią wartość
basic_event::flags::value_2 ); //"zerujemy" ostatnią wartość
}
}
else
@@ -137,7 +137,7 @@ void TIsolated::Modify(int i, TDynamicObject *o)
if (Global.iMultiplayer) // jeśli multiplayer
multiplayer::WyslijString(asName, 11); // wysłanie pakietu o zajęciu
if (pMemCell) // w powiązanej komórce
pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) | 1, update_memval2 ); // zmieniamy ostatnią wartość na nieparzystą
pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) | 1, basic_event::flags::value_2 ); // zmieniamy ostatnią wartość na nieparzystą
}
}
// pass the event to the parent
@@ -933,7 +933,7 @@ bool TTrack::AssignEvents() {
return ( lookupfail == false );
}
bool TTrack::AssignForcedEvents(TEvent *NewEventPlus, TEvent *NewEventMinus)
bool TTrack::AssignForcedEvents(basic_event *NewEventPlus, basic_event *NewEventMinus)
{ // ustawienie eventów sygnalizacji rozprucia
if (SwitchExtension)
{
@@ -959,7 +959,7 @@ void TTrack::QueueEvents( event_sequence const &Events, TDynamicObject const *Ow
for( auto const &event : Events ) {
if( ( event.second != nullptr )
&& ( event.second->fDelay <= Delaylimit) ) {
&& ( event.second->m_delay <= Delaylimit) ) {
simulation::Events.AddToQuery( event.second, Owner );
}
}
@@ -1115,7 +1115,7 @@ bool TTrack::InMovement()
return false;
};
void TTrack::RaAssign( TAnimModel *am, TEvent *done, TEvent *joined )
void TTrack::RaAssign( TAnimModel *am, basic_event *done, basic_event *joined )
{ // Ra: wiązanie toru z modelem obrotnicy
if (eType == tt_Table)
{
@@ -2839,7 +2839,7 @@ TTrack::export_as_text_( std::ostream &Output ) const {
Output
<< eventsequence.first << ' '
<< ( event.second != nullptr ?
event.second->asName :
event.second->m_name :
event.first )
<< ' ';
}

14
Track.h
View File

@@ -44,7 +44,7 @@ enum TEnvironmentType {
};
// Ra: opracować alternatywny system cieni/świateł z definiowaniem koloru oświetlenia w halach
class TEvent;
class basic_event;
class TTrack;
class TGroundNode;
class TSubRect;
@@ -89,7 +89,7 @@ class TSwitchExtension
bool bMovement = false; // czy w trakcie animacji
scene::basic_cell *pOwner = nullptr; // TODO: convert this to observer pattern
TTrack *pNextAnim = nullptr; // następny tor do animowania
TEvent *evPlus = nullptr,
basic_event *evPlus = nullptr,
*evMinus = nullptr; // zdarzenia sygnalizacji rozprucia
float fVelocity = -1.0; // maksymalne ograniczenie prędkości (ustawianej eventem)
Math3D::vector3 vTrans; // docelowa translacja przesuwnicy
@@ -127,8 +127,8 @@ public:
return pParent; }
// members
std::string asName; // nazwa obiektu, baza do nazw eventów
TEvent *evBusy { nullptr }; // zdarzenie wyzwalane po zajęciu grupy
TEvent *evFree { nullptr }; // zdarzenie wyzwalane po całkowitym zwolnieniu zajętości grupy
basic_event *evBusy { nullptr }; // zdarzenie wyzwalane po zajęciu grupy
basic_event *evFree { nullptr }; // zdarzenie wyzwalane po całkowitym zwolnieniu zajętości grupy
TMemCell *pMemCell { nullptr }; // automatyczna komórka pamięci, która współpracuje z odcinkiem izolowanym
private:
// members
@@ -175,7 +175,7 @@ private:
public:
using dynamics_sequence = std::deque<TDynamicObject *>;
using event_sequence = std::vector<std::pair<std::string, TEvent *> >;
using event_sequence = std::vector<std::pair<std::string, basic_event *> >;
dynamics_sequence Dynamics;
event_sequence
@@ -251,7 +251,7 @@ public:
1 ); }
void Load(cParser *parser, glm::dvec3 const &pOrigin);
bool AssignEvents();
bool AssignForcedEvents(TEvent *NewEventPlus, TEvent *NewEventMinus);
bool AssignForcedEvents(basic_event *NewEventPlus, basic_event *NewEventMinus);
void QueueEvents( event_sequence const &Events, TDynamicObject const *Owner );
void QueueEvents( event_sequence const &Events, TDynamicObject const *Owner, double const Delaylimit );
bool CheckDynamicObject(TDynamicObject *Dynamic);
@@ -272,7 +272,7 @@ public:
void RaOwnerSet( scene::basic_cell *o ) {
if( SwitchExtension ) { SwitchExtension->pOwner = o; } };
bool InMovement(); // czy w trakcie animacji?
void RaAssign( TAnimModel *am, TEvent *done, TEvent *joined );
void RaAssign( TAnimModel *am, basic_event *done, basic_event *joined );
void RaAnimListAdd(TTrack *t);
TTrack * RaAnimate();

View File

@@ -3729,7 +3729,7 @@ void TTrain::OnCommand_generictoggle( TTrain *Train, command_data const &Command
if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
if( item.GetValue() < 0.25 ) {
if( item.GetDesiredValue() < 0.5 ) {
// turn on
// visual feedback
item.UpdateValue( 1.0, Train->dsbSwitch );

View File

@@ -77,7 +77,7 @@ private:
// members
drivermode_input m_input;
std::array<TEvent *, 10> KeyEvents { nullptr }; // eventy wyzwalane z klawiaury
std::array<basic_event *, 10> KeyEvents { nullptr }; // eventy wyzwalane z klawiaury
TCamera Camera;
TCamera DebugCamera;
TDynamicObject *pDynamicNearest { nullptr }; // vehicle nearest to the active camera. TODO: move to camera

View File

@@ -684,7 +684,7 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
if( ( mechanik.VelNext == 0.0 )
&& ( mechanik.eSignNext ) ) {
// jeśli ma zapamiętany event semafora, nazwa eventu semafora
Output.emplace_back( "Current signal: " + Bezogonkow( mechanik.eSignNext->asName ), Global.UITextColor );
Output.emplace_back( "Current signal: " + Bezogonkow( mechanik.eSignNext->m_name ), Global.UITextColor );
}
// distances
@@ -805,19 +805,19 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
&& ( eventtableindex < 30 ) ) {
if( ( false == event->m_ignored )
&& ( true == event->bEnabled ) ) {
&& ( false == event->m_passive ) ) {
auto const delay { " " + to_string( std::max( 0.0, event->fStartTime - time ), 1 ) };
auto const delay { " " + to_string( std::max( 0.0, event->m_launchtime - time ), 1 ) };
textline =
"Delay: " + delay.substr( delay.length() - 6 )
+ ", Event: " + event->asName
+ ( event->Activator ? " (by: " + event->Activator->asName + ")" : "" )
+ ( event->evJoined ? " (joint event)" : "" );
+ ", Event: " + event->m_name
+ ( event->m_activator ? " (by: " + event->m_activator->asName + ")" : "" )
+ ( event->m_sibling ? " (joint event)" : "" );
Output.emplace_back( textline, Global.UITextColor );
++eventtableindex;
}
event = event->evNext;
event = event->m_next;
}
if( Output.empty() ) {
textline = "(no queued events)";

View File

@@ -148,7 +148,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
}
textline += (
event.second != nullptr ?
event.second->asName :
event.second->m_name :
event.first + " (missing)" );
}
textline += "] ";

View File

@@ -64,9 +64,9 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
if( Global.iMultiplayer ) {
auto *event = simulation::Events.FindEvent( std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) );
if( event != nullptr ) {
if( ( event->Type == tp_Multiple )
|| ( event->Type == tp_Lights )
|| ( event->evJoined != 0 ) ) {
if( ( typeid( *event ) == typeid( multi_event ) )
|| ( 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
}

View File

@@ -77,7 +77,7 @@ node_groups::insert( scene::group_handle const Group, scene::basic_node *Node )
// places provided event in specified group
void
node_groups::insert( scene::group_handle const Group, TEvent *Event ) {
node_groups::insert( scene::group_handle const Group, basic_event *Event ) {
// TBD, TODO: automatically unregister the event from its current group?
Event->group( Group );

View File

@@ -16,7 +16,7 @@ namespace scene {
struct basic_group {
// members
std::vector<scene::basic_node *> nodes;
std::vector<TEvent *> events;
std::vector<basic_event *> events;
};
// holds lists of grouped scene nodes
@@ -41,7 +41,7 @@ public:
insert( scene::group_handle const Group, scene::basic_node *Node );
// places provided event in specified group
void
insert( scene::group_handle const Group, TEvent *Event );
insert( scene::group_handle const Group, basic_event *Event );
// grants direct access to specified group
scene::basic_group &
group( scene::group_handle const Group ) {

View File

@@ -244,15 +244,14 @@ void
state_serializer::deserialize_event( cParser &Input, scene::scratch_data &Scratchpad ) {
// TODO: refactor event class and its de/serialization. do offset and rotation after deserialization is done
auto *event = new TEvent();
Math3D::vector3 offset = (
Scratchpad.location.offset.empty() ?
Math3D::vector3() :
Math3D::vector3(
Scratchpad.location.offset.top().x,
Scratchpad.location.offset.top().y,
Scratchpad.location.offset.top().z ) );
event->Load( &Input, offset );
auto *event = make_event( Input, Scratchpad );
if( event == nullptr ) {
// something went wrong at initial stage, move on
skip_until( Input, "endevent" );
return;
}
event->deserialize( Input, Scratchpad );
if( true == simulation::Events.insert( event ) ) {
scene::Groups.insert( scene::Groups.handle(), event );