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

build 190701. basic radio call event launch support

This commit is contained in:
tmj-fstate
2019-07-02 01:37:05 +02:00
parent 0f0c30dbff
commit 06b7f009cc
14 changed files with 135 additions and 33 deletions

View File

@@ -56,12 +56,25 @@ bool TEventLauncher::Load(cParser *parser)
dRadius *= dRadius; // do kwadratu, pod warunkiem, że nie jest ujemne
parser->getTokens(); // klawisz sterujący
*parser >> token;
if (token != "none")
{
if( token.size() == 1 )
if (token != "none") {
if( token.size() == 1 ) {
// single char, assigned activation key
iKey = vk_to_glfw_key( token[ 0 ] );
else
iKey = vk_to_glfw_key(stol_def( token, 0 )); // a jak więcej, to jakby numer klawisza jest
}
else {
// this launcher may be activated by radio message
std::map<std::string, int> messages {
{ "radio_call1", radio_message::call1 },
{ "radio_call3", radio_message::call3 }
};
auto lookup = messages.find( token );
iKey = (
lookup != messages.end() ?
lookup->second :
// a jak więcej, to jakby numer klawisza jest
vk_to_glfw_key( stol_def( token, 0 ) ) );
}
}
parser->getTokens();
*parser >> DeltaTime;
@@ -139,7 +152,7 @@ bool TEventLauncher::check_activation() {
auto bCond { false };
if( iKey != 0 ) {
if( iKey > 0 ) {
if( iKey > 255 ) {
// key and modifier
auto const modifier = ( iKey & 0xff00 ) >> 8;
@@ -203,6 +216,11 @@ bool TEventLauncher::IsGlobal() const {
&& ( dRadius < 0.0 ) ); // bez ograniczenia zasięgu
}
bool TEventLauncher::IsRadioActivated() const {
return ( iKey < 0 );
}
// radius() subclass details, calculates node's bounding radius
float
TEventLauncher::radius_() {

View File

@@ -14,6 +14,12 @@ http://mozilla.org/MPL/2.0/.
#include "Classes.h"
#include "scenenode.h"
// radio-transmitted event launch messages
enum radio_message {
call3 = -3,
call1 = -1
};
class TEventLauncher : public scene::basic_node {
public:
@@ -27,7 +33,11 @@ public:
bool check_activation();
// checks conditions associated with the event. returns: true if the conditions are met
bool check_conditions();
inline
auto key() const {
return iKey; }
bool IsGlobal() const;
bool IsRadioActivated() const;
// members
std::string asEvent1Name;
std::string asEvent2Name;

View File

@@ -1034,7 +1034,7 @@ logvalues_event::export_as_text_( std::ostream &Output ) const {
void
multi_event::init() {
auto const conditiontchecksmemcell { m_conditions.flags & ( flags::text | flags::value_1 | flags::value_2 ) };
auto const conditiontchecksmemcell { ( m_conditions.flags & ( flags::text | flags::value_1 | flags::value_2 ) ) != 0 };
// not all multi-events have memory cell checks, for the ones which don't we can keep quiet about it
init_targets( simulation::Memory, "memory cell", conditiontchecksmemcell );
if( m_ignored ) {
@@ -1932,6 +1932,22 @@ event_manager::queue( TEventLauncher *Launcher ) {
m_launcherqueue.emplace_back( Launcher );
}
// inserts in the event query events assigned to event launchers capable of receiving specified radio message sent from specified location
void
event_manager::queue_receivers( radio_message const Message, glm::dvec3 const &Location ) {
for( auto *launcher : m_radiodrivenlaunchers.sequence() ) {
if( ( launcher->key() == Message )
&& ( ( launcher->dRadius < 0 )
|| ( glm::length2( launcher->location() - Location ) < launcher->dRadius ) )
&& ( true == launcher->check_conditions() ) ) {
// NOTE: only execution of event1 is supported for radio messages
// TBD, TODO: consider ability/way to execute event2
simulation::Events.AddToQuery( launcher->Event1, nullptr );
}
}
}
// legacy method, updates event queues
void
event_manager::update() {
@@ -2135,32 +2151,39 @@ event_manager::InitEvents() {
void
event_manager::InitLaunchers() {
for( auto *launcher : m_launchers.sequence() ) {
std::vector<basic_table<TEventLauncher> *> launchertables {
&m_inputdrivenlaunchers,
&m_radiodrivenlaunchers
};
if( launcher->iCheckMask != 0 ) {
if( launcher->asMemCellName != "none" ) {
// jeśli jest powiązana komórka pamięci
launcher->MemCell = simulation::Memory.find( launcher->asMemCellName );
if( launcher->MemCell == nullptr ) {
ErrorLog( "Bad scenario: event launcher \"" + launcher->name() + "\" can't find memcell \"" + launcher->asMemCellName + "\"" );
for( auto *launchertable : launchertables ) {
for( auto *launcher : launchertable->sequence() ) {
if( launcher->iCheckMask != 0 ) {
if( launcher->asMemCellName != "none" ) {
// jeśli jest powiązana komórka pamięci
launcher->MemCell = simulation::Memory.find( launcher->asMemCellName );
if( launcher->MemCell == nullptr ) {
ErrorLog( "Bad scenario: event launcher \"" + launcher->name() + "\" can't find memcell \"" + launcher->asMemCellName + "\"" );
}
}
else {
launcher->MemCell = nullptr;
}
}
else {
launcher->MemCell = nullptr;
}
}
if( launcher->asEvent1Name != "none" ) {
launcher->Event1 = simulation::Events.FindEvent( launcher->asEvent1Name );
if( launcher->Event1 == nullptr ) {
ErrorLog( "Bad scenario: event launcher \"" + launcher->name() + "\" can't find event \"" + launcher->asEvent1Name + "\"" );
if( launcher->asEvent1Name != "none" ) {
launcher->Event1 = simulation::Events.FindEvent( launcher->asEvent1Name );
if( launcher->Event1 == nullptr ) {
ErrorLog( "Bad scenario: event launcher \"" + launcher->name() + "\" can't find event \"" + launcher->asEvent1Name + "\"" );
}
}
}
if( launcher->asEvent2Name != "none" ) {
launcher->Event2 = simulation::Events.FindEvent( launcher->asEvent2Name );
if( launcher->Event2 == nullptr ) {
ErrorLog( "Bad scenario: event launcher \"" + launcher->name() + "\" can't find event \"" + launcher->asEvent2Name + "\"" );
if( launcher->asEvent2Name != "none" ) {
launcher->Event2 = simulation::Events.FindEvent( launcher->asEvent2Name );
if( launcher->Event2 == nullptr ) {
ErrorLog( "Bad scenario: event launcher \"" + launcher->name() + "\" can't find event \"" + launcher->asEvent2Name + "\"" );
}
}
}
}
@@ -2176,8 +2199,14 @@ event_manager::export_as_text( std::ostream &Output ) const {
event->export_as_text( Output );
}
}
Output << "// event launchers\n";
for( auto const *launcher : m_launchers.sequence() ) {
Output << "// event launchers, basic\n";
for( auto const *launcher : m_inputdrivenlaunchers.sequence() ) {
if( launcher->group() == null_handle ) {
launcher->export_as_text( Output );
}
}
Output << "// event launchers, radio driven\n";
for( auto const *launcher : m_radiodrivenlaunchers.sequence() ) {
if( launcher->group() == null_handle ) {
launcher->export_as_text( Output );
}

11
Event.h
View File

@@ -559,6 +559,9 @@ public:
// adds specified event launcher to the list of global launchers
void
queue( TEventLauncher *Launcher );
// inserts in the event query events assigned to event launchers capable of receiving specified radio message sent from specified location
void
queue_receivers( radio_message const Message, glm::dvec3 const &Location );
// legacy method, updates event queues
void
update();
@@ -569,7 +572,10 @@ public:
inline
bool
insert( TEventLauncher *Launcher ) {
return m_launchers.insert( Launcher ); }
return (
Launcher->IsRadioActivated() ?
m_radiodrivenlaunchers.insert( Launcher ) :
m_inputdrivenlaunchers.insert( Launcher ) ); }
// returns first event in the queue
inline
basic_event *
@@ -609,7 +615,8 @@ private:
basic_event *QueryRootEvent { nullptr };
basic_event *m_workevent { nullptr };
event_map m_eventmap;
basic_table<TEventLauncher> m_launchers;
basic_table<TEventLauncher> m_inputdrivenlaunchers;
basic_table<TEventLauncher> m_radiodrivenlaunchers;
eventlauncher_sequence m_launcherqueue;
};

View File

@@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/.
#include "Globals.h"
#include "simulation.h"
#include "Event.h"
#include "simulationtime.h"
#include "Camera.h"
#include "Logs.h"
@@ -339,6 +340,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::radiochanneldecrease, &TTrain::OnCommand_radiochanneldecrease },
{ user_command::radiostopsend, &TTrain::OnCommand_radiostopsend },
{ user_command::radiostoptest, &TTrain::OnCommand_radiostoptest },
{ user_command::radiocall3send, &TTrain::OnCommand_radiocall3send },
{ user_command::cabchangeforward, &TTrain::OnCommand_cabchangeforward },
{ user_command::cabchangebackward, &TTrain::OnCommand_cabchangebackward },
{ user_command::generictoggle0, &TTrain::OnCommand_generictoggle },
@@ -5014,6 +5016,7 @@ void TTrain::OnCommand_radiostoptest( TTrain *Train, command_data const &Command
if( Command.action == GLFW_PRESS ) {
if( ( Train->RadioChannel() == 10 )
&& ( true == Train->mvOccupied->Radio )
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) {
Train->Dynamic()->RadioStop();
}
@@ -5026,6 +5029,23 @@ void TTrain::OnCommand_radiostoptest( TTrain *Train, command_data const &Command
}
}
void TTrain::OnCommand_radiocall3send( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
if( ( Train->RadioChannel() != 10 )
&& ( true == Train->mvOccupied->Radio )
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) {
simulation::Events.queue_receivers( radio_message::call3, Train->Dynamic()->GetPosition() );
}
// visual feedback
Train->ggRadioCall3.UpdateValue( 1.0 );
}
else if( Command.action == GLFW_RELEASE ) {
// visual feedback
Train->ggRadioCall3.UpdateValue( 0.0 );
}
}
void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
@@ -6141,6 +6161,7 @@ bool TTrain::Update( double const Deltatime )
ggRadioChannelNext.Update();
ggRadioStop.Update();
ggRadioTest.Update();
ggRadioCall3.Update();
ggDepartureSignalButton.Update();
ggPantFrontButton.Update();
@@ -7351,6 +7372,7 @@ void TTrain::clear_cab_controls()
ggRadioChannelNext.Clear();
ggRadioStop.Clear();
ggRadioTest.Clear();
ggRadioCall3.Clear();
ggDoorLeftPermitButton.Clear();
ggDoorRightPermitButton.Clear();
ggDoorPermitPresetButton.Clear();
@@ -8037,6 +8059,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "radiochannelnext_sw:", ggRadioChannelNext },
{ "radiostop_sw:", ggRadioStop },
{ "radiotest_sw:", ggRadioTest },
{ "radiocall3_sw:", ggRadioCall3 },
{ "pantfront_sw:", ggPantFrontButton },
{ "pantrear_sw:", ggPantRearButton },
{ "pantfrontoff_sw:", ggPantFrontButtonOff },

View File

@@ -341,6 +341,7 @@ class TTrain
static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command );
static void OnCommand_radiostopsend( TTrain *Train, command_data const &Command );
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
static void OnCommand_radiocall3send( TTrain *Train, command_data const &Command );
static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command );
static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command );
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
@@ -411,6 +412,7 @@ public: // reszta może by?publiczna
TGauge ggRadioChannelNext;
TGauge ggRadioTest;
TGauge ggRadioStop;
TGauge ggRadioCall3;
TGauge ggUpperLightButton;
TGauge ggLeftLightButton;
TGauge ggRightLightButton;

View File

@@ -123,6 +123,7 @@ commanddescription_sequence Commands_descriptions = {
{ "radiochanneldecrease", command_target::vehicle },
{ "radiostopsend", command_target::vehicle },
{ "radiostoptest", command_target::vehicle },
{ "radiocall3send", command_target::vehicle },
// TBD, TODO: make cab change controls entity-centric
{ "cabchangeforward", command_target::vehicle },
{ "cabchangebackward", command_target::vehicle },

View File

@@ -117,6 +117,7 @@ enum class user_command {
radiochanneldecrease,
radiostopsend,
radiostoptest,
radiocall3send,
cabchangeforward,
cabchangebackward,

View File

@@ -128,6 +128,7 @@ driverkeyboard_input::default_bindings() {
{ user_command::radiochanneldecrease, GLFW_KEY_R },
{ user_command::radiostopsend, GLFW_KEY_PAUSE | keymodifier::shift | keymodifier::control },
{ user_command::radiostoptest, GLFW_KEY_R | keymodifier::shift | keymodifier::control },
{ user_command::radiocall3send, GLFW_KEY_BACKSPACE },
{ user_command::cabchangeforward, GLFW_KEY_HOME },
{ user_command::cabchangebackward, GLFW_KEY_END },
// viewturn,

View File

@@ -711,6 +711,9 @@ drivermouse_input::default_bindings() {
{ "radiotest_sw:", {
user_command::radiostoptest,
user_command::none } },
{ "radiocall3_sw:", {
user_command::radiocall3send,
user_command::none } },
{ "pantfront_sw:", {
user_command::pantographtogglefront,
user_command::none } },

View File

@@ -516,7 +516,10 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
}
else {
scene::Groups.insert( scene::Groups.handle(), eventlauncher );
simulation::Region->insert( eventlauncher );
if( false == eventlauncher->IsRadioActivated() ) {
// NOTE: radio-activated launchers due to potentially large activation radius are resolved on global level rather than put in a region cell
simulation::Region->insert( eventlauncher );
}
}
}
else if( nodedata.type == "sound" ) {

View File

@@ -157,6 +157,7 @@ init() {
"radio channel",
"radiostop test",
"radiostop",
"radio call 3",
"pantograph A",
"pantograph B",
"pantograph A",
@@ -323,6 +324,7 @@ init() {
"kanal radia",
"test radiostopu",
"radiostop",
"zew 3",
"pantograf A",
"pantograf B",
"pantograf A",
@@ -442,6 +444,7 @@ init() {
"radiochannelnext_sw:",
"radiotest_sw:",
"radiostop_sw:",
"radiocall3_sw:",
"pantfront_sw:",
"pantrear_sw:",
"pantfrontoff_sw:",

View File

@@ -146,6 +146,7 @@ enum string {
cab_radiochannelnext_sw,
cab_radiotest_sw,
cab_radiostop_sw,
cab_radiocall3_sw,
cab_pantfront_sw,
cab_pantrear_sw,
cab_pantfrontoff_sw,

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 19
#define VERSION_MINOR 614
#define VERSION_MINOR 701
#define VERSION_REVISION 0