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

build 190402. basic implementation for script generated vehicle destination sign textures

This commit is contained in:
tmj-fstate
2019-04-02 18:51:17 +02:00
parent 1ced1239e0
commit 8600550dcd
14 changed files with 215 additions and 59 deletions

View File

@@ -40,6 +40,7 @@ class powergridsource_table;
class instance_table; class instance_table;
class vehicle_table; class vehicle_table;
struct light_array; struct light_array;
struct dictionary_source;
namespace scene { namespace scene {
struct node_data; struct node_data;

View File

@@ -407,9 +407,9 @@ private:
// methods // methods
public: public:
std::string TrainName() const; std::string TrainName() const;
Mtable::TTrainParameters const * TrainTimetable() const;
private: private:
std::string Relation() const; std::string Relation() const;
Mtable::TTrainParameters const * TrainTimetable() const;
int StationIndex() const; int StationIndex() const;
int StationCount() const; int StationCount() const;
bool IsStop() const; bool IsStop() const;

View File

@@ -160,6 +160,39 @@ void TAnim::Parovoz(){
// animowanie tłoka i rozrządu parowozu // animowanie tłoka i rozrządu parowozu
}; };
*/ */
void TDynamicObject::destination_data::deserialize( cParser &Input ) {
while( true == deserialize_mapping( Input ) ) {
; // all work done by while()
}
}
bool TDynamicObject::destination_data::deserialize_mapping( cParser &Input ) {
// token can be a key or block end
auto const key { Input.getToken<std::string>( true, "\n\r\t ,;[]" ) };
if( ( true == key.empty() ) || ( key == "}" ) ) { return false; }
if( key == "{" ) {
script = Input.getToken<std::string>();
}
else if( key == "update:" ) {
auto const value { Input.getToken<std::string>() };
// TODO: implement
}
else if( key == "instance:" ) {
instancing = Input.getToken<std::string>();
}
else if( key == "parameters:" ) {
parameters = Input.getToken<std::string>();
}
return true;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
TDynamicObject * TDynamicObject::FirstFind(int &coupler_nr, int cf) TDynamicObject * TDynamicObject::FirstFind(int &coupler_nr, int cf)
{ // szukanie skrajnego połączonego pojazdu w pociagu { // szukanie skrajnego połączonego pojazdu w pociagu
@@ -5569,6 +5602,15 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
parser >> JointCabs; parser >> JointCabs;
} }
else if( token == "pydestinationsign:" ) {
DestinationSign.deserialize( parser );
// supply vehicle folder as script path if none is provided
if( ( false == DestinationSign.script.empty() )
&& ( substr_path( DestinationSign.script ).empty() ) ) {
DestinationSign.script = asBaseDir + DestinationSign.script;
}
}
} while( token != "" ); } while( token != "" );
} // internaldata: } // internaldata:
@@ -6147,9 +6189,41 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer) {
DestinationSign.destination = DestinationFind( destination ); DestinationSign.destination = DestinationFind( destination );
if( DestinationSign.destination != null_handle ) { if( DestinationSign.destination != null_handle ) {
// got what we wanted, we're done here // got what we wanted, we're done here
break; return;
} }
} }
// if we didn't get static texture we might be able to make one
if( DestinationSign.script.empty() ) { return; } // no script so no way to make the texture
if( numer == "none" ) { return; } // blank or incomplete/malformed timetable, don't bother
std::string signrequest {
"make:"
+ DestinationSign.script + "?"
// timetable include
+ "$timetable=" + (
ctOwner == nullptr ?
MoverParameters->Name : // leading vehicle, can point to it directly
ctOwner->Vehicle()->MoverParameters->Name ) + "&" // owned vehicle, safer to point to owner as carriages can have identical names
// basic instancing string
// NOTE: underscore doesn't have any magic meaning for the time being, it's just less likely to conflict with regular dictionary keys
+ "_id1=" + (
ctOwner != nullptr ? ctOwner->TrainName() :
Mechanik != nullptr ? Mechanik->TrainName() :
"none" ) }; // shouldn't get here but, eh
// TBD, TODO: replace instancing with support for variables in extra parameters string?
if( false == DestinationSign.instancing.empty() ) {
signrequest +=
"&_id2=" + (
DestinationSign.instancing == "name" ? MoverParameters->Name :
DestinationSign.instancing == "type" ? MoverParameters->TypeName :
"none" );
}
// optionl extra parameters
if( false == DestinationSign.parameters.empty() ) {
signrequest += "&" + DestinationSign.parameters;
}
DestinationSign.destination = GfxRenderer.Fetch_Material( signrequest );
} }
material_handle TDynamicObject::DestinationFind( std::string Destination ) { material_handle TDynamicObject::DestinationFind( std::string Destination ) {

View File

@@ -205,6 +205,14 @@ public:
bool has_light { false }; // the submodel was originally configured with self-illumination attribute bool has_light { false }; // the submodel was originally configured with self-illumination attribute
material_handle destination { null_handle }; // most recently assigned non-blank destination texture material_handle destination { null_handle }; // most recently assigned non-blank destination texture
material_handle destination_off { null_handle }; // blank destination sign material_handle destination_off { null_handle }; // blank destination sign
std::string script; // potential python script used to generate texture data
int update_rate { 0 }; // -1: per stop, 0: none, >0: fps // TBD, TODO: implement?
std::string instancing; // potential method to generate more than one texture per timetable
std::string parameters; // potential extra parameters supplied by mmd file
// methods
void deserialize( cParser &Input );
private:
bool deserialize_mapping( cParser &Input );
} DestinationSign; } DestinationSign;
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?) float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
float LoadOffset { 0.f }; float LoadOffset { 0.f };

View File

@@ -10,9 +10,8 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h" #include "stdafx.h"
#include "PyInt.h" #include "PyInt.h"
#include "Globals.h" #include "dictionary.h"
#include "application.h" #include "application.h"
#include "renderer.h"
#include "Logs.h" #include "Logs.h"
void render_task::run() { void render_task::run() {

18
PyInt.h
View File

@@ -23,24 +23,6 @@ http://mozilla.org/MPL/2.0/.
#define PyGetBool(param) param ? Py_True : Py_False #define PyGetBool(param) param ? Py_True : Py_False
#define PyGetString(param) PyString_FromString(param) #define PyGetString(param) PyString_FromString(param)
// collection of keyword-value pairs
// NOTE: since our python dictionary operates on a few types, most of the class was hardcoded for simplicity
struct dictionary_source {
// types
template <typename Type_>
using keyvaluepair_sequence = std::vector<std::pair<std::string, Type_>>;
// members
keyvaluepair_sequence<double> floats;
keyvaluepair_sequence<int> integers;
keyvaluepair_sequence<bool> bools;
keyvaluepair_sequence<std::string> strings;
// methods
inline void insert( std::string const &Key, double const Value ) { floats.emplace_back( Key, Value ); }
inline void insert( std::string const &Key, int const Value ) { integers.emplace_back( Key, Value ); }
inline void insert( std::string const &Key, bool const Value ) { bools.emplace_back( Key, Value ); }
inline void insert( std::string const &Key, std::string const Value ) { strings.emplace_back( Key, Value ); }
};
// TODO: extract common base and inherit specialization from it // TODO: extract common base and inherit specialization from it
class render_task { class render_task {

View File

@@ -20,11 +20,13 @@ http://mozilla.org/MPL/2.0/.
#include "GL/glew.h" #include "GL/glew.h"
#include "application.h" #include "application.h"
#include "utilities.h" #include "dictionary.h"
#include "Globals.h" #include "Globals.h"
#include "Logs.h" #include "Logs.h"
#include "utilities.h"
#include "sn_utils.h" #include "sn_utils.h"
#define EU07_DEFERRED_TEXTURE_UPLOAD #define EU07_DEFERRED_TEXTURE_UPLOAD
texture_manager::texture_manager() { texture_manager::texture_manager() {
@@ -96,17 +98,9 @@ void
opengl_texture::make_request() { opengl_texture::make_request() {
auto const components { Split( name, '?' ) }; auto const components { Split( name, '?' ) };
auto const query { Split( components.back(), '&' ) };
auto *dictionary { new dictionary_source }; auto *dictionary { new dictionary_source( components.back() ) };
if( dictionary != nullptr ) { if( dictionary == nullptr ) { return; }
for( auto const &querypair : query ) {
auto const valuepos { querypair.find( '=' ) };
dictionary->insert(
ToLower( querypair.substr( 0, valuepos ) ),
querypair.substr( valuepos + 1 ) );
}
}
Application.request( { ToLower( components.front() ), dictionary, id } ); Application.request( { ToLower( components.front() ), dictionary, id } );
} }

View File

@@ -30,6 +30,7 @@ http://mozilla.org/MPL/2.0/.
#include "Console.h" #include "Console.h"
#include "application.h" #include "application.h"
#include "renderer.h" #include "renderer.h"
#include "dictionary.h"
/* /*
namespace input { namespace input {
@@ -543,31 +544,8 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "velnext", driver->VelNext ); dict->insert( "velnext", driver->VelNext );
dict->insert( "actualproximitydist", driver->ActualProximityDist ); dict->insert( "actualproximitydist", driver->ActualProximityDist );
// train data // train data
auto const *timetable{ driver->TrainTimetable() }; driver->TrainTimetable()->serialize( dict );
dict->insert( "train_stationstart", driver->iStationStart );
dict->insert( "trainnumber", driver->TrainName() );
dict->insert( "train_brakingmassratio", timetable->BrakeRatio );
dict->insert( "train_enginetype", timetable->LocSeries );
dict->insert( "train_engineload", timetable->LocLoad );
dict->insert( "train_stationindex", driver->iStationStart );
auto const stationcount { driver->StationCount() };
dict->insert( "train_stationcount", stationcount );
if( stationcount > 0 ) {
// timetable stations data, if there's any
for( auto stationidx = 1; stationidx <= stationcount; ++stationidx ) {
auto const stationlabel { "train_station" + std::to_string( stationidx ) + "_" };
auto const &timetableline { timetable->TimeTable[ stationidx ] };
dict->insert( ( stationlabel + "name" ), Bezogonkow( timetableline.StationName ) );
dict->insert( ( stationlabel + "fclt" ), Bezogonkow( timetableline.StationWare ) );
dict->insert( ( stationlabel + "lctn" ), timetableline.km );
dict->insert( ( stationlabel + "vmax" ), timetableline.vmax );
dict->insert( ( stationlabel + "ah" ), timetableline.Ah );
dict->insert( ( stationlabel + "am" ), timetableline.Am );
dict->insert( ( stationlabel + "dh" ), timetableline.Dh );
dict->insert( ( stationlabel + "dm" ), timetableline.Dm );
}
}
dict->insert( "train_atpassengerstop", driver->IsAtPassengerStop ); dict->insert( "train_atpassengerstop", driver->IsAtPassengerStop );
// world state data // world state data
dict->insert( "scenario", Global.SceneryFile ); dict->insert( "scenario", Global.SceneryFile );

55
dictionary.cpp Normal file
View File

@@ -0,0 +1,55 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "dictionary.h"
#include "simulation.h"
#include "utilities.h"
#include "DynObj.h"
#include "Driver.h"
#include "mtable.h"
dictionary_source::dictionary_source( std::string const &Input ) {
auto const keyvaluepairs { Split( Input, '&' ) };
for( auto const &keyvaluepair : keyvaluepairs ) {
auto const valuepos { keyvaluepair.find( '=' ) };
if( keyvaluepair[ 0 ] != '$' ) {
// regular key, value pairs
insert(
ToLower( keyvaluepair.substr( 0, valuepos ) ),
keyvaluepair.substr( valuepos + 1 ) );
}
else {
// special case, $key indicates request to include certain dataset clarified by value
auto const key { ToLower( keyvaluepair.substr( 0, valuepos ) ) };
auto const value { keyvaluepair.substr( valuepos + 1 ) };
if( key == "$timetable" ) {
// timetable pulled from (preferably) the owner/direct controller of specified vehicle
auto const *vehicle { simulation::Vehicles.find( value ) };
auto const *controller { (
vehicle == nullptr ? nullptr :
vehicle->ctOwner == nullptr ? vehicle->Mechanik :
vehicle->ctOwner ) };
auto const *timetable { (
controller != nullptr ?
controller->TrainTimetable() :
nullptr ) };
if( timetable != nullptr ) {
timetable->serialize( this );
}
}
}
}
}

31
dictionary.h Normal file
View File

@@ -0,0 +1,31 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#pragma once
// collection of keyword-value pairs
// NOTE: since our python dictionary operates on a few types, most of the class was hardcoded for simplicity
struct dictionary_source {
// types
template <typename Type_>
using keyvaluepair_sequence = std::vector<std::pair<std::string, Type_>>;
// members
keyvaluepair_sequence<double> floats;
keyvaluepair_sequence<int> integers;
keyvaluepair_sequence<bool> bools;
keyvaluepair_sequence<std::string> strings;
// constructors
dictionary_source() = default;
dictionary_source( std::string const &Input );
// methods
inline void insert( std::string const &Key, double const Value ) { floats.emplace_back( Key, Value ); }
inline void insert( std::string const &Key, int const Value ) { integers.emplace_back( Key, Value ); }
inline void insert( std::string const &Key, bool const Value ) { bools.emplace_back( Key, Value ); }
inline void insert( std::string const &Key, std::string const Value ) { strings.emplace_back( Key, Value ); }
};

View File

@@ -339,6 +339,9 @@
<ClCompile Include="ref\stb\stb_vorbis.c"> <ClCompile Include="ref\stb\stb_vorbis.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="dictionary.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Globals.h"> <ClInclude Include="Globals.h">
@@ -623,6 +626,9 @@
<ClInclude Include="openglcolor.h"> <ClInclude Include="openglcolor.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="dictionary.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="maszyna.rc"> <ResourceCompile Include="maszyna.rc">

View File

@@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/.
#include "Globals.h" #include "Globals.h"
#include "simulationtime.h" #include "simulationtime.h"
#include "dictionary.h"
#include "utilities.h" #include "utilities.h"
double TTrainParameters::CheckTrainLatency() double TTrainParameters::CheckTrainLatency()
@@ -523,3 +524,29 @@ bool TTrainParameters::DirectionChange()
return true; return true;
return false; return false;
} }
void TTrainParameters::serialize( dictionary_source *Output ) const {
Output->insert( "trainnumber", TrainName );
Output->insert( "train_brakingmassratio", BrakeRatio );
Output->insert( "train_enginetype", LocSeries );
Output->insert( "train_engineload", LocLoad );
Output->insert( "train_stationindex", StationIndex );
Output->insert( "train_stationcount", StationCount );
if( StationCount > 0 ) {
// timetable stations data, if there's any
for( auto stationidx = 1; stationidx <= StationCount; ++stationidx ) {
auto const stationlabel { "train_station" + std::to_string( stationidx ) + "_" };
auto const &timetableline { TimeTable[ stationidx ] };
Output->insert( ( stationlabel + "name" ), Bezogonkow( timetableline.StationName ) );
Output->insert( ( stationlabel + "fclt" ), Bezogonkow( timetableline.StationWare ) );
Output->insert( ( stationlabel + "lctn" ), timetableline.km );
Output->insert( ( stationlabel + "vmax" ), timetableline.vmax );
Output->insert( ( stationlabel + "ah" ), timetableline.Ah );
Output->insert( ( stationlabel + "am" ), timetableline.Am );
Output->insert( ( stationlabel + "dh" ), timetableline.Dh );
Output->insert( ( stationlabel + "dm" ), timetableline.Dm );
}
}
}

View File

@@ -83,6 +83,7 @@ class TTrainParameters
bool LoadTTfile(std::string scnpath, int iPlus, double vmax); bool LoadTTfile(std::string scnpath, int iPlus, double vmax);
bool DirectionChange(); bool DirectionChange();
void StationIndexInc(); void StationIndexInc();
void serialize( dictionary_source *Output ) const;
}; };
class TMTableTime class TMTableTime

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 19 #define VERSION_MAJOR 19
#define VERSION_MINOR 327 #define VERSION_MINOR 402
#define VERSION_REVISION 0 #define VERSION_REVISION 0