17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 10:59:20 +02:00
Files
maszyna/vehicle/Button.cpp
maj00r b8f040e6fd propagate template headers transitively, import Console where used
AnimModel.cpp reaches cParser through the simulation core, not a direct
import, so the previous pass missed it; the propagation now follows the
whole import closure. Train.cpp, drivermode.cpp and Globals.cpp call
Console:: inside _WIN32 guards without importing eu07.console - invisible
on Linux, where those blocks are skipped.
2026-09-10 01:41:24 +02:00

179 lines
4.7 KiB
C++

module;
#include <chrono>
#include <cstddef>
#include <deque>
#include <mutex>
#include <ostream>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
#include <sstream>
#include <cstdint>
#include <array>
#include <limits>
#include <string>
#include "vehicle/DynObj_macros.h"
module eu07.simcore;
import eu07.utilities.parser;
import eu07.simulation.simulation;
import eu07.console;
import eu07.utilities.logs;
import eu07.rendering.renderer;
/*
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/.
*/
void TButton::Clear(int i)
{
*this = TButton();
if( i >= 0 ) {
FeedbackBitSet( i );
}
Update(); // kasowanie bitu Feedback, o ile jakiś ustawiony
};
bool TButton::Init( std::string const &asName, TModel3d const *pModel, bool bNewOn ) {
if( pModel == nullptr ) { return false; }
pModelOn = pModel->GetFromName( asName + "_on" );
pModelOff = pModel->GetFromName( asName + "_off" );
m_state = bNewOn;
Update();
return pModelOn != nullptr || pModelOff != nullptr;
};
void TButton::Load( cParser &Parser, TDynamicObject const *Owner ) {
std::string submodelname;
Parser.getTokens();
if( Parser.peek() != "{" ) {
// old fixed size config
Parser >> submodelname;
}
else {
// new, block type config
// TODO: rework the base part into yaml-compatible flow style mapping
submodelname = Parser.getToken<std::string>( false );
while( true == Load_mapping( Parser ) ) {
; // all work done by while()
}
}
// bind defined sounds with the button owner
m_soundfxincrease.owner( Owner );
m_soundfxdecrease.owner( Owner );
std::array<TModel3d *, 3> sources { Owner->mdKabina, Owner->mdLowPolyInt, Owner->mdModel };
for( auto const *source : sources ) {
if( true == Init( submodelname, source, false ) ) {
// got what we wanted, don't need to search further
break;
}
}
if( pModelOn == nullptr
&& pModelOff == nullptr ) {
// if we failed to locate even one state submodel, cry
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model(s) of \"" + Owner->name() + "\"", logtype::model );
}
// pass submodel location to defined sounds
auto const nulloffset { glm::vec3{} };
auto const offset { model_offset() };
if( m_soundfxincrease.offset() == nulloffset ) {
m_soundfxincrease.offset( offset );
}
if( m_soundfxdecrease.offset() == nulloffset ) {
m_soundfxdecrease.offset( offset );
}
}
bool
TButton::Load_mapping( cParser &Input ) {
// token can be a key or block end
std::string const key { Input.getToken<std::string>( true, "\n\r\t ,;" ) };
if( true == key.empty() || key == "}" ) { return false; }
// if not block end then the key is followed by assigned value or sub-block
if( key == "soundinc:" ) { m_soundfxincrease.deserialize( Input, sound_type::single ); }
else if( key == "sounddec:" ) { m_soundfxdecrease.deserialize( Input, sound_type::single ); }
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
}
// returns offset of submodel associated with the button from the model centre
glm::vec3
TButton::model_offset() const {
auto const
submodel { (
pModelOn ? pModelOn :
pModelOff ? pModelOff :
nullptr ) };
return submodel != nullptr ? submodel->offset(std::numeric_limits<float>::max()) : glm::vec3();
}
void
TButton::Turn( bool const State ) {
if( State != m_state ) {
m_state = State;
play();
Update();
}
}
void TButton::Update( bool const Power ) {
// TODO: remove passing manually power state when LD is in place
auto const state { Power && ( bData ? *bData : m_state ) };
if( state != m_state ) {
m_state = state;
play();
}
if( pModelOn != nullptr ) { pModelOn->iVisible = m_state; }
if( pModelOff != nullptr ) { pModelOff->iVisible = !m_state; }
#ifdef _WIN32
if (iFeedbackBit) {
// jeżeli generuje informację zwrotną
if (m_state) // zapalenie
Console::BitsSet(iFeedbackBit);
else
Console::BitsClear(iFeedbackBit);
}
#endif
};
void TButton::AssignBool(bool const *bValue) {
bData = bValue;
}
void
TButton::play() {
if( m_state == true ) { m_soundfxincrease.play(); }
else { m_soundfxdecrease.play(); }
}
void
TButton::gain(float new_volume) {
m_soundfxincrease.gain(new_volume);
m_soundfxdecrease.gain(new_volume);
}