Added enum property values support
Dieser Commit ist enthalten in:
Ursprung
5be0bedd3d
Commit
09a6503eb0
@ -31,6 +31,7 @@
|
||||
#include "method.hpp"
|
||||
#include "tablemodel.hpp"
|
||||
#include <traintastic/enum/interfaceitemtype.hpp>
|
||||
#include <traintastic/enum/attributetype.hpp>
|
||||
#include <traintastic/locale/locale.hpp>
|
||||
//#include <enum/valuetype.hpp>
|
||||
//#include <enum/propertyflags.hpp>
|
||||
@ -371,8 +372,14 @@ ObjectPtr Connection::readObject(const Message& message)
|
||||
{
|
||||
message.readBlock(); // item
|
||||
const AttributeName attributeName = message.read<AttributeName>();
|
||||
const ValueType type = message.read<ValueType>();
|
||||
|
||||
switch(message.read<AttributeType>())
|
||||
{
|
||||
case AttributeType::Value:
|
||||
{
|
||||
QVariant value;
|
||||
switch(message.read<ValueType>())
|
||||
switch(type)
|
||||
{
|
||||
case ValueType::Boolean:
|
||||
value = message.read<bool>();
|
||||
@ -393,13 +400,59 @@ ObjectPtr Connection::readObject(const Message& message)
|
||||
|
||||
case ValueType::Object:
|
||||
case ValueType::Invalid:
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if(Q_LIKELY(value.isValid()))
|
||||
item->m_attributes[attributeName] = value;
|
||||
break;
|
||||
}
|
||||
case AttributeType::Values:
|
||||
{
|
||||
const int length = message.read<int>(); // read uint32_t as int, Qt uses int for length
|
||||
QList<QVariant> values;
|
||||
switch(type)
|
||||
{
|
||||
case ValueType::Boolean:
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
values.append(message.read<bool>());
|
||||
break;
|
||||
}
|
||||
case ValueType::Enum:
|
||||
case ValueType::Integer:
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
values.append(message.read<qint64>());
|
||||
break;
|
||||
}
|
||||
case ValueType::Float:
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
values.append(message.read<double>());
|
||||
break;
|
||||
}
|
||||
case ValueType::String:
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
values.append(QString::fromUtf8(message.read<QByteArray>()));
|
||||
break;
|
||||
}
|
||||
case ValueType::Object:
|
||||
case ValueType::Invalid:
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
if(Q_LIKELY(values.length() == length))
|
||||
item->m_attributes[attributeName] = values;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
message.readBlockEnd(); // end attribute
|
||||
}
|
||||
message.readBlockEnd(); // end attributes
|
||||
|
||||
46
client/src/utils/internalupdateholder.hpp
Normale Datei
46
client/src/utils/internalupdateholder.hpp
Normale Datei
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* client/src/utils/internalupdateholder.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_CLIENT_UTILS_INTERNALUPDATEHOLDER_HPP
|
||||
#define TRAINTASTIC_CLIENT_UTILS_INTERNALUPDATEHOLDER_HPP
|
||||
|
||||
class InternalUpdateHolder
|
||||
{
|
||||
private:
|
||||
bool& m_value;
|
||||
|
||||
public:
|
||||
inline InternalUpdateHolder(bool& value) :
|
||||
m_value{value}
|
||||
{
|
||||
Q_ASSERT(!m_value);
|
||||
m_value = true;
|
||||
}
|
||||
|
||||
inline ~InternalUpdateHolder()
|
||||
{
|
||||
Q_ASSERT(m_value);
|
||||
m_value = false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
56
client/src/utils/translateenum.cpp
Normale Datei
56
client/src/utils/translateenum.cpp
Normale Datei
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* client/src/utils/translateenum.cpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "translateenum.hpp"
|
||||
#include <traintastic/locale/locale.hpp>
|
||||
#include <traintastic/enum/decoderprotocol.hpp>
|
||||
#include <traintastic/enum/direction.hpp>
|
||||
#include <traintastic/enum/lengthunit.hpp>
|
||||
#include <traintastic/enum/loconetcommandstation.hpp>
|
||||
#include <traintastic/enum/loconetserialinterface.hpp>
|
||||
#include <traintastic/enum/serialflowcontrol.hpp>
|
||||
#include <traintastic/enum/speedunit.hpp>
|
||||
#include <traintastic/enum/weightunit.hpp>
|
||||
#include <traintastic/enum/worldscale.hpp>
|
||||
#include <traintastic/enum/xpressnetcommandstation.hpp>
|
||||
#include <traintastic/enum/xpressnetserialinterface.hpp>
|
||||
|
||||
#define TRANSLATE_ENUM(_type) \
|
||||
if(enumName == EnumName<_type>::value) \
|
||||
{ return Locale::tr(enumName + ":" + EnumValues<_type>::value.at(static_cast<_type>(value))); } \
|
||||
else
|
||||
|
||||
QString translateEnum(const QString& enumName, qint64 value)
|
||||
{
|
||||
TRANSLATE_ENUM(DecoderProtocol)
|
||||
TRANSLATE_ENUM(Direction)
|
||||
TRANSLATE_ENUM(LengthUnit)
|
||||
TRANSLATE_ENUM(LocoNetCommandStation)
|
||||
TRANSLATE_ENUM(LocoNetSerialInterface)
|
||||
TRANSLATE_ENUM(SerialFlowControl)
|
||||
TRANSLATE_ENUM(SpeedUnit)
|
||||
TRANSLATE_ENUM(WeightUnit)
|
||||
TRANSLATE_ENUM(WorldScale)
|
||||
TRANSLATE_ENUM(XpressNetCommandStation)
|
||||
TRANSLATE_ENUM(XpressNetSerialInterface)
|
||||
return enumName + "@" + QString::number(value);
|
||||
}
|
||||
31
client/src/utils/translateenum.hpp
Normale Datei
31
client/src/utils/translateenum.hpp
Normale Datei
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* client/src/utils/translateenum.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TRAINTASTIC_CLIENT_UTILS_TRANSLATEENUM_HPP
|
||||
#define TRAINTASTIC_CLIENT_UTILS_TRANSLATEENUM_HPP
|
||||
|
||||
#include <QString>
|
||||
|
||||
QString translateEnum(const QString& enumName, qint64 value);
|
||||
|
||||
#endif
|
||||
@ -22,26 +22,7 @@
|
||||
|
||||
#include "propertycheckbox.hpp"
|
||||
#include "../network/property.hpp"
|
||||
|
||||
class InternalUpdateHolder
|
||||
{
|
||||
private:
|
||||
bool& m_value;
|
||||
|
||||
public:
|
||||
inline InternalUpdateHolder(bool& value) :
|
||||
m_value{value}
|
||||
{
|
||||
Q_ASSERT(!m_value);
|
||||
m_value = true;
|
||||
}
|
||||
|
||||
inline ~InternalUpdateHolder()
|
||||
{
|
||||
Q_ASSERT(m_value);
|
||||
m_value = false;
|
||||
}
|
||||
};
|
||||
#include "../utils/internalupdateholder.hpp"
|
||||
|
||||
PropertyCheckBox::PropertyCheckBox(Property& property, QWidget* parent) :
|
||||
QCheckBox(parent),
|
||||
|
||||
@ -22,21 +22,25 @@
|
||||
|
||||
#include "propertycombobox.hpp"
|
||||
#include "../network/property.hpp"
|
||||
#include "../utils/internalupdateholder.hpp"
|
||||
#include "../utils/translateenum.hpp"
|
||||
|
||||
PropertyComboBox::PropertyComboBox(Property& property, QWidget* parent) :
|
||||
QComboBox(parent),
|
||||
m_property{property}
|
||||
m_property{property},
|
||||
m_internalUpdate{false}
|
||||
{
|
||||
Q_ASSERT(m_property.type() == ValueType::Enum);
|
||||
setEnabled(m_property.getAttributeBool(AttributeName::Enabled, true));
|
||||
setVisible(m_property.getAttributeBool(AttributeName::Visible, true));
|
||||
//setChecked(m_property.toBool());
|
||||
//connect(&m_property, &Property::valueChangedBool,
|
||||
// [this](bool value)
|
||||
// {
|
||||
// InternalUpdateHolder hold(m_internalUpdate);
|
||||
// setChecked(value);
|
||||
// });
|
||||
|
||||
connect(&m_property, &Property::valueChangedInt64,
|
||||
[this](qint64 value)
|
||||
{
|
||||
InternalUpdateHolder hold(m_internalUpdate);
|
||||
if(int index = findData(value); index != -1)
|
||||
setCurrentIndex(index);
|
||||
});
|
||||
connect(&m_property, &Property::attributeChanged,
|
||||
[this](AttributeName name, const QVariant& value)
|
||||
{
|
||||
@ -50,14 +54,43 @@ PropertyComboBox::PropertyComboBox(Property& property, QWidget* parent) :
|
||||
setVisible(value.toBool());
|
||||
break;
|
||||
|
||||
case AttributeName::Values:
|
||||
updateValues();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
//connect(this, &PropertyCheckBox::toggled,
|
||||
// [this](bool value)
|
||||
// {
|
||||
// if(!m_internalUpdate)
|
||||
// m_property.setValueBool(value);
|
||||
// });
|
||||
connect(this, static_cast<void(PropertyComboBox::*)(int)>(&PropertyComboBox::currentIndexChanged),
|
||||
[this](int)
|
||||
{
|
||||
if(!m_internalUpdate)
|
||||
if(QVariant v = currentData(); v.canConvert<int>())
|
||||
m_property.setValueInt(v.toInt());
|
||||
});
|
||||
|
||||
updateValues();
|
||||
}
|
||||
|
||||
void PropertyComboBox::updateValues()
|
||||
{
|
||||
Q_ASSERT(m_property.type() == ValueType::Enum);
|
||||
|
||||
QVariant values = m_property.getAttribute(AttributeName::Values, QVariant());
|
||||
if(Q_LIKELY(values.isValid()))
|
||||
{
|
||||
InternalUpdateHolder hold(m_internalUpdate);//QSignalBlocker block(this);
|
||||
clear();
|
||||
if(Q_LIKELY(values.userType() == QMetaType::QVariantList))
|
||||
{
|
||||
for(QVariant& v : values.toList())
|
||||
{
|
||||
const qint64 value = v.toLongLong();
|
||||
addItem(translateEnum(m_property.enumName(), value), value);
|
||||
if(m_property.toInt64() == value)
|
||||
setCurrentIndex(count() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,8 +29,13 @@ class Property;
|
||||
|
||||
class PropertyComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
Property& m_property;
|
||||
bool m_internalUpdate;
|
||||
|
||||
void updateValues();
|
||||
|
||||
public:
|
||||
PropertyComboBox(Property& property, QWidget* parent = nullptr);
|
||||
|
||||
@ -13,6 +13,7 @@ greaterThan(QT_MINOR_VERSION, 11): { # >= 5.12
|
||||
|
||||
INCLUDEPATH += \
|
||||
../shared/src \
|
||||
../server/thirdparty \
|
||||
thirdparty
|
||||
|
||||
SOURCES += \
|
||||
@ -51,7 +52,8 @@ SOURCES += \
|
||||
src/network/connection.cpp \
|
||||
src/mdiarea.cpp \
|
||||
src/network/method.cpp \
|
||||
src/dialog/worldlistdialog.cpp
|
||||
src/dialog/worldlistdialog.cpp \
|
||||
src/utils/translateenum.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/mainwindow.hpp \
|
||||
@ -93,7 +95,9 @@ HEADERS += \
|
||||
src/network/connection.hpp \
|
||||
src/mdiarea.hpp \
|
||||
src/network/method.hpp \
|
||||
src/dialog/worldlistdialog.hpp
|
||||
src/dialog/worldlistdialog.hpp \
|
||||
src/utils/translateenum.hpp \
|
||||
src/utils/internalupdateholder.hpp
|
||||
|
||||
RESOURCES += \
|
||||
dark.qrc
|
||||
|
||||
132
lang/en-us.txt
132
lang/en-us.txt
@ -1,19 +1,19 @@
|
||||
## Traintastic language file: English (US)
|
||||
|
||||
:address=Address
|
||||
:baudrate=Baudrate
|
||||
:command_station=Command station
|
||||
:controllers=Controllers
|
||||
:decoders=Decoders
|
||||
:emergency_stop=Emergency stop
|
||||
:id=Id
|
||||
:loconet=LocoNet
|
||||
:name=Name
|
||||
:notes=Notes
|
||||
:track_power=Track power
|
||||
:online=Online
|
||||
:port=Port
|
||||
:track_power=Track power
|
||||
:xpressnet=XpressNet
|
||||
:loconet=LocoNet
|
||||
:baudrate=Baudrate
|
||||
:decoders=Decoders
|
||||
|
||||
clock:day=Day
|
||||
clock:hour=Hour
|
||||
@ -22,48 +22,71 @@ clock:month=Month
|
||||
clock:multiplier=Multiplier
|
||||
clock:year=Year
|
||||
|
||||
command_station.loconet_serial:flow_control=Flow control
|
||||
command_station.loconet_serial:interface=Interface
|
||||
|
||||
command_station.z21:filtered_main_current=Filtered main current
|
||||
command_station.z21:firmware_version=Firmware version
|
||||
command_station.z21:hardware_type=Hardware type
|
||||
command_station.z21:high_temperature=High temperature
|
||||
command_station.z21:hostname=Hostname
|
||||
command_station.z21:main_current=Main current
|
||||
command_station.z21:power_lost=Power lost
|
||||
command_station.z21:prog_current=Prog current
|
||||
command_station.z21:programming_mode_active=Programming mode active
|
||||
command_station.z21:serial_number=Serial number
|
||||
command_station.z21:short_circuit=Short circuit
|
||||
command_station.z21:short_circut_external=Short circut external
|
||||
command_station.z21:short_circut_internal=Short circut internal
|
||||
command_station.z21:supply_voltage=Supply voltage
|
||||
command_station.z21:temperature=Temperature
|
||||
command_station.z21:vcc_voltage=VCC voltage
|
||||
|
||||
command_station_list:add=Add
|
||||
command_station_list:remove=Remove
|
||||
|
||||
console:level=Level
|
||||
console:message=Message
|
||||
console:object=Object
|
||||
console:time=Time
|
||||
|
||||
controller.z21_app:active=Active
|
||||
|
||||
controller:active=Active
|
||||
|
||||
controller_list:add=Add
|
||||
|
||||
decoder:direction=Direction
|
||||
decoder:functions=Functions
|
||||
decoder:long_address=Long address
|
||||
decoder:protocol=Protocol
|
||||
decoder:speed_step=Speed step
|
||||
decoder:speed_steps=Speed steps
|
||||
|
||||
decoder_function:id=Id
|
||||
decoder_function:momentary=Momentary
|
||||
decoder_function:number=Number
|
||||
decoder_function:value=Value
|
||||
|
||||
decoder_function_list:add=Add function
|
||||
decoder_function_list:f_hash=F#
|
||||
|
||||
decoder_list:add=Add
|
||||
|
||||
hardware.command_station.z21:filtered_main_current=Filtered main current
|
||||
hardware.command_station.z21:firmware_version=Firmware version
|
||||
hardware.command_station.z21:hardware_type=Hardware type
|
||||
hardware.command_station.z21:high_temperature=High temperature
|
||||
hardware.command_station.z21:hostname=Hostname
|
||||
hardware.command_station.z21:main_current=Main current
|
||||
hardware.command_station.z21:power_lost=Power lost
|
||||
hardware.command_station.z21:prog_current=Prog current
|
||||
hardware.command_station.z21:programming_mode_active=Programming mode active
|
||||
hardware.command_station.z21:serial_number=Serial number
|
||||
hardware.command_station.z21:short_circuit=Short circuit
|
||||
hardware.command_station.z21:short_circut_external=Short circut external
|
||||
hardware.command_station.z21:short_circut_internal=Short circut internal
|
||||
hardware.command_station.z21:supply_voltage=Supply voltage
|
||||
hardware.command_station.z21:temperature=Temperature
|
||||
hardware.command_station.z21:vcc_voltage=VCC voltage
|
||||
|
||||
hardware.controller.z21_app:active=Active
|
||||
|
||||
hardware.controller:active=Active
|
||||
|
||||
hardware.decoder:direction=Direction
|
||||
hardware.decoder:functions=Functions
|
||||
hardware.decoder:protocol=Protocol
|
||||
hardware.decoder:speed_step=Speed step
|
||||
hardware.decoder:speed_steps=Speed steps
|
||||
|
||||
hardware.decoder_function:id=Id
|
||||
hardware.decoder_function:momentary=Momentary
|
||||
hardware.decoder_function:number=Number
|
||||
hardware.decoder_function:value=Value
|
||||
|
||||
hardware.decoder_function_list:f_hash=F#
|
||||
|
||||
language:de-de=German
|
||||
language:en-us=English (US)
|
||||
language:nl-nl=Dutch
|
||||
|
||||
list.train:add=Create train
|
||||
|
||||
loconet_command_station:custom=Custom
|
||||
loconet_command_station:digikeijs_dr5000=Digikeijs DR5000
|
||||
loconet_command_station:uhlenbrock_intellibox=Uhlenbrock Intellibox
|
||||
|
||||
loconet_serial_interface:custom=Custom
|
||||
loconet_serial_interface:digikeijs_dr5000=Digikeijs DR5000
|
||||
loconet_serial_interface:rosoft_loconet_interface=RoSoft LocoNet interface
|
||||
|
||||
lua.script:active=Active
|
||||
lua.script:code=Code
|
||||
|
||||
@ -102,15 +125,22 @@ qtapp.mainmenu:settings=Settings
|
||||
qtapp.mainmenu:tools=Tools
|
||||
qtapp.mainmenu:view=View
|
||||
|
||||
qtapp.world_list_dialog:world_list=World list
|
||||
qtapp.world_list_dialog:load=Load
|
||||
qtapp.world_list_dialog:cancel=Cancel
|
||||
world_list:uuid=UUID
|
||||
qtapp.world_list_dialog:load=Load
|
||||
qtapp.world_list_dialog:world_list=World list
|
||||
|
||||
serial_flow_control:hardware=Hardware
|
||||
serial_flow_control:none=None
|
||||
|
||||
settings:default_world=Default world
|
||||
settings:localhost_only=Localhost only
|
||||
settings:port=Port
|
||||
|
||||
train:lob=LOB
|
||||
train:speed=Speed
|
||||
train:throttle_speed=Throttle speed
|
||||
train:weight=Weight
|
||||
|
||||
world:clock=Clock
|
||||
world:command_stations=Command stations
|
||||
world:decoders=Decoders
|
||||
@ -118,21 +148,15 @@ world:edit=Edit world
|
||||
world:emergency_stop=Emergency stop
|
||||
world:inputs=Inputs
|
||||
world:lua_scripts=Lua scripts
|
||||
world:rail_vehicles=Rail vehicles
|
||||
world:scale=Scale
|
||||
world:track_power_off=Track power off
|
||||
world:track_power_on=Track power on
|
||||
world:rail_vehicles=Rail vehicles
|
||||
|
||||
|
||||
console:message=Message
|
||||
console:time=Time
|
||||
console:level=Level
|
||||
console:object=Object
|
||||
|
||||
world:trains=Trains
|
||||
list.train:add=Create train
|
||||
train:lob=LOB
|
||||
train:speed=Speed
|
||||
|
||||
world_list:uuid=UUID
|
||||
|
||||
|
||||
#! Garbage
|
||||
#! Garbage
|
||||
train:speedMax=Maximum speed
|
||||
train:throttle_speed=Throttle speed
|
||||
train:weight=Weight
|
||||
|
||||
@ -32,6 +32,8 @@ hardware.decoder:speed_steps=Snelheid stappen
|
||||
hardware.decoder_function:number=Nummer
|
||||
hardware.decoder_function:value=Waarde
|
||||
|
||||
hardware.decoder_function_list:f_hash=F#
|
||||
|
||||
language:de-de=Duits
|
||||
language:en-us=Engels (VS)
|
||||
language:nl-nl=Nederlands
|
||||
@ -53,7 +55,6 @@ qtapp.connect_dialog:server=Server
|
||||
qtapp.connect_dialog:username=Gebruikersnaam
|
||||
|
||||
qtapp.mainmenu:about=Over
|
||||
qtapp.mainmenu:settings=Instellingen
|
||||
qtapp.mainmenu:connect_to_server=Verbind met server
|
||||
qtapp.mainmenu:disconnect_from_server=Verbreek verbinding met server
|
||||
qtapp.mainmenu:export_world=Wereld exporteren
|
||||
@ -69,6 +70,7 @@ qtapp.mainmenu:quit=Afsluiten
|
||||
qtapp.mainmenu:save_world=Wereld opslaan
|
||||
qtapp.mainmenu:server_console=Server console
|
||||
qtapp.mainmenu:server_settings=Server instellingen
|
||||
qtapp.mainmenu:settings=Instellingen
|
||||
qtapp.mainmenu:tools=Extra
|
||||
qtapp.mainmenu:view=Beeld
|
||||
|
||||
@ -83,10 +85,3 @@ world:lua_scripts=Lua scripts
|
||||
world:scale=Schaal
|
||||
world:track_power_off=Railspanning uit
|
||||
world:track_power_on=Railspanning aan
|
||||
|
||||
|
||||
|
||||
|
||||
hardware.decoder_function_list:f_hash=F#
|
||||
|
||||
|
||||
|
||||
@ -24,7 +24,20 @@ WeightProperty
|
||||
- decoder2
|
||||
|
||||
|
||||
# train
|
||||
- trothlle speed
|
||||
- weight simulation: 0=off, 1=real, 2=half
|
||||
|
||||
# netwerk
|
||||
enum als string over netwerk?? nummers zijn dan alleen intern, niet in json/netwerk
|
||||
|
||||
# controller usb xpressnet interface
|
||||
- allow estop
|
||||
- allow power off
|
||||
- mode:
|
||||
- direct: multimaus decoder addr == decoder addr
|
||||
- virtual decoder: multimaus decoder addr = assigend decoder addr
|
||||
- virtual maus: multimaus addr = assigend decoder addr
|
||||
|
||||
|
||||
# task thread
|
||||
|
||||
@ -24,10 +24,10 @@
|
||||
#include "interfaceitem.hpp"
|
||||
#include "object.hpp"
|
||||
|
||||
AbstractAttribute::AbstractAttribute(InterfaceItem& item, AttributeName name, ValueType type) :
|
||||
m_item{item},
|
||||
m_name{name},
|
||||
m_type{type}
|
||||
AbstractAttribute::AbstractAttribute(InterfaceItem& _item, AttributeName _name, ValueType _type) :
|
||||
m_item{_item},
|
||||
m_name{_name},
|
||||
m_type{_type}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -39,16 +39,12 @@ class AbstractAttribute
|
||||
void changed();
|
||||
|
||||
public:
|
||||
AbstractAttribute(InterfaceItem& item, AttributeName name, ValueType type);
|
||||
AbstractAttribute(InterfaceItem& _item, AttributeName _name, ValueType _type);
|
||||
virtual ~AbstractAttribute() = default;
|
||||
|
||||
inline InterfaceItem& item() const { return m_item; }
|
||||
inline AttributeName name() const { return m_name; }
|
||||
inline ValueType type() const { return m_type; }
|
||||
|
||||
virtual bool toBool() const = 0;
|
||||
virtual int64_t toInt64() const = 0;
|
||||
virtual double toDouble() const = 0;
|
||||
virtual std::string toString() const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
#include <traintastic/enum/propertyflags.hpp>
|
||||
#include "objectptr.hpp"
|
||||
#include <cassert>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "../utils/json.hpp"
|
||||
|
||||
class AbstractProperty : public InterfaceItem
|
||||
{
|
||||
|
||||
42
server/src/core/abstractvalueattribute.hpp
Normale Datei
42
server/src/core/abstractvalueattribute.hpp
Normale Datei
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* server/src/core/abstractvalueattribute.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_CORE_ABSTRACTVALUEATTRIBUTE_HPP
|
||||
#define TRAINTASTIC_SERVER_CORE_ABSTRACTVALUEATTRIBUTE_HPP
|
||||
|
||||
#include "abstractattribute.hpp"
|
||||
|
||||
class AbstractValueAttribute : public AbstractAttribute
|
||||
{
|
||||
public:
|
||||
AbstractValueAttribute(InterfaceItem& _item, AttributeName _name, ValueType _type) :
|
||||
AbstractAttribute(_item, _name, _type)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool toBool() const = 0;
|
||||
virtual int64_t toInt64() const = 0;
|
||||
virtual double toDouble() const = 0;
|
||||
virtual std::string toString() const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
44
server/src/core/abstractvaluesattribute.hpp
Normale Datei
44
server/src/core/abstractvaluesattribute.hpp
Normale Datei
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* server/src/core/abstractvaluesattribute.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_CORE_ABSTRACTVALUESATTRIBUTE_HPP
|
||||
#define TRAINTASTIC_SERVER_CORE_ABSTRACTVALUESATTRIBUTE_HPP
|
||||
|
||||
#include "abstractattribute.hpp"
|
||||
|
||||
class AbstractValuesAttribute : public AbstractAttribute
|
||||
{
|
||||
public:
|
||||
AbstractValuesAttribute(InterfaceItem& _item, AttributeName _name, ValueType _type) :
|
||||
AbstractAttribute(_item, _name, _type)
|
||||
{
|
||||
}
|
||||
|
||||
virtual uint32_t length() const = 0;
|
||||
|
||||
virtual bool getBool(uint32_t index) const = 0;
|
||||
virtual int64_t getInt64(uint32_t index) const = 0;
|
||||
virtual double getDouble(uint32_t index) const = 0;
|
||||
virtual std::string getString(uint32_t index) const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
74
server/src/core/arrayattribute.hpp
Normale Datei
74
server/src/core/arrayattribute.hpp
Normale Datei
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* server/src/core/arrayattribute.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_CORE_ARRAYATTRIBUTE_HPP
|
||||
#define TRAINTASTIC_SERVER_CORE_ARRAYATTRIBUTE_HPP
|
||||
|
||||
#include <array>
|
||||
#include "abstractvaluesattribute.hpp"
|
||||
#include "to.hpp"
|
||||
|
||||
template<typename T, size_t N>
|
||||
class ArrayAttribute : public AbstractValuesAttribute
|
||||
{
|
||||
protected:
|
||||
const std::array<T, N>& m_values;
|
||||
|
||||
public:
|
||||
ArrayAttribute(InterfaceItem& _item, AttributeName _name, const std::array<T, N>& values) :
|
||||
AbstractValuesAttribute(_item, _name, value_type_v<T>),
|
||||
m_values{values}
|
||||
{
|
||||
static_assert(value_type_v<T> != ValueType::Invalid);
|
||||
}
|
||||
|
||||
virtual uint32_t length() const final
|
||||
{
|
||||
return m_values.size();
|
||||
}
|
||||
|
||||
virtual bool getBool(uint32_t index) const final
|
||||
{
|
||||
assert(index < length());
|
||||
return to<bool>(m_values[index]);
|
||||
}
|
||||
|
||||
virtual int64_t getInt64(uint32_t index) const final
|
||||
{
|
||||
assert(index < length());
|
||||
return to<int64_t>(m_values[index]);
|
||||
}
|
||||
|
||||
virtual double getDouble(uint32_t index) const final
|
||||
{
|
||||
assert(index < length());
|
||||
return to<double>(m_values[index]);
|
||||
}
|
||||
|
||||
virtual std::string getString(uint32_t index) const final
|
||||
{
|
||||
assert(index < length());
|
||||
return to<std::string>(m_values[index]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -23,21 +23,22 @@
|
||||
#ifndef TRAINTASTIC_SERVER_CORE_ATTRIBUTE_HPP
|
||||
#define TRAINTASTIC_SERVER_CORE_ATTRIBUTE_HPP
|
||||
|
||||
#include "abstractattribute.hpp"
|
||||
#include "abstractvalueattribute.hpp"
|
||||
#include "to.hpp"
|
||||
#include "valuetypetraits.hpp"
|
||||
|
||||
template<typename T>
|
||||
class Attribute : public AbstractAttribute
|
||||
class Attribute : public AbstractValueAttribute
|
||||
{
|
||||
protected:
|
||||
T m_value;
|
||||
|
||||
public:
|
||||
Attribute(InterfaceItem& item, AttributeName name, const T& value) :
|
||||
AbstractAttribute{item, name, value_type_v<T>},
|
||||
AbstractValueAttribute{item, name, value_type_v<T>},
|
||||
m_value{value}
|
||||
{
|
||||
static_assert(value_type_v<T> != ValueType::Invalid);
|
||||
}
|
||||
|
||||
bool toBool() const final
|
||||
|
||||
64
server/src/core/attributes.hpp
Normale Datei
64
server/src/core/attributes.hpp
Normale Datei
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* server/src/core/attributes.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_CORE_ATTRIBUTES_HPP
|
||||
#define TRAINTASTIC_SERVER_CORE_ATTRIBUTES_HPP
|
||||
|
||||
#include "interfaceitem.hpp"
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
static inline void addCategory(InterfaceItem& item, Category value)
|
||||
{
|
||||
item.addAttribute(AttributeName::Category, value);
|
||||
}
|
||||
|
||||
static inline void addEnabled(InterfaceItem& item, bool value)
|
||||
{
|
||||
item.addAttribute(AttributeName::Enabled, value);
|
||||
}
|
||||
|
||||
static inline void addVisible(InterfaceItem& item, bool value)
|
||||
{
|
||||
item.addAttribute(AttributeName::Visible, value);
|
||||
}
|
||||
|
||||
static inline void addObjectEditor(InterfaceItem& item, bool value)
|
||||
{
|
||||
item.addAttribute(AttributeName::ObjectEditor, value);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
static inline void addValues(Property<T>& property, const std::array<T, N>& values)
|
||||
{
|
||||
property.addAttribute(AttributeName::Values, values);
|
||||
}
|
||||
|
||||
|
||||
//inline InterfaceItem& addAttributeSubObject(bool value) { return addAttribute(AttributeName::SubObject, value); }
|
||||
/*
|
||||
template<typename T, std::size_t N>
|
||||
inline InterfaceItem& addAttributeValues(const std::array<T, N>& values) { return addAttribute(AttributeName::Values, values); }
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -21,7 +21,8 @@
|
||||
#include "idobject.hpp"
|
||||
#include "traintastic.hpp"
|
||||
#include "console.hpp"
|
||||
#include "../world/world.hpp"
|
||||
#include "../world/getworld.hpp"
|
||||
#include "attributes.hpp"
|
||||
|
||||
IdObject::IdObject(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
Object{},
|
||||
@ -29,7 +30,10 @@ IdObject::IdObject(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
id{this, "id", std::string(_id.data(), _id.size()), PropertyFlags::ReadWrite | PropertyFlags::Store, nullptr,
|
||||
[this](std::string& value)
|
||||
{
|
||||
auto& m = Traintastic::instance->world->m_objects;
|
||||
auto w = getWorld(this);
|
||||
if(!w)
|
||||
return false;
|
||||
auto& m = w->m_objects;
|
||||
if(m.find(value) != m.end())
|
||||
return false;
|
||||
auto n = m.extract(id);
|
||||
@ -41,8 +45,8 @@ IdObject::IdObject(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
auto w = world.lock();
|
||||
const bool editable = w && contains(w->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(id)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(id, editable);
|
||||
m_interfaceItems.add(id);
|
||||
}
|
||||
|
||||
IdObject::~IdObject()
|
||||
|
||||
@ -27,12 +27,15 @@
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "attribute.hpp"
|
||||
#include "arrayattribute.hpp"
|
||||
#include <traintastic/enum/category.hpp>
|
||||
|
||||
class Object;
|
||||
|
||||
class InterfaceItem
|
||||
{
|
||||
friend struct Attributes;
|
||||
|
||||
public:
|
||||
using Attributes = std::unordered_map<AttributeName, std::unique_ptr<AbstractAttribute>>;
|
||||
|
||||
@ -42,10 +45,15 @@ class InterfaceItem
|
||||
Attributes m_attributes;
|
||||
|
||||
template<typename T>
|
||||
InterfaceItem& addAttribute(AttributeName name, const T& value)
|
||||
void addAttribute(AttributeName name, const T& value)
|
||||
{
|
||||
m_attributes.emplace(name, std::make_unique<Attribute<T>>(*this, name, value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void addAttribute(AttributeName name, const std::array<T, N>& values)
|
||||
{
|
||||
m_attributes.emplace(name, std::make_unique<ArrayAttribute<T, N>>(*this, name, values));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -80,15 +88,6 @@ class InterfaceItem
|
||||
return m_attributes;
|
||||
}
|
||||
|
||||
inline InterfaceItem& addAttributeCategory(Category value) { return addAttribute(AttributeName::Category, value); }
|
||||
inline InterfaceItem& addAttributeEnabled(bool value) { return addAttribute(AttributeName::Enabled, value); }
|
||||
inline InterfaceItem& addAttributeVisible(bool value) { return addAttribute(AttributeName::Visible, value); }
|
||||
inline InterfaceItem& addAttributeObjectEditor(bool value) { return addAttribute(AttributeName::ObjectEditor, value); }
|
||||
inline InterfaceItem& addAttributeSubObject(bool value) { return addAttribute(AttributeName::SubObject, value); }
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
inline InterfaceItem& addAttributeValues(const std::array<T, N>& values) { return addAttribute(AttributeName::Values, values); }
|
||||
|
||||
inline void setAttributeEnabled(bool value) { setAttribute(AttributeName::Enabled, value); }
|
||||
};
|
||||
|
||||
|
||||
@ -24,22 +24,39 @@
|
||||
#include "interfaceitem.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include "abstractproperty.hpp"
|
||||
|
||||
static void check(const InterfaceItem& item)
|
||||
{
|
||||
if(const AbstractProperty* property = dynamic_cast<const AbstractProperty*>(&item))
|
||||
{
|
||||
if(property->type() == ValueType::Enum)
|
||||
assert(property->attributes().find(AttributeName::Values) != property->attributes().cend()); // enum property must have a Values attribute
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
InterfaceItem* InterfaceItems::find(const std::string& name) const
|
||||
{
|
||||
auto it = m_items.find(name);
|
||||
return (it != m_items.end()) ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
InterfaceItem& InterfaceItems::add(InterfaceItem& item)
|
||||
void InterfaceItems::add(InterfaceItem& item)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
check(item);
|
||||
#endif
|
||||
m_items.emplace(item.name(), item);
|
||||
m_itemOrder.push_back(item.name());
|
||||
return item;
|
||||
}
|
||||
|
||||
InterfaceItem& InterfaceItems::insertBefore(InterfaceItem& item, const InterfaceItem& before)
|
||||
void InterfaceItems::insertBefore(InterfaceItem& item, const InterfaceItem& before)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
check(item);
|
||||
#endif
|
||||
m_items.emplace(item.name(), item);
|
||||
m_itemOrder.insert(std::find(m_itemOrder.begin(), m_itemOrder.end(), before.name()), item.name());
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -45,8 +45,8 @@ class InterfaceItems
|
||||
|
||||
InterfaceItem* find(const std::string& name) const;
|
||||
|
||||
InterfaceItem& add(InterfaceItem& item);
|
||||
InterfaceItem& insertBefore(InterfaceItem& item, const InterfaceItem& before);
|
||||
void add(InterfaceItem& item);
|
||||
void insertBefore(InterfaceItem& item, const InterfaceItem& before);
|
||||
|
||||
inline InterfaceItem& operator[](const std::string& name) const { return m_items.at(name); }
|
||||
};
|
||||
|
||||
@ -26,8 +26,10 @@
|
||||
#include "traintastic.hpp"
|
||||
#include "client.hpp"
|
||||
#include "abstractproperty.hpp"
|
||||
#include "abstractattribute.hpp"
|
||||
#include "abstractvalueattribute.hpp"
|
||||
#include "abstractvaluesattribute.hpp"
|
||||
#include <traintastic/enum/interfaceitemtype.hpp>
|
||||
#include <traintastic/enum/attributetype.hpp>
|
||||
#include "tablemodel.hpp"
|
||||
#include "../world/world.hpp"
|
||||
#include "idobject.hpp"
|
||||
@ -434,31 +436,7 @@ void Session::writeObject(Message& message, const ObjectPtr& object)
|
||||
{
|
||||
const AbstractAttribute& attribute = *it.second;
|
||||
message.writeBlock(); // attribute
|
||||
message.write(attribute.name());
|
||||
message.write(attribute.type());
|
||||
switch(attribute.type())
|
||||
{
|
||||
case ValueType::Boolean:
|
||||
message.write(attribute.toBool());
|
||||
break;
|
||||
|
||||
case ValueType::Enum:
|
||||
case ValueType::Integer:
|
||||
message.write(attribute.toInt64());
|
||||
break;
|
||||
|
||||
case ValueType::Float:
|
||||
message.write(attribute.toDouble());
|
||||
break;
|
||||
|
||||
case ValueType::String:
|
||||
message.write(attribute.toString());
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
writeAttribute(message, attribute);
|
||||
message.writeBlockEnd(); // end attribute
|
||||
}
|
||||
|
||||
@ -547,6 +525,8 @@ void Session::objectAttributeChanged(AbstractAttribute& attribute)
|
||||
auto event = Message::newEvent(Message::Command::ObjectAttributeChanged);
|
||||
event->write(m_handles.getHandle(attribute.item().object().shared_from_this()));
|
||||
event->write(attribute.item().name());
|
||||
writeAttribute(*event, attribute);
|
||||
/*
|
||||
event->write(attribute.name());
|
||||
event->write(attribute.type());
|
||||
switch(attribute.type())
|
||||
@ -568,5 +548,74 @@ void Session::objectAttributeChanged(AbstractAttribute& attribute)
|
||||
//event->write(attribute.toString());
|
||||
break;
|
||||
}
|
||||
*/
|
||||
m_client->sendMessage(std::move(event));
|
||||
}
|
||||
|
||||
void Session::writeAttribute(Message& message , const AbstractAttribute& attribute)
|
||||
{
|
||||
message.write(attribute.name());
|
||||
message.write(attribute.type());
|
||||
if(const AbstractValueAttribute* valueAttribute = dynamic_cast<const AbstractValueAttribute*>(&attribute))
|
||||
{
|
||||
message.write(AttributeType::Value);
|
||||
switch(attribute.type())
|
||||
{
|
||||
case ValueType::Boolean:
|
||||
message.write(valueAttribute->toBool());
|
||||
break;
|
||||
|
||||
case ValueType::Enum:
|
||||
case ValueType::Integer:
|
||||
message.write(valueAttribute->toInt64());
|
||||
break;
|
||||
|
||||
case ValueType::Float:
|
||||
message.write(valueAttribute->toDouble());
|
||||
break;
|
||||
|
||||
case ValueType::String:
|
||||
message.write(valueAttribute->toString());
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(const AbstractValuesAttribute* valuesAttributes = dynamic_cast<const AbstractValuesAttribute*>(&attribute))
|
||||
{
|
||||
const uint32_t length = valuesAttributes->length();
|
||||
message.write(AttributeType::Values);
|
||||
message.write(length);
|
||||
switch(attribute.type())
|
||||
{
|
||||
case ValueType::Boolean:
|
||||
for(uint32_t i = 0; i < length; i++)
|
||||
message.write(valuesAttributes->getBool(i));
|
||||
break;
|
||||
|
||||
case ValueType::Enum:
|
||||
case ValueType::Integer:
|
||||
for(uint32_t i = 0; i < length; i++)
|
||||
message.write(valuesAttributes->getInt64(i));
|
||||
break;
|
||||
|
||||
case ValueType::Float:
|
||||
for(uint32_t i = 0; i < length; i++)
|
||||
message.write(valuesAttributes->getDouble(i));
|
||||
break;
|
||||
|
||||
case ValueType::String:
|
||||
for(uint32_t i = 0; i < length; i++)
|
||||
message.write(valuesAttributes->getString(i));
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@ -39,6 +39,9 @@ class Session : public std::enable_shared_from_this<Session>
|
||||
{
|
||||
friend class Client;
|
||||
|
||||
private:
|
||||
static void writeAttribute(Message& message , const AbstractAttribute& attribute);
|
||||
|
||||
protected:
|
||||
using Handle = uint32_t;
|
||||
using Handles = HandleList<Handle, ObjectPtr>;
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "../utils/json.hpp"
|
||||
|
||||
class not_writable_error : public std::runtime_error
|
||||
{
|
||||
@ -101,10 +101,15 @@ To to(const From& value)
|
||||
}
|
||||
else if constexpr(std::is_same_v<From, nlohmann::json>)
|
||||
{
|
||||
// if constexpr(std::is_same_v<To, bool>)
|
||||
return value;//.get<To>();
|
||||
if constexpr(std::is_enum_v<To>)
|
||||
{
|
||||
To e;
|
||||
from_json(value, e);
|
||||
return e;
|
||||
}
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
throw conversion_error();
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ class UnitProperty : public AbstractProperty//InterfaceItem
|
||||
void load(const nlohmann::json& value) final
|
||||
{
|
||||
m_value = to<T>(value["value"]);
|
||||
m_unit = value["unit"];
|
||||
from_json(value["unit"], m_unit);
|
||||
}
|
||||
|
||||
void load(const ObjectPtr& value) final
|
||||
|
||||
@ -31,16 +31,12 @@ template<typename T>
|
||||
class VectorAttribute : public AbstractAttribute
|
||||
{
|
||||
protected:
|
||||
std::vector<T> m_value;
|
||||
std::vector<T> m_values;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
//dsjfnkjdnvjkdnkvjf
|
||||
|
||||
Attribute(InterfaceItem& item, AttributeName name, const T& value) :
|
||||
VectorAttribute(InterfaceItem& item, AttributeName name, const T& values) :
|
||||
AbstractAttribute{item, name, value_type_v<T>},
|
||||
m_value{value}
|
||||
m_value{values}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -29,14 +29,6 @@
|
||||
#include "../lua/enumvalues.hpp"
|
||||
#endif
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(CommandStationStatus,
|
||||
{
|
||||
{CommandStationStatus::Offline, "offline"},
|
||||
{CommandStationStatus::Initializing, "initializing"},
|
||||
{CommandStationStatus::Online, "online"},
|
||||
{CommandStationStatus::Error, "error"},
|
||||
})
|
||||
|
||||
#ifndef DISABLE_LUA_SCRIPTING
|
||||
LUA_ENUM_VALUES(CommandStationStatus, 4,
|
||||
{
|
||||
|
||||
@ -29,12 +29,11 @@
|
||||
#include "../lua/enumvalues.hpp"
|
||||
#endif
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(DecoderProtocol,
|
||||
{
|
||||
{DecoderProtocol::Auto, "AUTO"},
|
||||
{DecoderProtocol::DCC, "DCC"},
|
||||
{DecoderProtocol::Custom, "CUSTOM"},
|
||||
})
|
||||
inline constexpr std::array<DecoderProtocol, 3> DecoderProtocolValues{{
|
||||
DecoderProtocol::Auto,
|
||||
DecoderProtocol::DCC,
|
||||
DecoderProtocol::Custom,
|
||||
}};
|
||||
|
||||
#ifndef DISABLE_LUA_SCRIPTING
|
||||
LUA_ENUM_VALUES(DecoderProtocol, 3,
|
||||
|
||||
@ -29,11 +29,11 @@
|
||||
#include "../lua/enumvalues.hpp"
|
||||
#endif
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(Direction,
|
||||
{
|
||||
{Direction::Forward, "forward"},
|
||||
{Direction::Reverse, "reverse"},
|
||||
})
|
||||
inline constexpr std::array<Direction, 2> DirectionValues{{
|
||||
Direction::Forward,
|
||||
Direction::Reverse,
|
||||
}};
|
||||
|
||||
|
||||
#ifndef DISABLE_LUA_SCRIPTING
|
||||
LUA_ENUM_VALUES(Direction, 2,
|
||||
|
||||
@ -24,16 +24,6 @@
|
||||
#define TRAINTASTIC_SERVER_ENUM_LENGTHUNIT_HPP
|
||||
|
||||
#include <traintastic/enum/lengthunit.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(LengthUnit,
|
||||
{
|
||||
{LengthUnit::Meter, "m"},
|
||||
{LengthUnit::CentiMeter, "cm"},
|
||||
{LengthUnit::MilliMeter, "mm"},
|
||||
{LengthUnit::Yard, "yd"},
|
||||
{LengthUnit::Foot, "ft"},
|
||||
{LengthUnit::Inch, "in"},
|
||||
})
|
||||
//#include <nlohmann/json.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@ -31,23 +31,16 @@
|
||||
|
||||
inline constexpr std::array<LocoNetCommandStation, 3> LocoNetCommandStationValues{{
|
||||
LocoNetCommandStation::Custom,
|
||||
LocoNetCommandStation::DigiKeijsDR5000,
|
||||
LocoNetCommandStation::DigikeijsDR5000,
|
||||
LocoNetCommandStation::UhlenbrockIntellibox,
|
||||
}};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(LocoNetCommandStation,
|
||||
{
|
||||
{LocoNetCommandStation::Custom, "custom"},
|
||||
{LocoNetCommandStation::UhlenbrockIntellibox, "uhlenbrock_intellibox"},
|
||||
{LocoNetCommandStation::DigiKeijsDR5000, "digikeijs_dr5000"},
|
||||
})
|
||||
|
||||
#ifndef DISABLE_LUA_SCRIPTING
|
||||
LUA_ENUM_VALUES(LocoNetCommandStation, 3,
|
||||
{
|
||||
{LocoNetCommandStation::Custom, "CUSTOM"},
|
||||
{LocoNetCommandStation::UhlenbrockIntellibox, "UHLENBROCK_INTELLIBOX"},
|
||||
{LocoNetCommandStation::DigiKeijsDR5000, "DIGIKEIJS_DR5000"},
|
||||
{LocoNetCommandStation::DigikeijsDR5000, "DIGIKEIJS_DR5000"},
|
||||
})
|
||||
#endif
|
||||
|
||||
|
||||
@ -31,22 +31,15 @@
|
||||
|
||||
inline constexpr std::array<LocoNetSerialInterface, 3> LocoNetSerialInterfaceValues{{
|
||||
LocoNetSerialInterface::Custom,
|
||||
LocoNetSerialInterface::DigiKeijsDR5000,
|
||||
LocoNetSerialInterface::DigikeijsDR5000,
|
||||
LocoNetSerialInterface::RoSoftLocoNetInterface,
|
||||
}};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(LocoNetSerialInterface,
|
||||
{
|
||||
{LocoNetSerialInterface::Custom, "custom"},
|
||||
{LocoNetSerialInterface::DigiKeijsDR5000, "digikeijs_dr5000"},
|
||||
{LocoNetSerialInterface::RoSoftLocoNetInterface, "rosoft_loconet_interface"},
|
||||
})
|
||||
|
||||
#ifndef DISABLE_LUA_SCRIPTING
|
||||
LUA_ENUM_VALUES(LocoNetSerialInterface, 3,
|
||||
{
|
||||
{LocoNetSerialInterface::Custom, "CUSTOM"},
|
||||
{LocoNetSerialInterface::DigiKeijsDR5000, "DIGIKEIJS_DR5000"},
|
||||
{LocoNetSerialInterface::DigikeijsDR5000, "DIGIKEIJS_DR5000"},
|
||||
{LocoNetSerialInterface::RoSoftLocoNetInterface, "ROSOFT_LOCONET_INTERFACE"},
|
||||
})
|
||||
#endif
|
||||
|
||||
@ -34,12 +34,6 @@ inline constexpr std::array<SerialFlowControl, 2> SerialFlowControlValues{{
|
||||
SerialFlowControl::Hardware,
|
||||
}};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(SerialFlowControl,
|
||||
{
|
||||
{SerialFlowControl::None, "none"},
|
||||
{SerialFlowControl::Hardware, "hardware"},
|
||||
})
|
||||
|
||||
#ifndef DISABLE_LUA_SCRIPTING
|
||||
LUA_ENUM_VALUES(SerialFlowControl, 2,
|
||||
{
|
||||
|
||||
36
server/src/enum/worldscale.hpp
Normale Datei
36
server/src/enum/worldscale.hpp
Normale Datei
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* server/src/enum/worldscale.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_ENUM_WORLDSCALE_HPP
|
||||
#define TRAINTASTIC_SERVER_ENUM_WORLDSCALE_HPP
|
||||
|
||||
#include <traintastic/enum/worldscale.hpp>
|
||||
|
||||
inline constexpr std::array<WorldScale, 5> WorldScaleValues{{
|
||||
WorldScale::H0,
|
||||
WorldScale::N,
|
||||
WorldScale::TT,
|
||||
WorldScale::Z,
|
||||
WorldScale::Custom,
|
||||
}};
|
||||
|
||||
#endif
|
||||
@ -24,18 +24,15 @@
|
||||
#define TRAINTASTIC_SERVER_ENUM_XPRESSNETCOMMANDSTATION_HPP
|
||||
|
||||
#include <traintastic/enum/xpressnetcommandstation.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#ifndef DISABLE_LUA_SCRIPTING
|
||||
#include "../lua/enumvalues.hpp"
|
||||
#endif
|
||||
|
||||
inline constexpr std::array<XpressNetCommandStation, 2> XpressNetCommandStationValues{{XpressNetCommandStation::Custom, XpressNetCommandStation::Roco10764}};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(XpressNetCommandStation,
|
||||
{
|
||||
{XpressNetCommandStation::Custom, "custom"},
|
||||
{XpressNetCommandStation::Roco10764, "roco_10764"},
|
||||
})
|
||||
inline constexpr std::array<XpressNetCommandStation, 3> XpressNetCommandStationValues{{
|
||||
XpressNetCommandStation::Custom,
|
||||
XpressNetCommandStation::Roco10764,
|
||||
XpressNetCommandStation::DigikeijsDR5000,
|
||||
}};
|
||||
|
||||
#ifndef DISABLE_LUA_SCRIPTING
|
||||
LUA_ENUM_VALUES(XpressNetCommandStation, 2,
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
#define TRAINTASTIC_SERVER_ENUM_XPRESSNETSERIALINTERFACE_HPP
|
||||
|
||||
#include <traintastic/enum/xpressnetserialinterface.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
inline constexpr std::array<XpressNetSerialInterface, 5> XpressNetSerialInterfaceValues{{
|
||||
XpressNetSerialInterface::Custom,
|
||||
@ -34,13 +33,4 @@ inline constexpr std::array<XpressNetSerialInterface, 5> XpressNetSerialInterfac
|
||||
XpressNetSerialInterface::RoSoftS88XPressNetLI,
|
||||
}};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(XpressNetSerialInterface,
|
||||
{
|
||||
{XpressNetSerialInterface::Custom, "custom"},
|
||||
{XpressNetSerialInterface::LenzLI100, "lenz_li100"},
|
||||
{XpressNetSerialInterface::LenzLI100F, "lenz_li100f"},
|
||||
{XpressNetSerialInterface::LenzLI101F, "lenz_li101f"},
|
||||
{XpressNetSerialInterface::RoSoftS88XPressNetLI, "rosoft_s88xpressnetli"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "../../world/world.hpp"
|
||||
#include "../decoder/decoder.hpp"
|
||||
#include "../decoder/decoderlist.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
CommandStation::CommandStation(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
IdObject(world, _id),
|
||||
@ -59,17 +60,21 @@ CommandStation::CommandStation(const std::weak_ptr<World>& world, std::string_vi
|
||||
auto w = world.lock();
|
||||
const bool editable = w && contains(w->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(name)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(name, editable);
|
||||
m_interfaceItems.add(name);
|
||||
|
||||
m_interfaceItems.add(online);
|
||||
m_interfaceItems.insertBefore(emergencyStop, notes)
|
||||
.addAttributeEnabled(editable)
|
||||
.addAttributeObjectEditor(false);
|
||||
m_interfaceItems.insertBefore(trackVoltageOff, notes)
|
||||
.addAttributeEnabled(editable)
|
||||
.addAttributeObjectEditor(false);
|
||||
|
||||
Attributes::addObjectEditor(emergencyStop, false);
|
||||
m_interfaceItems.insertBefore(emergencyStop, notes);
|
||||
|
||||
Attributes::addObjectEditor(trackVoltageOff, false);
|
||||
m_interfaceItems.insertBefore(trackVoltageOff, notes);
|
||||
|
||||
m_interfaceItems.add(decoders);
|
||||
|
||||
m_interfaceItems.add(controllers);
|
||||
|
||||
m_interfaceItems.add(notes);
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "commandstations.hpp"
|
||||
#include "../../world/world.hpp"
|
||||
#include "../../world/getworld.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
CommandStationList::CommandStationList(Object& _parent, const std::string& parentPropertyName) :
|
||||
ObjectList<CommandStation>(_parent, parentPropertyName),
|
||||
@ -47,10 +48,11 @@ CommandStationList::CommandStationList(Object& _parent, const std::string& paren
|
||||
auto world = getWorld(&_parent);
|
||||
const bool editable = world && contains(world->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(add)
|
||||
.addAttributeEnabled(editable);
|
||||
m_interfaceItems.add(remove)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(add, editable);
|
||||
m_interfaceItems.add(add);
|
||||
|
||||
Attributes::addEnabled(remove, editable);
|
||||
m_interfaceItems.add(remove);
|
||||
}
|
||||
|
||||
TableModelPtr CommandStationList::getModel()
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_CREATE_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_CREATE_HPP
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_COMMANDSTATIONS_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_COMMANDSTATIONS_HPP
|
||||
|
||||
#include "commandstation.hpp"
|
||||
|
||||
|
||||
@ -21,9 +21,9 @@
|
||||
*/
|
||||
|
||||
#include "loconetserial.hpp"
|
||||
//#include "../../world/world.hpp"
|
||||
#include "../../core/traintastic.hpp"
|
||||
#include "../../core/eventloop.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
LocoNetSerial::LocoNetSerial(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
SerialCommandStation(world, _id),
|
||||
@ -35,7 +35,7 @@ LocoNetSerial::LocoNetSerial(const std::weak_ptr<World>& world, std::string_view
|
||||
case LocoNetSerialInterface::Custom:
|
||||
break;
|
||||
|
||||
case LocoNetSerialInterface::DigiKeijsDR5000:
|
||||
case LocoNetSerialInterface::DigikeijsDR5000:
|
||||
baudrate = 115200;
|
||||
flowControl = SerialFlowControl::Hardware;
|
||||
break;
|
||||
@ -51,31 +51,11 @@ LocoNetSerial::LocoNetSerial(const std::weak_ptr<World>& world, std::string_view
|
||||
name = "LocoNet (serial)";
|
||||
loconet.setValueInternal(std::make_shared<LocoNet::LocoNet>(*this, loconet.name(), std::bind(&LocoNetSerial::send, this, std::placeholders::_1)));
|
||||
|
||||
interface.addAttributeEnabled(!online);
|
||||
|
||||
Attributes::addEnabled(interface, !online);
|
||||
Attributes::addValues(interface, LocoNetSerialInterfaceValues);
|
||||
m_interfaceItems.insertBefore(interface, baudrate);
|
||||
m_interfaceItems.insertBefore(loconet, notes);
|
||||
}
|
||||
/*
|
||||
bool LocoNetSerial::setOnline(bool& value)
|
||||
{
|
||||
if(!m_serialPort.is_open() && value)
|
||||
{
|
||||
if(!start())
|
||||
{
|
||||
value = false;
|
||||
return false;
|
||||
}
|
||||
m_readBufferOffset = 0;
|
||||
read();
|
||||
|
||||
loconet->queryLocoSlots();
|
||||
}
|
||||
else if(m_serialPort.is_open() && !value)
|
||||
stop();
|
||||
|
||||
return true;
|
||||
}*/
|
||||
|
||||
void LocoNetSerial::emergencyStopChanged(bool value)
|
||||
{
|
||||
@ -115,6 +95,11 @@ bool LocoNetSerial::send(const LocoNet::Message& message)
|
||||
return true;
|
||||
}
|
||||
|
||||
void LocoNetSerial::started()
|
||||
{
|
||||
loconet->queryLocoSlots();
|
||||
}
|
||||
|
||||
void LocoNetSerial::read()
|
||||
{
|
||||
m_serialPort.async_read_some(boost::asio::buffer(m_readBuffer.data() + m_readBufferOffset, m_readBuffer.size() - m_readBufferOffset),
|
||||
|
||||
@ -26,8 +26,6 @@
|
||||
#include "serialcommandstation.hpp"
|
||||
#include "../protocol/loconet/loconet.hpp"
|
||||
#include "../../enum/loconetserialinterface.hpp"
|
||||
//#include "../../enum/serialflowcontrol.hpp"
|
||||
//#include <boost/asio/serial_port.hpp>
|
||||
|
||||
class LocoNetSerial : public SerialCommandStation
|
||||
{
|
||||
@ -39,6 +37,7 @@ class LocoNetSerial : public SerialCommandStation
|
||||
bool start();
|
||||
void stop();
|
||||
bool send(const LocoNet::Message& msg);
|
||||
void started() final;
|
||||
void read() final;
|
||||
|
||||
public:
|
||||
|
||||
@ -1,370 +0,0 @@
|
||||
/**
|
||||
* server/src/hardware/commandstation/protocol/xpressnet.cpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* hardware/protocol/xpressnet.cpp - XpressNet protocol
|
||||
*
|
||||
* This file is part of the traintastic-server source code
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra <reinderfeenstra@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#if 0
|
||||
#include "xpressnet.hpp"
|
||||
#include "../commandstation.hpp"
|
||||
#include "../../decoder/decoder.hpp"
|
||||
#include "../../decoder/decoderchangeflags.hpp"
|
||||
#include "../../decoder/decoderfunction.hpp"
|
||||
|
||||
|
||||
|
||||
#include "../../../core/traintastic.hpp"
|
||||
|
||||
|
||||
namespace Protocol {
|
||||
|
||||
inline void addressLowHigh(uint16_t address, uint8_t& addressLow, uint8_t& addressHigh)
|
||||
{
|
||||
addressLow = address & 0xff;
|
||||
if(address <= 99)
|
||||
addressHigh = 0x00;
|
||||
else
|
||||
addressHigh = (0xC0 | address >> 8);
|
||||
}
|
||||
|
||||
struct EmergencyStopLocomotive
|
||||
{
|
||||
const uint8_t headerByte = 0x92;
|
||||
uint8_t addressHigh;
|
||||
uint8_t addressLow;
|
||||
uint8_t checksum;
|
||||
|
||||
EmergencyStopLocomotive(uint16_t address)
|
||||
{
|
||||
addressLowHigh(address, addressLow, addressHigh);
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
struct SpeedAndDirectionInstruction
|
||||
{
|
||||
const uint8_t headerByte = 0xE4;
|
||||
uint8_t identification;
|
||||
uint8_t addressHigh;
|
||||
uint8_t addressLow;
|
||||
uint8_t speedAndDirection;
|
||||
uint8_t checksum;
|
||||
|
||||
SpeedAndDirectionInstruction(uint16_t address)
|
||||
{
|
||||
addressLowHigh(address, addressLow, addressHigh);
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
struct FunctionInstructionGroup
|
||||
{
|
||||
const uint8_t headerByte = 0xE4;
|
||||
uint8_t identification;
|
||||
uint8_t addressHigh;
|
||||
uint8_t addressLow;
|
||||
uint8_t functions = 0x00;
|
||||
uint8_t checksum;
|
||||
|
||||
FunctionInstructionGroup(uint8_t group, uint16_t address)
|
||||
{
|
||||
assert(group >= 1 && group <= 3);
|
||||
identification = 0x1f + group;
|
||||
addressLowHigh(address, addressLow, addressHigh);
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
struct SetFunctionStateGroup
|
||||
{
|
||||
const uint8_t headerByte = 0xE4;
|
||||
uint8_t identification;
|
||||
uint8_t addressHigh;
|
||||
uint8_t addressLow;
|
||||
uint8_t state = 0x00;
|
||||
uint8_t checksum;
|
||||
|
||||
SetFunctionStateGroup(uint8_t group, uint16_t address)
|
||||
{
|
||||
assert(group >= 1 && group <= 3);
|
||||
identification = 0x23 + group;
|
||||
addressLowHigh(address, addressLow, addressHigh);
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
struct RocoSetFunctionStateF13F20
|
||||
{
|
||||
const uint8_t headerByte = 0xE4;
|
||||
const uint8_t identification = 0xF3;
|
||||
uint8_t addressHigh;
|
||||
uint8_t addressLow;
|
||||
uint8_t state = 0x00;
|
||||
uint8_t checksum;
|
||||
|
||||
RocoSetFunctionStateF13F20(uint16_t address)
|
||||
{
|
||||
addressLowHigh(address, addressLow, addressHigh);
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
XpressNet::XpressNet(const std::weak_ptr<World>& world, const std::string& id, std::function<void(const void*)>&& send) :
|
||||
IdObject(world, id),
|
||||
m_send{std::move(send)},
|
||||
commandStation{this, "command_station", XpressNetCommandStation::Custom, PropertyFlags::ReadWrite},
|
||||
useFunctionStateCommands{this, "use_function_state_commands", false, PropertyFlags::ReadWrite},
|
||||
useRocoF13F20Command{this, "use_roco_f13_f20_command", false, PropertyFlags::ReadWrite}
|
||||
{
|
||||
assert(m_send);
|
||||
m_interfaceItems.add(commandStation);
|
||||
m_interfaceItems.add(useFunctionStateCommands);
|
||||
}
|
||||
|
||||
bool XpressNet::isDecoderSupported(const Decoder& decoder) const
|
||||
{
|
||||
return
|
||||
decoder.protocol == DecoderProtocol::DCC &&
|
||||
decoder.address >= addressMin &&
|
||||
decoder.address <= addressMax;
|
||||
}
|
||||
|
||||
|
||||
uint8_t XpressNet::calcChecksum(const void* cmd)
|
||||
{
|
||||
const uint8_t* p = static_cast<const uint8_t*>(cmd);
|
||||
const int length = p[0] & 0x0f;
|
||||
uint8_t checksum = p[0];
|
||||
for(int i = 1; i <= length; i++)
|
||||
checksum ^= p[i];
|
||||
return checksum;
|
||||
}
|
||||
|
||||
void XpressNet::sendEmergencyStop(const Decoder& decoder)
|
||||
{
|
||||
logDebug(id, "XpressNet::sendEmergencyStop");
|
||||
|
||||
EmergencyStopLocomotive cmd(decoder.address);
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
void XpressNet::sendSpeedAndDirectionInstruction(const Decoder& decoder)
|
||||
{
|
||||
logDebug(id, "XpressNet::sendSpeedAndDirectionInstruction");
|
||||
|
||||
SpeedAndDirectionInstruction cmd(decoder.address);
|
||||
|
||||
assert(decoder.speedStep <= decoder.speedSteps);
|
||||
switch(decoder.speedSteps)
|
||||
{
|
||||
case 14:
|
||||
cmd.identification = 0x10;
|
||||
if(decoder.emergencyStop)
|
||||
cmd.speedAndDirection = 0x01;
|
||||
else if(decoder.speedStep > 0)
|
||||
cmd.speedAndDirection = decoder.speedStep + 1;
|
||||
break;
|
||||
|
||||
case 27:
|
||||
cmd.identification = 0x11;
|
||||
if(decoder.emergencyStop)
|
||||
cmd.speedAndDirection = 0x01;
|
||||
else if(decoder.speedStep > 0)
|
||||
{
|
||||
const uint8_t speedStep = decoder.speedStep + 1;
|
||||
cmd.speedAndDirection = ((speedStep & 0x01) << 4) | (speedStep >> 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 28:
|
||||
cmd.identification = 0x12;
|
||||
if(decoder.emergencyStop)
|
||||
cmd.speedAndDirection = 0x01;
|
||||
else if(decoder.speedStep > 0)
|
||||
{
|
||||
const uint8_t speedStep = decoder.speedStep + 1;
|
||||
cmd.speedAndDirection = ((speedStep & 0x01) << 4) | (speedStep >> 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 126:
|
||||
cmd.identification = 0x13;
|
||||
if(decoder.emergencyStop)
|
||||
cmd.speedAndDirection = 0x01;
|
||||
else if(decoder.speedStep > 0)
|
||||
cmd.speedAndDirection = decoder.speedStep + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(decoder.direction == Direction::Forward)
|
||||
cmd.speedAndDirection |= 0x80;
|
||||
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
void XpressNet::sendFunctionInstructionGroup1(const Decoder& decoder)
|
||||
{
|
||||
FunctionInstructionGroup cmd(1, decoder.address);
|
||||
|
||||
// FL/F0:
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(0);
|
||||
if(f && f->value)
|
||||
cmd.functions |= 0x10;
|
||||
|
||||
// F1 .. F4:
|
||||
for(uint32_t i = 1; i <= 4; i++)
|
||||
{
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(i);
|
||||
if(f && f->value)
|
||||
cmd.functions |= 1 << (i - 1);
|
||||
}
|
||||
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
void XpressNet::sendFunctionInstructionGroup2(const Decoder& decoder)
|
||||
{
|
||||
FunctionInstructionGroup cmd(2, decoder.address);
|
||||
|
||||
// F5 .. F8:
|
||||
for(uint32_t i = 5; i <= 8; i++)
|
||||
{
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(i);
|
||||
if(f && f->value)
|
||||
cmd.functions |= 1 << (i - 5);
|
||||
}
|
||||
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
void XpressNet::sendFunctionInstructionGroup3(const Decoder& decoder)
|
||||
{
|
||||
FunctionInstructionGroup cmd(3, decoder.address);
|
||||
|
||||
// F9 .. F12:
|
||||
for(uint32_t i = 9; i <= 12; i++)
|
||||
{
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(i);
|
||||
if(f && f->value)
|
||||
cmd.functions |= 1 << (i - 9);
|
||||
}
|
||||
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
void XpressNet::sendSetFunctionStateGroup1(const Decoder& decoder)
|
||||
{
|
||||
SetFunctionStateGroup cmd(1, decoder.address);
|
||||
|
||||
// FL/F0:
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(0);
|
||||
if(f && f->momentary)
|
||||
cmd.state |= 0x10;
|
||||
|
||||
// F1 .. F4:
|
||||
for(uint32_t i = 1; i <= 4; i++)
|
||||
{
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(i);
|
||||
if(f && f->momentary)
|
||||
cmd.state |= 1 << (i - 1);
|
||||
}
|
||||
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
void XpressNet::sendSetFunctionStateGroup2(const Decoder& decoder)
|
||||
{
|
||||
SetFunctionStateGroup cmd(2, decoder.address);
|
||||
|
||||
// F5 .. F8:
|
||||
for(uint32_t i = 5; i <= 8; i++)
|
||||
{
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(i);
|
||||
if(f && f->momentary)
|
||||
cmd.state |= 1 << (i - 5);
|
||||
}
|
||||
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
void XpressNet::sendSetFunctionStateGroup3(const Decoder& decoder)
|
||||
{
|
||||
SetFunctionStateGroup cmd(3, decoder.address);
|
||||
|
||||
// F9 .. F12:
|
||||
for(uint32_t i = 9; i <= 12; i++)
|
||||
{
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(i);
|
||||
if(f && f->momentary)
|
||||
cmd.state |= 1 << (i - 9);
|
||||
}
|
||||
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
void XpressNet::sendRocoSetFunctionStateF13F20(const Decoder& decoder)
|
||||
{
|
||||
RocoSetFunctionStateF13F20 cmd(decoder.address);
|
||||
|
||||
// F13 .. F20:
|
||||
for(uint32_t i = 13; i <= 20; i++)
|
||||
{
|
||||
const std::shared_ptr<DecoderFunction>& f = decoder.getFunction(i);
|
||||
if(f && f->value)
|
||||
cmd.state |= 1 << (i - 13);
|
||||
}
|
||||
|
||||
cmd.checksum = calcChecksum(&cmd);
|
||||
|
||||
m_send(&cmd);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@ -1,76 +0,0 @@
|
||||
/**
|
||||
* server/src/hardware/commandstation/protocol/xpressnet.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#if 0//ndef SERVER_HARDWARE_COMMANDSTATION_PROTOCOL_XPRESSNET_HPP
|
||||
#define SERVER_HARDWARE_COMMANDSTATION_PROTOCOL_XPRESSNET_HPP
|
||||
|
||||
#include "../../../core/idobject.hpp"
|
||||
#include "../../../core/property.hpp"
|
||||
#include "../../../enum/xpressnetcommandstation.hpp"
|
||||
|
||||
namespace Hardware {
|
||||
|
||||
class Decoder;
|
||||
enum class DecoderChangeFlags;
|
||||
|
||||
namespace CommandStation::Protocol {
|
||||
|
||||
|
||||
|
||||
class XpressNet : public IdObject
|
||||
{
|
||||
protected:
|
||||
static constexpr uint16_t addressMin = 1;
|
||||
static constexpr uint16_t addressMax = 9999;
|
||||
|
||||
std::function<void(const void*)> m_send;
|
||||
|
||||
void sendEmergencyStop(const Decoder& decoder);
|
||||
void sendSpeedAndDirectionInstruction(const Decoder& decoder);
|
||||
void sendFunctionInstructionGroup1(const Decoder& decoder);
|
||||
void sendFunctionInstructionGroup2(const Decoder& decoder);
|
||||
void sendFunctionInstructionGroup3(const Decoder& decoder);
|
||||
void sendSetFunctionStateGroup1(const Decoder& decoder);
|
||||
void sendSetFunctionStateGroup2(const Decoder& decoder);
|
||||
void sendSetFunctionStateGroup3(const Decoder& decoder);
|
||||
|
||||
void sendRocoSetFunctionStateF13F20(const Decoder& decoder);
|
||||
|
||||
public:
|
||||
CLASS_ID("command_station.protocol.xpressnet")
|
||||
|
||||
static uint8_t calcChecksum(const void* cmd);
|
||||
|
||||
Property<XpressNetCommandStation> commandStation;
|
||||
Property<bool> useFunctionStateCommands;
|
||||
Property<bool> useRocoF13F20Command;
|
||||
|
||||
XpressNet(const std::weak_ptr<World>& world, const std::string& id, std::function<void(const void*)>&& send);
|
||||
|
||||
bool isDecoderSupported(const Decoder& decoder) const;
|
||||
|
||||
void decoderChanged(const Decoder& decoder, DecoderChangeFlags changes, uint32_t functionNumber);
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
||||
@ -24,6 +24,7 @@
|
||||
#include "../../core/traintastic.hpp"
|
||||
#include "../../world/world.hpp"
|
||||
#include "../../core/eventloop.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
#include "../decoder/decoderchangeflags.hpp"
|
||||
#include "../protocol/xpressnet/messages.hpp"
|
||||
#include "../protocol/z21.hpp"
|
||||
@ -87,41 +88,41 @@ RocoZ21::RocoZ21(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
return false;
|
||||
}));
|
||||
|
||||
m_interfaceItems.insertBefore(hostname, notes)
|
||||
.addAttributeEnabled(true);
|
||||
m_interfaceItems.insertBefore(port, notes)
|
||||
.addAttributeEnabled(true);
|
||||
Attributes::addEnabled(hostname, true);
|
||||
m_interfaceItems.insertBefore(hostname, notes);
|
||||
Attributes::addEnabled(port, true);
|
||||
m_interfaceItems.insertBefore(port, notes);
|
||||
m_interfaceItems.insertBefore(loconet, notes);
|
||||
m_interfaceItems.insertBefore(serialNumber, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(hardwareType, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(firmwareVersion, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(mainCurrent, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(progCurrent, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(filteredMainCurrent, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(temperature, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(supplyVoltage, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(vccVoltage, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(shortCircuit, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(programmingModeActive, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(highTemperature, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(powerLost, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(shortCircutInternal, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
m_interfaceItems.insertBefore(shortCircutExternal, notes)
|
||||
.addAttributeCategory(Category::Info);
|
||||
Attributes::addCategory(serialNumber, Category::Info);
|
||||
m_interfaceItems.insertBefore(serialNumber, notes);
|
||||
Attributes::addCategory(hardwareType, Category::Info);
|
||||
m_interfaceItems.insertBefore(hardwareType, notes);
|
||||
Attributes::addCategory(firmwareVersion, Category::Info);
|
||||
m_interfaceItems.insertBefore(firmwareVersion, notes);
|
||||
Attributes::addCategory(mainCurrent, Category::Info);
|
||||
m_interfaceItems.insertBefore(mainCurrent, notes);
|
||||
Attributes::addCategory(progCurrent, Category::Info);
|
||||
m_interfaceItems.insertBefore(progCurrent, notes);
|
||||
Attributes::addCategory(filteredMainCurrent, Category::Info);
|
||||
m_interfaceItems.insertBefore(filteredMainCurrent, notes);
|
||||
Attributes::addCategory(temperature, Category::Info);
|
||||
m_interfaceItems.insertBefore(temperature, notes);
|
||||
Attributes::addCategory(firmwareVersion, Category::Info);
|
||||
m_interfaceItems.insertBefore(supplyVoltage, notes);
|
||||
Attributes::addCategory(vccVoltage, Category::Info);
|
||||
m_interfaceItems.insertBefore(vccVoltage, notes);
|
||||
Attributes::addCategory(firmwareVersion, Category::Info);
|
||||
m_interfaceItems.insertBefore(shortCircuit, notes);
|
||||
Attributes::addCategory(programmingModeActive, Category::Info);
|
||||
m_interfaceItems.insertBefore(programmingModeActive, notes);
|
||||
Attributes::addCategory(highTemperature, Category::Info);
|
||||
m_interfaceItems.insertBefore(highTemperature, notes);
|
||||
Attributes::addCategory(powerLost, Category::Info);
|
||||
m_interfaceItems.insertBefore(powerLost, notes);
|
||||
Attributes::addCategory(shortCircutInternal, Category::Info);
|
||||
m_interfaceItems.insertBefore(shortCircutInternal, notes);
|
||||
Attributes::addCategory(shortCircutExternal, Category::Info);
|
||||
m_interfaceItems.insertBefore(shortCircutExternal, notes);
|
||||
}
|
||||
|
||||
void RocoZ21::emergencyStopChanged(bool value)
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_Z21_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_Z21_HPP
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_ROCOZ21_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_ROCOZ21_HPP
|
||||
|
||||
#include "commandstation.hpp"
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "serialcommandstation.hpp"
|
||||
#include "../../core/traintastic.hpp"
|
||||
#include "../../core/eventloop.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
SerialCommandStation::SerialCommandStation(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
CommandStation(world, _id),
|
||||
@ -40,12 +41,12 @@ SerialCommandStation::SerialCommandStation(const std::weak_ptr<World>& world, st
|
||||
//interface = LocoNetSerialInterface::Custom;
|
||||
}}
|
||||
{
|
||||
port.addAttributeEnabled(!online);
|
||||
baudrate.addAttributeEnabled(!online);
|
||||
flowControl.addAttributeEnabled(!online);
|
||||
|
||||
Attributes::addEnabled(port, !online);
|
||||
m_interfaceItems.insertBefore(port, notes);
|
||||
Attributes::addEnabled(baudrate, !online);
|
||||
m_interfaceItems.insertBefore(baudrate, notes);
|
||||
Attributes::addEnabled(flowControl, !online);
|
||||
Attributes::addValues(flowControl, SerialFlowControlValues);
|
||||
m_interfaceItems.insertBefore(flowControl, notes);
|
||||
}
|
||||
|
||||
@ -60,8 +61,6 @@ bool SerialCommandStation::setOnline(bool& value)
|
||||
}
|
||||
m_readBufferOffset = 0;
|
||||
read();
|
||||
|
||||
//loconet->queryLocoSlots();
|
||||
}
|
||||
else if(m_serialPort.is_open() && !value)
|
||||
stop();
|
||||
|
||||
@ -38,6 +38,8 @@ class SerialCommandStation : public CommandStation
|
||||
|
||||
bool start();
|
||||
void stop();
|
||||
|
||||
virtual void started() {}
|
||||
virtual void read() = 0;
|
||||
|
||||
public:
|
||||
|
||||
@ -1,223 +0,0 @@
|
||||
/**
|
||||
* server/src/hardware/commandstation/xpressnet/xpressnet.cpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "xpressnet.hpp"
|
||||
#include "../../../core/traintastic.hpp"
|
||||
#include "../../decoder/decoder.hpp"
|
||||
#include "../../decoder/decoderlist.hpp"
|
||||
#include "../../decoder/decoderchangeflags.hpp"
|
||||
|
||||
namespace CommandStation {
|
||||
|
||||
XpressNet::XpressNet(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
CommandStation(world, _id),
|
||||
/*emergencyStop{this, "emergency_stop", false, PropertyFlags::ReadWrite | PropertyFlags::StoreState,
|
||||
[this](bool value)
|
||||
{
|
||||
if(online)
|
||||
{
|
||||
if(value)
|
||||
send(EmergencyStop());
|
||||
else
|
||||
send(NormalOperationResumed());
|
||||
}
|
||||
}},
|
||||
trackVoltageOff{this, "track_voltage_off", false, PropertyFlags::ReadWrite | PropertyFlags::StoreState,
|
||||
[this](bool value)
|
||||
{
|
||||
if(online)
|
||||
{
|
||||
if(value)
|
||||
send(TrackPowerOff());
|
||||
else
|
||||
send(NormalOperationResumed());
|
||||
}
|
||||
}},*/
|
||||
commandStation{this, "command_station", XpressNetCommandStation::Custom, PropertyFlags::ReadWrite,
|
||||
[this](XpressNetCommandStation value)
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case XpressNetCommandStation::Custom:
|
||||
break;
|
||||
|
||||
case XpressNetCommandStation::Roco10764:
|
||||
useEmergencyStopLocomotiveCommand.setValueInternal(false);
|
||||
useFunctionStateCommands.setValueInternal(false);
|
||||
useRocoF13F20Command.setValueInternal(true);
|
||||
break;
|
||||
}
|
||||
}},
|
||||
useEmergencyStopLocomotiveCommand{this, "use_emergency_stop_locomotive_command", false, PropertyFlags::ReadWrite,
|
||||
[this](bool)
|
||||
{
|
||||
commandStation = XpressNetCommandStation::Custom;
|
||||
}},
|
||||
useFunctionStateCommands{this, "use_function_state_commands", false, PropertyFlags::ReadWrite,
|
||||
[this](bool)
|
||||
{
|
||||
commandStation = XpressNetCommandStation::Custom;
|
||||
}},
|
||||
useRocoF13F20Command{this, "use_roco_f13_f20_command", false, PropertyFlags::ReadWrite,
|
||||
[this](bool)
|
||||
{
|
||||
commandStation = XpressNetCommandStation::Custom;
|
||||
}}
|
||||
{
|
||||
m_interfaceItems.add(emergencyStop)
|
||||
.addAttributeObjectEditor(false);
|
||||
m_interfaceItems.add(trackVoltageOff)
|
||||
.addAttributeObjectEditor(false);
|
||||
m_interfaceItems.insertBefore(commandStation, notes)
|
||||
.addAttributeValues(XpressNetCommandStationValues)
|
||||
.addAttributeCategory(Category::XpressNet)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.insertBefore(useEmergencyStopLocomotiveCommand, notes)
|
||||
.addAttributeCategory(Category::XpressNet)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.insertBefore(useFunctionStateCommands, notes)
|
||||
.addAttributeCategory(Category::XpressNet)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.insertBefore(useRocoF13F20Command, notes)
|
||||
.addAttributeCategory(Category::XpressNet)
|
||||
.addAttributeEnabled(false);
|
||||
}
|
||||
|
||||
void XpressNet::worldEvent(WorldState state, WorldEvent event)
|
||||
{
|
||||
CommandStation::worldEvent(state, event);
|
||||
|
||||
commandStation.setAttributeEnabled(mode == TraintasticMode::Edit);
|
||||
useEmergencyStopLocomotiveCommand.setAttributeEnabled(mode == TraintasticMode::Edit);
|
||||
useFunctionStateCommands.setAttributeEnabled(mode == TraintasticMode::Edit);
|
||||
useRocoF13F20Command.setAttributeEnabled(mode == TraintasticMode::Edit);
|
||||
}
|
||||
|
||||
void XpressNet::decoderChanged(const Decoder& decoder, DecoderChangeFlags changes, uint32_t functionNumber)
|
||||
{
|
||||
if(!online)
|
||||
return;
|
||||
|
||||
logDebug(id, "XpressNet::decoderChanged");
|
||||
|
||||
if(useEmergencyStopLocomotiveCommand && changes == DecoderChangeFlags::EmergencyStop && decoder.emergencyStop)
|
||||
send(EmergencyStopLocomotive(
|
||||
decoder.address,
|
||||
decoder.longAddress));
|
||||
else if(has(changes, DecoderChangeFlags::EmergencyStop | DecoderChangeFlags::Direction | DecoderChangeFlags::SpeedStep | DecoderChangeFlags::SpeedSteps))
|
||||
{
|
||||
switch(decoder.speedSteps)
|
||||
{
|
||||
case 14:
|
||||
send(SpeedAndDirectionInstruction14(
|
||||
decoder.address,
|
||||
decoder.longAddress,
|
||||
decoder.emergencyStop,
|
||||
decoder.direction,
|
||||
decoder.speedStep,
|
||||
getFunctionValue(decoder, 0)));
|
||||
break;
|
||||
|
||||
case 27:
|
||||
send(SpeedAndDirectionInstruction27(
|
||||
decoder.address,
|
||||
decoder.longAddress,
|
||||
decoder.emergencyStop,
|
||||
decoder.direction,
|
||||
decoder.speedStep));
|
||||
break;
|
||||
|
||||
case 28:
|
||||
send(SpeedAndDirectionInstruction28(
|
||||
decoder.address,
|
||||
decoder.longAddress,
|
||||
decoder.emergencyStop,
|
||||
decoder.direction,
|
||||
decoder.speedStep));
|
||||
break;
|
||||
|
||||
case 126:
|
||||
case 128:
|
||||
send(SpeedAndDirectionInstruction128(
|
||||
decoder.address,
|
||||
decoder.longAddress,
|
||||
decoder.emergencyStop,
|
||||
decoder.direction,
|
||||
decoder.speedStep));
|
||||
break;
|
||||
|
||||
default:
|
||||
logWarning((id, std::to_string(decoder.speedSteps) + " speed steps not supported");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(has(changes, DecoderChangeFlags::FunctionValue))
|
||||
{
|
||||
if(functionNumber <= 4)
|
||||
send(FunctionInstructionGroup1(
|
||||
decoder.address,
|
||||
decoder.longAddress,
|
||||
getFunctionValue(decoder, 0),
|
||||
getFunctionValue(decoder, 1),
|
||||
getFunctionValue(decoder, 2),
|
||||
getFunctionValue(decoder, 3),
|
||||
getFunctionValue(decoder, 4)));
|
||||
else if(functionNumber <= 8)
|
||||
send(FunctionInstructionGroup2(
|
||||
decoder.address,
|
||||
decoder.longAddress,
|
||||
getFunctionValue(decoder, 5),
|
||||
getFunctionValue(decoder, 6),
|
||||
getFunctionValue(decoder, 7),
|
||||
getFunctionValue(decoder, 8)));
|
||||
else if(functionNumber <= 12)
|
||||
send(FunctionInstructionGroup3(
|
||||
decoder.address,
|
||||
decoder.longAddress,
|
||||
getFunctionValue(decoder, 9),
|
||||
getFunctionValue(decoder, 10),
|
||||
getFunctionValue(decoder, 11),
|
||||
getFunctionValue(decoder, 12)));
|
||||
else if(useRocoF13F20Command && functionNumber <= 20)
|
||||
send(Roco::FunctionInstructionF13F20(
|
||||
decoder.address,
|
||||
decoder.longAddress,
|
||||
getFunctionValue(decoder, 13),
|
||||
getFunctionValue(decoder, 14),
|
||||
getFunctionValue(decoder, 15),
|
||||
getFunctionValue(decoder, 16),
|
||||
getFunctionValue(decoder, 17),
|
||||
getFunctionValue(decoder, 18),
|
||||
getFunctionValue(decoder, 19),
|
||||
getFunctionValue(decoder, 20)));
|
||||
else
|
||||
logWarning((id, "Function F" + std::to_string(functionNumber) + " not supported");
|
||||
}
|
||||
}
|
||||
|
||||
bool XpressNet::getFunctionValue(const Decoder& decoder, uint32_t number)
|
||||
{
|
||||
const auto& f = decoder.getFunction(number);
|
||||
return f && f->value;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
/**
|
||||
* server/src/hardware/commandstation/xpressnet/xpressnet.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_XPRESSNET_XPRESSNET_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_COMMANDSTATION_XPRESSNET_XPRESSNET_HPP
|
||||
|
||||
#include "../commandstation.hpp"
|
||||
#include "../../protocol/xpressnet.hpp"
|
||||
#include "../../../enum/xpressnetcommandstation.hpp"
|
||||
|
||||
namespace CommandStation {
|
||||
|
||||
class XpressNet : public CommandStation
|
||||
{
|
||||
protected:
|
||||
static bool getFunctionValue(const Decoder& decoder, uint32_t number);
|
||||
|
||||
void worldEvent(WorldState state, WorldEvent event) override;
|
||||
void decoderChanged(const Decoder& decoder, DecoderChangeFlags changes, uint32_t functionNumber) override;
|
||||
|
||||
virtual void send(const Protocol::XpressNet::Message& msg) = 0;
|
||||
|
||||
public:
|
||||
|
||||
Property<XpressNetCommandStation> commandStation;
|
||||
Property<bool> useEmergencyStopLocomotiveCommand;
|
||||
Property<bool> useFunctionStateCommands;
|
||||
Property<bool> useRocoF13F20Command;
|
||||
|
||||
XpressNet(const std::weak_ptr<World>& world, std::string_view _id);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -24,6 +24,7 @@
|
||||
#include "../../world/world.hpp"
|
||||
#include "../../core/traintastic.hpp"
|
||||
#include "../../core/eventloop.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
XpressNetSerial::XpressNetSerial(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
SerialCommandStation(world, _id),
|
||||
@ -57,6 +58,7 @@ XpressNetSerial::XpressNetSerial(const std::weak_ptr<World>& world, std::string_
|
||||
name = "XpressNet (serial)";
|
||||
xpressnet.setValueInternal(std::make_shared<XpressNet::XpressNet>(*this, xpressnet.name(), std::bind(&XpressNetSerial::send, this, std::placeholders::_1)));
|
||||
|
||||
Attributes::addValues(interface, XpressNetSerialInterfaceValues);
|
||||
m_interfaceItems.insertBefore(interface, baudrate);
|
||||
m_interfaceItems.insertBefore(xpressnet, notes);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "controllerlisttablemodel.hpp"
|
||||
#include "../commandstation/commandstation.hpp"
|
||||
#include "../../world/getworld.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
Controller::Controller(const std::weak_ptr<World>& _world, std::string_view _id) :
|
||||
IdObject(_world, _id),
|
||||
@ -51,8 +52,8 @@ Controller::Controller(const std::weak_ptr<World>& _world, std::string_view _id)
|
||||
const bool editable = world && contains(world->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(name);
|
||||
m_interfaceItems.add(commandStation)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(commandStation, editable);
|
||||
m_interfaceItems.add(commandStation);
|
||||
m_interfaceItems.add(active);
|
||||
m_interfaceItems.add(notes);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "controllers.hpp"
|
||||
#include "../commandstation/commandstation.hpp"
|
||||
#include "../../world/getworld.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
ControllerList::ControllerList(Object& _parent, const std::string& parentPropertyName) :
|
||||
ObjectList<Controller>(_parent, parentPropertyName),
|
||||
@ -45,8 +46,8 @@ ControllerList::ControllerList(Object& _parent, const std::string& parentPropert
|
||||
auto world = getWorld(&_parent);
|
||||
const bool editable = world && contains(world->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(add)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(add, editable);
|
||||
m_interfaceItems.add(add);
|
||||
}
|
||||
|
||||
TableModelPtr ControllerList::getModel()
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "../decoder/decoder.hpp"
|
||||
#include "../protocol/z21.hpp"
|
||||
#include "../../utils/to_hex.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
WLANmaus::WLANmaus(const std::weak_ptr<World> world, std::string_view _id) :
|
||||
Controller(world, _id),
|
||||
@ -34,8 +35,8 @@ WLANmaus::WLANmaus(const std::weak_ptr<World> world, std::string_view _id) :
|
||||
m_blockLocoInfo{nullptr},
|
||||
port{this, "port", 21105, PropertyFlags::ReadWrite | PropertyFlags::Store}
|
||||
{
|
||||
m_interfaceItems.add(port)
|
||||
.addAttributeEnabled(!active);
|
||||
Attributes::addEnabled(port, !active);
|
||||
m_interfaceItems.add(port);
|
||||
}
|
||||
|
||||
bool WLANmaus::setActive(bool& value)
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "decoderfunctionlist.hpp"
|
||||
#include "../../world/world.hpp"
|
||||
#include "../commandstation/commandstation.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
//constexpr uint16_t addressDCCMin = 1;
|
||||
constexpr uint16_t addressDCCShortMax = 127;
|
||||
@ -103,20 +104,22 @@ Decoder::Decoder(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
//auto w = world.lock();
|
||||
// const bool editable = w && contains(w->state.value(), WorldState::Edit) && speedStep == 0;
|
||||
|
||||
m_interfaceItems.add(name)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.add(commandStation)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.add(protocol)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.add(address)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.add(longAddress)
|
||||
.addAttributeEnabled(false);
|
||||
Attributes::addEnabled(name, false);
|
||||
m_interfaceItems.add(name);
|
||||
Attributes::addEnabled(commandStation, false);
|
||||
m_interfaceItems.add(commandStation);
|
||||
Attributes::addEnabled(protocol, false);
|
||||
Attributes::addValues(protocol, DecoderProtocolValues);
|
||||
m_interfaceItems.add(protocol);
|
||||
Attributes::addEnabled(address, false);
|
||||
m_interfaceItems.add(address);
|
||||
Attributes::addEnabled(longAddress, false);
|
||||
m_interfaceItems.add(longAddress);
|
||||
m_interfaceItems.add(emergencyStop);
|
||||
Attributes::addValues(direction, DirectionValues);
|
||||
m_interfaceItems.add(direction);
|
||||
m_interfaceItems.add(speedSteps)
|
||||
.addAttributeEnabled(false);
|
||||
Attributes::addEnabled(speedSteps, false);
|
||||
m_interfaceItems.add(speedSteps);
|
||||
m_interfaceItems.add(speedStep);
|
||||
m_interfaceItems.add(functions);
|
||||
m_interfaceItems.add(notes);
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "decoder.hpp"
|
||||
#include "decoderchangeflags.hpp"
|
||||
#include "../../world/world.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
const std::shared_ptr<DecoderFunction> DecoderFunction::null;
|
||||
|
||||
@ -41,10 +42,10 @@ DecoderFunction::DecoderFunction(Decoder& decoder, std::string_view _id) :
|
||||
auto w = decoder.world().lock();
|
||||
const bool editable = w && contains(w->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(number)
|
||||
.addAttributeEnabled(editable);
|
||||
m_interfaceItems.add(name)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(number, editable);
|
||||
m_interfaceItems.add(number);
|
||||
Attributes::addEnabled(name, editable);
|
||||
m_interfaceItems.add(name);
|
||||
}
|
||||
|
||||
void DecoderFunction::worldEvent(WorldState state, WorldEvent event)
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "decoderfunctionlisttablemodel.hpp"
|
||||
#include "decoder.hpp"
|
||||
#include "../../world/getworld.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
DecoderFunctionList::DecoderFunctionList(Object& _parent, const std::string& parentPropertyName) :
|
||||
ObjectList<DecoderFunction>(_parent, parentPropertyName),
|
||||
@ -57,8 +58,8 @@ DecoderFunctionList::DecoderFunctionList(Object& _parent, const std::string& par
|
||||
auto world = getWorld(&_parent);
|
||||
const bool editable = world && contains(world->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(add)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(add, editable);
|
||||
m_interfaceItems.add(add);
|
||||
}
|
||||
|
||||
TableModelPtr DecoderFunctionList::getModel()
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "decoderlisttablemodel.hpp"
|
||||
#include "../commandstation/commandstation.hpp"
|
||||
#include "../../world/getworld.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
DecoderList::DecoderList(Object& _parent, const std::string& parentPropertyName) :
|
||||
ObjectList<Decoder>(_parent, parentPropertyName),
|
||||
@ -45,8 +46,8 @@ DecoderList::DecoderList(Object& _parent, const std::string& parentPropertyName)
|
||||
auto world = getWorld(&_parent);
|
||||
const bool editable = world && contains(world->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(add)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(add, editable);
|
||||
m_interfaceItems.add(add);
|
||||
}
|
||||
|
||||
TableModelPtr DecoderList::getModel()
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "loconetinput.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
LocoNetInput::LocoNetInput(const std::weak_ptr<World> world, std::string_view _id) :
|
||||
Input(world, _id),
|
||||
@ -44,10 +45,10 @@ LocoNetInput::LocoNetInput(const std::weak_ptr<World> world, std::string_view _i
|
||||
return false;
|
||||
}}
|
||||
{
|
||||
m_interfaceItems.add(loconet)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.add(address)
|
||||
.addAttributeEnabled(false);
|
||||
Attributes::addEnabled(loconet, false);
|
||||
m_interfaceItems.add(loconet);
|
||||
Attributes::addEnabled(address, false);
|
||||
m_interfaceItems.add(address);
|
||||
}
|
||||
|
||||
void LocoNetInput::worldEvent(WorldState state, WorldEvent event)
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "../../../core/traintastic.hpp"
|
||||
#include "../../commandstation/commandstation.hpp"
|
||||
#include "../../input/loconetinput.hpp"
|
||||
#include "../../../core/attributes.hpp"
|
||||
|
||||
namespace LocoNet {
|
||||
|
||||
@ -44,9 +45,9 @@ LocoNet::LocoNet(Object& _parent, const std::string& parentPropertyName, std::fu
|
||||
SubObject(_parent, parentPropertyName),
|
||||
m_commandStation{dynamic_cast<CommandStation*>(&_parent)},
|
||||
m_send{std::move(send)},
|
||||
m_debugLog{true/*false*/},
|
||||
m_debugLog{false},
|
||||
m_queryLocoSlots{SLOT_UNKNOWN},
|
||||
commandStation{this, "command_station", LocoNetCommandStation::Custom, PropertyFlags::ReadWrite,
|
||||
commandStation{this, "command_station", LocoNetCommandStation::Custom, PropertyFlags::ReadWrite | PropertyFlags::Store,
|
||||
[this](LocoNetCommandStation value)
|
||||
{
|
||||
switch(value)
|
||||
@ -54,7 +55,7 @@ LocoNet::LocoNet(Object& _parent, const std::string& parentPropertyName, std::fu
|
||||
case LocoNetCommandStation::Custom:
|
||||
break;
|
||||
|
||||
case LocoNetCommandStation::DigiKeijsDR5000:
|
||||
case LocoNetCommandStation::DigikeijsDR5000:
|
||||
break;
|
||||
|
||||
case LocoNetCommandStation::UhlenbrockIntellibox:
|
||||
@ -69,8 +70,9 @@ LocoNet::LocoNet(Object& _parent, const std::string& parentPropertyName, std::fu
|
||||
{
|
||||
assert(m_send);
|
||||
|
||||
m_interfaceItems.add(commandStation)
|
||||
.addAttributeEnabled(false);
|
||||
Attributes::addEnabled(commandStation, m_commandStation && !m_commandStation->online);
|
||||
Attributes::addValues(commandStation, LocoNetCommandStationValues);
|
||||
m_interfaceItems.add(commandStation);
|
||||
m_interfaceItems.add(debugLog);
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "../../../core/traintastic.hpp"
|
||||
#include "../../../core/eventloop.hpp"
|
||||
#include "../../decoder/decoder.hpp"
|
||||
#include "../../../core/attributes.hpp"
|
||||
|
||||
namespace XpressNet {
|
||||
|
||||
@ -42,21 +43,28 @@ XpressNet::XpressNet(Object& _parent, const std::string& parentPropertyName, std
|
||||
|
||||
case XpressNetCommandStation::Roco10764:
|
||||
useEmergencyStopLocomotiveCommand.setValueInternal(false);
|
||||
useFunctionStateCommands.setValueInternal(false);
|
||||
//useFunctionStateCommands.setValueInternal(false);
|
||||
useRocoF13F20Command.setValueInternal(true);
|
||||
break;
|
||||
|
||||
case XpressNetCommandStation::DigikeijsDR5000:
|
||||
useEmergencyStopLocomotiveCommand.setValueInternal(false); // ?????
|
||||
//useFunctionStateCommands.setValueInternal(false);
|
||||
useRocoF13F20Command.setValueInternal(true);
|
||||
break;
|
||||
}
|
||||
// TODO: updateEnabled();
|
||||
}},
|
||||
useEmergencyStopLocomotiveCommand{this, "use_emergency_stop_locomotive_command", false, PropertyFlags::ReadWrite | PropertyFlags::Store,
|
||||
[this](bool)
|
||||
{
|
||||
commandStation = XpressNetCommandStation::Custom;
|
||||
}},
|
||||
useFunctionStateCommands{this, "use_function_state_commands", false, PropertyFlags::ReadWrite | PropertyFlags::Store,
|
||||
[this](bool)
|
||||
{
|
||||
commandStation = XpressNetCommandStation::Custom;
|
||||
}},
|
||||
//useFunctionStateCommands{this, "use_function_state_commands", false, PropertyFlags::ReadWrite | PropertyFlags::Store,
|
||||
// [this](bool)
|
||||
// {
|
||||
// commandStation = XpressNetCommandStation::Custom;
|
||||
// }},
|
||||
useRocoF13F20Command{this, "use_roco_f13_f20_command", false, PropertyFlags::ReadWrite | PropertyFlags::Store,
|
||||
[this](bool)
|
||||
{
|
||||
@ -68,14 +76,15 @@ XpressNet::XpressNet(Object& _parent, const std::string& parentPropertyName, std
|
||||
m_debugLog = value;
|
||||
}}
|
||||
{
|
||||
m_interfaceItems.add(commandStation)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.add(useEmergencyStopLocomotiveCommand)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.add(useFunctionStateCommands)
|
||||
.addAttributeEnabled(false);
|
||||
m_interfaceItems.add(useRocoF13F20Command)
|
||||
.addAttributeEnabled(false);
|
||||
Attributes::addEnabled(commandStation, false);
|
||||
Attributes::addValues(commandStation, XpressNetCommandStationValues);
|
||||
m_interfaceItems.add(commandStation);
|
||||
Attributes::addEnabled(useEmergencyStopLocomotiveCommand, false);
|
||||
m_interfaceItems.add(useEmergencyStopLocomotiveCommand);
|
||||
//Attributes::addEnabled(useFunctionStateCommands, false);
|
||||
//m_interfaceItems.add(useFunctionStateCommands);
|
||||
Attributes::addEnabled(useRocoF13F20Command, false);
|
||||
m_interfaceItems.add(useRocoF13F20Command);
|
||||
}
|
||||
|
||||
void XpressNet::worldEvent(WorldState state, WorldEvent event)
|
||||
@ -86,7 +95,7 @@ void XpressNet::worldEvent(WorldState state, WorldEvent event)
|
||||
|
||||
commandStation.setAttributeEnabled(editable);
|
||||
useEmergencyStopLocomotiveCommand.setAttributeEnabled(editable);
|
||||
useFunctionStateCommands.setAttributeEnabled(editable);
|
||||
//useFunctionStateCommands.setAttributeEnabled(editable);
|
||||
useRocoF13F20Command.setAttributeEnabled(editable);
|
||||
}
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ class XpressNet : public SubObject
|
||||
|
||||
Property<XpressNetCommandStation> commandStation;
|
||||
Property<bool> useEmergencyStopLocomotiveCommand;
|
||||
Property<bool> useFunctionStateCommands;
|
||||
//Property<bool> useFunctionStateCommands;
|
||||
Property<bool> useRocoF13F20Command;
|
||||
Property<bool> debugLog;
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "../world/world.hpp"
|
||||
#include "../enum/worldevent.hpp"
|
||||
#include "../set/worldstate.hpp"
|
||||
#include "../core/attributes.hpp"
|
||||
|
||||
namespace Lua {
|
||||
|
||||
@ -49,8 +50,8 @@ Script::Script(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
|
||||
m_interfaceItems.add(name);
|
||||
m_interfaceItems.add(active);
|
||||
m_interfaceItems.add(code)
|
||||
.addAttributeEnabled(!active && editable);
|
||||
Attributes::addEnabled(code, !active && editable);
|
||||
m_interfaceItems.add(code);
|
||||
}
|
||||
|
||||
void Script::addToWorld()
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "scriptlist.hpp"
|
||||
#include "scriptlisttablemodel.hpp"
|
||||
#include "../world/getworld.hpp"
|
||||
#include "../core/attributes.hpp"
|
||||
|
||||
namespace Lua {
|
||||
|
||||
@ -42,8 +43,8 @@ ScriptList::ScriptList(Object& _parent, const std::string& parentPropertyName) :
|
||||
auto world = getWorld(&_parent);
|
||||
const bool editable = world && contains(world->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(add)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(add, editable);
|
||||
m_interfaceItems.add(add);
|
||||
}
|
||||
|
||||
TableModelPtr ScriptList::getModel()
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "train.hpp"
|
||||
#include "../world/world.hpp"
|
||||
#include "trainlisttablemodel.hpp"
|
||||
#include "../core/attributes.hpp"
|
||||
|
||||
Train::Train(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
IdObject(world, _id),
|
||||
@ -37,13 +38,14 @@ Train::Train(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
auto w = world.lock();
|
||||
const bool editable = w && contains(w->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(name)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(name, editable);
|
||||
m_interfaceItems.add(name);
|
||||
m_interfaceItems.add(lob);
|
||||
Attributes::addValues(direction, DirectionValues);
|
||||
m_interfaceItems.add(direction);
|
||||
m_interfaceItems.add(speed);
|
||||
m_interfaceItems.add(speedMax)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(speedMax, editable);
|
||||
m_interfaceItems.add(speedMax);
|
||||
m_interfaceItems.add(throttleSpeed);
|
||||
m_interfaceItems.add(weight);
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "trainlisttablemodel.hpp"
|
||||
#include "../world/world.hpp"
|
||||
#include "../world/getworld.hpp"
|
||||
#include "../core/attributes.hpp"
|
||||
|
||||
TrainList::TrainList(Object& _parent, const std::string& parentPropertyName) :
|
||||
ObjectList<Train>(_parent, parentPropertyName),
|
||||
@ -39,8 +40,8 @@ TrainList::TrainList(Object& _parent, const std::string& parentPropertyName) :
|
||||
auto world = getWorld(&_parent);
|
||||
const bool editable = world && contains(world->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(add)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(add, editable);
|
||||
m_interfaceItems.add(add);
|
||||
}
|
||||
|
||||
TableModelPtr TrainList::getModel()
|
||||
|
||||
60
server/src/utils/json.hpp
Normale Datei
60
server/src/utils/json.hpp
Normale Datei
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* server/src/utils/json.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_UTILS_JSON_HPP
|
||||
#define TRAINTASTIC_SERVER_UTILS_JSON_HPP
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <traintastic/enum/enum.hpp>
|
||||
#include <traintastic/set/set.hpp>
|
||||
|
||||
template<typename BasicJsonType, typename EnumType>
|
||||
inline void to_json(const BasicJsonType& j, const EnumType& e, typename std::enable_if_t<std::is_enum_v<EnumType> && !is_set_v<EnumType>>* = nullptr)
|
||||
{
|
||||
e = EnumValues<EnumType>::value.at(e);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename EnumType>
|
||||
inline void from_json(const BasicJsonType& j, EnumType& e, typename std::enable_if_t<std::is_enum_v<EnumType> && !is_set_v<EnumType>>* = nullptr)
|
||||
{
|
||||
auto it = std::find_if(EnumValues<EnumType>::value.cbegin(), EnumValues<EnumType>::value.cend(),
|
||||
[j](const auto& v)
|
||||
{
|
||||
return v.second == j;
|
||||
});
|
||||
|
||||
e = it != EnumValues<EnumType>::value.cend() ? it->first : EnumValues<EnumType>::value.cbegin()->first;
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename EnumType>
|
||||
inline void to_json(const BasicJsonType& j, const EnumType& e, typename std::enable_if_t<is_set_v<EnumType>>* = nullptr)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename EnumType>
|
||||
inline void from_json(const BasicJsonType& j, EnumType& e, typename std::enable_if_t<is_set_v<EnumType>>* = nullptr)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -23,8 +23,8 @@
|
||||
#include "railvehiclelist.hpp"
|
||||
#include "railvehiclelisttablemodel.hpp"
|
||||
#include "railvehicles.hpp"
|
||||
#include "../../world/world.hpp"
|
||||
#include "../../world/getworld.hpp"
|
||||
#include "../../core/attributes.hpp"
|
||||
|
||||
RailVehicleList::RailVehicleList(Object& _parent, const std::string& parentPropertyName) :
|
||||
ObjectList<RailVehicle>(_parent, parentPropertyName),
|
||||
@ -40,8 +40,8 @@ RailVehicleList::RailVehicleList(Object& _parent, const std::string& parentPrope
|
||||
auto world = getWorld(&_parent);
|
||||
const bool editable = world && contains(world->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(add)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(add, editable);
|
||||
m_interfaceItems.add(add);
|
||||
}
|
||||
|
||||
TableModelPtr RailVehicleList::getModel()
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
#include "vehicle.hpp"
|
||||
#include "../world/world.hpp"
|
||||
#include "../core/attributes.hpp"
|
||||
|
||||
Vehicle::Vehicle(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
IdObject(world, _id),
|
||||
@ -30,8 +31,8 @@ Vehicle::Vehicle(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
auto w = world.lock();
|
||||
const bool editable = w && contains(w->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(name)
|
||||
.addAttributeEnabled(editable);
|
||||
Attributes::addEnabled(name, editable);
|
||||
m_interfaceItems.add(name);
|
||||
}
|
||||
|
||||
void Vehicle::worldEvent(WorldState state, WorldEvent event)
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "worldsaver.hpp"
|
||||
#include "../core/traintastic.hpp"
|
||||
#include "../core/objectlisttablemodel.hpp"
|
||||
#include "../core/attributes.hpp"
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
@ -121,6 +122,7 @@ World::World(Private) :
|
||||
m_filename = Traintastic::instance->worldDir() / to_string(m_uuid) / filename;
|
||||
|
||||
m_interfaceItems.add(name);
|
||||
Attributes::addValues(scale, WorldScaleValues);
|
||||
m_interfaceItems.add(scale);
|
||||
|
||||
m_interfaceItems.add(commandStations);
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <traintastic/enum/worldevent.hpp>
|
||||
#include <traintastic/enum/worldscale.hpp>
|
||||
#include "../enum/worldscale.hpp"
|
||||
#include <traintastic/set/worldstate.hpp>
|
||||
#include "../clock/clock.hpp"
|
||||
#include "../hardware/commandstation/commandstationlist.hpp"
|
||||
|
||||
34
shared/src/traintastic/enum/attributetype.hpp
Normale Datei
34
shared/src/traintastic/enum/attributetype.hpp
Normale Datei
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* shared/src/traintastic/enum/attributetype.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SHARED_TRAINTASTIC_ENUM_ATTRIBUTETYPE_HPP
|
||||
#define TRAINTASTIC_SHARED_TRAINTASTIC_ENUM_ATTRIBUTETYPE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class AttributeType : uint8_t
|
||||
{
|
||||
Value = 1,
|
||||
Values = 2,
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -40,4 +40,12 @@ struct EnumName<CommandStationStatus>
|
||||
static constexpr char const* value = "command_station_status";
|
||||
};
|
||||
|
||||
ENUM_VALUES(CommandStationStatus, 4,
|
||||
{
|
||||
{CommandStationStatus::Offline, "offline"},
|
||||
{CommandStationStatus::Initializing, "initializing"},
|
||||
{CommandStationStatus::Online, "online"},
|
||||
{CommandStationStatus::Error, "error"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -30,10 +30,10 @@ enum class DecoderProtocol : uint8_t
|
||||
{
|
||||
Auto = 0,
|
||||
DCC = 1,
|
||||
Motorola = 2,
|
||||
MFX = 3,
|
||||
Selectrix = 4,
|
||||
FMZ = 5,
|
||||
//Motorola = 2,
|
||||
//MFX = 3,
|
||||
//Selectrix = 4,
|
||||
//FMZ = 5,
|
||||
Custom = 255,
|
||||
};
|
||||
|
||||
@ -43,4 +43,11 @@ struct EnumName<DecoderProtocol>
|
||||
static constexpr char const* value = "decoder_protocol";
|
||||
};
|
||||
|
||||
ENUM_VALUES(DecoderProtocol, 3,
|
||||
{
|
||||
{DecoderProtocol::Auto, "AUTO"},
|
||||
{DecoderProtocol::DCC, "DCC"},
|
||||
{DecoderProtocol::Custom, "CUSTOM"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -38,4 +38,10 @@ struct EnumName<Direction>
|
||||
static constexpr char const* value = "direction";
|
||||
};
|
||||
|
||||
ENUM_VALUES(Direction, 2,
|
||||
{
|
||||
{Direction::Forward, "forward"},
|
||||
{Direction::Reverse, "reverse"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -24,10 +24,32 @@
|
||||
#ifndef TRAINTASTIC_SHARED_TRAINTASTIC_ENUM_ENUM_HPP
|
||||
#define TRAINTASTIC_SHARED_TRAINTASTIC_ENUM_ENUM_HPP
|
||||
|
||||
#include <frozen/map.h>
|
||||
|
||||
#define ENUM_NAME(_type, _name) \
|
||||
template<> \
|
||||
struct EnumName<_type> \
|
||||
{ \
|
||||
static constexpr char const* value = _name; \
|
||||
};
|
||||
|
||||
#define ENUM_VALUES(_type, _size, ...) \
|
||||
template<> \
|
||||
struct EnumValues<_type> \
|
||||
{ \
|
||||
static constexpr frozen::map<_type, const char*, _size> value = { __VA_ARGS__ }; \
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct EnumName
|
||||
{
|
||||
static_assert(sizeof(T) != sizeof(T), "template specialization required");
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct EnumValues
|
||||
{
|
||||
static_assert(sizeof(T) != sizeof(T), "template specialization required");
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -41,4 +41,14 @@ struct EnumName<LengthUnit>
|
||||
static constexpr char const* value = "length_unit";
|
||||
};
|
||||
|
||||
ENUM_VALUES(LengthUnit, 6,
|
||||
{
|
||||
{LengthUnit::Meter, "m"},
|
||||
{LengthUnit::CentiMeter, "cm"},
|
||||
{LengthUnit::MilliMeter, "mm"},
|
||||
{LengthUnit::Yard, "yd"},
|
||||
{LengthUnit::Foot, "ft"},
|
||||
{LengthUnit::Inch, "in"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -25,18 +25,22 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include "enum.hpp"
|
||||
#include <frozen/map.h>
|
||||
|
||||
enum class LocoNetCommandStation : uint16_t
|
||||
{
|
||||
Custom = 0,
|
||||
UhlenbrockIntellibox = 1,
|
||||
DigiKeijsDR5000 = 2,
|
||||
DigikeijsDR5000 = 2,
|
||||
};
|
||||
|
||||
template<>
|
||||
struct EnumName<LocoNetCommandStation>
|
||||
ENUM_NAME(LocoNetCommandStation, "loconet_command_station")
|
||||
|
||||
ENUM_VALUES(LocoNetCommandStation, 3,
|
||||
{
|
||||
static constexpr char const* value = "loconet_command_station";
|
||||
};
|
||||
{LocoNetCommandStation::Custom, "custom"},
|
||||
{LocoNetCommandStation::UhlenbrockIntellibox, "uhlenbrock_intellibox"},
|
||||
{LocoNetCommandStation::DigikeijsDR5000, "digikeijs_dr5000"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -29,14 +29,17 @@
|
||||
enum class LocoNetSerialInterface : uint16_t
|
||||
{
|
||||
Custom = 0,
|
||||
DigiKeijsDR5000 = 1,
|
||||
DigikeijsDR5000 = 1,
|
||||
RoSoftLocoNetInterface = 2,
|
||||
};
|
||||
|
||||
template<>
|
||||
struct EnumName<LocoNetSerialInterface>
|
||||
ENUM_NAME(LocoNetSerialInterface, "loconet_serial_interface")
|
||||
|
||||
ENUM_VALUES(LocoNetSerialInterface, 3,
|
||||
{
|
||||
static constexpr char const* value = "loconet_serial_interface";
|
||||
};
|
||||
{LocoNetSerialInterface::Custom, "custom"},
|
||||
{LocoNetSerialInterface::DigikeijsDR5000, "digikeijs_dr5000"},
|
||||
{LocoNetSerialInterface::RoSoftLocoNetInterface, "rosoft_loconet_interface"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -20,30 +20,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* shared/src/enum/serialflowcontrol.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SHARED_ENUM_serialflowcontrol_HPP
|
||||
#define traintastic_shared_enum_serialflowcontrol_hpp
|
||||
#ifndef TRAINTASTIC_SHARED_TRAINTASTIC_ENUM_SERIALFLOWCONTROL_HPP
|
||||
#define TRAINTASTIC_SHARED_TRAINTASTIC_ENUM_SERIALFLOWCONTROL_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include "enum.hpp"
|
||||
@ -54,10 +32,12 @@ enum class SerialFlowControl : uint8_t
|
||||
Hardware = 1,
|
||||
};
|
||||
|
||||
template<>
|
||||
struct EnumName<SerialFlowControl>
|
||||
ENUM_NAME(SerialFlowControl, "serial_flow_control")
|
||||
|
||||
ENUM_VALUES(SerialFlowControl, 2,
|
||||
{
|
||||
static constexpr char const* value = "serial_flow_control";
|
||||
};
|
||||
{SerialFlowControl::None, "none"},
|
||||
{SerialFlowControl::Hardware, "hardware"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -38,4 +38,11 @@ struct EnumName<SpeedUnit>
|
||||
static constexpr char const* value = "speed_unit";
|
||||
};
|
||||
|
||||
ENUM_VALUES(SpeedUnit, 3,
|
||||
{
|
||||
{SpeedUnit::MeterPerSecond, "mps"},
|
||||
{SpeedUnit::KiloMeterPerHour, "kmph"},
|
||||
{SpeedUnit::MilePerHour, "mph"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -39,4 +39,12 @@ struct EnumName<WeightUnit>
|
||||
static constexpr char const* value = "weight_unit";
|
||||
};
|
||||
|
||||
ENUM_VALUES(WeightUnit, 4,
|
||||
{
|
||||
{WeightUnit::KiloGram, "kg"},
|
||||
{WeightUnit::Ton, "ton"},
|
||||
{WeightUnit::ShortTons, "short_tons"},
|
||||
{WeightUnit::LongTons, "long_tons"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -43,4 +43,15 @@ struct EnumName<WorldEvent>
|
||||
static constexpr char const* value = "world_event";
|
||||
};
|
||||
|
||||
ENUM_VALUES(WorldEvent, 7,
|
||||
{
|
||||
{WorldEvent::Stop, "stop"},
|
||||
{WorldEvent::Run, "run"},
|
||||
{WorldEvent::EditDisabled, "edit_disabled"},
|
||||
{WorldEvent::EditEnabled, "edit_enabled"},
|
||||
{WorldEvent::TrackPowerOff, "track_power_off"},
|
||||
{WorldEvent::TrackPowerOn, "track_power_on"},
|
||||
{WorldEvent::EmergencyStop, "emergency_stop"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -41,4 +41,13 @@ struct EnumName<WorldScale>
|
||||
static constexpr char const* value = "world_scale";
|
||||
};
|
||||
|
||||
ENUM_VALUES(WorldScale, 5,
|
||||
{
|
||||
{WorldScale::H0, "h0"},
|
||||
{WorldScale::N, "n"},
|
||||
{WorldScale::TT, "tt"},
|
||||
{WorldScale::Z, "z"},
|
||||
{WorldScale::Custom, "custom"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -30,6 +30,7 @@ enum class XpressNetCommandStation : uint16_t
|
||||
{
|
||||
Custom = 0,
|
||||
Roco10764 = 1,
|
||||
DigikeijsDR5000 = 2,
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -38,4 +39,11 @@ struct EnumName<XpressNetCommandStation>
|
||||
static constexpr char const* value = "xpressnet_command_station";
|
||||
};
|
||||
|
||||
ENUM_VALUES(XpressNetCommandStation, 3,
|
||||
{
|
||||
{XpressNetCommandStation::Custom, "custom"},
|
||||
{XpressNetCommandStation::Roco10764, "roco_10764"},
|
||||
{XpressNetCommandStation::DigikeijsDR5000, "digikeijs_dr5000"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
@ -41,4 +41,13 @@ struct EnumName<XpressNetSerialInterface>
|
||||
static constexpr char const* value = "xpressnet_serial_interface";
|
||||
};
|
||||
|
||||
ENUM_VALUES(XpressNetSerialInterface, 5,
|
||||
{
|
||||
{XpressNetSerialInterface::Custom, "custom"},
|
||||
{XpressNetSerialInterface::LenzLI100, "lenz_li100"},
|
||||
{XpressNetSerialInterface::LenzLI100F, "lenz_li100f"},
|
||||
{XpressNetSerialInterface::LenzLI101F, "lenz_li101f"},
|
||||
{XpressNetSerialInterface::RoSoftS88XPressNetLI, "rosoft_s88xpressnetli"},
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren