mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-17 23:39:18 +02:00
scenario ui panel
This commit is contained in:
51
Driver.cpp
51
Driver.cpp
@@ -15,8 +15,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "stdafx.h"
|
||||
#include "Driver.h"
|
||||
|
||||
#include <direct.h>
|
||||
//#include <direct.h>
|
||||
#include "Globals.h"
|
||||
#include "translation.h"
|
||||
#include "Logs.h"
|
||||
#include "Train.h"
|
||||
#include "mtable.h"
|
||||
@@ -1696,9 +1697,54 @@ std::string TController::Order2Str(TOrders Order) const {
|
||||
}
|
||||
}
|
||||
|
||||
std::array<char, 64> orderbuffer;
|
||||
|
||||
std::string TController::OrderCurrent() const
|
||||
{ // pobranie aktualnego rozkazu celem wyświetlenia
|
||||
return "[" + std::to_string(OrderPos) + "] " + Order2Str(OrderList[OrderPos]);
|
||||
auto const order { OrderCurrentGet() };
|
||||
if( order & Change_direction ) {
|
||||
return locale::strings[ locale::string::driver_scenario_changedirection ];
|
||||
}
|
||||
|
||||
switch( OrderList[ OrderPos ] ) {
|
||||
case Wait_for_orders: { return locale::strings[ locale::string::driver_scenario_waitfororders ]; }
|
||||
case Prepare_engine: { return locale::strings[ locale::string::driver_scenario_prepareengine ]; }
|
||||
case Release_engine: { return locale::strings[ locale::string::driver_scenario_releaseengine ]; }
|
||||
case Change_direction: { return locale::strings[ locale::string::driver_scenario_changedirection ]; }
|
||||
case Connect: { return locale::strings[ locale::string::driver_scenario_connect ]; }
|
||||
case Disconnect: {
|
||||
if( iVehicleCount < 0 ) {
|
||||
// done with uncoupling, order should update shortly
|
||||
return locale::strings[ locale::string::driver_scenario_waitfororders ];
|
||||
}
|
||||
// try to provide some task details
|
||||
auto const count { iVehicleCount };
|
||||
|
||||
if( iVehicleCount > 1 ) {
|
||||
std::snprintf(
|
||||
orderbuffer.data(), orderbuffer.size(),
|
||||
( iVehicleCount < 5 ?
|
||||
locale::strings[ locale::string::driver_scenario_fewvehicles ].c_str() : // 2-4
|
||||
locale::strings[ locale::string::driver_scenario_somevehicles ].c_str() ), // 5+
|
||||
count );
|
||||
}
|
||||
auto const countstring { (
|
||||
count == 0 ? locale::strings[ locale::string::driver_scenario_allvehicles ] :
|
||||
count == 1 ? locale::strings[ locale::string::driver_scenario_onevehicle ] :
|
||||
orderbuffer.data() ) };
|
||||
|
||||
std::snprintf(
|
||||
orderbuffer.data(), orderbuffer.size(),
|
||||
locale::strings[ locale::string::driver_scenario_disconnect ].c_str(),
|
||||
countstring.c_str() );
|
||||
return orderbuffer.data();
|
||||
}
|
||||
case Shunt: { return locale::strings[ locale::string::driver_scenario_shunt ]; }
|
||||
case Loose_shunt: { return locale::strings[ locale::string::driver_scenario_looseshunt ]; }
|
||||
case Obey_train: { return locale::strings[ locale::string::driver_scenario_obeytrain ]; }
|
||||
case Bank: { return locale::strings[ locale::string::driver_scenario_bank ]; }
|
||||
default: { return{}; }
|
||||
}
|
||||
};
|
||||
|
||||
void TController::OrdersClear()
|
||||
@@ -4699,7 +4745,6 @@ TController::UpdateSituation(double dt) {
|
||||
n = 0; // nie ma co dalej sprawdzać, doczepianie zakończone
|
||||
}
|
||||
} while (n--);
|
||||
// write down what vehicle we're uncoupling, we might need to fiddle with remainder of the consist afterwards
|
||||
if( ( p == nullptr )
|
||||
|| ( p->MoverParameters->Couplers[ d ].Connected == nullptr ) ) {
|
||||
// no target, or already just virtual coupling
|
||||
|
||||
6
Driver.h
6
Driver.h
@@ -312,6 +312,10 @@ private:
|
||||
public:
|
||||
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm);
|
||||
bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm );
|
||||
// defines assignment data
|
||||
inline auto assignment() -> std::string & { return m_assignment; }
|
||||
inline auto assignment() const -> std::string const & { return m_assignment; }
|
||||
std::string OrderCurrent() const;
|
||||
private:
|
||||
void RecognizeCommand(); // odczytuje komende przekazana lokomotywie
|
||||
void JumpToNextOrder();
|
||||
@@ -324,9 +328,9 @@ private:
|
||||
void OrdersInit(double fVel);
|
||||
void OrdersClear();
|
||||
void OrdersDump();
|
||||
std::string OrderCurrent() const;
|
||||
std::string Order2Str(TOrders Order) const;
|
||||
// members
|
||||
std::string m_assignment;
|
||||
Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used
|
||||
TOrders OrderList[ maxorders ]; // lista rozkazów
|
||||
int OrderPos = 0,
|
||||
|
||||
2
Train.h
2
Train.h
@@ -17,6 +17,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "PyInt.h"
|
||||
#include "command.h"
|
||||
|
||||
#undef snprintf // pyint.h->python
|
||||
|
||||
// typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State;
|
||||
|
||||
const int maxcab = 2;
|
||||
|
||||
@@ -23,12 +23,17 @@ driver_ui::driver_ui() {
|
||||
clear_panels();
|
||||
// bind the panels with ui object. maybe not the best place for this but, eh
|
||||
push_back( &m_aidpanel );
|
||||
push_back( &m_scenariopanel );
|
||||
push_back( &m_timetablepanel );
|
||||
push_back( &m_debugpanel );
|
||||
push_back( &m_transcriptspanel );
|
||||
|
||||
m_aidpanel.title = locale::strings[ locale::string::driver_aid_header ];
|
||||
|
||||
m_scenariopanel.title = locale::strings[ locale::string::driver_scenario_header ];
|
||||
m_scenariopanel.size_min = { 435, 85 };
|
||||
m_scenariopanel.size_max = { Global.iWindowWidth * 0.95, Global.iWindowHeight * 0.95 };
|
||||
|
||||
m_timetablepanel.title = locale::strings[ locale::string::driver_timetable_header ];
|
||||
m_timetablepanel.size_min = { 435, 110 };
|
||||
m_timetablepanel.size_max = { 435, Global.iWindowHeight * 0.95 };
|
||||
@@ -65,6 +70,7 @@ driver_ui::on_key_( int const Key, int const Scancode, int const Action, int con
|
||||
|
||||
case GLFW_KEY_F1:
|
||||
case GLFW_KEY_F2:
|
||||
case GLFW_KEY_F3:
|
||||
case GLFW_KEY_F10:
|
||||
case GLFW_KEY_F12: { // ui mode selectors
|
||||
|
||||
@@ -112,6 +118,12 @@ driver_ui::on_key_( int const Key, int const Scancode, int const Action, int con
|
||||
return true;
|
||||
}
|
||||
|
||||
case GLFW_KEY_F3: {
|
||||
// debug panel
|
||||
m_scenariopanel.is_open = !m_scenariopanel.is_open;
|
||||
return true;
|
||||
}
|
||||
|
||||
case GLFW_KEY_F12: {
|
||||
// debug panel
|
||||
m_debugpanel.is_open = !m_debugpanel.is_open;
|
||||
|
||||
@@ -41,6 +41,7 @@ private:
|
||||
on_mouse_button_( int const Button, int const Action, int const Mods ) override;
|
||||
// members
|
||||
drivingaid_panel m_aidpanel { "Driving Aid", true };
|
||||
scenario_panel m_scenariopanel { "Scenario", true };
|
||||
timetable_panel m_timetablepanel { "Timetable", false };
|
||||
debug_panel m_debugpanel { "Debug Data", false };
|
||||
transcripts_panel m_transcriptspanel { "Transcripts", true }; // voice transcripts
|
||||
|
||||
@@ -27,8 +27,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "utilities.h"
|
||||
#include "Logs.h"
|
||||
|
||||
#undef snprintf // defined by train.h->pyint.h->python
|
||||
|
||||
void
|
||||
drivingaid_panel::update() {
|
||||
|
||||
@@ -152,6 +150,79 @@ drivingaid_panel::update() {
|
||||
size = { sizex, 85 };
|
||||
}
|
||||
|
||||
void
|
||||
scenario_panel::update() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
text_lines.clear();
|
||||
|
||||
auto const *train { simulation::Train };
|
||||
auto const *controlled { ( train ? train->Dynamic() : nullptr ) };
|
||||
auto const &camera { Global.pCamera };
|
||||
m_nearest = (
|
||||
false == FreeFlyModeFlag ? controlled :
|
||||
camera.m_owner != nullptr ? camera.m_owner :
|
||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( camera.Pos, 20, false, false ) ) ); // w trybie latania lokalizujemy wg mapy
|
||||
if( m_nearest == nullptr ) { return; }
|
||||
auto const *owner { (
|
||||
( ( m_nearest->Mechanik != nullptr ) && ( m_nearest->Mechanik->Primary() ) ) ?
|
||||
m_nearest->Mechanik :
|
||||
m_nearest->ctOwner ) };
|
||||
if( owner == nullptr ) { return; }
|
||||
|
||||
std::string textline =
|
||||
locale::strings[ locale::string::driver_scenario_currenttask ] + "\n "
|
||||
+ owner->OrderCurrent();
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
void
|
||||
scenario_panel::render() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
if( true == text_lines.empty() ) { return; }
|
||||
if( m_nearest == nullptr ) { return; } // possibly superfluous given the above but, eh
|
||||
|
||||
auto flags =
|
||||
ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
|
||||
|
||||
if( size.x > 0 ) {
|
||||
ImGui::SetNextWindowSize( ImVec2( size.x, size.y ) );
|
||||
}
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||
}
|
||||
auto const panelname { (
|
||||
title.empty() ?
|
||||
name :
|
||||
title )
|
||||
+ "###" + name };
|
||||
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
// potential assignment section
|
||||
auto const *owner { (
|
||||
( ( m_nearest->Mechanik != nullptr ) && ( m_nearest->Mechanik->Primary() ) ) ?
|
||||
m_nearest->Mechanik :
|
||||
m_nearest->ctOwner ) };
|
||||
if( owner != nullptr ) {
|
||||
auto const assignmentheader { locale::strings[ locale::string::driver_scenario_assignment ] };
|
||||
if( ( false == owner->assignment().empty() )
|
||||
&& ( true == ImGui::CollapsingHeader( assignmentheader.c_str() ) ) ) {
|
||||
ImGui::TextWrapped( owner->assignment().c_str() );
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
// current task
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void
|
||||
timetable_panel::update() {
|
||||
|
||||
@@ -370,7 +441,12 @@ debug_panel::render() {
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||
}
|
||||
if( true == ImGui::Begin( name.c_str(), &is_open, flags ) ) {
|
||||
auto const panelname { (
|
||||
title.empty() ?
|
||||
name :
|
||||
title )
|
||||
+ "###" + name };
|
||||
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
// header section
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
@@ -676,7 +752,9 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
||||
auto const &mechanik{ *m_input.mechanik };
|
||||
|
||||
// biezaca komenda dla AI
|
||||
auto textline = "Current order: " + mechanik.OrderCurrent();
|
||||
auto textline =
|
||||
"Current order: [" + std::to_string( mechanik.OrderPos ) + "] "
|
||||
+ mechanik.OrderCurrent();
|
||||
|
||||
if( mechanik.fStopTime < 0.0 ) {
|
||||
textline += "\n stop time: " + to_string( std::abs( mechanik.fStopTime ), 1 );
|
||||
|
||||
@@ -28,6 +28,21 @@ private:
|
||||
std::array<char, 256> m_buffer;
|
||||
};
|
||||
|
||||
class scenario_panel : public ui_panel {
|
||||
|
||||
public:
|
||||
scenario_panel( std::string const &Name, bool const Isopen )
|
||||
: ui_panel( Name, Isopen ) {}
|
||||
|
||||
void update() override;
|
||||
void render() override;
|
||||
|
||||
private:
|
||||
// members
|
||||
// std::array<char, 256> m_buffer;
|
||||
TDynamicObject const *m_nearest { nullptr };
|
||||
};
|
||||
|
||||
class timetable_panel : public ui_panel {
|
||||
|
||||
public:
|
||||
|
||||
1
scene.h
1
scene.h
@@ -51,6 +51,7 @@ struct scratch_data {
|
||||
std::vector<int> couplings;
|
||||
TDynamicObject * driver { nullptr };
|
||||
bool is_open { false };
|
||||
std::unordered_map<std::string, std::string> assignment;
|
||||
} trainset;
|
||||
|
||||
std::string name;
|
||||
|
||||
@@ -70,6 +70,7 @@ state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad )
|
||||
std::string,
|
||||
deserializefunction> > functionlist = {
|
||||
{ "area", &state_serializer::deserialize_area },
|
||||
{ "assignment", &state_serializer::deserialize_assignment },
|
||||
{ "atmo", &state_serializer::deserialize_atmo },
|
||||
{ "camera", &state_serializer::deserialize_camera },
|
||||
{ "config", &state_serializer::deserialize_config },
|
||||
@@ -142,6 +143,20 @@ state_serializer::deserialize_area( cParser &Input, scene::scratch_data &Scratch
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
state_serializer::deserialize_assignment( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||
|
||||
std::string token { Input.getToken<std::string>() };
|
||||
while( ( false == token.empty() )
|
||||
&& ( token != "endassignment" ) ) {
|
||||
// assignment is expected to come as string pairs: language id and the actual assignment enclosed in quotes to form a single token
|
||||
auto assignment{ Input.getToken<std::string>() };
|
||||
win1250_to_ascii( assignment );
|
||||
Scratchpad.trainset.assignment.emplace( token, assignment );
|
||||
token = Input.getToken<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
state_serializer::deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||
|
||||
@@ -628,6 +643,11 @@ state_serializer::deserialize_endtrainset( cParser &Input, scene::scratch_data &
|
||||
&& ( vehicle->Mechanik->Primary() ) ) {
|
||||
// primary driver will receive the timetable for this trainset
|
||||
Scratchpad.trainset.driver = vehicle;
|
||||
// they'll also receive assignment data if there's any
|
||||
auto const lookup { Scratchpad.trainset.assignment.find( Global.asLang ) };
|
||||
if( lookup != Scratchpad.trainset.assignment.end() ) {
|
||||
vehicle->Mechanik->assignment() = lookup->second;
|
||||
}
|
||||
}
|
||||
if( vehicleindex > 0 ) {
|
||||
// from second vehicle on couple it with the previous one
|
||||
|
||||
@@ -30,6 +30,7 @@ private:
|
||||
// restores class data from provided stream
|
||||
void deserialize( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_area( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_assignment( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_config( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
|
||||
@@ -38,6 +38,24 @@ init() {
|
||||
" Loading/unloading in progress (%d s left)",
|
||||
" Another vehicle ahead (distance: %.1f m)",
|
||||
|
||||
"Scenario",
|
||||
"Assignment",
|
||||
"Current task:",
|
||||
"Wait for orders",
|
||||
"Start the engine",
|
||||
"Shut down the engine",
|
||||
"Change direction",
|
||||
"Couple to consist ahead",
|
||||
"Uncouple %s",
|
||||
"the engine",
|
||||
"the engine plus the next vehicle",
|
||||
"the engine plus %d next vehicles",
|
||||
"the engine plus %d next vehicles",
|
||||
"Shunt according to signals",
|
||||
"Loose shunt according to signals",
|
||||
"Drive according to signals and timetable",
|
||||
"Bank consist ahead",
|
||||
|
||||
"Timetable",
|
||||
"Time: %d:%02d:%02d",
|
||||
"(no timetable)",
|
||||
@@ -183,6 +201,24 @@ init() {
|
||||
" Wsiadanie/wysiadanie pasazerow (do zakonczenia %d s)",
|
||||
" Inny pojazd na drodze (odleglosc: %.1f m)",
|
||||
|
||||
"Scenariusz",
|
||||
"Zlecenie",
|
||||
"Biezace zadanie:",
|
||||
"Oczekiwac dalszych polecen",
|
||||
"Przygotowac pojazd do jazdy",
|
||||
"Wylaczyc pojazd",
|
||||
"Zmienic kierunek jazdy",
|
||||
"Sprzac sie ze skladem z przodu",
|
||||
"Odpiac %s",
|
||||
"pojazd prowadzacy",
|
||||
"pojazd prowadzacy plus kolejny",
|
||||
"pojazd prowadzacy plus %d kolejne",
|
||||
"pojazd prowadzacy plus %d kolejnych",
|
||||
"Prowadzic manewry wedlug sygnalow",
|
||||
"Prowadzic manewry przetaczania odrzutem",
|
||||
"Prowadzic sklad wedlug sygnalow i rozkladu",
|
||||
"Popychac sklad z przodu",
|
||||
|
||||
"Rozklad jazdy",
|
||||
"Godzina: %d:%02d:%02d",
|
||||
"(brak rozkladu)",
|
||||
|
||||
@@ -27,6 +27,24 @@ enum string {
|
||||
driver_aid_loadinginprogress,
|
||||
driver_aid_vehicleahead,
|
||||
|
||||
driver_scenario_header,
|
||||
driver_scenario_assignment,
|
||||
driver_scenario_currenttask,
|
||||
driver_scenario_waitfororders,
|
||||
driver_scenario_prepareengine,
|
||||
driver_scenario_releaseengine,
|
||||
driver_scenario_changedirection,
|
||||
driver_scenario_connect,
|
||||
driver_scenario_disconnect,
|
||||
driver_scenario_allvehicles,
|
||||
driver_scenario_onevehicle,
|
||||
driver_scenario_fewvehicles,
|
||||
driver_scenario_somevehicles,
|
||||
driver_scenario_shunt,
|
||||
driver_scenario_looseshunt,
|
||||
driver_scenario_obeytrain,
|
||||
driver_scenario_bank,
|
||||
|
||||
driver_timetable_header,
|
||||
driver_timetable_time,
|
||||
driver_timetable_notimetable,
|
||||
|
||||
Reference in New Issue
Block a user