mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-31 13:29:07 +01:00
Catenary as plain node entries in scenery files
This commit is contained in:
@@ -78,6 +78,8 @@ struct scene_file {
|
||||
std::vector<scene_file> Files;
|
||||
// warstwa scenerii (plik), która dołącza plik sieci dyrektywą "catenary"; dla plików z edytora ta, do której trafi dyrektywa
|
||||
std::map<std::string, std::size_t> FileLayers;
|
||||
// "pliki" sieci, których wpisy są zwykłymi wpisami node w pliku scenerii (warstwie): zapisuje je zapis scenerii, nie catenary_scene_save()
|
||||
std::set<std::string> InlineFiles;
|
||||
|
||||
// łańcuch sieci z pliku: przęsła od podwieszenia do podwieszenia
|
||||
struct scene_chain {
|
||||
@@ -1649,6 +1651,86 @@ umbrella_members( std::string const &Name ) {
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
|
||||
// wpisy rozebranego pliku (albo jednego wpisu node ze scenerii) do sceny: podwieszenia czekają na catenary_scene_resolve(),
|
||||
// bramki, kotwienia i łańcuchy są od razu
|
||||
void
|
||||
add_content( catenary::suspension_file const &File, std::string const &Filename ) {
|
||||
for( auto const &entry : File.entries ) {
|
||||
scene_suspension suspension;
|
||||
suspension.data = entry;
|
||||
suspension.skin = ( entry.skin.empty() ? File.skin : entry.skin );
|
||||
suspension.file = Filename;
|
||||
Suspensions.emplace_back( suspension );
|
||||
}
|
||||
for( auto const &line : File.gantries ) {
|
||||
scene_gantry gantry;
|
||||
gantry.data = line;
|
||||
gantry.file = Filename;
|
||||
Gantries.emplace_back( gantry );
|
||||
assemble_gantry( Gantries.back() );
|
||||
}
|
||||
// kotwienia przed łańcuchami: ostatnie przęsło łańcucha kończy się na ich urządzeniu (łańcuch wpisany wcześniej idzie za nim)
|
||||
for( auto const &line : File.anchors ) {
|
||||
scene_anchor anchor;
|
||||
anchor.data = line;
|
||||
anchor.file = Filename;
|
||||
Anchors.emplace_back( anchor );
|
||||
assemble_anchor( Anchors.back() );
|
||||
follow_anchor( Anchors.back() );
|
||||
}
|
||||
// przęsła łańcuchów powstają od razu: przed inicjalizacją scenerii łączy je InitTraction razem z resztą sieci
|
||||
for( auto const &line : File.chains ) {
|
||||
scene_chain chain;
|
||||
chain.data = line;
|
||||
chain.file = Filename;
|
||||
Chains.emplace_back( chain );
|
||||
rebuild_chain( Chains.back() );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void
|
||||
catenary_scene_node( cParser &Input, std::string const &Type, double const RangeMax, double const RangeMin, std::string const &Name, std::string const &File ) {
|
||||
|
||||
// treść wpisu do jego końca, z wielkością liter (symbole typów sieci, ścieżki tekstur)
|
||||
auto const closing { "end" + Type };
|
||||
std::vector<std::string> tokens { "node", std::to_string( RangeMax ), std::to_string( RangeMin ), ( Name.empty() ? std::string( "none" ) : Name ), Type };
|
||||
auto const line { Input.Line() };
|
||||
while( true ) {
|
||||
auto token { Input.getToken<std::string>( false ) };
|
||||
if( token.empty() ) {
|
||||
ErrorLog( "Bad scenario: " + Type + " \"" + Name + "\" without \"" + closing + "\" in file \"" + Input.Name() + "\" (line " + std::to_string( line ) + ")" );
|
||||
return;
|
||||
}
|
||||
auto lower { token };
|
||||
std::transform( lower.begin(), lower.end(), lower.begin(), []( unsigned char const C ) { return static_cast<char>( std::tolower( C ) ); } );
|
||||
tokens.emplace_back( token );
|
||||
if( lower == closing ) { tokens.back() = closing; break; }
|
||||
}
|
||||
if( false == Global.bLoadTraction ) { return; }
|
||||
catenary::suspension_file file;
|
||||
std::vector<std::string> errors;
|
||||
catenary::parse_suspensions( tokens, File, file, errors );
|
||||
for( auto const &error : errors ) {
|
||||
ErrorLog( error );
|
||||
}
|
||||
InlineFiles.emplace( File );
|
||||
if( file_named( File ) == nullptr ) {
|
||||
scene_file known;
|
||||
known.name = File;
|
||||
Files.emplace_back( known );
|
||||
}
|
||||
FileLayers.emplace( File, static_cast<std::size_t>( scene::Layers.handle() ) );
|
||||
add_content( file, File );
|
||||
if( Initialized ) {
|
||||
// wpis po FirstInit: tory, przęsła i modele już są
|
||||
catenary_scene_resolve();
|
||||
}
|
||||
}
|
||||
|
||||
// obsługa dyrektywy "catenary" ze scenerii: wczytuje wskazany plik podwieszeń
|
||||
void
|
||||
catenary_scene_load( cParser &Input ) {
|
||||
@@ -1686,36 +1768,7 @@ catenary_scene_load( cParser &Input ) {
|
||||
for( auto const &error : errors ) {
|
||||
ErrorLog( error );
|
||||
}
|
||||
for( auto const &entry : file.entries ) {
|
||||
scene_suspension suspension;
|
||||
suspension.data = entry;
|
||||
suspension.skin = ( entry.skin.empty() ? file.skin : entry.skin );
|
||||
suspension.file = filename;
|
||||
Suspensions.emplace_back( suspension );
|
||||
}
|
||||
for( auto const &line : file.gantries ) {
|
||||
scene_gantry gantry;
|
||||
gantry.data = line;
|
||||
gantry.file = filename;
|
||||
Gantries.emplace_back( gantry );
|
||||
assemble_gantry( Gantries.back() );
|
||||
}
|
||||
// kotwienia przed łańcuchami: ostatnie przęsło łańcucha kończy się na ich urządzeniu
|
||||
for( auto const &line : file.anchors ) {
|
||||
scene_anchor anchor;
|
||||
anchor.data = line;
|
||||
anchor.file = filename;
|
||||
Anchors.emplace_back( anchor );
|
||||
assemble_anchor( Anchors.back() );
|
||||
}
|
||||
// przęsła łańcuchów powstają od razu: przed inicjalizacją scenerii łączy je InitTraction razem z resztą sieci
|
||||
for( auto const &line : file.chains ) {
|
||||
scene_chain chain;
|
||||
chain.data = line;
|
||||
chain.file = filename;
|
||||
Chains.emplace_back( chain );
|
||||
rebuild_chain( Chains.back() );
|
||||
}
|
||||
add_content( file, filename );
|
||||
// wczytywany z pliku tej warstwy (tylko przy otwarciu scenerii do edycji, inaczej warstw nie ma)
|
||||
FileLayers.emplace( filename, static_cast<std::size_t>( scene::Layers.handle() ) );
|
||||
if( file_named( filename ) == nullptr ) {
|
||||
@@ -1837,6 +1890,7 @@ catenary_scene_clear() {
|
||||
Anchors.clear();
|
||||
Files.clear();
|
||||
FileLayers.clear();
|
||||
InlineFiles.clear();
|
||||
Notes.clear();
|
||||
Resolved = 0;
|
||||
Initialized = false;
|
||||
@@ -2090,10 +2144,59 @@ catenary_scene_changed() {
|
||||
std::vector<std::string>
|
||||
catenary_scene_new_files() {
|
||||
std::vector<std::string> names;
|
||||
for( auto const &file : Files ) { if( file.created ) { names.push_back( file.name ); } }
|
||||
for( auto const &file : Files ) { if( file.created && InlineFiles.count( file.name ) == 0 ) { names.push_back( file.name ); } }
|
||||
return names;
|
||||
}
|
||||
|
||||
bool
|
||||
catenary_scene_file_inline( std::string const &File ) {
|
||||
return InlineFiles.count( File ) != 0;
|
||||
}
|
||||
|
||||
void
|
||||
catenary_scene_file_inline( std::string const &File, bool const Inline ) {
|
||||
if( Inline ) { InlineFiles.emplace( File ); }
|
||||
else { InlineFiles.erase( File ); }
|
||||
}
|
||||
|
||||
bool
|
||||
catenary_scene_file_changed( std::string const &File ) {
|
||||
auto const *file { file_named( File ) };
|
||||
return file != nullptr && file->changed;
|
||||
}
|
||||
|
||||
void
|
||||
catenary_scene_file_saved( std::string const &File ) {
|
||||
if( auto *file { file_named( File ) }; file != nullptr ) {
|
||||
file->changed = false;
|
||||
file->created = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
catenary_scene_entries( std::string const &File ) {
|
||||
// w kolejności wczytywania wpisów node: podwieszenia, bramki, kotwienia, łańcuchy
|
||||
std::vector<std::string> lines;
|
||||
auto const *file { file_named( File ) };
|
||||
auto const skin { file != nullptr ? file->skin : std::string() };
|
||||
for( auto const &suspension : Suspensions ) {
|
||||
if( suspension.removed || suspension.file != File ) { continue; }
|
||||
auto data { suspension.data };
|
||||
if( data.skin.empty() ) { data.skin = skin; }
|
||||
lines.emplace_back( catenary::write_suspension( data ) );
|
||||
}
|
||||
for( auto const &gantry : Gantries ) {
|
||||
if( false == gantry.removed && gantry.file == File ) { lines.emplace_back( catenary::write_gantry( gantry.data ) ); }
|
||||
}
|
||||
for( auto const &anchor : Anchors ) {
|
||||
if( false == anchor.removed && anchor.file == File ) { lines.emplace_back( catenary::write_anchor( anchor.data ) ); }
|
||||
}
|
||||
for( auto const &chain : Chains ) {
|
||||
if( false == chain.removed && chain.file == File ) { lines.emplace_back( catenary::write_chain( chain.data ) ); }
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
void
|
||||
catenary_scene_file_included( std::string const &File ) {
|
||||
if( auto *file { file_named( File ) }; file != nullptr ) { file->created = false; }
|
||||
@@ -2138,7 +2241,8 @@ catenary_scene_save( std::string &Message ) {
|
||||
|
||||
std::vector<std::string> written;
|
||||
for( auto &file : Files ) {
|
||||
if( false == file.changed ) { continue; }
|
||||
// wpisy w pliku scenerii zapisuje zapis scenerii
|
||||
if( false == file.changed || InlineFiles.count( file.name ) != 0 ) { continue; }
|
||||
// wpisy w kolejności listy; usunięte pomijane. CRLF jak w pozostałych plikach scenerii
|
||||
std::string text;
|
||||
std::istringstream header { file.header };
|
||||
@@ -2200,6 +2304,8 @@ catenary_scene_new_chain_name( std::string const &File ) {
|
||||
auto stem { File };
|
||||
if( auto const slash { stem.find_last_of( "/\\" ) }; slash != std::string::npos ) { stem.erase( 0, slash + 1 ); }
|
||||
if( auto const dot { stem.rfind( '.' ) }; dot != std::string::npos ) { stem.erase( dot ); }
|
||||
// małymi literami: nazwy wpisów node w scenerii parser czyta małymi literami
|
||||
std::transform( stem.begin(), stem.end(), stem.begin(), []( unsigned char const C ) { return static_cast<char>( std::tolower( C ) ); } );
|
||||
for( int number = 1; ; ++number ) {
|
||||
auto const name { stem + "_l" + std::to_string( number ) };
|
||||
auto const taken { std::any_of( Chains.begin(), Chains.end(), [ & ]( scene_chain const &Chain ) { return Chain.data.name == name; } ) };
|
||||
@@ -2389,6 +2495,8 @@ catenary_scene_new_gantry_name( std::string const &File ) {
|
||||
auto stem { File };
|
||||
if( auto const slash { stem.find_last_of( "/\\" ) }; slash != std::string::npos ) { stem.erase( 0, slash + 1 ); }
|
||||
if( auto const dot { stem.rfind( '.' ) }; dot != std::string::npos ) { stem.erase( dot ); }
|
||||
// małymi literami: nazwy wpisów node w scenerii parser czyta małymi literami
|
||||
std::transform( stem.begin(), stem.end(), stem.begin(), []( unsigned char const C ) { return static_cast<char>( std::tolower( C ) ); } );
|
||||
for( int number = 1; ; ++number ) {
|
||||
auto const name { stem + "_b" + std::to_string( number ) };
|
||||
if( std::none_of( Gantries.begin(), Gantries.end(), [ & ]( scene_gantry const &Gantry ) { return Gantry.data.name == name; } ) ) { return name; }
|
||||
|
||||
@@ -18,6 +18,9 @@ class cParser;
|
||||
|
||||
// obsługa dyrektywy "catenary" ze scenerii: wczytuje wskazany plik podwieszeń
|
||||
void catenary_scene_load( cParser &Input );
|
||||
// wpis "node <max> <min> <nazwa> suspension|chain|gantry|anchor ... end<typ>" wprost w pliku scenerii; Input stoi za typem.
|
||||
// File: plik scenerii (warstwa), do którego wpis należy - jego wpisy sieci zapisuje zapis scenerii
|
||||
void catenary_scene_node( cParser &Input, std::string const &Type, double RangeMax, double RangeMin, std::string const &Name, std::string const &File );
|
||||
// po wczytaniu scenerii: wiąże podwieszenia z konstrukcjami wsporczymi i przęsłami po nazwach, zgłasza braki
|
||||
void catenary_scene_resolve();
|
||||
// przed wczytaniem nowej scenerii: usuwa podwieszenia poprzedniej
|
||||
@@ -73,6 +76,14 @@ bool catenary_scene_changed();
|
||||
std::vector<std::string> catenary_scene_new_files();
|
||||
// sceneria dołącza już plik (edytor dopisał dyrektywę "catenary")
|
||||
void catenary_scene_file_included( std::string const &File );
|
||||
// wpisy pliku są zwykłymi wpisami node w pliku scenerii o tej nazwie (warstwie): zapisuje je zapis scenerii, bez dyrektywy "catenary"
|
||||
bool catenary_scene_file_inline( std::string const &File );
|
||||
void catenary_scene_file_inline( std::string const &File, bool Inline );
|
||||
bool catenary_scene_file_changed( std::string const &File );
|
||||
// zapis scenerii zapisał wpisy pliku
|
||||
void catenary_scene_file_saved( std::string const &File );
|
||||
// wpisy pliku jako linie tekstu (wpisy node), w kolejności, w jakiej sceneria ma je wczytać
|
||||
std::vector<std::string> catenary_scene_entries( std::string const &File );
|
||||
// warstwa scenerii (uchwyt scene::Layers), której plik dołącza plik sieci, a dla pliku założonego w edytorze ta, do której ma
|
||||
// trafić jego dyrektywa; 0 gdy nieznana (wtedy plik scenariusza)
|
||||
std::size_t catenary_scene_file_layer( std::string const &File );
|
||||
|
||||
Reference in New Issue
Block a user