17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 05:09:20 +02:00

Fix/sonar maintainability rebased (#209)

* refactor(sonar): use override instead of redundant virtual (cpp:S3471)

* refactor(sonar): remove empty statements, one declaration per statement (cpp:S1116, cpp:S1659)

* refactor(sonar): drop redundant lambda return types (cpp:S3574)

* refactor(sonar): prefer using over typedef (cpp:S5416)

* refactor(sonar): use =default for trivial special members (cpp:S3490)

* refactor(sonar): use nullptr literal (cpp:S4962)

* refactor(sonar): remove redundant access specifiers (cpp:S3539)

* refactor(sonar): remove redundant casts (cpp:S1905)

* refactor(sonar): use std::scoped_lock instead of std::lock_guard (cpp:S5997)

* refactor(sonar): construct elements in place with emplace_back (cpp:S6003)

* refactor(sonar): make narrowing conversions explicit (cpp:S5276)

* refactor(sonar): mark unused parameters (cpp:S1172)

Unused names are commented out; parameters used only on some platforms
are marked [[maybe_unused]].

* refactor(sonar): declare non-mutating member functions const (cpp:S5817)

Virtual functions are left untouched so overrides keep matching.

* refactor(sonar): merge collapsible nested if statements (cpp:S1066)

Comments that preceded the inner if are kept above the merged statement.

* refactor(sonar): scope single-use variables in if init-statements (cpp:S6004)

* fix(sonar): give polymorphic base classes virtual destructors (cpp:S1235)

* refactor(sonar): use try_emplace for map insertion (cpp:S6030)

* refactor(sonar): use auto where the type is spelled out on the right (cpp:S5827)

* refactor(sonar): remove redundant parentheses (cpp:S1110)

* refactor(sonar): document intentionally empty functions (cpp:S1186)

* refactor(sonar): remove dead stores (cpp:S1854)

Side effects (e.g. LISTLINE++) are kept.

* refactor(sonar): remove unused variables, captures and private fields (cpp:S1481, cpp:S1068)

* refactor(sonar): use structured bindings for pair access (cpp:S6005)

* refactor(sonar): use range-based loops and ranges algorithms (cpp:S5566)

* refactor(sonar): split chained assignments (cpp:S1121)

* refactor(sonar): add default cases to switch statements (cpp:S3562)

* refactor(sonar): use std::size for array lengths (cpp:S7127)

* refactor(sonar): use std::ranges algorithms and std::erase(_if) (cpp:S6197)

* refactor(sonar): access static members through the class (cpp:S2209)

* refactor(sonar): add braces around nested if-else (cpp:S5261)

* refactor(sonar): avoid side effects inside typeid operands (cpp:S5279)

* refactor(sonar): drop top-level const from by-value return types (cpp:S5951)

* refactor(sonar): declare variables separately from their type definitions (cpp:S3646)

* refactor(sonar): declare loop counters in the for statement (cpp:S5955)

* refactor(sonar): rely on class template argument deduction (cpp:S6012)

* refactor(sonar): inherit base constructors instead of forwarding them (cpp:S5952)

* refactor(sonar): rename locals that shadow outer declarations (cpp:S1117)

Only local variables and definition parameters are renamed; shadowing
struct fields and enumerators in headers are left for a separate change.

* refactor(sonar): reduce enum qualification with using enum (cpp:S6177)

Applied only where no unqualified name in the block could be captured by
the introduced enumerators.

* refactor(sonar): mark converting constructors explicit (cpp:S1709)

sound_source and the gl::object conversion operators stay implicit; they
are relied upon by copy-list-initialisation and GL calls.

* refactor(sonar): initialise members in initialiser lists or declarations (cpp:S3230)

* refactor(sonar): make read-only local references and pointers const (cpp:S5350)

* refactor(sonar): take read-only pointer and reference parameters as const (cpp:S995)

TTrain command handlers keep their signature, it is fixed by the handler table.

* refactor(sonar): pass expensive-to-copy parameters by const reference (cpp:S1238)

Signatures declared in files touched by PR 206 (Driver.h, EU07.cpp) and
virtual overrides are left unchanged.

* refactor(sonar): use transparent comparators for string-keyed maps (cpp:S6045)

std::unordered_map instances and map types exposed in headers used by
other modules are left as they are.

* fix(sonar): do not use UI text as a printf format string (cpp:S5281)

Text lines containing '%' would otherwise be interpreted as format
specifiers by ImGui::TextColored.

* refactor(sonar): use std::bind_front for callbacks (cpp:S5995)

* refactor(sonar): drop const_cast on string literals passed to the Python C API (cpp:S859)

* refactor(sonar): take read-only string parameters as std::string_view (cpp:S6009)

The Windows messaging helpers keep std::string, they need c_str().

* refactor(sonar): make read-only global tables const (cpp:S5421)

Mutable global state (flags, timers, singletons) is left as is.

* refactor(sonar): replace single-case switch statements with if (cpp:S1301)

* refactor(sonar): format UUIDs and log timestamps with std::format (cpp:S6494, cpp:S5945)

* refactor(sonar): use std::array for local fixed-size arrays (cpp:S5945)

Arrays that are class members or part of headers are left unchanged.

* fix(sonar): test the bearing damage bit, not bit 0 (cpp:S872)

'DamageFlag & dtrain_bearing > 0' parsed as 'DamageFlag & (dtrain_bearing > 0)',
i.e. DamageFlag & 1, so bearing friction reacted to the wrong damage flag.

* refactor(sonar): assorted small fixes

- empty() instead of size() comparisons (cpp:S1155)
- member initialisers in declaration order (cpp:S3229)
- no redundant c_str() when a std::string is accepted (cpp:S7121)
- contains() on associative containers (cpp:S6171)
- const reference instead of a copying range-for (cpp:S6032)
- starts_with() for prefix checks (cpp:S6178)
- no std::move on temporaries (cpp:S5274)
- has_value() on std::optional (cpp:S7172)
- bool literals for bool members (cpp:S5820)
- inline only on the definition (cpp:S3548)
- explicit base access specifier (cpp:S5965)
- explicit element access instead of dereferencing an array (cpp:S7116)
- rely on the C++20 rewritten operator!= (cpp:S6186)

* refactor(sonar): more small fixes

- std::format instead of iostream manipulators in to_string/to_hex_str (cpp:S6495);
  output verified identical, negative hex values keep the unsigned form
- remove an empty compound statement (cpp:S108)
- drop an always-false unsigned < 0 branch (cpp:S1768)
- explicit lambda capture (cpp:S3608)
- std::make_unique (cpp:S5950)

* chore: strip stray carriage returns left in TTrain constructor comments

* fix: keep quantize() in its own value type

The S5276 change cast the result of the generic quantize<Type_>() to
unsigned int, which truncated float/double callers (shadow angle slider,
editor rotation snapping, AI speed control steps) and broke negative values.

* fix(sonar): use integer loop counters in segment sampling (cpp:S2193)

* refactor(sonar): clean up issues reported on PR 209

- remove locals left unused after the dead-store cleanup (cpp:S1481, cpp:S1854)
- unnamed unused parameter (cpp:S1172)
- single-use declarations moved into if init-statements (cpp:S6004)
- auto for casted initialisers (cpp:S5827)
- const references and pointers where nothing is modified (cpp:S5350)
- rename structured bindings shadowed by inner declarations (cpp:S1117)
This commit is contained in:
jerrrrycho
2026-10-11 13:22:33 +02:00
committed by GitHub
parent c26041f2e7
commit 6263fe539b
162 changed files with 4220 additions and 4598 deletions

View File

@@ -34,14 +34,14 @@ int vk_to_glfw_key( int const Keycode ) {
char key = 0;
if (Keycode < 'A') {
key = Keycode;
key = static_cast<char>(Keycode);
} else if (Keycode <= 'Z') {
key = Keycode;
key = static_cast<char>(Keycode);
modifier = GLFW_MOD_SHIFT;
} else if (Keycode < 'a') {
key = Keycode;
key = static_cast<char>(Keycode);
} else if (Keycode <= 'z') {
key = Keycode - 32;
key = static_cast<char>(Keycode - 32);
} else {
ErrorLog("unknown key: " + std::to_string(Keycode));
}
@@ -66,7 +66,7 @@ bool TEventLauncher::Load(cParser *parser)
}
else {
// this launcher may be activated by radio message
std::map<std::string, int> messages {
std::map<std::string, int, std::less<>> messages {
{ "radio_call1", radio_message::call1 },
{ "radio_call3", radio_message::call3 }
};
@@ -138,8 +138,7 @@ bool TEventLauncher::Load(cParser *parser)
iHour = int( DeltaTime - iMinute ) / 100; // godzina to setki
DeltaTime = 0; // bez powtórzeń
// potentially shift the provided time by requested offset
auto const timeoffset{ static_cast<int>( Global.ScenarioTimeOffset * 60 ) };
if( timeoffset != 0 ) {
if( auto const timeoffset{ static_cast<int>( Global.ScenarioTimeOffset * 60 ) }; timeoffset != 0 ) {
auto const adjustedtime{ clamp_circular( iHour * 60 + iMinute + timeoffset, 24 * 60 ) };
iHour = adjustedtime / 60 % 24;
iMinute = adjustedtime % 60;
@@ -156,7 +155,7 @@ bool TEventLauncher::Load(cParser *parser)
return true;
}
bool TEventLauncher::check_activation_key() {
bool TEventLauncher::check_activation_key() const {
if (iKey <= 0)
return false;
@@ -164,7 +163,7 @@ bool TEventLauncher::check_activation_key() {
bool result = Console::Pressed(key);
char modifier = iKey >> 8;
auto modifier = static_cast<char>(iKey >> 8);
if (modifier & GLFW_MOD_SHIFT)
result &= Global.shiftState;
if (modifier & GLFW_MOD_CONTROL)
@@ -195,12 +194,10 @@ bool TEventLauncher::check_activation() {
else {
// jeśli nie cykliczny, to sprawdzić czas
if( simulation::Time.data().wHour == iHour ) {
if( simulation::Time.data().wMinute == iMinute ) {
// zgodność czasu uruchomienia
if( UpdatedTime < 10 ) {
UpdatedTime = 20; // czas do kolejnego wyzwolenia?
bCond = true;
}
// zgodność czasu uruchomienia
if (simulation::Time.data().wMinute == iMinute && UpdatedTime < 10) {
UpdatedTime = 20; // czas do kolejnego wyzwolenia?
bCond = true;
}
}
else {
@@ -211,7 +208,7 @@ bool TEventLauncher::check_activation() {
return bCond;
}
bool TEventLauncher::check_conditions() {
bool TEventLauncher::check_conditions() const {
auto bCond { true };
@@ -239,7 +236,7 @@ bool TEventLauncher::IsRadioActivated() const {
float
TEventLauncher::radius_() {
return std::sqrt( dRadius );
return static_cast<float>(std::sqrt( dRadius ));
}
// serialize() subclass details, sends content of the subclass to provided stream
@@ -271,9 +268,8 @@ TEventLauncher::export_as_text_( std::ostream &Output ) const {
// activation key
if( iKey != 0 ) {
auto key { iKey & 0xff };
auto const modifier { iKey >> 8 };
if (key >= 'A' && key <= 'Z' && !(modifier & GLFW_MOD_SHIFT))
if (auto const modifier { iKey >> 8 }; key >= 'A' && key <= 'Z' && !(modifier & GLFW_MOD_SHIFT))
key += 32;
Output << (char)key;

View File

@@ -30,10 +30,10 @@ public:
// methods
bool Load( cParser *parser );
bool check_activation_key();
bool check_activation_key() const;
bool check_activation();
// checks conditions associated with the event. returns: true if the conditions are met
bool check_conditions();
bool check_conditions() const;
inline
auto key() const {
return iKey; }
@@ -53,13 +53,13 @@ public:
private:
// methods
// radius() subclass details, calculates node's bounding radius
float radius_();
float radius_() override;
// serialize() subclass details, sends content of the subclass to provided stream
void serialize_( std::ostream &Output ) const;
void serialize_( std::ostream &Output ) const override;
// deserialize() subclass details, restores content of the subclass from provided stream
void deserialize_( std::istream &Input );
void deserialize_( std::istream &Input ) override;
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
void export_as_text_( std::ostream &Output ) const;
void export_as_text_( std::ostream &Output ) const override;
// members
int iKey { 0 };

View File

@@ -25,7 +25,7 @@ http://mozilla.org/MPL/2.0/.
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 )
void TMemCell::UpdateValues( std::string_view szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask )
{
if (CheckMask & basic_event::flags::mode_add)
{ // dodawanie wartości
@@ -51,48 +51,49 @@ void TMemCell::UpdateValues( std::string const &szNewText, double const fNewValu
TCommandType TMemCell::CommandCheck()
{ // rozpoznanie komendy
using enum TCommandType;
if( szText == "SetVelocity" ) // najpopularniejsze
{
eCommand = TCommandType::cm_SetVelocity;
eCommand = cm_SetVelocity;
bCommand = false; // ta komenda nie jest wysyłana
}
else if( szText == "ShuntVelocity" ) // w tarczach manewrowych
{
eCommand = TCommandType::cm_ShuntVelocity;
eCommand = cm_ShuntVelocity;
bCommand = false; // ta komenda nie jest wysyłana
}
else if( szText == "Change_direction" ) // zdarza się
{
eCommand = TCommandType::cm_ChangeDirection;
eCommand = cm_ChangeDirection;
bCommand = true; // do wysłania
}
else if( szText == "OutsideStation" ) // zdarza się
{
eCommand = TCommandType::cm_OutsideStation;
eCommand = cm_OutsideStation;
bCommand = false; // tego nie powinno być w komórce
}
else if( szText.starts_with("PassengerStopPoint:") ) // porównanie początków
{
eCommand = TCommandType::cm_PassengerStopPoint;
eCommand = cm_PassengerStopPoint;
bCommand = false; // tego nie powinno być w komórce
}
else if( szText == "SetProximityVelocity" ) // nie powinno tego być
{
eCommand = TCommandType::cm_SetProximityVelocity;
eCommand = cm_SetProximityVelocity;
bCommand = false; // ta komenda nie jest wysyłana
}
else if( szText == "Emergency_brake" )
{
eCommand = TCommandType::cm_EmergencyBrake;
eCommand = cm_EmergencyBrake;
bCommand = false;
}
else if( szText == "CabSignal" ) {
eCommand = TCommandType::cm_SecuritySystemMagnet;
eCommand = cm_SecuritySystemMagnet;
bCommand = false;
}
else
{
eCommand = TCommandType::cm_Unknown; // ciąg nierozpoznany (nie jest komendą)
eCommand = cm_Unknown; // ciąg nierozpoznany (nie jest komendą)
bCommand = true; // do wysłania
}
return eCommand;
@@ -157,11 +158,11 @@ bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1,
if( TestFlag( CheckMask, basic_event::flags::text ) ) {
// porównać teksty
auto range = szTestText.find( '*' );
auto wildcardpos = szTestText.find( '*' );
auto const result { (
range == std::string::npos ?
wildcardpos == std::string::npos ?
compare( szText, szTestText, TextOperator ) :
compare( szText.substr( 0, range ), szTestText.substr( 0, range ), TextOperator ) ) };
compare( szText.substr( 0, wildcardpos ), szTestText.substr( 0, wildcardpos ), TextOperator ) ) };
checkpassed |= result;
checkfailed |= !result;
}
@@ -177,20 +178,22 @@ bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1,
}
switch( Pass ) {
case comparison_pass::all: { return checkfailed == false; }
case comparison_pass::any: { return checkpassed == true; }
case comparison_pass::none: { return checkpassed == false; }
using enum comparison_pass;
case all: { return checkfailed == false; }
case any: { return checkpassed == true; }
case none: { return checkpassed == false; }
default: { return false; }
}
};
bool TMemCell::IsVelocity() const
{ // sprawdzenie, czy event odczytu tej komórki ma być do skanowania, czy do kolejkowania
if (eCommand == TCommandType::cm_SetVelocity)
using enum TCommandType;
if (eCommand == cm_SetVelocity)
return true;
if (eCommand == TCommandType::cm_ShuntVelocity)
if (eCommand == cm_ShuntVelocity)
return true;
return eCommand == TCommandType::cm_SetProximityVelocity;
return eCommand == cm_SetProximityVelocity;
};
void TMemCell::StopCommandSent()
@@ -258,7 +261,7 @@ TMemCell::export_as_text_( std::ostream &Output ) const {
// legacy method, initializes traction after deserialization from scenario file
void
memory_table::InitCells() {
memory_table::InitCells() const {
for( auto *cell : m_items ) {
// Ra: eventy komórek pamięci, wykonywane po wysłaniu komendy do zatrzymanego pojazdu
@@ -275,9 +278,9 @@ memory_table::InitCells() {
// legacy method, sends content of all cells to the log
void
memory_table::log_all() {
memory_table::log_all() const {
for( auto *cell : m_items ) {
for( auto const *cell : m_items ) {
cell->LogValues();
}
}

View File

@@ -21,7 +21,7 @@ public:
explicit TMemCell( scene::node_data const &Nodedata );
// methods
void
UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask );
UpdateValues( std::string_view szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask );
bool
Load(cParser *parser);
void
@@ -61,11 +61,11 @@ public:
private:
// methods
// serialize() subclass details, sends content of the subclass to provided stream
void serialize_( std::ostream &Output ) const;
void serialize_( std::ostream &Output ) const override;
// deserialize() subclass details, restores content of the subclass from provided stream
void deserialize_( std::istream &Input );
void deserialize_( std::istream &Input ) override;
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
void export_as_text_( std::ostream &Output ) const;
void export_as_text_( std::ostream &Output ) const override;
// members
// content
@@ -85,10 +85,10 @@ class memory_table : public basic_table<TMemCell> {
public:
// legacy method, initializes traction after deserialization from scenario file
void
InitCells();
InitCells() const;
// legacy method, sends content of all cells to the log
void
log_all();
log_all() const;
};
//---------------------------------------------------------------------------

View File

@@ -67,8 +67,8 @@ bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 N
CPointIn = NewCPointIn;
Point2 = NewPoint2;
// poprawienie przechyłki
fRoll1 = glm::radians(fNewRoll1); // Ra: przeliczone jest bardziej przydatne do obliczeń
fRoll2 = glm::radians(fNewRoll2);
fRoll1 = static_cast<float>(glm::radians(fNewRoll1)); // Ra: przeliczone jest bardziej przydatne do obliczeń
fRoll2 = static_cast<float>(glm::radians(fNewRoll2));
bCurve = bIsCurve;
if (Global.bRollFix)
{ // Ra: poprawianie przechyłki
@@ -85,7 +85,7 @@ bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 N
Point1.y += w1; // modyfikacja musi być przed policzeniem dalszych parametrów
if (bCurve)
CPointOut.y += w1; // prosty ma wektory jednostkowe
pOwner->MovedUp1(w1); // zwrócić trzeba informację o podwyższeniu podsypki
pOwner->MovedUp1(static_cast<float>(w1)); // zwrócić trzeba informację o podwyższeniu podsypki
}
if (fRoll2 != 0.f)
{
@@ -125,7 +125,7 @@ bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 N
fStep = fLength / ( 3.0 * Global.SplineFidelity );
}
// iSegCount = static_cast<int>( std::ceil( fLength / fStep ) ); // potrzebne do VBO
iSegCount = pOwner->eType == tt_Switch ? 6 * Global.SplineFidelity : static_cast<int>(std::ceil(fLength / fStep)); // potrzebne do VBO
iSegCount = pOwner->eType == tt_Switch ? static_cast<int>(6 * Global.SplineFidelity) : static_cast<int>(std::ceil(fLength / fStep)); // potrzebne do VBO
fStep = fLength / iSegCount; // update step to equalize size of individual pieces
@@ -242,7 +242,7 @@ double TSegment::FastGetTFromS(double const s) const
double const h01 = -2.0 * u3 + 3.0 * u2;
double const t = ( ( 1.0 - h01 ) * fTsBuffer[ i ] +
( u3 - 2.0 * u2 + u ) * fTsSlope [ i ] +
( h01 ) * fTsBuffer[ i + 1 ] +
h01 * fTsBuffer[ i + 1 ] +
( u3 - u2 ) * fTsSlope [ i + 1 ] );
return t;
}
@@ -263,10 +263,11 @@ double TSegment::ComputeLength() const // McZapkie-150503: dlugosc miedzy punkta
// Ra: koniec rekurencji jeśli po podziale suma długości nie różni się więcej niż 0.5mm od
// poprzedniej
// Ra: ewentualnie rozpoznać łuk okręgu płaskiego i liczyć ze wzoru na długość łuku
double t, l = 0;
double t;
double l = 0;
glm::dvec3 last{0, 0, 0}; // długość liczona po przesunięciu odcinka do początku układu
glm::dvec3 tmp = Point2 - Point1;
int m = 20.0 * glm::length(tmp); // było zawsze do 10000, teraz jest liczone odcinkami po około 5cm
auto m = static_cast<int>(20.0 * glm::length(tmp)); // było zawsze do 10000, teraz jest liczone odcinkami po około 5cm
for (int i = 1; i <= m; i++)
{
t = double(i) / double(m); // wyznaczenie parametru na krzywej z przedziału (0,1>
@@ -334,7 +335,7 @@ glm::dvec3 TSegment::GetDirection(double const fDistance) const
return FastGetPoint(t2) - FastGetPoint(t1);
}
glm::dvec3 TSegment::FastGetDirection(double fDistance, double fOffset)
glm::dvec3 TSegment::FastGetDirection(double fDistance, double fOffset) const
{ // takie toporne liczenie pochodnej dla parametru 0.0÷1.0
double t1 = fDistance - fOffset;
if (t1 <= 0.0)
@@ -371,22 +372,22 @@ void TSegment::RaPositionGet(double const fDistance, glm::dvec3 &position, glm::
auto const t = FastGetTFromS(fDistance); // aproksymacja dystansu na krzywej Beziera na parametr (t)
position = FastGetPoint( t );
// przechyłka w danym miejscu (zmienia się liniowo)
rotation.x = std::lerp( fRoll1, fRoll2, t );
rotation.x = static_cast<float>(std::lerp( fRoll1, fRoll2, t ));
// pochodna
auto const tangent = GetFirstDerivative( t );
// pochylenie krzywej (w pionie)
rotation.y = std::atan( tangent.y );
rotation.y = static_cast<float>(std::atan( tangent.y ));
// kierunek krzywej w planie
rotation.z = -std::atan2( tangent.x, tangent.z );
rotation.z = static_cast<float>(-std::atan2( tangent.x, tangent.z ));
}
else {
// wyliczenie dla odcinka prostego jest prostsze
auto const t = fDistance / fLength; // zerowych torów nie ma
position = FastGetPoint( t );
// przechyłka w danym miejscu (zmienia się liniowo)
rotation.x = std::lerp( fRoll1, fRoll2, t );
rotation.y = fStoop; // pochylenie toru prostego
rotation.z = fDirection; // kierunek toru w planie
rotation.x = static_cast<float>(std::lerp( fRoll1, fRoll2, t ));
rotation.y = static_cast<float>(fStoop); // pochylenie toru prostego
rotation.z = static_cast<float>(fDirection); // kierunek toru w planie
}
};
@@ -404,20 +405,35 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
if( fTsBuffer.empty() )
return false; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
glm::vec3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
float s, step, fOffset, tv1, tv2, t, fEnd;
glm::vec3 pos1;
glm::vec3 pos2;
glm::vec3 dir;
glm::vec3 parallel1;
glm::vec3 parallel2;
glm::vec3 pt;
glm::vec3 norm;
float s;
float step;
float fOffset;
float tv1;
float tv2;
float t;
float fEnd;
auto const iNumShapePoints = Transition ? ShapePoints.size() / 2 : ShapePoints.size();
float const texturelength = fTextureLength * Texturescale;
float const texturescale = Texturescale;
auto const texturelength = static_cast<float>(fTextureLength * Texturescale);
auto const texturescale = static_cast<float>(Texturescale);
float m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
step = fStep;
float m1;
float jmm1;
float m2;
float jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
step = static_cast<float>(fStep);
tv1 = 1.0; // Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
s = static_cast<float>(fStep * iSkip); // iSkip - ile odcinków z początku pominąć
int i = iSkip; // domyślnie 0
t = fTsBuffer[ i ]; // tabela wattości t dla segmentów
t = static_cast<float>(fTsBuffer[ i ]); // tabela wattości t dla segmentów
// BUG: length of spline can be 0, we should skip geometry generation for such cases
fOffset = 0.1 / fLength; // pierwsze 10cm
fOffset = static_cast<float>(0.1 / fLength); // pierwsze 10cm
pos1 = glm::dvec3{ FastGetPoint( t ) - Origin }; // wektor początku segmentu
dir = glm::dvec3{ FastGetDirection( t, fOffset ) }; // wektor kierunku
parallel1 = glm::vec3{ -dir.z, 0.f, dir.x }; // wektor poprzeczny
@@ -428,11 +444,11 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
parallel1 = glm::normalize( parallel1 );
if( iEnd == 0 )
iEnd = iSegCount;
fEnd = fLength * double( iEnd ) / double( iSegCount );
fEnd = static_cast<float>(fLength * double( iEnd ) / double( iSegCount ));
/*
m2 = s / fEnd;
*/
m2 = static_cast<float>( i - iSkip ) / ( iEnd - iSkip );
m2 = static_cast<float>( i - iSkip ) / ( static_cast<float>(iEnd - iSkip) );
jmm2 = 1.f - m2;
@@ -445,7 +461,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
/*
m2 = s / fEnd;
*/
m2 = static_cast<float>( i - iSkip ) / ( iEnd - iSkip );
m2 = static_cast<float>( i - iSkip ) / ( static_cast<float>(iEnd - iSkip) );
jmm2 = 1.f - m2; // nowa pozycja
if( i == iEnd ) { // gdy przekroczyliśmy koniec - stąd dziury w torach...
@@ -462,7 +478,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
tv1 = clamp_circular( tv1, 1.0f );
tv2 = tv1 - step / texturelength; // mapowanie na końcu segmentu
t = fTsBuffer[ i ]; // szybsze od GetTFromS(s);
t = static_cast<float>(fTsBuffer[ i ]); // szybsze od GetTFromS(s);
pos2 = glm::dvec3{ FastGetPoint( t ) - Origin };
dir = glm::dvec3{ FastGetDirection( t, fOffset ) }; // nowy wektor kierunku
parallel2 = glm::vec3{ -dir.z, 0.f, dir.x }; // wektor poprzeczny
@@ -486,13 +502,12 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
glm::normalize( norm ),
glm::vec2 { ( jmm1 * ShapePoints[ j ].texture.x + m1 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv1 } );
}
if( p ) // jeśli jest wskaźnik do tablicy
if( *p )
if( !j ) // to dla pierwszego punktu
{
**p = pt;
( *p )++;
} // zapamiętanie brzegu jezdni
// jeśli jest wskaźnik do tablicy
if (p && *p && !j) // to dla pierwszego punktu
{
**p = pt;
( *p )++;
} // zapamiętanie brzegu jezdni
// dla trapezu drugi koniec ma inne współrzędne
pt = parallel2 * ( jmm2 * ( ShapePoints[ j ].position.x - fOffsetX.first ) + m2 * ( ShapePoints[ j + iNumShapePoints ].position.x - fOffsetX.second ) ) + pos2;
pt.y += jmm2 * ShapePoints[ j ].position.y + m2 * ShapePoints[ j + iNumShapePoints ].position.y;
@@ -505,13 +520,12 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
glm::normalize( norm ),
glm::vec2 { ( jmm2 * ShapePoints[ j ].texture.x + m2 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv2 } );
}
if( p ) // jeśli jest wskaźnik do tablicy
if( *p )
if( !j ) // to dla pierwszego punktu
if( i == iSegCount ) {
**p = pt;
( *p )++;
} // zapamiętanie brzegu jezdni
// jeśli jest wskaźnik do tablicy
// to dla pierwszego punktu
if (p && *p && !j && i == iSegCount) {
**p = pt;
( *p )++;
} // zapamiętanie brzegu jezdni
}
}
else {
@@ -549,39 +563,38 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
void TSegment::render_lines(std::vector<gfx::basic_vertex> &out, float quality) const
{
float step = 1.0f / iSegCount / quality;
float step = 1.0f / static_cast<float>(iSegCount) / quality;
float x;
glm::vec3 previous = FastGetPoint(0.0);
for (x = step; x <= 1.0f; x += step) {
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
for (int i = 1; static_cast<float>(i) * step <= 1.0f; ++i) {
float const x = static_cast<float>(i) * step;
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
previous = glm::vec3(FastGetPoint(x));
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
}
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
previous = glm::vec3(FastGetPoint(1.0));
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
}
glm::vec3 TSegment::get_nearest_point(const glm::dvec3 &point, float quality) const
{
float step = 1.0f / iSegCount / quality;
float step = 1.0f / static_cast<float>(iSegCount) / quality;
float x;
glm::vec3 nearest;
float min = std::numeric_limits<float>::max();
for (x = step; x <= 1.0f; x += step) {
for (int i = 1; static_cast<float>(i) * step <= 1.0f; ++i) {
float const x = static_cast<float>(i) * step;
glm::vec3 p1 = FastGetPoint(x);
glm::vec3 p2 = FastGetPoint(glm::min(1.0f, x + step));
if (p1 != p2) {
if (glm::vec3 p2 = FastGetPoint(glm::min(1.0f, x + step)); p1 != p2) {
float l2 = glm::distance2(p1, p2);
float t = glm::max(0.0f, glm::min(1.0f, glm::dot((glm::vec3)point - p1, p2 - p1) / l2));
glm::vec3 proj = p1 + t * (p2 - p1);

View File

@@ -41,10 +41,12 @@ struct segment_data {
class TSegment
{ // aproksymacja toru (zwrotnica ma dwa takie, jeden z nich jest aktywny)
private:
glm::dvec3 Point1, CPointOut, CPointIn, Point2;
float
fRoll1 { 0.f },
fRoll2 { 0.f }; // przechyłka na końcach
glm::dvec3 Point1;
glm::dvec3 CPointOut;
glm::dvec3 CPointIn;
glm::dvec3 Point2;
float fRoll1 { 0.f };
float fRoll2 { 0.f }; // przechyłka na końcach
double fLength { -1.0 }; // długość policzona
std::vector<double> fTsBuffer; // wartości parametru krzywej t dla równych odcinków s
std::vector<double> fTsSlope; // nachylenie dt/du (= dt/ds * fStep) w tych samych punktach
@@ -52,7 +54,9 @@ class TSegment
int iSegCount = 0; // ilość odcinków do rysowania krzywej
double fDirection = 0.0; // Ra: kąt prostego w planie; dla łuku kąt od Point1
double fStoop = 0.0; // Ra: kąt wzniesienia; dla łuku od Point1
glm::dvec3 vA, vB, vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
glm::dvec3 vA;
glm::dvec3 vB;
glm::dvec3 vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
TTrack *pOwner = nullptr; // wskaźnik na właściciela
glm::dvec3 GetFirstDerivative(double const fTime) const;
@@ -66,7 +70,7 @@ class TSegment
public:
bool bCurve = false;
TSegment(TTrack *owner);
explicit TSegment(TTrack *owner);
bool Init(glm::dvec3 NewPoint1, glm::dvec3 NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0);
bool Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 NewCPointIn, glm::dvec3 &NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0, bool bIsCurve = true);
double
@@ -89,7 +93,7 @@ public:
GetDirection() const {
return CPointOut; };
glm::dvec3
FastGetDirection(double const fDistance, double const fOffset);
FastGetDirection(double const fDistance, double const fOffset) const;
/*
Math3D::vector3
GetPoint(double const fDistance) const;

View File

@@ -13,19 +13,18 @@ http://mozilla.org/MPL/2.0/.
void TSpring::Init(double nKs, double nKd) {
Ks = nKs;
Kd = nKd;
ks = Ks;
kd = Kd;
ks = static_cast<float>(Ks);
kd = static_cast<float>(Kd);
}
glm::dvec3 TSpring::ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2) {
glm::dvec3 TSpring::ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2) const {
glm::vec3 springForce;
// p1 = &system[spring->p1];
// p2 = &system[spring->p2];
// VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance
auto deltaP = pPosition1 - pPosition2;
// dist = VectorLength(&deltaP); // Magnitude of deltaP
auto dist = glm::length(deltaP);
if( dist > restLen ) {
if( auto dist = glm::length(deltaP); dist > restLen ) {
// Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest)
auto Hterm = ( dist - restLen ) * Ks; // Ks * (dist - rest)

View File

@@ -27,7 +27,7 @@ public:
// void Init(TParticnp1, TParticle *np2, double nKs= 0.5f, double nKd= 0.002f,
// double nrestLen= -1.0f);
void Init(double nKs = 0.5f, double nKd = 0.002f);
glm::dvec3 ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2);
glm::dvec3 ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2) const;
//private:
// members
double restLen { 0.01 }; // LENGTH OF SPRING AT REST

View File

@@ -114,10 +114,9 @@ TTraction::Load( cParser *parser, glm::dvec3 const &pOrigin ) {
// SKB70-C, CuCd70-2C, KB95-2C, C95-C, C95-2C, YC95-2C, YpC95-2C, YC120-2C
// YpC120-2C, YzC120-2C, YwsC120-2C, YC150-C150, YC150-2C150, C150-C150
// C120-2C, 2C120-2C, 2C120-2C-1, 2C120-2C-2, 2C120-2C-3, 2C120-2C-4
auto const material = parser->getToken<std::string>();
// 1=miedziana, rysuje się na zielono albo czerwono
// 2=aluminiowa, rysuje się na czarno
if( material == "none" ) { Material = 0; }
if( auto const material = parser->getToken<std::string>(); material == "none" ) { Material = 0; }
else if( material == "al" ) { Material = 2; }
else { Material = 1; }
parser->getTokens( 2 );
@@ -131,7 +130,7 @@ TTraction::Load( cParser *parser, glm::dvec3 const &pOrigin ) {
auto const minheight { parser->getToken<double>() };
fHeightDifference = ( pPoint3.y - pPoint1.y + pPoint4.y - pPoint2.y ) * 0.5 - minheight;
auto const segmentlength { parser->getToken<double>() };
iNumSections = segmentlength ? glm::length(pPoint1 - pPoint2) / segmentlength : 0;
iNumSections = segmentlength != 0.0 ? static_cast<int>(glm::length(pPoint1 - pPoint2) / segmentlength) : 0;
parser->getTokens( 2 );
*parser
>> Wires
@@ -164,7 +163,7 @@ TTraction::endpoints() const {
}
std::size_t
TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
TTraction::create_geometry( gfx::geometrybank_handle const &Geometrybank ) {
if( m_geometry != null_handle ) {
return GfxRenderer->Vertices( m_geometry ).size() / 2;
}
@@ -175,7 +174,8 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
if( Wires == 2 )
WireOffset = 0;
// jezdny
gfx::basic_vertex startvertex, endvertex;
gfx::basic_vertex startvertex;
gfx::basic_vertex endvertex;
startvertex.position =
glm::vec3(
pPoint1.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - m_origin.x,
@@ -189,7 +189,12 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
vertices.emplace_back( startvertex );
vertices.emplace_back( endvertex );
// Nie wiem co 'Marcin
glm::dvec3 pt1, pt2, pt3, pt4, v1, v2;
glm::dvec3 pt1;
glm::dvec3 pt2;
glm::dvec3 pt3;
glm::dvec3 pt4;
glm::dvec3 v1;
glm::dvec3 v2;
v1 = pPoint4 - pPoint3;
v2 = pPoint2 - pPoint1;
float step = 0;
@@ -207,7 +212,7 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
pPoint3.z - m_origin.z );
for( int i = 0; i < iNumSections - 1; ++i ) {
pt3 = pPoint3 + v1 * f;
t = 1 - std::fabs(f - mid) * 2;
t = static_cast<float>(1 - std::fabs(f - mid) * 2);
if( Wires < 4
|| ( i != 0
&& i != iNumSections - 2 ) ) {
@@ -256,7 +261,7 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
pPoint3.z - m_origin.z );
for( int i = 0; i < iNumSections - 1; ++i ) {
pt3 = pPoint3 + v1 * f;
t = 1 - std::fabs(f - mid) * 2;
t = static_cast<float>(1 - std::fabs(f - mid) * 2);
endvertex.position =
glm::vec3(
pt3.x - m_origin.x,
@@ -288,7 +293,7 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
for( int i = 0; i < iNumSections - 1; ++i ) {
pt3 = pPoint3 + v1 * f;
pt4 = pPoint1 + v2 * f;
t = 1 - std::fabs(f - mid) * 2;
t = static_cast<float>(1 - std::fabs(f - mid) * 2);
if( i % 2 == 0 ) {
startvertex.position =
glm::vec3(
@@ -338,12 +343,12 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
auto const elementcount = vertices.size() / 2;
gfx::userdata_array empty_userdata{};
m_geometry = GfxRenderer->Insert( vertices, empty_userdata, Bank, GL_LINES );
m_geometry = GfxRenderer->Insert( vertices, empty_userdata, Geometrybank, GL_LINES );
return elementcount;
}
int TTraction::TestPoint(glm::dvec3 const &Point)
int TTraction::TestPoint(glm::dvec3 const &Point) const
{ // sprawdzanie, czy przęsła można połączyć
if( hvNext[0] == nullptr
&& glm::all(glm::epsilonEqual(Point, pPoint1, 0.025)) ) {
@@ -410,7 +415,8 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
{ //(this) jest przęsłem zasilanym, o rezystancji (r), policzyć rezystancję zastępczą sąsiednich
if (d >= 0)
{ // podążanie we wskazanym kierunku
TTraction *t = hvNext[d], *p;
TTraction *t = hvNext[d];
TTraction const *p;
if (ps)
psPower[d ^ 1] = ps; // podłączenie podanego
else
@@ -432,7 +438,7 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
}
}
t->psPower[d] = ps; // skopiowanie wskaźnika zasilacza od danej strony
t->fResistance[d] = r; // wpisanie rezystancji w kierunku tego zasilacza
t->fResistance[d] = static_cast<float>(r); // wpisanie rezystancji w kierunku tego zasilacza
r += t->fResistivity * glm::length(t->vParametric); // doliczenie oporu kolejnego odcinka
p = t; // zapamiętanie dotychczasowego
t = p->hvNext[d ^ 1]; // podążanie w tę samą stronę
@@ -457,17 +463,18 @@ void TTraction::PowerSet(TTractionPowerSource *ps)
else
{ // ustalenie punktu zasilania (nie ma jeszcze połączeń między przęsłami)
psPowered = ps; // ustawienie bezpośredniego zasilania dla przęsła
psPower[0] = psPower[1] = ps; // a to chyba nie jest dobry pomysł, bo nawet zasilane przęsło
psPower[0] = ps; // a to chyba nie jest dobry pomysł, bo nawet zasilane przęsło
psPower[1] = ps;
// powinno mieć wskazania na inne
fResistance[0] = fResistance[1] = 0.0; // a liczy się tylko rezystancja zasilacza
fResistance[0] = 0.0; // a liczy się tylko rezystancja zasilacza
fResistance[1] = 0.0;
}
};
double TTraction::VoltageGet(double u, double i)
{ // pobranie napięcia na przęśle po podłączeniu do niego rezystancji (res) - na razie jest to prąd
if (!psSection)
if (!psPowered)
return NominalVoltage; // jak nie ma zasilacza, to napięcie podane w przęśle
if (!psSection && !psPowered)
return NominalVoltage; // jak nie ma zasilacza, to napięcie podane w przęśle
// na początek można założyć, że wszystkie podstacje mają to samo napięcie i nie płynie prąd
// pomiędzy nimi
// dla danego przęsła mamy 3 źródła zasilania
@@ -485,8 +492,12 @@ double TTraction::VoltageGet(double u, double i)
return 0.0;
}
double r0t, r1t, r0g, r1g;
double i0, i1;
double r0t;
double r1t;
double r0g;
double r1g;
double i0;
double i1;
r0t = fResistance[0]; //średni pomysł, ale lepsze niż nic
r1t = fResistance[1]; // bo nie uwzględnia spadków z innych pojazdów
if (psPower[0] && psPower[1])
@@ -729,29 +740,25 @@ traction_table::InitTraction() {
break;
}
}
if( traction->hvNext[ 0 ] ) {
// jeśli został podłączony
if( traction->psSection != nullptr
&& matchingtraction->psSection != nullptr ) {
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
if( traction->psSection != matchingtraction->psSection ) {
// połączone odcinki mają różne zasilacze
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
if( true == traction->psSection->bSection
&& false == matchingtraction->psSection->bSection ) {
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
}
else if( false == traction->psSection->bSection
&& true == matchingtraction->psSection->bSection ) {
//(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
traction->PowerSet( matchingtraction->psSection ); // zastąpienie wskazaniem sekcji
}
else {
// jeśli obie to sekcje albo obie podstacje, to będzie błąd
ErrorLog( "Bad scenario: faulty traction power connection at location " + to_string( traction->pPoint1 ) );
}
}
// jeśli został podłączony
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
if (traction->hvNext[ 0 ] && traction->psSection != nullptr
&& matchingtraction->psSection != nullptr && traction->psSection != matchingtraction->psSection) {
// połączone odcinki mają różne zasilacze
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
if( true == traction->psSection->bSection
&& false == matchingtraction->psSection->bSection ) {
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
}
else if( false == traction->psSection->bSection
&& true == matchingtraction->psSection->bSection ) {
//(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
traction->PowerSet( matchingtraction->psSection ); // zastąpienie wskazaniem sekcji
}
else {
// jeśli obie to sekcje albo obie podstacje, to będzie błąd
ErrorLog( "Bad scenario: faulty traction power connection at location " + to_string( traction->pPoint1 ) );
}
}
}
@@ -768,28 +775,24 @@ traction_table::InitTraction() {
break;
}
}
if( traction->hvNext[ 1 ] ) {
// jeśli został podłączony
if( traction->psSection != nullptr
&& matchingtraction->psSection != nullptr ) {
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
if( traction->psSection != matchingtraction->psSection ) {
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
if( true == traction->psSection->bSection
&& false == matchingtraction->psSection->bSection ) {
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
}
else if( false == traction->psSection->bSection
&& true == matchingtraction->psSection->bSection ) {
//(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
traction->PowerSet( matchingtraction->psSection ); // zastąpienie wskazaniem sekcji
}
else {
// jeśli obie to sekcje albo obie podstacje, to będzie błąd
ErrorLog( "Bad scenario: faulty traction power connection at location " + to_string( traction->pPoint2 ) );
}
}
// jeśli został podłączony
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
if (traction->hvNext[ 1 ] && traction->psSection != nullptr
&& matchingtraction->psSection != nullptr && traction->psSection != matchingtraction->psSection) {
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
if( true == traction->psSection->bSection
&& false == matchingtraction->psSection->bSection ) {
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
}
else if( false == traction->psSection->bSection
&& true == matchingtraction->psSection->bSection ) {
//(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
traction->PowerSet( matchingtraction->psSection ); // zastąpienie wskazaniem sekcji
}
else {
// jeśli obie to sekcje albo obie podstacje, to będzie błąd
ErrorLog( "Bad scenario: faulty traction power connection at location " + to_string( traction->pPoint2 ) );
}
}
}
@@ -822,8 +825,7 @@ traction_table::InitTraction() {
}
else if( traction->hvParallel == nullptr ) {
// jeśli jeszcze nie został włączony w kółko
auto *nTemp = find( traction->asParallel );
if( nTemp != nullptr ) {
if( auto *nTemp = find( traction->asParallel ); nTemp != nullptr ) {
// o ile zostanie znalezione przęsło o takiej nazwie
if( nTemp->hvParallel == nullptr ) {
// jeśli tamten jeszcze nie ma wskaźnika bieżni wspólnej

View File

@@ -29,8 +29,10 @@ class TTraction : public scene::basic_node
TTraction *hvNext[ 2 ] { nullptr, nullptr }; //łączenie drutów w sieć
int iNext[ 2 ] { 0, 0 }; // do którego końca się łączy
int iLast { 0 }; //że niby ostatni drut // ustawiony bit 0, jeśli jest ostatnim drutem w sekcji; bit1 - przedostatni
public:
glm::dvec3 pPoint1, pPoint2, pPoint3, pPoint4;
glm::dvec3 pPoint1;
glm::dvec3 pPoint2;
glm::dvec3 pPoint3;
glm::dvec3 pPoint4;
glm::dvec3 vParametric; // współczynniki równania parametrycznego odcinka
double fHeightDifference { 0.0 };
int iNumSections { 0 };
@@ -66,7 +68,7 @@ class TTraction : public scene::basic_node
// creates geometry data in specified geometry bank. returns: number of created elements, or NULL
// NOTE: deleting nodes doesn't currently release geometry data owned by the node. TODO: implement erasing individual geometry chunks and banks
std::size_t create_geometry( gfx::geometrybank_handle const &Bank );
int TestPoint(glm::dvec3 const &Point);
int TestPoint(glm::dvec3 const &Point) const;
void Connect(int my, TTraction *with, int to);
void Init();
bool WhereIs();
@@ -78,13 +80,13 @@ private:
// methods
glm::vec3 wire_color() const;
// radius() subclass details, calculates node's bounding radius
float radius_();
float radius_() override;
// serialize() subclass details, sends content of the subclass to provided stream
void serialize_( std::ostream &Output ) const;
void serialize_( std::ostream &Output ) const override;
// deserialize() subclass details, restores content of the subclass from provided stream
void deserialize_( std::istream &Input );
void deserialize_( std::istream &Input ) override;
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
void export_as_text_( std::ostream &Output ) const;
void export_as_text_( std::ostream &Output ) const override;
};

View File

@@ -125,7 +125,7 @@ double TTractionPowerSource::CurrentGet(double res)
}
if (res > 0 || (res < 0 && (Recuperation || true)))
TotalAdmitance += 1.0 / res; // połączenie równoległe rezystancji jest równoważne sumie admitancji
float NomVolt = TotalPreviousAdmitance < 0 ? NominalVoltage * 1.083 : NominalVoltage;
float NomVolt = TotalPreviousAdmitance < 0 ? static_cast<float>(NominalVoltage * 1.083) : static_cast<float>(NominalVoltage);
TotalCurrent = TotalPreviousAdmitance != 0.0 ?
NomVolt / (InternalRes + 1.0 / TotalPreviousAdmitance) :
0.0; // napięcie dzielone przez sumę rezystancji wewnętrznej i obciążenia

View File

@@ -19,7 +19,7 @@ class TTractionPowerSource : public scene::basic_node {
public:
// constructor
TTractionPowerSource( scene::node_data const &Nodedata );
explicit TTractionPowerSource( scene::node_data const &Nodedata );
// methods
void Init(double const u, double const i);
bool Load(cParser *parser);
@@ -38,11 +38,11 @@ public:
private:
// methods
// serialize() subclass details, sends content of the subclass to provided stream
void serialize_( std::ostream &Output ) const;
void serialize_( std::ostream &Output ) const override;
// deserialize() subclass details, restores content of the subclass from provided stream
void deserialize_( std::istream &Input );
void deserialize_( std::istream &Input ) override;
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
void export_as_text_( std::ostream &Output ) const;
void export_as_text_( std::ostream &Output ) const override;
// members
double NominalVoltage = 0.0;

View File

@@ -14,7 +14,7 @@ http://mozilla.org/MPL/2.0/.
#include "utilities/dictionary.h"
#include "utilities/utilities.h"
double TTrainParameters::CheckTrainLatency()
double TTrainParameters::CheckTrainLatency() const
{
if (LastStationLatency > 1.0 || LastStationLatency < 0)
return LastStationLatency; /*spoznienie + lub do przodu - z tolerancja 1 min*/
@@ -22,7 +22,7 @@ double TTrainParameters::CheckTrainLatency()
return 0;
}
double TTrainParameters::WatchMTable(double DistCounter)
double TTrainParameters::WatchMTable(double DistCounter) const
{ // zwraca odleglość do najblizszej stacji z zatrzymaniem
double dist;
@@ -105,7 +105,7 @@ bool TTrainParameters::UpdateMTable( scenario_time const &Time, std::string cons
return UpdateMTable( Time.data().wHour, Time.data().wMinute + Time.data().wSecond * 0.0167, NewName );
}
bool TTrainParameters::UpdateMTable(double hh, double mm, std::string const &NewName)
bool TTrainParameters::UpdateMTable(double hh, double mm, std::string_view NewName)
/*odfajkowanie dojechania do stacji (NewName) i przeliczenie opóźnienia*/
{
bool OK;
@@ -163,7 +163,7 @@ void TTrainParameters::StationIndexInc()
++StationIndex;
}
bool TTrainParameters::IsTimeToGo(double hh, double mm)
bool TTrainParameters::IsTimeToGo(double hh, double mm) const
// sprawdzenie, czy można już odjechać z aktualnego zatrzymania
// StationIndex to numer następnego po dodarciu do aktualnego
{
@@ -205,7 +205,7 @@ TTrainParameters::TTrainParameters(std::string const &NewTrainName)
NewName(NewTrainName);
}
void TTrainParameters::NewName(std::string const &NewTrainName)
void TTrainParameters::NewName(std::string_view NewTrainName)
/*wstępne ustawienie parametrów rozkładu jazdy*/
{
TrainName = NewTrainName;
@@ -217,9 +217,9 @@ void TTrainParameters::NewName(std::string const &NewTrainName)
Direction = 1;
Relation1 = "";
Relation2 = "";
for (int i = 0; i < MaxTTableSize + 1; ++i)
for (auto &tableline : TimeTable)
{
TimeTable[ i ] = TMTableLine();
tableline = TMTableLine();
}
TTVmax = 100; /*wykasowac*/
BrakeRatio = 0;
@@ -227,7 +227,7 @@ void TTrainParameters::NewName(std::string const &NewTrainName)
LocLoad = 0;
}
void TTrainParameters::UpdateVelocity(int StationCount, double vActual)
void TTrainParameters::UpdateVelocity(int /*Stationcount*/, double vActual)
// zapisywanie prędkości maksymalnej do wcześniejszych odcinków
// wywoływane z numerem ostatniego przetworzonego przystanku
{
@@ -235,7 +235,7 @@ void TTrainParameters::UpdateVelocity(int StationCount, double vActual)
// TTVmax:=vActual; {PROWIZORKA!!!}
while (i >= 0 && TimeTable[i].vmax == -1)
{
TimeTable[i].vmax = vActual; // prędkość dojazdu do przystanku i
TimeTable[i].vmax = static_cast<float>(vActual); // prędkość dojazdu do przystanku i
--i; // ewentualnie do poprzedniego też
}
}
@@ -245,7 +245,7 @@ void TTrainParameters::UpdateVelocity(int StationCount, double vActual)
// return false;
//}
bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
bool TTrainParameters::LoadTTfile(std::string const &scnpath, int iPlus, double vmax)
// wczytanie pliku-tabeli z rozkładem przesuniętym o (fPlus); (vMax) nie ma znaczenia
{
std::string lines;
@@ -254,7 +254,7 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
bool EndTable;
double vActual;
int ConversionError = 0;
int conversionerror = 0;
EndTable = false;
if (TrainName == "")
{ // jeśli pusty rozkład
@@ -262,7 +262,6 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
}
else
{
ConversionError = 666;
vActual = -1;
s = scnpath + TrainName + ".txt";
replace_slashes(s);
@@ -278,15 +277,15 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
{
TTVmax = vmax; // Ra 2014-07: zamiast rozkładu można podać Vmax
UpdateVelocity(StationCount, vmax); // ograniczenie do prędkości startowej
ConversionError = 0;
conversionerror = 0;
}
else
ConversionError = -8; /*Ra: ten błąd jest niepotrzebny*/
conversionerror = -8; /*Ra: ten błąd jest niepotrzebny*/
}
else
{ /*analiza rozkładu jazdy*/
ConversionError = 0;
while (fin.good() && !(ConversionError != 0 || EndTable))
conversionerror = 0;
while (fin.good() && !(conversionerror != 0 || EndTable))
{
std::getline(fin, lines); /*wczytanie linii*/
if (contains( lines, "___________________") ) /*linia pozioma górna*/
@@ -354,7 +353,7 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
win1250_to_ascii( Relation1 );
}
else
ConversionError = -5;
conversionerror = -5;
while (fin >> s || !fin.bad())
{
if (s == "Relacja")
@@ -409,10 +408,10 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
if (s == "[")
fin >> s;
else
ConversionError = -4;
conversionerror = -4;
if (false == contains( s,"|") )
{
record->km = atof(s.c_str());
record->km = static_cast<float>(atof(s.c_str()));
fin >> s;
}
if (contains( s,"|_____|")) /*zmiana predkosci szlakowej*/
@@ -439,12 +438,12 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
if (contains( s, hrsd) )
{
record->Ah = atoi( s.substr(0, s.find(hrsd)).c_str()); // godzina przyjazdu
record->Am = atof(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta przyjazdu
record->Am = static_cast<float>(atof(s.substr(s.find(hrsd) + 1, s.length()).c_str())); // minuta przyjazdu
}
else
{
record->Ah = TimeTable[StationCount - 1].Ah; // godzina z poprzedniej pozycji
record->Am = atof(s.c_str()); // bo tylko minuty podane
record->Am = static_cast<float>(atof(s.c_str())); // bo tylko minuty podane
}
}
do
@@ -452,7 +451,7 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
fin >> s;
} while (!(s != "|" || fin.bad()));
if (s != "]")
record->tm = atof(s.c_str());
record->tm = static_cast<float>(atof(s.c_str()));
do
{
fin >> s;
@@ -490,10 +489,10 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
if( entry.front() != 'R' ) {
continue;
}
auto const entrysplit { split_string_and_number( entry ) };
if( entrysplit.first == "R"
&& entrysplit.second <= 10 ) {
auto const radiochannel { entrysplit.second };
auto const [entrytype, entrynumber]{ split_string_and_number( entry ) };
if( entrytype == "R"
&& entrynumber <= 10 ) {
auto const radiochannel { entrynumber };
if( record->radio_channel == -1
|| radiochannel != activeradiochannel ) {
// if the station has more than one radiochannel listed,
@@ -514,12 +513,12 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
if (contains( s, hrsd) )
{
record->Dh = atoi(s.substr(0, s.find(hrsd)).c_str()); // godzina odjazdu
record->Dm = atof(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta odjazdu
record->Dm = static_cast<float>(atof(s.substr(s.find(hrsd) + 1, s.length()).c_str())); // minuta odjazdu
}
else
{
record->Dh = TimeTable[StationCount - 1].Dh; // godzina z poprzedniej pozycji
record->Dm = atof(s.c_str()); // bo tylko minuty podane
record->Dm = static_cast<float>(atof(s.c_str())); // bo tylko minuty podane
}
}
else
@@ -532,7 +531,7 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
fin >> s;
} while (!(s != "|" || fin.bad()));
if (s != "]")
record->tm = atof(s.c_str());
record->tm = static_cast<float>(atof(s.c_str()));
do
{
fin >> s;
@@ -565,20 +564,16 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
fin.close();
}
}
if (ConversionError == 0)
{
if (TimeTable[1].StationName == Relation1) // jeśli nazwa pierwszego zgodna z relacją
if (TimeTable[1].Ah < 0) // a nie podany czas przyjazdu
{ // to mamy zatrzymanie na pierwszym, a nie przelot
TimeTable[1].Ah = TimeTable[1].Dh;
TimeTable[1].Am = TimeTable[1].Dm;
}
// jeśli nazwa pierwszego zgodna z relacją
if (conversionerror == 0 && TimeTable[1].StationName == Relation1 && TimeTable[1].Ah < 0) // a nie podany czas przyjazdu
{ // to mamy zatrzymanie na pierwszym, a nie przelot
TimeTable[1].Ah = TimeTable[1].Dh;
TimeTable[1].Am = TimeTable[1].Dm;
}
//
load_sounds();
// potentially offset table times
auto const timeoffset { static_cast<int>( Global.ScenarioTimeOffset * 60 ) + iPlus };
if( timeoffset != 0 ) // jeżeli jest przesunięcie rozkładu
if( auto const timeoffset { static_cast<int>( Global.ScenarioTimeOffset * 60 ) + iPlus }; timeoffset != 0 ) // jeżeli jest przesunięcie rozkładu
{
long i_end = StationCount + 1;
float adjustedtime; // do zwiększania czasu
@@ -586,19 +581,19 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
{
if (TimeTable[i].Ah >= 0)
{
adjustedtime = clamp_circular<float>( TimeTable[i].Ah * 60 + TimeTable[i].Am + timeoffset, 24 * 60 ); // nowe minuty
adjustedtime = clamp_circular<float>( static_cast<float>(TimeTable[i].Ah * 60) + TimeTable[i].Am + static_cast<float>(timeoffset), 24 * 60 ); // nowe minuty
TimeTable[i].Am = int(60 * adjustedtime) % 3600 / 60.f;
TimeTable[i].Ah = int(adjustedtime / 60) % 24;
}
if (TimeTable[i].Dh >= 0)
{
adjustedtime = clamp_circular<float>( TimeTable[i].Dh * 60 + TimeTable[i].Dm + timeoffset, 24 * 60 ); // nowe minuty
adjustedtime = clamp_circular<float>( static_cast<float>(TimeTable[i].Dh * 60) + TimeTable[i].Dm + static_cast<float>(timeoffset), 24 * 60 ); // nowe minuty
TimeTable[i].Dm = int(60 * adjustedtime) % 3600 / 60.f;
TimeTable[i].Dh = int(adjustedtime / 60) % 24;
}
}
}
return ConversionError == 0;
return conversionerror == 0;
}
void
@@ -615,26 +610,26 @@ TTrainParameters::load_sounds() {
station.StationName.substr( 0, station.StationName.size() - 3 ) :
station.StationName ) };
auto const lookup {
auto const [filepath, fileextension]{
FileExists(
{ Global.asCurrentSceneryPath + stationname, std::string{ paths::sounds } + "sip/" + stationname },
{ ".ogg", ".flac", ".wav" } ) };
if( lookup.first.empty() ) {
if( filepath.empty() ) {
continue;
}
// wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
station.name_sound =
sound_source{ sound_placement::engine, EU07_SOUND_CABANNOUNCEMENTCUTOFFRANGE }
.deserialize( lookup.first + lookup.second, sound_type::single );
.deserialize( filepath + fileextension, sound_type::single );
}
}
bool TTrainParameters::DirectionChange()
bool TTrainParameters::DirectionChange() const
// sprawdzenie, czy po zatrzymaniu wykonać kolejne komendy
{
if (StationIndex > 0 && StationIndex < StationCount) // dla ostatniej stacji nie
if (contains( TimeTable[StationIndex].StationWare, '@') )
return true;
// dla ostatniej stacji nie
if (StationIndex > 0 && StationIndex < StationCount && contains( TimeTable[StationIndex].StationWare, '@'))
return true;
return false;
}

View File

@@ -18,7 +18,7 @@ namespace Mtable
{
static int const MaxTTableSize = 100; // można by to robić dynamicznie
static char const *hrsd = ".";
static char const *const hrsd = ".";
// Ra: pozycja zerowa rozkładu chyba nie ma sensu
// Ra: numeracja przystanków jest 1..StationCount
@@ -42,7 +42,7 @@ struct TMTableLine
sound_source name_sound{ sound_placement::engine };
};
typedef TMTableLine TMTable[MaxTTableSize + 1];
using TMTable = TMTableLine[MaxTTableSize + 1];
// typedef TTrainParameters *PTrainParameters;
@@ -65,27 +65,27 @@ class TTrainParameters
std::string NextStationName;
double LastStationLatency;
int Direction; /*kierunek jazdy w/g kilometrazu*/
double CheckTrainLatency();
double CheckTrainLatency() const;
/*todo: str hh:mm to int i z powrotem*/
std::string ShowRelation() const;
double WatchMTable(double DistCounter);
double WatchMTable(double DistCounter) const;
std::string NextStop() const;
sound_source next_stop_sound() const;
sound_source last_stop_sound() const;
bool IsStop() const;
bool IsLastStop() const;
bool IsMaintenance() const;
bool IsTimeToGo(double hh, double mm);
bool IsTimeToGo(double hh, double mm) const;
// returns: difference between specified time and scheduled departure from current stop, in seconds
double seconds_until_departure( double const Hour, double const Minute ) const;
bool UpdateMTable(double hh, double mm, std::string const &NewName);
bool UpdateMTable(double hh, double mm, std::string_view NewName);
bool UpdateMTable( scenario_time const &Time, std::string const &NewName );
bool RewindTimeTable( std::string actualStationName );
TTrainParameters( std::string const &NewTrainName = "none" );
void NewName(std::string const &NewTrainName);
explicit TTrainParameters( std::string const &NewTrainName = "none" );
void NewName(std::string_view NewTrainName);
void UpdateVelocity(int StationCount, double vActual);
bool LoadTTfile(std::string scnpath, int iPlus, double vmax);
bool DirectionChange();
bool LoadTTfile(std::string const &scnpath, int iPlus, double vmax);
bool DirectionChange() const;
void StationIndexInc();
void serialize( dictionary_source *Output ) const;
// returns: radio channel associated with current station, or -1

View File

@@ -22,7 +22,7 @@ basic_station Station;
// exchanges load with consist attached to specified vehicle, operating on specified schedule
double
basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform ) {
basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform ) const {
// TODO: filter out maintenance stops when determining first and last stop
auto const firststop { Schedule.StationIndex == 1 };
@@ -63,7 +63,7 @@ basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Sch
maintenancestop ? 0 :
std::min<float>(
parameters.LoadAmount,
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) ) );
static_cast<float>(Random( parameters.MaxLoad * 0.15f * stationsizemodifier )) ) );
auto loadcount = static_cast<int>(
TestFlag( parameters.DamageFlag, dtrain_out ) ? 0 :
laststop ? 0 :

View File

@@ -18,7 +18,7 @@ public:
// methods
// exchanges load with consist attached to specified vehicle, operating on specified schedule; returns: time needed for exchange, in seconds
double
update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform );
update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform ) const;
};
namespace simulation {