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

minor refactoring and diagnostics enhancements, fixed some memory leaks, radiostop test command

This commit is contained in:
tmj-fstate
2017-08-30 19:54:43 +02:00
parent decbcd8055
commit e5980f946c
27 changed files with 1584 additions and 1617 deletions

View File

@@ -42,9 +42,9 @@ void TAirCoupler::Init(std::string const &asName, TModel3d *pModel)
{ // wyszukanie submodeli
if (!pModel)
return; // nie ma w czym szukać
pModelOn = pModel->GetFromName( (asName + "_on").c_str() ); // połączony na wprost
pModelOff = pModel->GetFromName( (asName + "_off").c_str() ); // odwieszony
pModelxOn = pModel->GetFromName( (asName + "_xon").c_str() ); // połączony na skos
pModelOn = pModel->GetFromName( asName + "_on" ); // połączony na wprost
pModelOff = pModel->GetFromName( asName + "_off" ); // odwieszony
pModelxOn = pModel->GetFromName( asName + "_xon" ); // połączony na skos
}
void TAirCoupler::Load(cParser *Parser, TModel3d *pModel)

View File

@@ -523,11 +523,11 @@ bool TAnimModel::Load(cParser *parser, bool ter)
return true;
}
TAnimContainer * TAnimModel::AddContainer(char *pName)
TAnimContainer * TAnimModel::AddContainer(std::string const &Name)
{ // dodanie sterowania submodelem dla egzemplarza
if (!pModel)
return NULL;
TSubModel *tsb = pModel->GetFromName(pName);
TSubModel *tsb = pModel->GetFromName(Name);
if (tsb)
{
TAnimContainer *tmp = new TAnimContainer();
@@ -539,16 +539,16 @@ TAnimContainer * TAnimModel::AddContainer(char *pName)
return NULL;
}
TAnimContainer * TAnimModel::GetContainer(char *pName)
TAnimContainer * TAnimModel::GetContainer(std::string const &Name)
{ // szukanie/dodanie sterowania submodelem dla egzemplarza
if (!pName)
if (true == Name.empty())
return pRoot; // pobranie pierwszego (dla obrotnicy)
TAnimContainer *pCurrent;
for (pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->pNext)
// if (pCurrent->GetName()==pName)
if (std::string(pName) == pCurrent->NameGet())
if (Name == pCurrent->NameGet())
return pCurrent;
return AddContainer(pName);
return AddContainer(Name);
}
// przeliczenie animacji - jednorazowo na klatkę

View File

@@ -163,8 +163,8 @@ private:
bool Init(TModel3d *pNewModel);
bool Init(std::string const &asName, std::string const &asReplacableTexture);
bool Load(cParser *parser, bool ter = false);
TAnimContainer * AddContainer(char *pName);
TAnimContainer * GetContainer(char *pName);
TAnimContainer * AddContainer(std::string const &Name);
TAnimContainer * GetContainer(std::string const &Name = "");
int Flags();
void RaAnglesSet(double a, double b, double c)
{

View File

@@ -28,8 +28,8 @@ void TButton::Init(std::string const &asName, TModel3d *pModel, bool bNewOn)
{
if( pModel == nullptr ) { return; }
pModelOn = pModel->GetFromName( (asName + "_on").c_str() );
pModelOff = pModel->GetFromName( (asName + "_off").c_str() );
pModelOn = pModel->GetFromName( asName + "_on" );
pModelOff = pModel->GetFromName( asName + "_off" );
m_state = bNewOn;
Update();
};

View File

@@ -1446,7 +1446,7 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
if( WriteLogFlag ) {
_mkdir( "physicslog\\" );
LogFile.open( std::string( "physicslog\\" + VehicleName + ".dat" ).c_str(),
LogFile.open( std::string( "physicslog\\" + VehicleName + ".dat" ),
std::ios::in | std::ios::out | std::ios::trunc );
#if LOGPRESS == 0
LogFile << std::string( " Time [s] Velocity [m/s] Acceleration [m/ss] Coupler.Dist[m] "
@@ -3337,34 +3337,37 @@ void TController::PhysicsLog()
}
};
bool TController::UpdateSituation(double dt)
{ // uruchamiać przynajmniej raz na sekundę
if ((iDrivigFlags & movePrimary) == 0)
return true; // pasywny nic nie robi
void
TController::UpdateSituation(double dt) {
// uruchamiać przynajmniej raz na sekundę
if( ( iDrivigFlags & movePrimary ) == 0 ) { return; } // pasywny nic nie robi
double AbsAccS = 0;
// double VelReduced; //o ile km/h może przekroczyć dozwoloną prędkość bez hamowania
bool UpdateOK = false;
if (AIControllFlag)
{ // yb: zeby EP nie musial sie bawic z ciesnieniem w PG
// if (mvOccupied->BrakeSystem==ElectroPneumatic)
// mvOccupied->PipePress=0.5; //yB: w SPKS są poprawnie zrobione pozycje
if (mvControlling->SlippingWheels)
{
mvControlling->Sandbox(true); // piasku!
// Controlling->SlippingWheels=false; //a to tu nie ma sensu, flaga używana w dalszej
// części
}
else {
// deactivate sandbox if we aren't slipping
if( mvControlling->SandDose ) {
mvControlling->Sandbox( false );
}
// update timers
ElapsedTime += dt;
WaitingTime += dt;
fBrakeTime -= dt; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
fStopTime += dt; // zliczanie czasu postoju, nie ruszy dopóki ujemne
fActionTime += dt; // czas używany przy regulacji prędkości i zamykaniu drzwi
LastReactionTime += dt;
LastUpdatedTime += dt;
// log vehicle data
if( ( WriteLogFlag )
&& ( LastUpdatedTime > deltalog ) ) {
// zapis do pliku DAT
PhysicsLog();
LastUpdatedTime -= deltalog;
}
if( ( fLastStopExpDist > 0.0 )
&& ( mvOccupied->DistCounter > fLastStopExpDist ) ) {
// zaktualizować wyświetlanie rozkładu
iStationStart = TrainParams->StationIndex;
fLastStopExpDist = -1.0; // usunąć licznik
}
// ABu-160305 testowanie gotowości do jazdy
// Ra: przeniesione z DynObj, skład użytkownika też jest testowany, żeby mu przekazać, że ma
// odhamować
// Ra: przeniesione z DynObj, skład użytkownika też jest testowany, żeby mu przekazać, że ma odhamować
int index = double(BrakeAccTableSize) * (mvOccupied->Vel / mvOccupied->Vmax);
index = std::min(BrakeAccTableSize, std::max(1, index));
fBrake_a0[0] = fBrake_a0[index];
@@ -3373,6 +3376,7 @@ bool TController::UpdateSituation(double dt)
fReady = 0.0; // założenie, że odhamowany
fAccGravity = 0.0; // przyspieszenie wynikające z pochylenia
double dy; // składowa styczna grawitacji, w przedziale <0,1>
double AbsAccS = 0;
TDynamicObject *p = pVehicles[0]; // pojazd na czole składu
while (p)
{ // sprawdzenie odhamowania wszystkich połączonych pojazdów
@@ -3397,22 +3401,22 @@ bool TController::UpdateSituation(double dt)
}
if (fReady < p->MoverParameters->BrakePress)
fReady = p->MoverParameters->BrakePress; // szukanie najbardziej zahamowanego
if ((dy = p->VectorFront().y) != 0.0) // istotne tylko dla pojazdów na pochyleniu
fAccGravity -= p->DirectionGet() * p->MoverParameters->TotalMassxg *
dy; // ciężar razy składowa styczna grawitacji
if( ( dy = p->VectorFront().y ) != 0.0 ) {
// istotne tylko dla pojazdów na pochyleniu
// ciężar razy składowa styczna grawitacji
fAccGravity -= p->DirectionGet() * p->MoverParameters->TotalMassxg * dy;
}
p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła)
}
if (iDirection)
fAccGravity /=
iDirection *
fMass; // siłę generują pojazdy na pochyleniu ale działa ona całość składu, więc a=F/m
if( iDirection ) {
// siłę generują pojazdy na pochyleniu ale działa ona całość składu, więc a=F/m
fAccGravity /= iDirection * fMass;
}
if (!Ready) // v367: jeśli wg powyższych warunków skład nie jest odhamowany
if (fAccGravity < -0.05) // jeśli ma pod górę na tyle, by się stoczyć
// if (mvOccupied->BrakePress<0.08) //to wystarczy, że zadziałają liniowe (nie ma ich
// jeszcze!!!)
// if (mvOccupied->BrakePress<0.08) //to wystarczy, że zadziałają liniowe (nie ma ich jeszcze!!!)
if (fReady < 0.8) // delikatniejszy warunek, obejmuje wszystkie wagony
Ready = true; //żeby uznać za odhamowany
HelpMeFlag = false;
// crude way to deal with automatic door opening on W4 preventing further ride
// for human-controlled vehicles with no door control and dynamic brake auto-activating with door open
@@ -3423,29 +3427,48 @@ bool TController::UpdateSituation(double dt)
Doors( false );
}
// Winger 020304
if (true == AIControllFlag)
{
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
{
if (mvOccupied->ScndPipePress > 4.3) // gdy główna sprężarka bezpiecznie nabije ciśnienie
mvControlling->bPantKurek3 = true; // to można przestawić kurek na zasilanie pantografów z głównej pneumatyki
fVoltage =
0.5 * (fVoltage +
fabs(mvControlling->RunningTraction.TractionVoltage)); // uśrednione napięcie
// sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas
if (fVoltage < mvControlling->EnginePowerSource.CollectorParameters
.MinV) // gdy rozłączenie WS z powodu niskiego napięcia
if (fActionTime >= 0) // jeśli czas oczekiwania nie został ustawiony
fActionTime =
-2 - Random(10); // losowy czas oczekiwania przed ponownym załączeniem jazdy
// basic situational ai operations
// TBD, TODO: move these to main routine, if it's not neccessary for them to fire every time?
if( AIControllFlag ) {
// wheel slip
if( mvControlling->SlippingWheels ) {
mvControlling->Sandbox( true ); // piasku!
}
if (mvOccupied->Vel > 0.0)
{ // jeżeli jedzie
if (iDrivigFlags & moveDoorOpened) // jeśli drzwi otwarte
if (mvOccupied->Vel > 1.0) // nie zamykać drzwi przy drganiach, bo zatrzymanie na W4
// akceptuje niewielkie prędkości
else {
// deactivate sandbox if we aren't slipping
if( mvControlling->SandDose ) {
mvControlling->Sandbox( false );
}
}
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector) {
if( mvOccupied->ScndPipePress > 4.3 ) {
// gdy główna sprężarka bezpiecznie nabije ciśnienie to można przestawić kurek na zasilanie pantografów z głównej pneumatyki
mvControlling->bPantKurek3 = true;
}
// uśrednione napięcie sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas
fVoltage = 0.5 * (fVoltage + std::abs(mvControlling->RunningTraction.TractionVoltage));
if( fVoltage < mvControlling->EnginePowerSource.CollectorParameters.MinV ) {
// gdy rozłączenie WS z powodu niskiego napięcia
if( fActionTime >= 0 ) {
// jeśli czas oczekiwania nie został ustawiony, losowy czas oczekiwania przed ponownym załączeniem jazdy
fActionTime = -2.0 - Random( 10 );
}
}
}
if (mvOccupied->Vel > 0.0) {
// jeżeli jedzie
if( iDrivigFlags & moveDoorOpened ) {
// jeśli drzwi otwarte
if( mvOccupied->Vel > 1.0 ) {
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
Doors( false );
}
}
/*
// NOTE: this section moved all cars to the edge of their respective roads
// it may have some use eventually for collision avoidance,
@@ -3463,8 +3486,7 @@ bool TController::UpdateSituation(double dt)
{
if ((fOverhead2 >= 0.0) || iOverheadZero)
{ // jeśli jazda bezprądowa albo z opuszczonym pantografem
while (DecSpeed(true))
; // zerowanie napędu
while( DecSpeed( true ) ) { ; } // zerowanie napędu
}
if ((fOverhead2 > 0.0) || iOverheadDown)
{ // jazda z opuszczonymi pantografami
@@ -3497,6 +3519,20 @@ bool TController::UpdateSituation(double dt)
}
}
}
// horn control
if( fWarningDuration > 0.0 ) {
// jeśli pozostało coś do wytrąbienia trąbienie trwa nadal
fWarningDuration -= dt;
if( fWarningDuration < 0.05 )
mvOccupied->WarningSignal = 0; // a tu się kończy
}
if( mvOccupied->Vel >= 3.0 ) {
// jesli jedzie, można odblokować trąbienie, bo się wtedy nie włączy
iDrivigFlags &= ~moveStartHornDone; // zatrąbi dopiero jak następnym razem stanie
iDrivigFlags |= moveStartHorn; // i trąbić przed następnym ruszeniem
}
if( ( true == TestFlag( iDrivigFlags, moveStartHornNow ) )
&& ( true == Ready )
&& ( iEngineActive != 0 )
@@ -3508,28 +3544,12 @@ bool TController::UpdateSituation(double dt)
iDrivigFlags &= ~moveStartHornNow; // trąbienie zostało zorganizowane
}
}
ElapsedTime += dt;
WaitingTime += dt;
fBrakeTime -= dt; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
fStopTime += dt; // zliczanie czasu postoju, nie ruszy dopóki ujemne
fActionTime += dt; // czas używany przy regulacji prędkości i zamykaniu drzwi
if (WriteLogFlag)
{
if (LastUpdatedTime > deltalog)
{ // zapis do pliku DAT
PhysicsLog();
if (fabs(mvOccupied->V) > 0.1) // Ra: [m/s]
deltalog = 0.05; // 0.2;
else
deltalog = 0.05; // 1.0;
LastUpdatedTime = 0.0;
}
else
LastUpdatedTime = LastUpdatedTime + dt;
}
// Ra: skanowanie również dla prowadzonego ręcznie, aby podpowiedzieć prędkość
if ((LastReactionTime > std::min(ReactionTime, 2.0)))
{
// main ai update routine
auto const reactiontime = std::min( ReactionTime, 2.0 );
if( LastReactionTime < reactiontime ) { return; }
LastReactionTime -= reactiontime;
// Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna STÓJ
// yB: otóż jest to jedna trzecia czasu napełniania na towarowym; może się przydać przy
// wdrażaniu hamowania, żeby nie ruszało kranem jak głupie
@@ -3559,8 +3579,8 @@ bool TController::UpdateSituation(double dt)
// dla nastawienia G koniecznie należy wydłużyć drogę na czas reakcji
fBrakeDist += 2 * mvOccupied->Vel;
}
// double scanmax=(mvOccupied->Vel>0.0)?3*fDriverDist+fBrakeDist:10.0*fDriverDist;
double scanmax = (
// route scan
double routescanrange = (
mvOccupied->Vel > 5.0 ?
400 + fBrakeDist :
30.0 * fDriverDist ); // 1500m dla stojących pociągów;
@@ -3570,20 +3590,24 @@ bool TController::UpdateSituation(double dt)
// czy stan się nie zmienił.
// 4. Ewentualnie uzupełnić tabelkę informacjami o sygnałach i ograniczeniach, jeśli się
// "zużyła".
TableCheck(scanmax); // wypełnianie tabelki i aktualizacja odległości
TableCheck(routescanrange); // wypełnianie tabelki i aktualizacja odległości
// 5. Sprawdzić stany sygnalizacji zapisanej w tabelce, wyznaczyć prędkości.
// 6. Z tabelki wyznaczyć krytyczną odległość i prędkość (najmniejsze przyspieszenie).
// 7. Jeśli jest inny pojazd z przodu, ewentualnie skorygować odległość i prędkość.
// 8. Ustalić częstotliwość świadomości AI (zatrzymanie precyzyjne - częściej, brak atrakcji
// - rzadziej).
// check for potential colliders
{
auto const scandistance = 300.0 + fBrakeDist;
auto const collisionscanrange = 300.0 + fBrakeDist;
auto rearvehicle = (
pVehicles[ 0 ] == pVehicles[ 1 ] ?
pVehicles[ 0 ] :
pVehicles[ 1 ] );
if( mvOccupied->V >= 0.0 ) {
// for moving vehicle determine heading from velocity; for standing fall back on the set direction
if( ( mvOccupied->V != 0.0 ?
mvOccupied->V > 0.0 :
iDirection > 0 ) ) {
// towards coupler 0
if( ( mvOccupied->V * iDirection < 0.0 )
|| ( ( rearvehicle->NextConnected != nullptr )
@@ -3599,7 +3623,7 @@ bool TController::UpdateSituation(double dt)
pVehicle->DirectionGet() == pVehicles[ 0 ]->DirectionGet() ?
1 :
-1 ),
scandistance );
collisionscanrange );
}
else {
// towards coupler 1
@@ -3617,14 +3641,13 @@ bool TController::UpdateSituation(double dt)
pVehicle->DirectionGet() == pVehicles[ 0 ]->DirectionGet() ?
-1 :
1 ),
scandistance );
collisionscanrange );
}
}
// tu bedzie logika sterowania
if (AIControllFlag) {
if (AIControllFlag)
{ // tu bedzie logika sterowania
if (mvOccupied->CommandIn.Command != "")
if( !mvOccupied->RunInternalCommand() ) {
// rozpoznaj komende bo lokomotywa jej nie rozpoznaje
@@ -3643,7 +3666,7 @@ bool TController::UpdateSituation(double dt)
}
}
// basic emergency stop handling, while at it
if( ( true == mvOccupied->EmergencyBrakeFlag ) // radio-stop
if( ( true == mvOccupied->RadioStopFlag ) // radio-stop
&& ( mvOccupied->Vel == 0.0 ) // and actual stop
&& ( true == mvOccupied->Radio ) ) { // and we didn't touch the radio yet
// turning off the radio should reset the flag, during security system check
@@ -3653,11 +3676,11 @@ bool TController::UpdateSituation(double dt)
m_radiocontroltime = 0.0;
}
else {
m_radiocontroltime += LastReactionTime;
m_radiocontroltime += reactiontime;
}
}
if( ( false == mvOccupied->Radio )
&& ( false == mvOccupied->EmergencyBrakeFlag ) ) {
&& ( false == mvOccupied->RadioStopFlag ) ) {
// otherwise if it's safe to do so, turn the radio back on
if( m_radiocontroltime > 10.0 ) {
// arbitrary 5 sec delay before switching radio back on
@@ -3665,7 +3688,7 @@ bool TController::UpdateSituation(double dt)
m_radiocontroltime = 0.0;
}
else {
m_radiocontroltime += LastReactionTime;
m_radiocontroltime += reactiontime;
}
}
}
@@ -3705,17 +3728,15 @@ bool TController::UpdateSituation(double dt)
}
else // if (pVehicles[0]->MoverParameters->DirAbsolute<0) //jeśli sprzęg 1
{ // sprzęg 1 - próba podczepienia
if (pVehicles[0]->MoverParameters->Couplers[1].Connected) // jeśli jest coś
// wykryte (a
// chyba jest,
// nie?)
if( pVehicles[ 0 ]->MoverParameters->Couplers[ 1 ].Connected ) {
// jeśli jest coś wykryte (a chyba jest, nie?)
if( pVehicles[ 0 ]->MoverParameters->Attach(
1, 2, pVehicles[ 0 ]->MoverParameters->Couplers[ 1 ].Connected,
iCoupler))
{
iCoupler ) ) {
// pVehicles[0]->dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
// pVehicles[0]->dsbCouplerAttach->Play(0,0,0);
}
}
// WriteLog("CoupleDist[1]="+AnsiString(Controlling->Couplers[1].CoupleDist)+",
// Connected[0]="+AnsiString(Controlling->Couplers[1].CouplingFlag));
ok = (pVehicles[0]->MoverParameters->Couplers[1].CouplingFlag ==
@@ -3815,7 +3836,9 @@ bool TController::UpdateSituation(double dt)
// za radą yB ustawiamy pozycję 3 kranu (ruszanie kranem w innych miejscach
// powino zostać wyłączone)
// WriteLog("Zahamowanie składu");
mvOccupied->BrakeLevelSet(mvOccupied->BrakeSystem == ElectroPneumatic ? 1 :
mvOccupied->BrakeLevelSet(
mvOccupied->BrakeSystem == ElectroPneumatic ?
1 :
3 );
double p = mvOccupied->BrakePressureActual.PipePressureVal;
if( p < 3.9 ) {
@@ -4032,19 +4055,13 @@ bool TController::UpdateSituation(double dt)
}
}
}
else if ((VelSignal == 0.0) && (VelNext > 0.0) && (mvOccupied->Vel < 1.0))
if (iCoupler ? true : (iDrivigFlags & moveStopHere) == 0) // Ra: tu jest coś nie
// tak, bo bez tego
// warunku ruszało w
// manewrowym !!!!
else if( ( VelSignal == 0.0 ) && ( VelNext > 0.0 ) && ( mvOccupied->Vel < 1.0 ) ) {
if( iCoupler ? true : ( iDrivigFlags & moveStopHere ) == 0 ) {
// Ra: tu jest coś nie tak, bo bez tego warunku ruszało w manewrowym !!!!
SetVelocity( VelNext, VelNext, stopSem ); // omijanie SBL
} // koniec samoistnego odjeżdżania
if( ( true == AIControllFlag )
&& ( ( true == HelpMeFlag )
|| ( mvControlling->DamageFlag > 0 ) ) ) {
HelpMeFlag = false;
}
}
} // koniec samoistnego odjeżdżania
if( ( true == AIControllFlag)
&& ( true == TestFlag( OrderList[ OrderPos ], Change_direction ) ) ) {
@@ -4087,18 +4104,21 @@ bool TController::UpdateSituation(double dt)
// jeśli ma rozkład i ograniczenie w rozkładzie to nie przekraczać rozkladowej
VelDesired = Global::Min0RSpeed( VelDesired, TrainParams->TTVmax );
}
SetDriverPsyche(); // ustawia AccPreferred (potrzebne tu?)
// Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci
// szukanie optymalnych wartości
AccDesired = AccPreferred; // AccPreferred wynika z osobowości mechanika
VelNext = VelDesired; // maksymalna prędkość wynikająca z innych czynników niż trajektoria ruchu
ActualProximityDist = scanmax; // funkcja Update() może pozostawić wartości bez zmian
// szukanie optymalnych wartości
ActualProximityDist = routescanrange; // funkcja Update() może pozostawić wartości bez zmian
// Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci
TCommandType comm = TableUpdate(VelDesired, ActualProximityDist, VelNext, AccDesired);
switch (comm)
{ // ustawienie VelSignal - trochę proteza = do przemyślenia
case cm_Ready: // W4 zezwolił na jazdę
// ewentualne doskanowanie trasy za W4, który zezwolił na jazdę
TableCheck( scanmax);
TableCheck( routescanrange);
TableUpdate(VelDesired, ActualProximityDist, VelNext, AccDesired); // aktualizacja po skanowaniu
if (VelNext == 0.0)
break; // ale jak coś z przodu zamyka, to ma stać
@@ -4120,45 +4140,43 @@ bool TController::UpdateSituation(double dt)
SetVelocity(VelSignal, VelNext);
break;
case cm_Command: // komenda z komórki
if (!(OrderList[OrderPos] &
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
if (mvOccupied->Vel < 0.1) // dopiero jak stanie
// iDrivigFlags|=moveStopHere moveStopCloser) //chyba że stanął za daleko
// (SU46 w WK staje za daleko)
{
PutCommand(eSignNext->CommandGet(), eSignNext->ValueGet(1),
eSignNext->ValueGet(2), NULL);
if( !( OrderList[ OrderPos ] & ~( Obey_train | Shunt ) ) ) {
// 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 );
eSignNext->StopCommandSent(); // się wykonało już
}
}
break;
}
if (VelNext == 0.0)
if (!(OrderList[OrderPos] &
~(Shunt | Connect))) // jedzie w Shunt albo Connect, albo Wait_for_orders
{ // jeżeli wolnej drogi nie ma, a jest w trybie manewrowym albo oczekiwania
// if
// ((OrderList[OrderPos]&Connect)?pVehicles[0]->fTrackBlock>ActualProximityDist:true)
// //pomiar odległości nie działa dobrze?
// w trybie Connect skanować do tyłu tylko jeśli przed kolejnym sygnałem nie
// ma taboru do podłączenia
if( VelNext == 0.0 ) {
if( !( OrderList[ OrderPos ] & ~( Shunt | Connect ) ) ) {
// jedzie w Shunt albo Connect, albo Wait_for_orders
// w trybie Connect skanować do tyłu tylko jeśli przed kolejnym sygnałem nie ma taboru do podłączenia
// Ra 2F1H: z tym (fTrackBlock) to nie jest najlepszy pomysł, bo lepiej by
// było porównać z odległością od sygnalizatora z przodu
if ((OrderList[OrderPos] & Connect) ? (pVehicles[0]->fTrackBlock > 2000 || pVehicles[0]->fTrackBlock > FirstSemaphorDist) :
true)
if ((comm = BackwardScan()) != cm_Unknown) // jeśli w drugą można jechać
{ // należy sprawdzać odległość od znalezionego sygnalizatora,
// aby w przypadku prędkości 0.1 wyciągnąć najpierw skład za
// sygnalizator
// i dopiero wtedy zmienić kierunek jazdy, oczekując podania
// prędkości >0.5
if (comm == cm_Command) // jeśli komenda Shunt
iDrivigFlags |= moveStopHere; // to ją odbierz bez przemieszczania się (np.
// odczep wagony po dopchnięciu do końca toru)
if( ( OrderList[ OrderPos ] & Connect ) ?
( pVehicles[ 0 ]->fTrackBlock > 2000 || pVehicles[ 0 ]->fTrackBlock > FirstSemaphorDist ) :
true ) {
if( ( comm = BackwardScan() ) != cm_Unknown ) {
// jeśli w drugą można jechać
// należy sprawdzać odległość od znalezionego sygnalizatora,
// aby w przypadku prędkości 0.1 wyciągnąć najpierw skład za sygnalizator
// i dopiero wtedy zmienić kierunek jazdy, oczekując podania prędkości >0.5
if( comm == cm_Command ) {
// jeśli komenda Shunt to ją odbierz bez przemieszczania się (np. odczep wagony po dopchnięciu do końca toru)
iDrivigFlags |= moveStopHere;
}
iDirectionOrder = -iDirection; // zmiana kierunku jazdy
// zmiana kierunku bez psucia kolejnych komend
OrderList[ OrderPos ] = TOrders( OrderList[ OrderPos ] | Change_direction );
}
}
}
}
double vel = mvOccupied->Vel; // prędkość w kierunku jazdy
if (iDirection * mvOccupied->V < 0)
vel = -vel; // ujemna, gdy jedzie w przeciwną stronę, niż powinien
@@ -4348,7 +4366,7 @@ bool TController::UpdateSituation(double dt)
// przeciwnie do zadanego kierunku jazdy
//(AccDesired) porównujemy z (fAccGravity) albo (AbsAccS)
if( ( VelNext >= 0.0 )
&& ( ActualProximityDist <= scanmax )
&& ( ActualProximityDist <= routescanrange )
&& ( vel >= VelNext ) ) {
// gdy zbliża się i jest za szybki do nowej prędkości, albo stoi na zatrzymaniu
if (vel > 0.0) {
@@ -4496,11 +4514,11 @@ bool TController::UpdateSituation(double dt)
SetDriverPsyche();
}
if( ( true == mvOccupied->EmergencyBrakeFlag ) // radio-stop
if( ( true == mvOccupied->RadioStopFlag ) // radio-stop
&& ( mvOccupied->Vel > 0.0 ) ) { // and still moving
// if the radio-stop was issued don't waste effort trying to fight it
while( true == DecSpeed() ) { ; } // just throttle down...
goto maintenance; // ...and don't touch any other controls
return; // ...and don't touch any other controls
}
if (mvControlling->ConvOvldFlag ||
@@ -4518,10 +4536,7 @@ bool TController::UpdateSituation(double dt)
mvControlling->DecScndCtrl(2); // nastawnik bocznikowania na 0
mvControlling->DecMainCtrl(2); // nastawnik jazdy na 0
mvControlling->MainSwitch(true); // Ra: dodałem, bo EN57 stawały po wywaleniu
if (!mvControlling->FuseOn())
HelpMeFlag = true;
else
{
if (mvControlling->FuseOn()) {
++iDriverFailCount;
if (iDriverFailCount > maxdriverfails)
Psyche = Easyman;
@@ -4772,40 +4787,6 @@ bool TController::UpdateSituation(double dt)
}
break; // rzeczy robione przy jezdzie
} // switch (OrderList[OrderPos])
// kasowanie licznika czasu
LastReactionTime = 0.0;
UpdateOK = true;
} // if ((LastReactionTime>Min0R(ReactionTime,2.0)))
else
LastReactionTime += dt;
maintenance:
if ((fLastStopExpDist > 0.0) && (mvOccupied->DistCounter > fLastStopExpDist))
{
iStationStart = TrainParams->StationIndex; // zaktualizować wyświetlanie rozkładu
fLastStopExpDist = -1.0f; // usunąć licznik
}
if (AIControllFlag)
{
if (fWarningDuration > 0.0) // jeśli pozostało coś do wytrąbienia
{ // trąbienie trwa nadal
fWarningDuration = fWarningDuration - dt;
if (fWarningDuration < 0.05)
mvOccupied->WarningSignal = 0; // a tu się kończy
if (ReactionTime > fWarningDuration)
ReactionTime =
fWarningDuration; // wcześniejszy przebłysk świadomości, by zakończyć trąbienie
}
if (mvOccupied->Vel >= 3.0) {
// jesli jedzie, można odblokować trąbienie, bo się wtedy nie włączy
iDrivigFlags &= ~moveStartHornDone; // zatrąbi dopiero jak następnym razem stanie
iDrivigFlags |= moveStartHorn; // i trąbić przed następnym ruszeniem
}
return UpdateOK;
}
else // if (AIControllFlag)
return false; // AI nie obsługuje
}
void TController::JumpToNextOrder()
@@ -5031,14 +5012,6 @@ std::string TController::StopReasonText()
//- rozpoznają tylko zerową prędkość (jako koniec toru i brak podstaw do dalszego skanowania)
//----------------------------------------------------------------------------------------------------------------------
/* //nie używane
double TController::Distance(vector3 &p1,vector3 &n,vector3 &p2)
{//Ra:obliczenie odległości punktu (p1) od płaszczyzny o wektorze normalnym (n) przechodzącej przez
(p2)
return n.x*(p1.x-p2.x)+n.y*(p1.y-p2.y)+n.z*(p1.z-p2.z); //ax1+by1+cz1+d, gdzie d=-(ax2+by2+cz2)
};
*/
bool TController::BackwardTrackBusy(TTrack *Track)
{ // najpierw sprawdzamy, czy na danym torze są pojazdy z innego składu
if( false == Track->Dynamics.empty() ) {
@@ -5062,8 +5035,7 @@ TEvent * TController::CheckTrackEventBackward(double fDirection, TTrack *Track)
return NULL;
};
TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection,
TTrack *Track, TEvent *&Event)
TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&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
@@ -5106,10 +5078,11 @@ TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection,
}
if (Track == pTrackFrom)
Track = NULL; // koniec, tak jak dla torów
if (Track ?
(Track->VelocityGet() == 0.0) || (Track->iDamageFlag & 128) ||
BackwardTrackBusy(Track) :
true)
if( ( Track ?
( ( Track->VelocityGet() == 0.0 )
|| ( Track->iDamageFlag & 128 )
|| ( true == BackwardTrackBusy( Track ) ) ) :
true ) )
{ // gdy dalej toru nie ma albo zerowa prędkość, albo uszkadza pojazd
fDistance = s;
return NULL; // zwraca NULL, że skanowanie nie dało sensownych rezultatów

View File

@@ -217,7 +217,6 @@ class TController
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations
TAction eAction = actSleep; // aktualny stan
bool HelpMeFlag = false; // wystawiane True jesli cos niedobrego sie dzieje
public:
inline TAction GetAction()
{
@@ -320,7 +319,7 @@ class TController
const TLocation &NewLocation, TStopReason reason = stopComm);
bool PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
const vector3 *NewLocation, TStopReason reason = stopComm);
bool UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
// procedury dotyczace rozkazow dla maszynisty
void SetVelocity(double NewVel, double NewVelNext,
TStopReason r = stopNone); // uaktualnia informacje o prędkości

View File

@@ -1945,14 +1945,14 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
compartmentindex < 10 ?
"0" + std::to_string( compartmentindex ) :
std::to_string( compartmentindex ) );
submodel = mdLowPolyInt->GetFromName( compartmentname.c_str() );
submodel = mdLowPolyInt->GetFromName( compartmentname );
if( submodel != nullptr ) {
// if specified compartment was found we check also for potential matching section in the currently assigned load
// NOTE: if the load gets changed this will invalidate stored pointers. TODO: rebuild the table on load change
SectionLightLevels.emplace_back(
submodel,
( mdLoad != nullptr ?
mdLoad->GetFromName( compartmentname.c_str() ):
mdLoad->GetFromName( compartmentname ):
nullptr ),
0.0f );
}
@@ -1965,11 +1965,11 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
for (int i = 0; i < 2; i++)
{
asAnimName = std::string("buffer_left0") + to_string(i + 1);
smBuforLewy[i] = mdModel->GetFromName(asAnimName.c_str());
smBuforLewy[i] = mdModel->GetFromName(asAnimName);
if (smBuforLewy[i])
smBuforLewy[i]->WillBeAnimated(); // ustawienie flagi animacji
asAnimName = std::string("buffer_right0") + to_string(i + 1);
smBuforPrawy[i] = mdModel->GetFromName(asAnimName.c_str());
smBuforPrawy[i] = mdModel->GetFromName(asAnimName);
if (smBuforPrawy[i])
smBuforPrawy[i]->WillBeAnimated();
}
@@ -4212,7 +4212,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for (int i = 0; i < iAnimType[ANIM_PANTS]; i++)
{ // Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string(i + 1);
sm = mdModel->GetFromName(asAnimName.c_str());
sm = mdModel->GetFromName(asAnimName);
pants[i].smElement[0] = sm; // jak NULL, to nie będzie animowany
if (sm)
{ // w EP09 wywalało się tu z powodu NULL
@@ -4304,7 +4304,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) {
// Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string( i + 1 );
sm = mdModel->GetFromName( asAnimName.c_str() );
sm = mdModel->GetFromName( asAnimName );
pants[ i ].smElement[ 1 ] = sm; // jak NULL, to nie będzie animowany
if( sm ) { // w EP09 wywalało się tu z powodu NULL
sm->WillBeAnimated();
@@ -4338,7 +4338,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) {
// Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string( i + 1 );
pants[ i ].smElement[ 2 ] = mdModel->GetFromName( asAnimName.c_str() );
pants[ i ].smElement[ 2 ] = mdModel->GetFromName( asAnimName );
pants[ i ].smElement[ 2 ]->WillBeAnimated();
}
}
@@ -4351,7 +4351,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) {
// Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string( i + 1 );
pants[ i ].smElement[ 3 ] = mdModel->GetFromName( asAnimName.c_str() );
pants[ i ].smElement[ 3 ] = mdModel->GetFromName( asAnimName );
pants[ i ].smElement[ 3 ]->WillBeAnimated();
}
}
@@ -4364,7 +4364,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) {
// Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string( i + 1 );
pants[ i ].smElement[ 4 ] = mdModel->GetFromName( asAnimName.c_str() );
pants[ i ].smElement[ 4 ] = mdModel->GetFromName( asAnimName );
pants[ i ].smElement[ 4 ]->WillBeAnimated();
/* pants[ i ].yUpdate = UpdatePant;
*/ pants[ i ].yUpdate = std::bind( &TDynamicObject::UpdatePant, this, std::placeholders::_1 );
@@ -4498,7 +4498,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for (int i = 1; i <= 4; i++)
{ // McZapkie-050402: wyszukiwanie max 4 wahaczy o nazwie str*
asAnimName = token + std::to_string(i);
smWahacze[i - 1] = mdModel->GetFromName(asAnimName.c_str());
smWahacze[i - 1] = mdModel->GetFromName(asAnimName);
smWahacze[i - 1]->WillBeAnimated();
}
parser.getTokens(); parser >> token;
@@ -4535,7 +4535,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
{ // NBMX wrzesien 2003: wyszukiwanie drzwi o nazwie str*
asAnimName = token + std::to_string(i + 1);
pAnimations[i + j].smAnimated =
mdModel->GetFromName(asAnimName.c_str()); // ustalenie submodelu
mdModel->GetFromName(asAnimName); // ustalenie submodelu
if (pAnimations[i + j].smAnimated)
{ //++iAnimatedDoors;
pAnimations[i + j].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu

View File

@@ -178,6 +178,7 @@ public: // parametry położenia pojazdu dostępne publicznie
int NextConnectedNo; // numer sprzęgu podłączonego z tyłu
int PrevConnectedNo; // numer sprzęgu podłączonego z przodu
double fScanDist; // odległość skanowania torów na obecność innych pojazdów
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
@@ -366,8 +367,6 @@ public: // modele składowe pojazdu
public:
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
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym
// pojazdem)
TDynamicObject * PrevAny();
TDynamicObject * Prev();
TDynamicObject * Next();

View File

@@ -78,7 +78,7 @@ void TEvent::Conditions(cParser *parser, std::string s)
if (!asNodeName.empty())
{ // podczepienie łańcucha, jeśli nie jest pusty
// BUG: source of a memory leak -- the array never gets deleted. fix the destructor
Params[9].asText = new char[asNodeName.length() + 1]; // usuwane i zamieniane na
Params[9].asText = new char[asNodeName.size() + 1]; // usuwane i zamieniane na
// wskaźnik
strcpy(Params[9].asText, asNodeName.c_str());
}
@@ -103,7 +103,7 @@ void TEvent::Conditions(cParser *parser, std::string s)
str = token;
if (str != "*") //"*" - nie brac command pod uwage
{ // zapamiętanie łańcucha do porównania
Params[10].asText = new char[255];
Params[10].asText = new char[str.size() + 1];
strcpy(Params[10].asText, str.c_str());
iFlags |= conditional_memstring;
}
@@ -144,7 +144,6 @@ void TEvent::Load(cParser *parser, vector3 *org)
int ti;
std::string token;
//string str;
char *ptr;
bEnabled = true; // zmieniane na false dla eventów używanych do skanowania sygnałów
@@ -222,14 +221,12 @@ void TEvent::Load(cParser *parser, vector3 *org)
// if (Type==tp_UpdateValues) iFlags=0; //co modyfikować
parser->getTokens(1, false); // case sensitive
*parser >> token;
// str = AnsiString(token.c_str());
Params[0].asText = new char[token.length() + 1]; // BUG: source of memory leak
Params[0].asText = new char[token.size() + 1]; // BUG: source of memory leak
strcpy(Params[0].asText, token.c_str());
if (token != "*") // czy ma zostać bez zmian?
iFlags |= update_memstring;
parser->getTokens();
*parser >> token;
// str = AnsiString(token.c_str());
if (token != "*") // czy ma zostać bez zmian?
{
Params[1].asdouble = atof(token.c_str());
@@ -239,7 +236,6 @@ void TEvent::Load(cParser *parser, vector3 *org)
Params[1].asdouble = 0;
parser->getTokens();
*parser >> token;
// str = AnsiString(token.c_str());
if (token != "*") // czy ma zostać bez zmian?
{
Params[2].asdouble = atof(token.c_str());
@@ -262,7 +258,7 @@ void TEvent::Load(cParser *parser, vector3 *org)
switch (++i)
{ // znaczenie kolejnych parametrów
case 1: // nazwa drugiej komórki (źródłowej)
Params[9].asText = new char[token.length() + 1]; // usuwane i zamieniane na wskaźnik
Params[9].asText = new char[token.size() + 1]; // usuwane i zamieniane na wskaźnik
strcpy(Params[9].asText, token.c_str());
break;
case 2: // maska wartości
@@ -353,7 +349,7 @@ void TEvent::Load(cParser *parser, vector3 *org)
}
else
Params[6].asCommand = cm_Unknown;
Params[0].asText = new char[token.length() + 1];
Params[0].asText = new char[token.size() + 1];
strcpy(Params[0].asText, token.c_str());
parser->getTokens();
*parser >> token;
@@ -561,7 +557,7 @@ void TEvent::Load(cParser *parser, vector3 *org)
{ // eventy rozpoczynające się od "none_" są ignorowane
if (token != "else")
{
Params[i].asText = new char[255];
Params[i].asText = new char[token.size() + 1];
strcpy(Params[i].asText, token.c_str());
if (ti)
iFlags |= conditional_else << i; // oflagowanie dla eventów "else"

View File

@@ -15,8 +15,7 @@ http://mozilla.org/MPL/2.0/.
using namespace Math3D;
typedef enum
{
enum TEventType {
tp_Unknown,
tp_Sound,
tp_SoundPos,
@@ -41,7 +40,7 @@ typedef enum
tp_Voltage,
tp_Message,
tp_Friction
} TEventType;
};
const int update_memstring = 0x0000001; // zmodyfikować tekst (UpdateValues)
const int update_memval1 = 0x0000002; // zmodyfikować pierwszą wartosć

View File

@@ -85,7 +85,7 @@ bool TGauge::Load(cParser &Parser, TModel3d *md1, TModel3d *md2, double mul) {
}
scale *= mul;
TSubModel *submodel = md1->GetFromName( submodelname.c_str() );
TSubModel *submodel = md1->GetFromName( submodelname );
if( scale == 0.0 ) {
ErrorLog( "Scale of 0.0 defined for sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\". Forcing scale of 1.0 to prevent division by 0" );
scale = 1.0;
@@ -93,7 +93,7 @@ bool TGauge::Load(cParser &Parser, TModel3d *md1, TModel3d *md2, double mul) {
if (submodel) // jeśli nie znaleziony
md2 = nullptr; // informacja, że znaleziony
else if (md2) // a jest podany drugi model (np. zewnętrzny)
submodel = md2->GetFromName(submodelname.c_str()); // to może tam będzie, co za różnica gdzie
submodel = md2->GetFromName(submodelname); // to może tam będzie, co za różnica gdzie
if( submodel == nullptr ) {
ErrorLog( "Failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\"" );
}

View File

@@ -1599,7 +1599,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
importedvertices.emplace_back( vertex0 );
}
if( importedvertices.size() % 2 != 0 ) {
ErrorLog( "Lines node specified odd number of vertices, encountered in file \"" + parser->Name() + "\"" );
ErrorLog( "Lines node specified odd number of vertices, encountered in file \"" + parser->Name() + "\" (line " + std::to_string( parser->Line() - 1 ) + ")" );
importedvertices.pop_back();
}
tmp->iType = GL_LINES;
@@ -1654,6 +1654,8 @@ TSubRect * TGround::GetSubRect(int iCol, int iRow)
TEvent * TGround::FindEvent(const std::string &asEventName)
{
if( asEventName.empty() ) { return nullptr; }
auto const lookup = m_eventmap.find( asEventName );
return (
lookup != m_eventmap.end() ?
@@ -1868,7 +1870,7 @@ bool TGround::Init(std::string File)
}
else
{
ErrorLog("Scene parsing error in file \"" + parser.Name() + "\", unexpected token \"" + token + "\"");
ErrorLog("Scene parsing error in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() ) + "), unexpected token \"" + token + "\"");
// break;
}
}
@@ -2208,7 +2210,7 @@ bool TGround::Init(std::string File)
bool TGround::InitEvents()
{ //łączenie eventów z pozostałymi obiektami
TGroundNode *tmp, *trk;
char buff[ 255 ]; std::string cellastext;
std::string cellastext;
int i;
for (TEvent *Current = RootEvent; Current; Current = Current->evNext2)
{
@@ -2216,19 +2218,16 @@ bool TGround::InitEvents()
{
case tp_AddValues: // sumowanie wartości
case tp_UpdateValues: // zmiana wartości
tmp = FindGroundNode(Current->asNodeName,
TP_MEMCELL); // nazwa komórki powiązanej z eventem
tmp = FindGroundNode(Current->asNodeName, TP_MEMCELL); // nazwa komórki powiązanej z eventem
if (tmp)
{ // McZapkie-100302
if (Current->iFlags & (conditional_trackoccupied | conditional_trackfree))
{ // jeśli chodzi o zajetosc toru (tor może być inny, niż wpisany w komórce)
trk = FindGroundNode(Current->asNodeName,
TP_TRACK); // nazwa toru ta sama, co nazwa komórki
trk = FindGroundNode(Current->asNodeName, TP_TRACK); // nazwa toru ta sama, co nazwa komórki
if (trk)
Current->Params[9].asTrack = trk->pTrack;
if (!Current->Params[9].asTrack)
ErrorLog("Bad event: track \"" + Current->asNodeName +
"\" does not exists in \"" + Current->asName + "\"");
ErrorLog("Bad event: track \"" + Current->asNodeName + "\" referenced in event \"" + Current->asName + "\" doesn't exist");
}
Current->Params[4].nGroundNode = tmp;
Current->Params[5].asMemCell = tmp->MemCell; // komórka do aktualizacji
@@ -2241,8 +2240,7 @@ bool TGround::InitEvents()
if (trk)
Current->Params[6].asTrack = trk->pTrack;
else
ErrorLog("Bad memcell: track \"" + tmp->MemCell->asTrackName +
"\" not exists in memcell \"" + tmp->asName + "\"");
ErrorLog("Bad memcell: track \"" + tmp->MemCell->asTrackName + "\" referenced in memcell \"" + tmp->asName + "\" doesn't exist");
}
else
Current->Params[6].asTrack = NULL;
@@ -2250,8 +2248,7 @@ bool TGround::InitEvents()
else
{ // nie ma komórki, to nie będzie działał poprawnie
Current->Type = tp_Ignored; // deaktywacja
ErrorLog("Bad event: \"" + Current->asName + "\" cannot find memcell \"" +
Current->asNodeName + "\"");
ErrorLog("Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
}
break;
case tp_LogValues: // skojarzenie z memcell
@@ -2275,8 +2272,7 @@ bool TGround::InitEvents()
else
{ // nie ma komórki, to nie będzie działał poprawnie
Current->Type = tp_Ignored; // deaktywacja
ErrorLog("Bad event: \"" + Current->asName + "\" cannot find memcell \"" +
Current->asNodeName + "\"");
ErrorLog("Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
}
break;
case tp_CopyValues: // skopiowanie komórki do innej
@@ -2292,15 +2288,13 @@ bool TGround::InitEvents()
if (trk)
Current->Params[6].asTrack = trk->pTrack;
else
ErrorLog("Bad memcell: track \"" + tmp->MemCell->asTrackName +
"\" not exists in memcell \"" + tmp->asName + "\"");
ErrorLog("Bad memcell: track \"" + tmp->MemCell->asTrackName + "\" referenced in memcell \"" + tmp->asName + "\" doesn't exists");
}
else
Current->Params[6].asTrack = NULL;
}
else
ErrorLog("Bad copyvalues: event \"" + Current->asName +
"\" cannot find memcell \"" + Current->asNodeName + "\"");
ErrorLog("Bad event: copyvalues event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
cellastext = Current->Params[ 9 ].asText;
SafeDeleteArray(Current->Params[9].asText); // usunięcie nazwy komórki
tmp = FindGroundNode( cellastext, TP_MEMCELL); // komórka źódłowa
@@ -2309,22 +2303,19 @@ bool TGround::InitEvents()
Current->Params[9].asMemCell = tmp->MemCell; // komórka źródłowa
}
else
ErrorLog("Bad copyvalues: event \"" + Current->asName +
"\" cannot find memcell \"" + cellastext + "\"");
ErrorLog("Bad event: copyvalues event \"" + Current->asName + "\" cannot find memcell \"" + cellastext + "\"");
break;
case tp_Animation: // animacja modelu
tmp = FindGroundNode(Current->asNodeName, TP_MODEL); // egzemplarza modelu do animowania
if (tmp)
{
strcpy(
buff,
Current->Params[9].asText); // skopiowanie nazwy submodelu do bufora roboczego
cellastext = Current->Params[9].asText; // skopiowanie nazwy submodelu do bufora roboczego
SafeDeleteArray(Current->Params[9].asText); // usunięcie nazwy submodelu
if (Current->Params[0].asInt == 4)
Current->Params[9].asModel = tmp->Model; // model dla całomodelowych animacji
else
{ // standardowo przypisanie submodelu
Current->Params[9].asAnimContainer = tmp->Model->GetContainer(buff); // submodel
Current->Params[9].asAnimContainer = tmp->Model->GetContainer(cellastext); // submodel
if (Current->Params[9].asAnimContainer)
{
Current->Params[9].asAnimContainer->WillBeAnimated(); // oflagowanie
@@ -2332,13 +2323,12 @@ bool TGround::InitEvents()
if (!Current->Params[9]
.asAnimContainer->Event()) // nie szukać, gdy znaleziony
Current->Params[9].asAnimContainer->EventAssign(
FindEvent(Current->asNodeName + "." + buff + ":done"));
FindEvent(Current->asNodeName + "." + cellastext + ":done"));
}
}
}
else
ErrorLog("Bad animation: event \"" + Current->asName + "\" cannot find model \"" +
Current->asNodeName + "\"");
ErrorLog("Bad event: animation event \"" + Current->asName + "\" cannot find model \"" + Current->asNodeName + "\"");
Current->asNodeName = "";
break;
case tp_Lights: // zmiana świeteł modelu
@@ -2346,8 +2336,7 @@ bool TGround::InitEvents()
if (tmp)
Current->Params[9].asModel = tmp->Model;
else
ErrorLog("Bad lights: event \"" + Current->asName + "\" cannot find model \"" +
Current->asNodeName + "\"");
ErrorLog("Bad event: lights event \"" + Current->asName + "\" cannot find model \"" + Current->asNodeName + "\"");
Current->asNodeName = "";
break;
case tp_Visible: // ukrycie albo przywrócenie obiektu
@@ -2359,8 +2348,7 @@ bool TGround::InitEvents()
if (tmp)
Current->Params[9].nGroundNode = tmp;
else
ErrorLog("Bad visibility: event \"" + Current->asName + "\" cannot find model \"" +
Current->asNodeName + "\"");
ErrorLog("Bad event: visibility event \"" + Current->asName + "\" cannot find model \"" + Current->asNodeName + "\"");
Current->asNodeName = "";
break;
case tp_Switch: // przełożenie zwrotnicy albo zmiana stanu obrotnicy
@@ -2378,8 +2366,7 @@ bool TGround::InitEvents()
Current->Params[2].asdouble); // przesłanie parametrów
}
else
ErrorLog("Bad switch: event \"" + Current->asName + "\" cannot find track \"" +
Current->asNodeName + "\"");
ErrorLog("Bad event: switch event \"" + Current->asName + "\" cannot find track \"" + Current->asNodeName + "\"");
Current->asNodeName = "";
break;
case tp_Sound: // odtworzenie dźwięku
@@ -2387,8 +2374,7 @@ bool TGround::InitEvents()
if (tmp)
Current->Params[9].tsTextSound = tmp->tsStaticSound;
else
ErrorLog("Bad sound: event \"" + Current->asName +
"\" cannot find static sound \"" + Current->asNodeName + "\"");
ErrorLog("Bad event: sound event \"" + Current->asName + "\" cannot find static sound \"" + Current->asNodeName + "\"");
Current->asNodeName = "";
break;
case tp_TrackVel: // ustawienie prędkości na torze
@@ -2402,8 +2388,7 @@ bool TGround::InitEvents()
Current->Params[9].asTrack = tmp->pTrack;
}
else
ErrorLog("Bad velocity: event \"" + Current->asName +
"\" cannot find track \"" + Current->asNodeName + "\"");
ErrorLog("Bad event: track velocity event \"" + Current->asName + "\" cannot find track \"" + Current->asNodeName + "\"");
}
Current->asNodeName = "";
break;
@@ -2416,54 +2401,53 @@ bool TGround::InitEvents()
if (tmp)
Current->Params[9].asDynamic = tmp->DynamicObject;
else
Error("Event \"" + Current->asName + "\" cannot find dynamic \"" +
Current->asNodeName + "\"");
Error("Bad event: vehicle velocity event \"" + Current->asName + "\" cannot find vehicle \"" + Current->asNodeName + "\"");
}
Current->asNodeName = "";
break;
case tp_Multiple:
if (Current->Params[9].asText != NULL)
{ // przepisanie nazwy do bufora
strcpy(buff, Current->Params[9].asText);
cellastext = Current->Params[ 9 ].asText;
SafeDeleteArray(Current->Params[9].asText);
Current->Params[9].asPointer = NULL; // zerowanie wskaźnika, aby wykryć brak obeiktu
}
else
buff[0] = '\0';
cellastext = "";
if (Current->iFlags & (conditional_trackoccupied | conditional_trackfree))
{ // jeśli chodzi o zajetosc toru
tmp = FindGroundNode(buff, TP_TRACK);
tmp = FindGroundNode(cellastext, TP_TRACK);
if (tmp)
Current->Params[9].asTrack = tmp->pTrack;
if (!Current->Params[9].asTrack)
{
ErrorLog("Bad event: Track \"" + std::string(buff) + "\" does not exist in \"" + Current->asName + "\"");
ErrorLog("Bad event: Track \"" + cellastext + "\" does not exist in \"" + Current->asName + "\"");
Current->iFlags &= ~(conditional_trackoccupied | conditional_trackfree); // zerowanie flag
}
}
else if (Current->iFlags & (conditional_memstring | conditional_memval1 | conditional_memval2))
{ // jeśli chodzi o komorke pamieciową
tmp = FindGroundNode(buff, TP_MEMCELL);
tmp = FindGroundNode(cellastext, TP_MEMCELL);
if (tmp)
Current->Params[9].asMemCell = tmp->MemCell;
if (!Current->Params[9].asMemCell)
{
ErrorLog("Bad event: MemCell \"" + std::string(buff) + "\" does not exist in \"" + Current->asName + "\"");
ErrorLog("Bad event: MemCell \"" + cellastext + "\" does not exist in \"" + Current->asName + "\"");
Current->iFlags &= ~(conditional_memstring | conditional_memval1 | conditional_memval2);
}
}
for (i = 0; i < 8; i++)
for (i = 0; i < 8; ++i)
{
if (Current->Params[i].asText != NULL)
{
strcpy(buff, Current->Params[i].asText);
cellastext = Current->Params[ i ].asText;
SafeDeleteArray(Current->Params[i].asText);
Current->Params[i].asEvent = FindEvent(buff);
Current->Params[i].asEvent = FindEvent(cellastext);
if( !Current->Params[ i ].asEvent ) { // Ra: tylko w logu informacja o braku
if( ( Current->Params[ i ].asText == NULL )
|| ( std::string( Current->Params[ i ].asText ).substr( 0, 5 ) != "none_" ) ) {
WriteLog( "Event \"" + std::string( buff ) + "\" does not exist" );
ErrorLog( "Missed event: " + std::string( buff ) + " in multiple " + Current->asName );
WriteLog( "Event \"" + cellastext + "\" does not exist" );
ErrorLog( "Missed event: " + cellastext + " in multiple " + Current->asName );
}
}
}
@@ -2472,13 +2456,11 @@ bool TGround::InitEvents()
case tp_Voltage: // zmiana napięcia w zasilaczu (TractionPowerSource)
if (!Current->asNodeName.empty())
{
tmp = FindGroundNode(Current->asNodeName,
TP_TRACTIONPOWERSOURCE); // podłączenie zasilacza
tmp = FindGroundNode(Current->asNodeName, TP_TRACTIONPOWERSOURCE); // podłączenie zasilacza
if (tmp)
Current->Params[9].psPower = tmp->psTractionPowerSource;
else
ErrorLog("Bad voltage: event \"" + Current->asName +
"\" cannot find power source \"" + Current->asNodeName + "\"");
ErrorLog("Bad event: voltage event \"" + Current->asName + "\" cannot find power source \"" + Current->asNodeName + "\"");
}
Current->asNodeName = "";
break;
@@ -2501,43 +2483,32 @@ void TGround::InitTracks()
TTrack *tmp; // znaleziony tor
TTrack *Track;
int iConnection;
std::string name;
// tracks=tracksfar=0;
for (Current = nRootOfType[TP_TRACK]; Current; Current = Current->nNext)
{
Track = Current->pTrack;
if (Global::iHiddenEvents & 1)
if (!Current->asName.empty())
{ // jeśli podana jest nazwa torów, można szukać eventów skojarzonych przez nazwę
if (Track->asEvent0Name.empty())
if (FindEvent(Current->asName + ":event0"))
Track->asEvent0Name = Current->asName + ":event0";
if (Track->asEvent1Name.empty())
if (FindEvent(Current->asName + ":event1"))
Track->asEvent1Name = Current->asName + ":event1";
if (Track->asEvent2Name.empty())
if (FindEvent(Current->asName + ":event2"))
Track->asEvent2Name = Current->asName + ":event2";
if (Track->asEventall0Name.empty())
if (FindEvent(Current->asName + ":eventall0"))
Track->asEventall0Name = Current->asName + ":eventall0";
if (Track->asEventall1Name.empty())
if (FindEvent(Current->asName + ":eventall1"))
Track->asEventall1Name = Current->asName + ":eventall1";
if (Track->asEventall2Name.empty())
if (FindEvent(Current->asName + ":eventall2"))
Track->asEventall2Name = Current->asName + ":eventall2";
}
for (Current = nRootOfType[TP_TRACK]; Current; Current = Current->nNext) {
Track = Current->pTrack;
// assign track events
Track->AssignEvents(
Track->asEvent0Name.empty() ? NULL : FindEvent(Track->asEvent0Name),
Track->asEvent1Name.empty() ? NULL : FindEventScan(Track->asEvent1Name),
Track->asEvent2Name.empty() ? NULL : FindEventScan(Track->asEvent2Name));
FindEvent( Track->asEvent0Name ),
FindEvent( Track->asEvent1Name ),
FindEvent( Track->asEvent2Name ) );
Track->AssignallEvents(
Track->asEventall0Name.empty() ? NULL : FindEvent(Track->asEventall0Name),
Track->asEventall1Name.empty() ? NULL : FindEvent(Track->asEventall1Name),
Track->asEventall2Name.empty() ? NULL :
FindEvent(Track->asEventall2Name)); // MC-280503
FindEvent( Track->asEventall0Name ),
FindEvent( Track->asEventall1Name ),
FindEvent( Track->asEventall2Name ) );
if( ( Global::iHiddenEvents & 1 )
&& ( false == Current->asName.empty() ) ) {
// jeśli podana jest nazwa torów, można szukać eventów skojarzonych przez nazwę
Track->AssignEvents(
FindEvent( Current->asName + ":event0" ),
FindEvent( Current->asName + ":event1" ),
FindEvent( Current->asName + ":event2" ) );
Track->AssignallEvents(
FindEvent( Current->asName + ":eventall0" ),
FindEvent( Current->asName + ":eventall1" ),
FindEvent( Current->asName + ":eventall2" ) );
}
switch (Track->eType)
{
case tt_Table: // obrotnicę też łączymy na starcie z innymi torami
@@ -2635,7 +2606,7 @@ void TGround::InitTracks()
FindEvent(Current->asName + ":forced-"));
break;
}
name = Track->IsolatedName(); // pobranie nazwy odcinka izolowanego
std::string const name = Track->IsolatedName(); // pobranie nazwy odcinka izolowanego
if (!name.empty()) // jeśli została zwrócona nazwa
Track->IsolatedEventsAssign(FindEvent(name + ":busy"), FindEvent(name + ":free"));
if (Current->asName.substr(0, 1) ==

View File

@@ -867,7 +867,8 @@ public:
/*
int BrakeStatus = b_off; //0 - odham, 1 - ham., 2 - uszk., 4 - odluzniacz, 8 - antyposlizg, 16 - uzyte EP, 32 - pozycja R, 64 - powrot z R
*/
bool EmergencyBrakeFlag = false; /*hamowanie nagle*/
bool EmergencyBrakeFlag = false; // manual emergency brake
bool RadioStopFlag = false; /*hamowanie nagle*/
int BrakeDelayFlag = 0; /*nastawa opoznienia ham. osob/towar/posp/exp 0/1/2/4*/
int BrakeDelays = 0; /*nastawy mozliwe do uzyskania*/
int BrakeOpModeFlag = 0; /*nastawa trybu pracy PS/PN/EP/MED 1/2/4/8*/
@@ -1082,7 +1083,7 @@ public:
bool IncManualBrakeLevel(int CtrlSpeed);
bool DecManualBrakeLevel(int CtrlSpeed);
bool DynamicBrakeSwitch(bool Switch);
bool EmergencyBrakeSwitch(bool Switch);
bool RadiostopSwitch(bool Switch);
bool AntiSlippingBrake(void);
bool BrakeReleaser(int state);
bool SwitchEPBrake(int state);

View File

@@ -2188,7 +2188,7 @@ void TMoverParameters::SecuritySystemCheck(double dt)
// obsady
// poza tym jest zdefiniowany we wszystkich 3 członach EN57
if ((!Radio))
EmergencyBrakeSwitch(false);
RadiostopSwitch(false);
if ((SecuritySystem.SystemType > 0) && (SecuritySystem.Status > 0) &&
(Battery)) // Ra: EZT ma teraz czuwak w rozrządczym
@@ -2259,7 +2259,7 @@ void TMoverParameters::SecuritySystemCheck(double dt)
}
else if (!Battery)
{ // wyłączenie baterii deaktywuje sprzęt
EmergencyBrakeSwitch(false);
RadiostopSwitch(false);
// SecuritySystem.Status = 0; //deaktywacja czuwaka
}
}
@@ -2777,14 +2777,14 @@ bool TMoverParameters::DynamicBrakeSwitch(bool Switch)
// Q: 20160711
// włączenie / wyłączenie hamowania awaryjnego
// *************************************************************************************************
bool TMoverParameters::EmergencyBrakeSwitch(bool Switch)
bool TMoverParameters::RadiostopSwitch(bool Switch)
{
bool EBS;
if ((BrakeSystem != Individual) && (BrakeCtrlPosNo > 0))
{
if ((!EmergencyBrakeFlag) && Switch)
if ((!RadioStopFlag) && Switch)
{
EmergencyBrakeFlag = Switch;
RadioStopFlag = Switch;
EBS = true;
}
else
@@ -2792,7 +2792,7 @@ bool TMoverParameters::EmergencyBrakeSwitch(bool Switch)
if ((abs(V) < 0.1) &&
(Switch == false)) // odblokowanie hamulca bezpieczenistwa tylko po zatrzymaniu
{
EmergencyBrakeFlag = Switch;
RadioStopFlag = Switch;
EBS = true;
}
else
@@ -3283,7 +3283,7 @@ void TMoverParameters::UpdatePipePressure(double dt)
}
// if(EmergencyBrakeFlag)and(BrakeCtrlPosNo=0)then //ulepszony hamulec bezp.
if ((EmergencyBrakeFlag) || (TestFlag(SecuritySystem.Status, s_SHPebrake)) ||
if ((RadioStopFlag) || (TestFlag(SecuritySystem.Status, s_SHPebrake)) ||
(TestFlag(SecuritySystem.Status, s_CAebrake)) ||
(s_CAtestebrake == true) ||
(TestFlag(EngDmgFlag, 32)) /* or (not Battery)*/) // ulepszony hamulec bezp.
@@ -8266,7 +8266,7 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
}
else if (Command == "Emergency_brake")
{
if (EmergencyBrakeSwitch(floor(CValue1) == 1)) // YB: czy to jest potrzebne?
if (RadiostopSwitch(floor(CValue1) == 1)) // YB: czy to jest potrzebne?
OK = true;
else
OK = false;

View File

@@ -842,23 +842,18 @@ struct ToLower
};
TSubModel *TSubModel::GetFromName(std::string const &search, bool i)
{
return GetFromName(search.c_str(), i);
};
TSubModel *TSubModel::GetFromName(char const *search, bool i)
{
TSubModel *result;
// std::transform(search.begin(),search.end(),search.begin(),ToLower());
// search=search.LowerCase();
// AnsiString name=AnsiString();
std::string search_lc = std::string(search);
std::string search_lc = search;
if (i)
std::transform(search_lc.begin(), search_lc.end(), search_lc.begin(), ::tolower);
std::string pName_lc = pName;
if (i)
std::transform(pName_lc.begin(), pName_lc.end(), pName_lc.begin(), ::tolower);
if (pName.size() && search)
if (pName.size() && search.size())
if (pName_lc == search_lc)
return this;
if (Next)
@@ -1147,23 +1142,19 @@ TModel3d::TModel3d()
Root = NULL;
iFlags = 0;
iSubModelsCount = 0;
iModel = NULL; // tylko jak wczytany model binarny
iNumVerts = 0; // nie ma jeszcze wierzchołków
};
TModel3d::~TModel3d()
{
// SafeDeleteArray(Materials);
if (iFlags & 0x0200)
{ // wczytany z pliku tekstowego, submodele sprzątają same
SafeDelete(Root); // submodele się usuną rekurencyjnie
}
else
{ // wczytano z pliku binarnego (jest właścicielem tablic)
TModel3d::~TModel3d() {
if (iFlags & 0x0200) {
// wczytany z pliku tekstowego, submodele sprzątają same
Root = nullptr;
delete[] iModel; // usuwamy cały wczytany plik i to wystarczy
}
// później się jeszcze usuwa obiekt z którego dziedziczymy tabelę VBO
else {
// wczytano z pliku binarnego (jest właścicielem tablic)
SafeDeleteArray( Root ); // submodele się usuną rekurencyjnie
}
};
TSubModel *TModel3d::AddToNamed(const char *Name, TSubModel *SubModel)
@@ -1190,16 +1181,16 @@ void TModel3d::AddTo(TSubModel *tmp, TSubModel *SubModel)
iFlags |= 0x0200; // submodele są oddzielne
};
TSubModel *TModel3d::GetFromName(const char *sName)
TSubModel *TModel3d::GetFromName(std::string const &Name)
{ // wyszukanie submodelu po nazwie
if (!sName)
if (Name.empty())
return Root; // potrzebne do terenu z E3D
if (iFlags & 0x0200) // wczytany z pliku tekstowego, wyszukiwanie rekurencyjne
return Root ? Root->GetFromName(sName) : nullptr;
return Root ? Root->GetFromName(Name) : nullptr;
else // wczytano z pliku binarnego, można wyszukać iteracyjnie
{
// for (int i=0;i<iSubModelsCount;++i)
return Root ? Root->GetFromName(sName) : nullptr;
return Root ? Root->GetFromName(Name) : nullptr;
}
};
@@ -1455,7 +1446,6 @@ void TSubModel::deserialize(std::istream &s)
void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
{
Root = nullptr;
float4x4 *tm = nullptr;
if( m_geometrybank == null_handle ) {
m_geometrybank = GfxRenderer.Create_Bank();
}
@@ -1478,7 +1468,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
iSubModelsCount = (int)sm_cnt;
Root = new TSubModel[sm_cnt];
size_t pos = s.tellg();
for (size_t i = 0; i < sm_cnt; i++)
for (size_t i = 0; i < sm_cnt; ++i)
{
s.seekg(pos + sm_size * i);
Root[i].deserialize(s);
@@ -1493,18 +1483,13 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
size_t vt_cnt = size / 32;
iNumVerts = (int)vt_cnt;
m_nVertexCount = (int)vt_cnt;
#ifdef EU07_USE_OLD_VERTEXBUFFER
assert( m_pVNT == nullptr );
m_pVNT = new basic_vertex[vt_cnt];
#else
m_pVNT.resize( vt_cnt );
#endif
for (size_t i = 0; i < vt_cnt; i++)
m_pVNT[i].deserialize(s);
*/
// we rely on the SUB chunk coming before the vertex data, and on the overall vertex count matching the size of data in the chunk
// we rely on the SUB chunk coming before the vertex data, and on the overall vertex count matching the size of data in the chunk.
// geometry associated with chunks isn't stored in the same order as the chunks themselves, so we need to sort that out first
std::vector< std::pair<int, int> > submodeloffsets;
std::vector< std::pair<int, int> > submodeloffsets; // vertex data offset, submodel index
submodeloffsets.reserve( iSubModelsCount );
for( int submodelindex = 0; submodelindex < iSubModelsCount; ++submodelindex ) {
auto const &submodel = Root[ submodelindex ];
@@ -1551,23 +1536,23 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
}
else if (type == MAKE_ID4('T', 'R', 'A', '0'))
{
if (tm != nullptr)
if( false == Matrices.empty() )
throw std::runtime_error("e3d: duplicated TRA chunk");
size_t t_cnt = size / 64;
tm = new float4x4[t_cnt];
for (size_t i = 0; i < t_cnt; i++)
tm[i].deserialize_float32(s);
Matrices.resize(t_cnt);
for (size_t i = 0; i < t_cnt; ++i)
Matrices[i].deserialize_float32(s);
}
else if (type == MAKE_ID4('T', 'R', 'A', '1'))
{
if (tm != nullptr)
if( false == Matrices.empty() )
throw std::runtime_error("e3d: duplicated TRA chunk");
size_t t_cnt = size / 128;
tm = new float4x4[t_cnt];
for (size_t i = 0; i < t_cnt; i++)
tm[i].deserialize_float64(s);
Matrices.resize( t_cnt );
for (size_t i = 0; i < t_cnt; ++i)
Matrices[i].deserialize_float64(s);
}
else if (type == MAKE_ID4('T', 'E', 'X', '0'))
{
@@ -1589,17 +1574,10 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
if (!Root)
throw std::runtime_error("e3d: no submodels");
/*
#ifdef EU07_USE_OLD_VERTEXBUFFER
if (!m_pVNT)
#else
if(m_pVNT.empty() )
#endif
throw std::runtime_error("e3d: no vertices");
*/
for (size_t i = 0; (int)i < iSubModelsCount; ++i)
{
Root[i].BinInit( Root, tm, &Textures, &Names, dynamic );
Root[i].BinInit( Root, Matrices.data(), &Textures, &Names, dynamic );
if (Root[i].ChildGet())
Root[i].ChildGet()->Parent = &Root[i];

View File

@@ -173,7 +173,6 @@ public:
void SetTranslate(float3 vNewTransVector);
void SetRotateIK1(float3 vNewAngles);
TSubModel * GetFromName( std::string const &search, bool i = true );
TSubModel * GetFromName(char const *search, bool i = true);
inline float4x4 * GetMatrix() { return fMatrix; };
inline void Hide() { iVisible = 0; };
@@ -232,7 +231,7 @@ public: // Ra: tymczasowo
private:
std::vector<std::string> Textures; // nazwy tekstur
std::vector<std::string> Names; // nazwy submodeli
int *iModel; // zawartość pliku binarnego
std::vector<float4x4> Matrices; // submodel matrices
int iSubModelsCount; // Ra: używane do tworzenia binarnych
std::string asBinary; // nazwa pod którą zapisać model binarny
std::string m_filename;
@@ -240,7 +239,7 @@ public:
inline TSubModel * GetSMRoot() { return (Root); };
TModel3d();
~TModel3d();
TSubModel * GetFromName(const char *sName);
TSubModel * GetFromName(std::string const &Name);
TSubModel * AddToNamed(const char *Name, TSubModel *SubModel);
void AddTo(TSubModel *tmp, TSubModel *SubModel);
void LoadFromTextFile(std::string const &FileName, bool dynamic);

View File

@@ -446,7 +446,7 @@ void TPythonScreens::init(cParser &parser, TModel3d *model, std::string const &n
>> asPyClassName;
std::string subModelName = ToLower( asSubModelName );
std::string pyClassName = ToLower( asPyClassName );
TSubModel *subModel = model->GetFromName(subModelName.c_str());
TSubModel *subModel = model->GetFromName(subModelName);
if (subModel == NULL)
{
WriteLog( "Python Screen: submodel " + subModelName + " not found - Ignoring screen" );

170
Track.cpp
View File

@@ -778,145 +778,127 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
}
}
// TODO: refactor this mess
bool TTrack::AssignEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2)
{
bool bError = false;
if (!evEvent0)
{
if (NewEvent0)
{
if( NewEvent0 == nullptr ) {
if( false == asEvent0Name.empty() ) {
ErrorLog( "Bad event: event \"" + asEvent0Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
}
else {
if( evEvent0 == nullptr ) {
evEvent0 = NewEvent0;
asEvent0Name = "";
iEvents |= 1; // sumaryczna informacja o eventach
}
else
{
if (!asEvent0Name.empty())
{
ErrorLog("Bad track: Event0 \"" + asEvent0Name +
"\" does not exist");
else {
ErrorLog( "Bad track: event \"" + NewEvent0->asName + "\" cannot be assigned to track, track already has one" );
bError = true;
}
}
}
else
{
ErrorLog( "Bad track: Event0 cannot be assigned to track, track already has one");
if( NewEvent1 == nullptr ) {
if( false == asEvent1Name.empty() ) {
ErrorLog( "Bad event: event \"" + asEvent1Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
if (!evEvent1)
{
if (NewEvent1)
{
}
else {
if( evEvent1 == nullptr ) {
evEvent1 = NewEvent1;
asEvent1Name = "";
iEvents |= 2; // sumaryczna informacja o eventach
}
else if (!asEvent1Name.empty())
{ // Ra: tylko w logu informacja
ErrorLog("Bad track: Event1 \"" + asEvent1Name + "\" does not exist");
else {
ErrorLog( "Bad track: event \"" + NewEvent1->asName + "\" cannot be assigned to track, track already has one" );
bError = true;
}
}
else
{
ErrorLog("Bad track: Event1 cannot be assigned to track, track already has one");
if( NewEvent2 == nullptr ) {
if( false == asEvent2Name.empty() ) {
ErrorLog( "Bad event: event \"" + asEvent2Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
if (!evEvent2)
{
if (NewEvent2)
{
}
else {
if( evEvent2 == nullptr ) {
evEvent2 = NewEvent2;
asEvent2Name = "";
iEvents |= 4; // sumaryczna informacja o eventach
}
else if (!asEvent2Name.empty())
{ // Ra: tylko w logu informacja
ErrorLog("Bad track: Event2 \"" + asEvent2Name + "\" does not exist");
else {
ErrorLog( "Bad track: event \"" + NewEvent2->asName + "\" cannot be assigned to track, track already has one" );
bError = true;
}
}
else
{
ErrorLog("Bad track: Event2 cannot be assigned to track, track already has one");
bError = true;
}
return !bError;
return ( bError == false );
}
bool TTrack::AssignallEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2)
{
bool bError = false;
if (!evEventall0)
{
if (NewEvent0)
{
if( NewEvent0 == nullptr ) {
if( false == asEventall0Name.empty() ) {
ErrorLog( "Bad event: event \"" + asEventall0Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
}
else {
if( evEventall0 == nullptr ) {
evEventall0 = NewEvent0;
asEventall0Name = "";
iEvents |= 8; // sumaryczna informacja o eventach
}
else
{
if (!asEvent0Name.empty())
{
Error("Eventall0 \"" + asEventall0Name +
"\" does not exist");
else {
ErrorLog( "Bad track: event \"" + NewEvent0->asName + "\" cannot be assigned to track, track already has one" );
bError = true;
}
}
}
else
{
Error("Eventall0 cannot be assigned to track, track already has one");
if( NewEvent1 == nullptr ) {
if( false == asEventall1Name.empty() ) {
ErrorLog( "Bad event: event \"" + asEventall1Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
if (!evEventall1)
{
if (NewEvent1)
{
evEventall1 = NewEvent1;
}
else {
if( evEventall1 == nullptr ) {
evEventall1 = NewEvent0;
asEventall1Name = "";
iEvents |= 16; // sumaryczna informacja o eventach
}
else
{
if (!asEvent0Name.empty())
{ // Ra: tylko w logu informacja
WriteLog("Eventall1 \"" + asEventall1Name + "\" does not exist");
else {
ErrorLog( "Bad track: event \"" + NewEvent1->asName + "\" cannot be assigned to track, track already has one" );
bError = true;
}
}
}
else
{
Error("Eventall1 cannot be assigned to track, track already has one");
if( NewEvent2 == nullptr ) {
if( false == asEventall2Name.empty() ) {
ErrorLog( "Bad event: event \"" + asEventall2Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
if (!evEventall2)
{
if (NewEvent2)
{
evEventall2 = NewEvent2;
}
else {
if( evEventall2 == nullptr ) {
evEventall2 = NewEvent0;
asEventall2Name = "";
iEvents |= 32; // sumaryczna informacja o eventach
}
else
{
if (!asEvent0Name.empty())
{ // Ra: tylko w logu informacja
WriteLog("Eventall2 \"" + asEventall2Name +
"\" does not exist");
else {
ErrorLog( "Bad track: event \"" + NewEvent2->asName + "\" cannot be assigned to track, track already has one" );
bError = true;
}
}
}
else
{
Error("Eventall2 cannot be assigned to track, track already has one");
bError = true;
}
return !bError;
return ( bError == false );
}
bool TTrack::AssignForcedEvents(TEvent *NewEventPlus, TEvent *NewEventMinus)
@@ -1079,8 +1061,10 @@ bool TTrack::InMovement()
if (!SwitchExtension->CurrentIndex)
return false; // 0=zablokowana się nie animuje
// trzeba każdorazowo porównywać z kątem modelu
TAnimContainer *ac =
SwitchExtension->pModel ? SwitchExtension->pModel->GetContainer(NULL) : NULL;
TAnimContainer *ac = (
SwitchExtension->pModel ?
SwitchExtension->pModel->GetContainer() :
nullptr );
return ac ?
(ac->AngleGet() != SwitchExtension->fOffset) ||
!(ac->TransGet() == SwitchExtension->vTrans) :
@@ -1090,10 +1074,7 @@ bool TTrack::InMovement()
}
return false;
};
void TTrack::RaAssign(TGroundNode *gn, TAnimContainer *ac){
// Ra: wiązanie toru z modelem obrotnicy
// if (eType==tt_Table) SwitchExtension->pAnim=p;
};
void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined)
{ // Ra: wiązanie toru z modelem obrotnicy
if (eType == tt_Table)
@@ -1104,8 +1085,8 @@ void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joi
SwitchExtension->evPlus =
joined; // event potwierdzenia połączenia (gdy nie znajdzie, to się nie połączy)
if (am)
if (am->GetContainer(NULL)) // może nie być?
am->GetContainer(NULL)->EventAssign(done); // zdarzenie zakończenia animacji
if (am->GetContainer()) // może nie być?
am->GetContainer()->EventAssign(done); // zdarzenie zakończenia animacji
}
};
@@ -2172,9 +2153,10 @@ TTrack * TTrack::RaAnimate()
SwitchExtension->CurrentIndex) // 0=zablokowana się nie animuje
{ // trzeba każdorazowo porównywać z kątem modelu
// //pobranie kąta z modelu
TAnimContainer *ac = SwitchExtension->pModel ?
SwitchExtension->pModel->GetContainer(NULL) :
NULL; // pobranie głównego submodelu
TAnimContainer *ac = (
SwitchExtension->pModel ?
SwitchExtension->pModel->GetContainer() : // pobranie głównego submodelu
nullptr );
if (ac)
if ((ac->AngleGet() != SwitchExtension->fOffset) ||
!(ac->TransGet() ==

View File

@@ -230,7 +230,6 @@ public:
if (SwitchExtension)
SwitchExtension->pOwner = o; };
bool InMovement(); // czy w trakcie animacji?
void RaAssign(TGroundNode *gn, TAnimContainer *ac);
void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined);
void RaAnimListAdd(TTrack *t);
TTrack * RaAnimate();

View File

@@ -264,6 +264,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::hornlowactivate, &TTrain::OnCommand_hornlowactivate },
{ user_command::hornhighactivate, &TTrain::OnCommand_hornhighactivate },
{ user_command::radiotoggle, &TTrain::OnCommand_radiotoggle },
{ user_command::radiostoptest, &TTrain::OnCommand_radiostoptest },
{ user_command::generictoggle0, &TTrain::OnCommand_generictoggle },
{ user_command::generictoggle1, &TTrain::OnCommand_generictoggle },
{ user_command::generictoggle2, &TTrain::OnCommand_generictoggle },
@@ -905,7 +906,7 @@ void TTrain::OnCommand_trainbrakeemergency( TTrain *Train, command_data const &C
Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->Handle->GetPos( bh_EB ) );
if( Train->mvOccupied->BrakeCtrlPosNo <= 0.1 ) {
// hamulec bezpieczeństwa dla wagonów
Train->mvOccupied->EmergencyBrakeFlag = true;
Train->mvOccupied->RadioStopFlag = true;
}
}
}
@@ -2036,6 +2037,10 @@ void TTrain::OnCommand_headlighttoggleleft( TTrain *Train, command_data const &C
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left;
// visual feedback
Train->ggLeftLightButton.UpdateValue( 1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable marker light
if( Train->ggLeftEndLightButton.SubModel == nullptr ) {
Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::redmarker_left;
}
}
else {
//turn off
@@ -2065,6 +2070,10 @@ void TTrain::OnCommand_headlighttoggleright( TTrain *Train, command_data const &
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right;
// visual feedback
Train->ggRightLightButton.UpdateValue( 1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable marker light
if( Train->ggRightEndLightButton.SubModel == nullptr ) {
Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::redmarker_right;
}
}
else {
//turn off
@@ -2122,14 +2131,30 @@ void TTrain::OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &C
// turn on
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left;
// visual feedback
if( Train->ggLeftEndLightButton.SubModel != nullptr ) {
Train->ggLeftEndLightButton.UpdateValue( 1.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggLeftLightButton.UpdateValue( -1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable the headlight
Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::headlight_left;
}
}
else {
//turn off
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left;
// visual feedback
if( Train->ggLeftEndLightButton.SubModel != nullptr ) {
Train->ggLeftEndLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggLeftLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
}
}
}
@@ -2151,14 +2176,30 @@ void TTrain::OnCommand_redmarkertoggleright( TTrain *Train, command_data const &
// turn on
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right;
// visual feedback
if( Train->ggRightEndLightButton.SubModel != nullptr ) {
Train->ggRightEndLightButton.UpdateValue( 1.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggRightLightButton.UpdateValue( -1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable the headlight
Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::headlight_right;
}
}
else {
//turn off
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right;
// visual feedback
if( Train->ggRightEndLightButton.SubModel != nullptr ) {
Train->ggRightEndLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggRightLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
}
}
}
@@ -2731,14 +2772,21 @@ void TTrain::OnCommand_radiotoggle( TTrain *Train, command_data const &Command )
}
}
void TTrain::OnCommand_radiostoptest( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
Train->Dynamic()->RadioStop();
}
}
void TTrain::OnKeyDown(int cKey)
{ // naciśnięcie klawisza
bool isEztOer;
isEztOer = ((mvControlled->TrainType == dt_EZT) && (mvControlled->Battery == true) &&
(mvControlled->EpFuse == true) && (mvOccupied->BrakeSubsystem == ss_ESt) &&
(mvControlled->ActiveDir != 0)); // od yB
// isEztOer=(mvControlled->TrainType==dt_EZT)&&(mvControlled->Mains)&&(mvOccupied->BrakeSubsystem==ss_ESt)&&(mvControlled->ActiveDir!=0);
// isEztOer=((mvControlled->TrainType==dt_EZT)&&(mvControlled->Battery==true)&&(mvControlled->EpFuse==true)&&(mvOccupied->BrakeSubsystem==Oerlikon)&&(mvControlled->ActiveDir!=0));
bool const isEztOer =
( ( mvControlled->TrainType == dt_EZT )
&& ( mvControlled->Battery == true )
&& ( mvControlled->EpFuse == true )
&& ( mvOccupied->BrakeSubsystem == ss_ESt )
&& ( mvControlled->ActiveDir != 0 ) ); // od yB
if (Global::shiftState)
{ // wciśnięty [Shift]

View File

@@ -188,6 +188,7 @@ class TTrain
static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command );
static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command );
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
// members

View File

@@ -62,6 +62,7 @@ commanddescription_sequence Commands_descriptions = {
{ "hornlowactivate", command_target::vehicle },
{ "hornhighactivate", command_target::vehicle },
{ "radiotoggle", command_target::vehicle },
{ "radiostoptest", command_target::vehicle },
/*
const int k_FailedEngineCutOff = 35;
*/
@@ -118,10 +119,6 @@ const int k_ProgramHelp = 48;
{ "interiorlightdimtoggle", command_target::vehicle },
{ "instrumentlighttoggle", command_target::vehicle },
/*
const int k_Univ1 = 66;
const int k_Univ2 = 67;
const int k_Univ3 = 68;
const int k_Univ4 = 69;
const int k_EndSign = 70;
const int k_Active = 71;
*/

View File

@@ -57,6 +57,7 @@ enum class user_command {
hornlowactivate,
hornhighactivate,
radiotoggle,
radiostoptest,
/*
const int k_FailedEngineCutOff = 35;
*/

View File

@@ -250,6 +250,8 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_A | keymodifier::shift },
// radiotoggle
{ GLFW_KEY_R | keymodifier::control },
// radiostoptest
{ GLFW_KEY_R | keymodifier::shift | keymodifier::control },
// viewturn
{ -1 },
// movevector

View File

@@ -21,32 +21,32 @@ http://mozilla.org/MPL/2.0/.
// cParser -- generic class for parsing text data.
// constructors
cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction )
{
LoadTraction = Loadtraction;
cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction ) :
mPath(Path),
LoadTraction( Loadtraction ) {
// build comments map
mComments.insert(commentmap::value_type("/*", "*/"));
mComments.insert(commentmap::value_type("//", "\n"));
// mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane
// store to calculate sub-sequent includes from relative path
mPath = Path;
if( Type == buffertype::buffer_FILE ) {
mFile = Stream;
}
// reset pointers and attach proper type of buffer
switch (Type)
{
case buffer_FILE:
switch (Type) {
case buffer_FILE: {
Path.append( Stream );
mStream = new std::ifstream(Path.c_str());
mStream = std::make_shared<std::ifstream>( Path );
break;
case buffer_TEXT:
mStream = new std::istringstream(Stream);
break;
default:
mStream = NULL;
}
mIncludeParser = NULL;
case buffer_TEXT: {
mStream = std::make_shared<std::istringstream>( Stream );
break;
}
default: {
break;
}
}
// calculate stream size
if (mStream)
{
@@ -56,19 +56,14 @@ cParser::cParser( std::string const &Stream, buffertype const Type, std::string
else {
mSize = mStream->rdbuf()->pubseekoff( 0, std::ios_base::end );
mStream->rdbuf()->pubseekoff( 0, std::ios_base::beg );
mLine = 1;
}
}
else
mSize = 0;
}
// destructor
cParser::~cParser()
{
if (mIncludeParser)
delete mIncludeParser;
if (mStream)
delete mStream;
cParser::~cParser() {
mComments.clear();
}
@@ -157,7 +152,7 @@ std::string cParser::readToken(bool ToLower, const char *Break)
// see if there's include parsing going on. clean up when it's done.
if (mIncludeParser)
{
token = (*mIncludeParser).readToken(ToLower, Break);
token = mIncludeParser->readToken(ToLower, Break);
if (!token.empty())
{
pos = token.find("(p");
@@ -182,13 +177,12 @@ std::string cParser::readToken(bool ToLower, const char *Break)
}
else
{
delete mIncludeParser;
mIncludeParser = NULL;
parameters.clear();
}
}
// get the token yourself if there's no child to delegate it to.
char c;
char c { 0 };
do
{
while (mStream->peek() != EOF && strchr(Break, c = mStream->get()) == NULL)
@@ -201,6 +195,10 @@ std::string cParser::readToken(bool ToLower, const char *Break)
if (trimComments(token)) // don't glue together words separated with comment
break;
}
if( c == '\n' ) {
// update line counter
++mLine;
}
} while (token == "" && mStream->peek() != EOF); // double check to deal with trailing spaces
// launch child parser if include directive found.
// NOTE: parameter collecting uses default set of token separators.
@@ -218,16 +216,18 @@ std::string cParser::readToken(bool ToLower, const char *Break)
&& (parameter.compare("end") != 0) )
{
parameters.push_back(parameter);
parameter = readToken(ToLower);
parameter = readToken(false);
}
// if (trtest2.find("tr/")!=0)
mIncludeParser = new cParser(includefile, buffer_FILE, mPath, LoadTraction);
mIncludeParser = std::make_shared<cParser>(includefile, buffer_FILE, mPath, LoadTraction);
if (mIncludeParser->mSize <= 0)
ErrorLog("Missed include: " + includefile);
}
else
while (token.compare("end") != 0)
token = readToken(ToLower);
else {
while( token.compare( "end" ) != 0 ) {
token = readToken( true ); // minimize risk of case mismatch on comparison
}
}
token = readToken(ToLower, Break);
}
return token;
@@ -235,8 +235,12 @@ std::string cParser::readToken(bool ToLower, const char *Break)
std::string cParser::readQuotes(char const Quote) { // read the stream until specified char or stream end
std::string token = "";
char c;
char c { 0 };
while( mStream->peek() != EOF && Quote != (c = mStream->get()) ) { // get all chars until the quote mark
if( c == '\n' ) {
// update line counter
++mLine;
}
token += c;
}
return token;
@@ -244,9 +248,16 @@ std::string cParser::readQuotes(char const Quote) { // read the stream until spe
void cParser::skipComment( std::string const &Endmark ) { // pobieranie znaków aż do znalezienia znacznika końca
std::string input = "";
char c { 0 };
auto const endmarksize = Endmark.size();
while( mStream->peek() != EOF ) { // o ile nie koniec pliku
input += mStream->get(); // pobranie znaku
while( mStream->peek() != EOF ) {
// o ile nie koniec pliku
c = mStream->get(); // pobranie znaku
if( c == '\n' ) {
// update line counter
++mLine;
}
input += c;
if( input.find( Endmark ) != std::string::npos ) // szukanie znacznika końca
break;
if( input.size() >= endmarksize ) {
@@ -319,8 +330,16 @@ void cParser::addCommentStyle( std::string const &Commentstart, std::string cons
// returns name of currently open file, or empty string for text type stream
std::string
cParser::Name() {
cParser::Name() const {
if( mIncludeParser ) { return mIncludeParser->Name(); }
else { return mPath + mFile; }
}
// returns number of currently processed line
std::size_t
cParser::Line() const {
if( mIncludeParser ) { return mIncludeParser->Line(); }
else { return mLine; }
}

View File

@@ -78,7 +78,9 @@ class cParser //: public std::stringstream
// add custom definition of text which should be ignored when retrieving tokens
void addCommentStyle( std::string const &Commentstart, std::string const &Commentend );
// returns name of currently open file, or empty string for text type stream
std::string Name();
std::string Name() const;
// returns number of currently processed line
std::size_t Line() const;
private:
// methods:
@@ -90,13 +92,14 @@ class cParser //: public std::stringstream
std::size_t count();
// members:
bool LoadTraction; // load traction?
std::istream *mStream; // relevant kind of buffer is attached on creation.
std::shared_ptr<std::istream> mStream; // relevant kind of buffer is attached on creation.
std::string mFile; // name of the open file, if any
std::string mPath; // path to open stream, for relative path lookups.
std::streamoff mSize; // size of open stream, for progress report.
std::streamoff mSize { 0 }; // size of open stream, for progress report.
std::size_t mLine { 0 }; // currently processed line
typedef std::map<std::string, std::string> commentmap;
commentmap mComments;
cParser *mIncludeParser; // child class to handle include directives.
std::shared_ptr<cParser> mIncludeParser; // child class to handle include directives.
std::vector<std::string> parameters; // parameter list for included file.
std::deque<std::string> tokens;
};

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 17
#define VERSION_MINOR 828
#define VERSION_REVISION 0
#define VERSION_MINOR 829
#define VERSION_REVISION 1