WIP
Dieser Commit ist enthalten in:
Ursprung
e8172078d6
Commit
0b800ef124
2
.gitignore
vendored
2
.gitignore
vendored
@ -40,3 +40,5 @@
|
||||
.build*
|
||||
build*
|
||||
CMakeLists.txt.*
|
||||
*~*
|
||||
.vscode
|
||||
|
||||
@ -25,9 +25,9 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="46.002732"
|
||||
inkscape:cy="45.48465"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="33.328085"
|
||||
inkscape:cy="30.22358"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
@ -51,7 +51,7 @@
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:title />
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-nc/4.0/" />
|
||||
</cc:Work>
|
||||
@ -104,5 +104,10 @@
|
||||
d="m 20.108333,286.41665 c -2.303233,-0.10271 -3.014867,3.1754 -0.78079,3.91852 2.232157,0.99084 3.0625,-2.19831 1.497019,-3.42866 -0.199377,-0.2124 -0.44335,-0.38535 -0.716229,-0.48986 z"
|
||||
id="path2025"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#003380;fill-opacity:1;stroke:#003380;stroke-width:1.41118586;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 16.933332,280.77231 c -0.859926,0 -1.552214,0.69228 -1.552214,1.55222 v 4.65664 h -4.656644 c -0.8599264,0 -1.5522144,0.69225 -1.5522144,1.55218 0,0.85996 0.692288,1.55219 1.5522144,1.55219 h 4.656644 v 4.65665 c 0,0.85991 0.692288,1.5522 1.552214,1.5522 0.85993,0 1.552218,-0.69229 1.552218,-1.5522 v -4.65665 h 4.656642 c 0.859928,0 1.552215,-0.69225 1.552215,-1.55219 0,-0.85993 -0.692287,-1.55218 -1.552215,-1.55218 H 18.48555 v -4.65664 c 0,-0.85994 -0.692288,-1.55222 -1.552218,-1.55222 z"
|
||||
id="rect843" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Vorher Breite: | Höhe: | Größe: 5.4 KiB Nachher Breite: | Höhe: | Größe: 6.1 KiB |
@ -42,6 +42,7 @@
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <locale/locale.hpp>
|
||||
#include <codename.hpp>
|
||||
|
||||
#define SETTING_PREFIX "mainwindow/"
|
||||
#define SETTING_GEOMETRY SETTING_PREFIX "geometry"
|
||||
@ -91,7 +92,9 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
if(Method* method = traintastic->getMethod("new_world"))
|
||||
method->call();
|
||||
});
|
||||
m_actionNewWorld->setShortcut(QKeySequence::New);
|
||||
m_actionLoadWorld = menu->addAction(QIcon(":/dark/world_load.svg"), Locale::tr("qtapp.mainmenu:load_world") + "...", this, &MainWindow::loadWorld);
|
||||
m_actionLoadWorld->setShortcut(QKeySequence::Open);
|
||||
m_actionSaveWorld = menu->addAction(QIcon(":/dark/world_save.svg"), Locale::tr("qtapp.mainmenu:save_world"),
|
||||
[this]()
|
||||
{
|
||||
@ -99,11 +102,12 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
if(Method* method = m_world->getMethod("save"))
|
||||
method->call();
|
||||
});
|
||||
m_actionSaveWorld->setShortcut(QKeySequence::Save);
|
||||
menu->addSeparator();
|
||||
m_actionImportWorld = menu->addAction(QIcon(":/dark/world_import.svg"), Locale::tr("qtapp.mainmenu:import_world") + "...", this, &MainWindow::importWorld);
|
||||
m_actionExportWorld = menu->addAction(QIcon(":/dark/world_export.svg"), Locale::tr("qtapp.mainmenu:export_world") + "...", this, &MainWindow::exportWorld);
|
||||
menu->addSeparator();
|
||||
menu->addAction(Locale::tr("qtapp.mainmenu:quit"), this, &MainWindow::close);
|
||||
menu->addAction(Locale::tr("qtapp.mainmenu:quit"), this, &MainWindow::close)->setShortcut(QKeySequence::Quit);
|
||||
|
||||
menu = menuBar()->addMenu(Locale::tr("qtapp.mainmenu:view"));
|
||||
actFullScreen = menu->addAction(Locale::tr("qtapp.mainmenu:fullscreen"), this, &MainWindow::toggleFullScreen);
|
||||
@ -112,11 +116,12 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
|
||||
m_menuObjects = menuBar()->addMenu(Locale::tr("qtapp.mainmenu:objects"));
|
||||
menu = m_menuObjects->addMenu(QIcon(":/dark/hardware.svg"), Locale::tr("qtapp.mainmenu:hardware"));
|
||||
menu->addAction(Locale::tr("world:command_stations") + "...", [this](){ showObject("world.command_stations"); });
|
||||
menu->addAction(Locale::tr("world:decoders") + "...", [this](){ showObject("world.decoders"); });
|
||||
menu->addAction(Locale::tr("world:inputs") + "...", [this](){ showObject("world.inputs"); });
|
||||
menu->addAction(Locale::tr("world:command_stations") + "...", [this](){ showObject("world.command_stations", Locale::tr("world:command_stations")); });
|
||||
menu->addAction(Locale::tr("world:decoders") + "...", [this](){ showObject("world.decoders", Locale::tr("world:decoders")); });
|
||||
menu->addAction(Locale::tr("world:inputs") + "...", [this](){ showObject("world.inputs", Locale::tr("world:inputs")); });
|
||||
menu->addAction(Locale::tr("world:controllers") + "...", [this](){ showObject("world.controllers", Locale::tr("world:controllers")); });
|
||||
m_menuObjects->addAction(Locale::tr("world:clock") + "...", [this](){ showObject("world.clock"); });
|
||||
m_menuObjects->addAction(QIcon(":/dark/lua.svg"), Locale::tr("world:lua_scripts") + "...", [this](){ showObject("world.lua_scripts"); });
|
||||
m_menuObjects->addAction(QIcon(":/dark/lua.svg"), Locale::tr("world:lua_scripts") + "...", [this](){ showObject("world.lua_scripts", Locale::tr("world:lua_scripts")); });
|
||||
|
||||
menu = menuBar()->addMenu(Locale::tr("qtapp.mainmenu:tools"));
|
||||
menu->addAction(Locale::tr("qtapp.mainmenu:settings") + "...")->setEnabled(false);
|
||||
@ -126,7 +131,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
m_actionServerConsole->setShortcut(Qt::Key_F12);
|
||||
|
||||
menu = menuBar()->addMenu(Locale::tr("qtapp.mainmenu:help"));
|
||||
menu->addAction(Locale::tr("qtapp.mainmenu:help"), [](){ QDesktopServices::openUrl("https://traintastic.org/manual?version=" + QApplication::applicationVersion()); })->setShortcut(Qt::Key_F1);
|
||||
menu->addAction(Locale::tr("qtapp.mainmenu:help"), [](){ QDesktopServices::openUrl("https://traintastic.org/manual?version=" + QApplication::applicationVersion()); })->setShortcut(QKeySequence::HelpContents);
|
||||
//menu->addSeparator();
|
||||
//menu->addAction(Locale::tr("qtapp.mainmenu:about_qt") + "...", qApp, &QApplication::aboutQt);
|
||||
menu->addAction(Locale::tr("qtapp.mainmenu:about") + "...", this, &MainWindow::showAbout);
|
||||
@ -224,16 +229,10 @@ void MainWindow::connectToServer()
|
||||
connect(m_connection.data(), &Connection::worldChanged,
|
||||
[this]()
|
||||
{
|
||||
m_world = m_connection->world();
|
||||
|
||||
if(m_world)
|
||||
{
|
||||
if(AbstractProperty* edit = m_world->getProperty("edit"))
|
||||
connect(edit, &AbstractProperty::valueChangedBool, m_actionEdit, &QAction::setChecked);
|
||||
}
|
||||
|
||||
worldChanged();
|
||||
updateActions();
|
||||
});
|
||||
worldChanged();
|
||||
clientStateChanged();
|
||||
}
|
||||
}
|
||||
@ -257,16 +256,16 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
/*void MainWindow::setMode(TraintasticMode value)
|
||||
void MainWindow::worldChanged()
|
||||
{
|
||||
if(!m_connection)
|
||||
return;
|
||||
m_world = m_connection->world();
|
||||
|
||||
if(m_connection->state() == Connection::State::Connected && m_connection->traintastic())
|
||||
m_connection->traintastic()->getProperty("mode")->setValueInt64(static_cast<int64_t>(value));
|
||||
else
|
||||
updateModeActions();
|
||||
}*/
|
||||
if(m_world)
|
||||
{
|
||||
if(AbstractProperty* edit = m_world->getProperty("edit"))
|
||||
connect(edit, &AbstractProperty::valueChangedBool, m_actionEdit, &QAction::setChecked);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::loadWorld()
|
||||
{
|
||||
@ -348,11 +347,13 @@ void MainWindow::showObject(const ObjectPtr& object)
|
||||
m_mdiArea->setActiveSubWindow(m_mdiSubWindows[id]);
|
||||
}
|
||||
|
||||
void MainWindow::showObject(const QString& id)
|
||||
void MainWindow::showObject(const QString& id, const QString& title)
|
||||
{
|
||||
if(!m_mdiSubWindows.contains(id))
|
||||
{
|
||||
QMdiSubWindow* window = new ObjectSubWindow(m_connection, id);
|
||||
if(!title.isEmpty())
|
||||
window->setWindowTitle(title);
|
||||
m_mdiSubWindows[id] = window;
|
||||
m_mdiArea->addSubWindow(window);
|
||||
window->setAttribute(Qt::WA_DeleteOnClose);
|
||||
@ -366,7 +367,7 @@ void MainWindow::showObject(const QString& id)
|
||||
void MainWindow::showAbout()
|
||||
{
|
||||
QMessageBox::about(this, tr("About Traintastic"),
|
||||
"<h2>Traintastic <small>v" + QApplication::applicationVersion() + "</small></h2>"
|
||||
"<h2>Traintastic v" + QApplication::applicationVersion() + " <small>" TRAINTASTIC_CODENAME "</small></h2>"
|
||||
"<p>Copyright © 2019-2020 Reinder Feenstra</p>"
|
||||
"<p>This program is free software; you can redistribute it and/or"
|
||||
" modify it under the terms of the GNU General Public License"
|
||||
|
||||
@ -65,7 +65,7 @@ class MainWindow : public QMainWindow
|
||||
QByteArray m_beforeFullScreenGeometry;
|
||||
|
||||
void closeEvent(QCloseEvent* event) final;
|
||||
void setMode(TraintasticMode value);
|
||||
void worldChanged();
|
||||
|
||||
protected slots:
|
||||
void disconnectFromServer();
|
||||
@ -89,7 +89,7 @@ class MainWindow : public QMainWindow
|
||||
public slots:
|
||||
void connectToServer();
|
||||
void showObject(const ObjectPtr& object);
|
||||
void showObject(const QString& id);
|
||||
void showObject(const QString& id, const QString& title = "");
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -66,5 +66,6 @@ void ObjectSubWindow::setObject(const ObjectPtr& object)
|
||||
{
|
||||
setWidget(createWidget(object));
|
||||
connect(widget(), &QWidget::windowTitleChanged, this, &ObjectSubWindow::setWindowTitle);
|
||||
setWindowTitle(widget()->windowTitle());
|
||||
if(!widget()->windowTitle().isEmpty())
|
||||
setWindowTitle(widget()->windowTitle());
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ QWidget* createWidgetIfCustom(const ObjectPtr& object, QWidget* parent)
|
||||
return new DecoderFunctionListWidget(object, parent);
|
||||
else if(classId == "input_list")
|
||||
return new InputListWidget(object, parent);
|
||||
else if(classId == "controller_list")
|
||||
return new ObjectListWidget(object, parent);
|
||||
else if(classId == "lua.script_list")
|
||||
return new LuaScriptListWidget(object, parent);
|
||||
else if(classId == "console")
|
||||
|
||||
@ -93,6 +93,13 @@ ObjectListWidget::ObjectListWidget(const ObjectPtr& object, QWidget* parent) :
|
||||
|
||||
});
|
||||
});
|
||||
m_actionAdd->setEnabled(method->getAttributeBool(AttributeName::Enabled, true));
|
||||
connect(method, &Method::attributeChanged,
|
||||
[this](AttributeName name, QVariant value)
|
||||
{
|
||||
if(name == AttributeName::Enabled)
|
||||
m_actionAdd->setEnabled(value.toBool());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
7
doc/css/bootstrap.min.css
vendored
Normale Datei
7
doc/css/bootstrap.min.css
vendored
Normale Datei
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
15
doc/css/traintastic-manual.css
Normale Datei
15
doc/css/traintastic-manual.css
Normale Datei
@ -0,0 +1,15 @@
|
||||
body {
|
||||
background: #DCDCDC;
|
||||
}
|
||||
|
||||
div#body {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto 0 auto;
|
||||
}
|
||||
|
||||
div#content {
|
||||
border-left: #BEBEBE 1px solid;
|
||||
border-right: #BEBEBE 1px solid;
|
||||
background: white;
|
||||
padding: 1em;
|
||||
}
|
||||
56
doc/data/pages.json
Normale Datei
56
doc/data/pages.json
Normale Datei
@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": "index",
|
||||
"md_file": "index.md",
|
||||
"sub_pages": [
|
||||
{
|
||||
"id": "installation",
|
||||
"md_file": "installation.md"
|
||||
},
|
||||
{
|
||||
"id": "getting_started",
|
||||
"md_file": "gettingstarted.md"
|
||||
},
|
||||
{
|
||||
"id": "hardware",
|
||||
"md_file": "hardware.md",
|
||||
"sub_pages": [
|
||||
{
|
||||
"id": "command_stations",
|
||||
"md_file": "commandstations.md",
|
||||
"sub_pages": [
|
||||
{
|
||||
"id": "dr5000",
|
||||
"md_file": "dr5000.md"
|
||||
},
|
||||
{
|
||||
"id": "intellibox",
|
||||
"md_file": "intellibox.md"
|
||||
},
|
||||
{
|
||||
"id": "z21",
|
||||
"md_file": "z21.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "decoder",
|
||||
"md_file": "decoder.md",
|
||||
"sub_pages": [
|
||||
{
|
||||
"id": "function",
|
||||
"md_file": "decoderfunction.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "lua",
|
||||
"md_file": "lua.md"
|
||||
},
|
||||
{
|
||||
"id": "command_line_options",
|
||||
"md_file": "commandlineoptions.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
162
doc/data/table/supportedcommandstations.json
Normale Datei
162
doc/data/table/supportedcommandstations.json
Normale Datei
@ -0,0 +1,162 @@
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"label": {
|
||||
"en-us": "Command station",
|
||||
"nl-nl": "Centrale"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": {
|
||||
"en-us": "Interface"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": {
|
||||
"en-us": "Features",
|
||||
},
|
||||
"columns": [
|
||||
{
|
||||
"label": {
|
||||
"en-us": "Decoder control"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": {
|
||||
"en-us": "Decoder programming"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "S88"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": {
|
||||
"en-us": "Operating system",
|
||||
},
|
||||
"columns": [
|
||||
{
|
||||
"label": "Windows"
|
||||
},
|
||||
{
|
||||
"label": "Linux"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"rows": [
|
||||
[
|
||||
{
|
||||
"text": "Digikeijs DR5000"
|
||||
},
|
||||
{
|
||||
"text": "LAN/Z21"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
"icon": "x_red"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"text": "Roco 10764"
|
||||
},
|
||||
{
|
||||
"text": "XpressNet"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
"icon": "x_red"
|
||||
},
|
||||
{
|
||||
"label": "-"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"text": "Roco/Fleischmann Z21"
|
||||
},
|
||||
{
|
||||
"text": "LAN/Z21"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
"icon": "x_red"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"text": "Uhlenbrock Intellibox (IB)"
|
||||
},
|
||||
[
|
||||
{
|
||||
"text": {
|
||||
"en-us": "Serial/P50X",
|
||||
"nl-nl": "Serieel/P50X"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Loconet"
|
||||
}
|
||||
],
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
"icon": "x_red"
|
||||
},
|
||||
[
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
"icon": "questionmark_blue"
|
||||
}
|
||||
]
|
||||
[
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"icon": "checkmark_green"
|
||||
},
|
||||
{
|
||||
}
|
||||
]
|
||||
]
|
||||
],
|
||||
"footnotes": {
|
||||
"1": ""
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1 +1,5 @@
|
||||
= Command line options
|
||||
# Command line options
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
15
doc/en-us/commandstations.md
Normale Datei
15
doc/en-us/commandstations.md
Normale Datei
@ -0,0 +1,15 @@
|
||||
# Command stations
|
||||
|
||||
|
||||
|
||||
## Supported command stations
|
||||
|
||||
{table:supportedcommandstations}
|
||||
|
||||
### Loconet
|
||||
|
||||
|
||||
|
||||
### XpressNet
|
||||
|
||||
|
||||
1
doc/en-us/decoder.md
Normale Datei
1
doc/en-us/decoder.md
Normale Datei
@ -0,0 +1 @@
|
||||
# Decoder
|
||||
1
doc/en-us/decoderfunction.md
Normale Datei
1
doc/en-us/decoderfunction.md
Normale Datei
@ -0,0 +1 @@
|
||||
# Decoder function
|
||||
2
doc/en-us/dr5000.md
Normale Datei
2
doc/en-us/dr5000.md
Normale Datei
@ -0,0 +1,2 @@
|
||||
# Digikeijs DR5000
|
||||
|
||||
@ -1 +1 @@
|
||||
= Getting started
|
||||
# Getting started
|
||||
|
||||
3
doc/en-us/hardware.md
Normale Datei
3
doc/en-us/hardware.md
Normale Datei
@ -0,0 +1,3 @@
|
||||
# Hardware
|
||||
- [objects/hardware/commandstations.md](Command stations)
|
||||
- [objects/hardware/decoders.md](Decoders)
|
||||
2
doc/en-us/index.md
Normale Datei
2
doc/en-us/index.md
Normale Datei
@ -0,0 +1,2 @@
|
||||
# Traintastic manual
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
= Installation
|
||||
# Installation
|
||||
|
||||
== Windows
|
||||
## Windows
|
||||
|
||||
== Linux
|
||||
## Linux
|
||||
|
||||
2
doc/en-us/intellibox.md
Normale Datei
2
doc/en-us/intellibox.md
Normale Datei
@ -0,0 +1,2 @@
|
||||
# Uhlenbrock Intellibox
|
||||
|
||||
@ -1 +1 @@
|
||||
= Lua scripting
|
||||
# Lua scripting
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
= Objects
|
||||
|
||||
== Hardware
|
||||
- [objects/hardware/commandstations.md](Command stations)
|
||||
- [objects/hardware/decoders.md](Decoders)
|
||||
@ -1,2 +0,0 @@
|
||||
= Command stations
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
= Digikeijs DR5000
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
= Roco/Fleischmann Z21
|
||||
|
||||
@ -1 +0,0 @@
|
||||
= Decoder
|
||||
@ -1 +0,0 @@
|
||||
= Decoder function
|
||||
2
doc/en-us/z21.md
Normale Datei
2
doc/en-us/z21.md
Normale Datei
@ -0,0 +1,2 @@
|
||||
# Roco/Fleischmann Z21
|
||||
|
||||
13
doc/en-us/z21app.md
Normale Datei
13
doc/en-us/z21app.md
Normale Datei
@ -0,0 +1,13 @@
|
||||
# Z21 app
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Known issues
|
||||
1. Locomotive status updates slow.
|
||||
Reason: If the traintastic-server is restarted or the Z21 app controller is temparary deacribated, it looses the client registtation ans it will no longer receive update.
|
||||
Solution: Restart the Z21 app on your phone/tablet, the it wil re-register and everything should work as expected.
|
||||
|
||||
|
||||
35
doc/gfx/traintastic-logo-white.svg
Normale Datei
35
doc/gfx/traintastic-logo-white.svg
Normale Datei
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="172.0002"
|
||||
width="172.0002"
|
||||
viewBox="-15 -190 172.0002 172.0002"
|
||||
version="1.1"
|
||||
id="ProfielUIC60E2">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<desc
|
||||
id="desc2">
|
||||
Op basis van 'Profilehandbuch_Section_Programme', van VoestAlpine Schienen GMBH
|
||||
</desc>
|
||||
<path
|
||||
d="m -1.9999008,-190 a 2,2 0 0 0 -2,2 v 5.81552 a 4,4 0 0 0 3.71501198,3.98984 l 15.73981082,1.12427 a 40,40 0 0 1 10.819841,2.30661 l 28.223767,10.26319 a 7,7 0 0 1 4.263605,4.41055 35,35 0 0 1 0.7875,2.81061 120,120 0 0 1 3.200464,27.52941 v 32.000001 a 120,120 0 0 1 -3.200465,27.529412 35,35 0 0 1 -0.787499,2.810609 7,7 0 0 1 -4.263605,4.41055 l -18.576167,6.75497 a 3,3 0 0 0 -1.971027,2.969193 l 1.048763,20.975266 a 13,13 0 0 0 9.972669,11.99639 80,80 0 0 0 15.799331,2.129409 300,300 0 0 0 20.456,0 80,80 0 0 0 15.79933,-2.129409 13,13 0 0 0 9.972671,-11.99639 l 1.04876,-20.975266 a 3,3 0 0 0 -1.97102,-2.969193 l -18.576172,-6.75497 a 7,7 0 0 1 -4.263605,-4.41055 35,35 0 0 1 -0.7875,-2.810609 120,120 0 0 1 -3.200464,-27.529412 V -129.75 a 120,120 0 0 1 3.200464,-27.52941 35,35 0 0 1 0.7875,-2.81061 7,7 0 0 1 4.263605,-4.41055 l 28.223772,-10.26319 a 40,40 0 0 1 10.81984,-2.30661 l 15.73981,-1.12427 a 4,4 0 0 0 3.71501,-3.98984 V -188 a 2,2 0 0 0 -2,-2 z"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="Profiel" />
|
||||
</svg>
|
||||
|
Nachher Breite: | Höhe: | Größe: 1.9 KiB |
7
doc/js/bootstrap.min.js
vendored
Normale Datei
7
doc/js/bootstrap.min.js
vendored
Normale Datei
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
2
doc/js/jquery-3.4.1.slim.min.js
vendored
Normale Datei
2
doc/js/jquery-3.4.1.slim.min.js
vendored
Normale Datei
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
5
doc/js/popper.min.js
vendored
Normale Datei
5
doc/js/popper.min.js
vendored
Normale Datei
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
10
doc/template/footer.html
vendored
Normale Datei
10
doc/template/footer.html
vendored
Normale Datei
@ -0,0 +1,10 @@
|
||||
</div>
|
||||
<div id="footer" class="text-center text-light bg-dark py-2">
|
||||
<small>Copyright © 2019-${year}</small>
|
||||
</div>
|
||||
</div>
|
||||
<script src="${js_path}jquery-3.4.1.slim.min.js"></script>
|
||||
<script src="${js_path}popper.min.js"></script>
|
||||
<script src="${js_path}bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
41
doc/template/header.html
vendored
Normale Datei
41
doc/template/header.html
vendored
Normale Datei
@ -0,0 +1,41 @@
|
||||
<!doctype html>
|
||||
<html lang="${language}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="${css_path}bootstrap.min.css">
|
||||
<link rel="stylesheet" href="${css_path}traintastic-manual.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-dark bg-dark navbar-expand-lg">
|
||||
<a class="navbar-brand" href="/"><img src="${gfx_path}traintastic-logo-white.svg" width="30" height="30" class="d-inline-block align-top" alt=""> Traintastic ${nav_manual}</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<!--div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item"><a class="nav-link" href="/usb-xpressnet-interface">USB XpressNet interface</a></li>
|
||||
</ul>
|
||||
</div-->
|
||||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-item nav-link dropdown-toggle mr-md-2" href="#" id="languages" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
${language}
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="languages">
|
||||
${language_menu}
|
||||
</div>
|
||||
</li>
|
||||
<!-- VERSION_BEGIN -->
|
||||
<li class="navbar-text">
|
||||
v?.?.?
|
||||
</li>
|
||||
<!-- VERSION_END -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://github.com/traintastic/traintastic" target="_blank" rel="noopener" aria-label="GitHub"><svg class="navbar-nav-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.36" focusable="false"><title>GitHub</title><path d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z" fill="currentColor" fill-rule="evenodd"></path></svg></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div id="body">
|
||||
<div id="content">
|
||||
@ -2,10 +2,12 @@
|
||||
|
||||
:address=Address
|
||||
:command_station=Command station
|
||||
:controllers=Controllers
|
||||
:emergency_stop=Emergency stop
|
||||
:id=Id
|
||||
:name=Name
|
||||
:notes=Notes
|
||||
:track_power=Track power
|
||||
|
||||
clock:day=Day
|
||||
clock:hour=Hour
|
||||
@ -14,7 +16,9 @@ clock:month=Month
|
||||
clock:multiplier=Multiplier
|
||||
clock:year=Year
|
||||
|
||||
decoder_function_list:add=Add
|
||||
decoder_function_list:add=Add function
|
||||
|
||||
decoder_list:add=Add
|
||||
|
||||
hardware.command_station.li10x:baudrate=Baudrate
|
||||
hardware.command_station.li10x:decoders=Decoders
|
||||
@ -46,6 +50,11 @@ hardware.command_station.z21:vcc_voltage=VCC voltage
|
||||
hardware.command_station:online=Online
|
||||
hardware.command_station:status=Status
|
||||
|
||||
hardware.controller.z21_app:active=Active
|
||||
hardware.controller.z21_app:port=Port
|
||||
|
||||
hardware.controller:active=Active
|
||||
|
||||
hardware.decoder:direction=Direction
|
||||
hardware.decoder:functions=Functions
|
||||
hardware.decoder:protocol=Protocol
|
||||
|
||||
@ -14,6 +14,8 @@ clock:month=Maand
|
||||
clock:multiplier=Vermenigvuldiger
|
||||
clock:year=Jaar
|
||||
|
||||
decoder_function_list:add=Functie toevoegen
|
||||
|
||||
hardware.command_station.li10x:baudrate=Baudrate
|
||||
hardware.command_station.li10x:decoders=Decoders
|
||||
hardware.command_station.li10x:online=Online
|
||||
|
||||
@ -28,6 +28,8 @@ file(GLOB SOURCES
|
||||
"src/enum/*.hpp"
|
||||
"src/hardware/commandstation/*.hpp"
|
||||
"src/hardware/commandstation/*.cpp"
|
||||
"src/hardware/controller/*.hpp"
|
||||
"src/hardware/controller/*.cpp"
|
||||
"src/hardware/decoder/*.hpp"
|
||||
"src/hardware/decoder/*.cpp"
|
||||
"src/hardware/input/*.hpp"
|
||||
@ -37,6 +39,7 @@ file(GLOB SOURCES
|
||||
"src/lua/*.hpp"
|
||||
"src/lua/*.cpp"
|
||||
"src/utils/*.hpp"
|
||||
"src/utils/*.cpp"
|
||||
"thirdparty/boost/libs/program_options/src/*.cpp")
|
||||
|
||||
add_executable(traintastic-server ${SOURCES})
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
@ -22,8 +22,8 @@
|
||||
|
||||
#include "clock.hpp"
|
||||
|
||||
Clock::Clock(Object& parent, const std::string& parentPropertyName) :
|
||||
SubObject(parent, parentPropertyName),
|
||||
Clock::Clock(Object& _parent, const std::string& parentPropertyName) :
|
||||
SubObject(_parent, parentPropertyName),
|
||||
year{this, "year", 2020, PropertyFlags::ReadWrite | PropertyFlags::StoreState},
|
||||
month{this, "month", 1, PropertyFlags::ReadWrite | PropertyFlags::StoreState},
|
||||
day{this, "day", 1, PropertyFlags::ReadWrite | PropertyFlags::StoreState},
|
||||
|
||||
@ -39,7 +39,7 @@ class Clock : public SubObject
|
||||
|
||||
Property<uint16_t> multiplier;
|
||||
|
||||
Clock(Object& parent, const std::string& parentPropertyName);
|
||||
Clock(Object& _parent, const std::string& parentPropertyName);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Traintastic
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra <reinderfeenstra@gmail.com>
|
||||
* 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
|
||||
@ -20,12 +20,13 @@
|
||||
|
||||
#include "idobject.hpp"
|
||||
#include "traintastic.hpp"
|
||||
#include "console.hpp"
|
||||
#include "world.hpp"
|
||||
|
||||
IdObject::IdObject(const std::weak_ptr<World> world, const std::string& _id) :
|
||||
IdObject::IdObject(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
Object{},
|
||||
m_world{world},
|
||||
id{this, "id", _id, PropertyFlags::ReadWrite | PropertyFlags::Store, nullptr,
|
||||
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;
|
||||
@ -37,8 +38,11 @@ IdObject::IdObject(const std::weak_ptr<World> world, const std::string& _id) :
|
||||
return true;
|
||||
}}
|
||||
{
|
||||
auto w = world.lock();
|
||||
const bool editable = w && contains(w->state.value(), WorldState::Edit);
|
||||
|
||||
m_interfaceItems.add(id)
|
||||
.addAttributeEnabled(false);
|
||||
.addAttributeEnabled(editable);
|
||||
}
|
||||
|
||||
IdObject::~IdObject()
|
||||
@ -59,3 +63,38 @@ void IdObject::worldEvent(WorldState state, WorldEvent event)
|
||||
|
||||
id.setAttributeEnabled(contains(state, WorldState::Edit));
|
||||
}
|
||||
|
||||
void IdObject::logDebug(const std::string& message)
|
||||
{
|
||||
Traintastic::instance->console->debug(id, message);
|
||||
}
|
||||
|
||||
void IdObject::logInfo(const std::string& message)
|
||||
{
|
||||
Traintastic::instance->console->info(id, message);
|
||||
}
|
||||
|
||||
void IdObject::logNotice(const std::string& message)
|
||||
{
|
||||
Traintastic::instance->console->notice(id, message);
|
||||
}
|
||||
|
||||
void IdObject::logWarning(const std::string& message)
|
||||
{
|
||||
Traintastic::instance->console->warning(id, message);
|
||||
}
|
||||
|
||||
void IdObject::logError(const std::string& message)
|
||||
{
|
||||
Traintastic::instance->console->error(id, message);
|
||||
}
|
||||
|
||||
void IdObject::logCritical(const std::string& message)
|
||||
{
|
||||
Traintastic::instance->console->critical(id, message);
|
||||
}
|
||||
|
||||
void IdObject::logFatal(const std::string& message)
|
||||
{
|
||||
Traintastic::instance->console->fatal(id, message);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -28,7 +28,7 @@
|
||||
#include <enum/traintasticmode.hpp>
|
||||
|
||||
#define CREATE(T) \
|
||||
static std::shared_ptr<T> create(const std::weak_ptr<World>& world, const std::string& _id) \
|
||||
static std::shared_ptr<T> create(const std::weak_ptr<World>& world, std::string_view _id) \
|
||||
{ \
|
||||
auto obj = std::make_shared<T>(world, _id); \
|
||||
obj->addToWorld(); \
|
||||
@ -42,10 +42,18 @@ class IdObject : public Object
|
||||
protected:
|
||||
std::weak_ptr<World> m_world;
|
||||
|
||||
IdObject(const std::weak_ptr<World> world, const std::string& _id);
|
||||
IdObject(const std::weak_ptr<World>& world, std::string_view _id);
|
||||
virtual void addToWorld();
|
||||
void worldEvent(WorldState state, WorldEvent event) override;
|
||||
|
||||
void logDebug(const std::string& message);
|
||||
void logInfo(const std::string& message);
|
||||
void logNotice(const std::string& message);
|
||||
void logWarning(const std::string& message);
|
||||
void logError(const std::string& message);
|
||||
void logCritical(const std::string& message);
|
||||
void logFatal(const std::string& message);
|
||||
|
||||
public:
|
||||
Property<std::string> id;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -57,6 +57,12 @@ class Object : public std::enable_shared_from_this<Object>
|
||||
Object();
|
||||
virtual ~Object();
|
||||
|
||||
template <typename Derived>
|
||||
inline std::shared_ptr<const Derived> shared_ptr() const
|
||||
{
|
||||
return std::static_pointer_cast<const Derived>(shared_from_this());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
std::shared_ptr<Derived> shared_ptr()
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -59,8 +59,8 @@ class ObjectList : public SubObject, public Table
|
||||
public:
|
||||
Property<uint32_t> length;
|
||||
|
||||
ObjectList(Object& parent, const std::string& parentPropertyName) :
|
||||
SubObject{parent, parentPropertyName},
|
||||
ObjectList(Object& _parent, const std::string& parentPropertyName) :
|
||||
SubObject{_parent, parentPropertyName},
|
||||
length{this, "length", 0, PropertyFlags::ReadOnly}
|
||||
{
|
||||
}
|
||||
@ -80,7 +80,7 @@ class ObjectList : public SubObject, public Table
|
||||
return m_items[index];
|
||||
}
|
||||
|
||||
void add(const std::shared_ptr<T>& object)
|
||||
void addObject(const std::shared_ptr<T>& object)
|
||||
{
|
||||
m_items.push_back(object);
|
||||
m_propertyChanged.emplace(object.get(), object->propertyChanged.connect(
|
||||
@ -102,7 +102,7 @@ class ObjectList : public SubObject, public Table
|
||||
rowCountChanged();
|
||||
}
|
||||
|
||||
void remove(const std::shared_ptr<T>& object)
|
||||
void removeObject(const std::shared_ptr<T>& object)
|
||||
{
|
||||
auto it = std::find(m_items.begin(), m_items.end(), object);
|
||||
if(it != m_items.end())
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Traintastic
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra <reinderfeenstra@gmail.com>
|
||||
* 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
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
#include "output.hpp"
|
||||
|
||||
Output::Output(const std::weak_ptr<World> world, const std::string& _id) :
|
||||
Output::Output(const std::weak_ptr<World> world, std::string_view _id) :
|
||||
IdObject{world, _id},
|
||||
value{this, "value", false, PropertyFlags::ReadWrite, std::bind(&Output::valueChanged, this, std::placeholders::_1), std::bind(&Output::setValue, this, std::placeholders::_1)}
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -34,7 +34,7 @@ class Output : public IdObject
|
||||
public:
|
||||
Property<bool> value;
|
||||
|
||||
Output(const std::weak_ptr<World> world, const std::string& _id);
|
||||
Output(const std::weak_ptr<World> world, std::string_view _id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -53,7 +53,7 @@ bool Session::processMessage(const Message& message)
|
||||
{
|
||||
switch(message.command())
|
||||
{
|
||||
case Message::Command::CreateObject:
|
||||
/*case Message::Command::CreateObject:
|
||||
{
|
||||
std::string classId;
|
||||
std::string id;
|
||||
@ -73,7 +73,7 @@ bool Session::processMessage(const Message& message)
|
||||
m_client->sendMessage(Message::newErrorResponse(message.command(), message.requestId(), Message::ErrorCode::UnknownClassId));
|
||||
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
case Message::Command::GetObject:
|
||||
{
|
||||
std::string id;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
@ -24,9 +24,9 @@
|
||||
#include "idobject.hpp"
|
||||
#include "world.hpp"
|
||||
|
||||
SubObject::SubObject(Object &parent, const std::string &parentPropertyName) :
|
||||
SubObject::SubObject(Object& _parent, const std::string& parentPropertyName) :
|
||||
Object(),
|
||||
m_parent{parent},
|
||||
m_parent{_parent},
|
||||
m_parentPropertyName{parentPropertyName}
|
||||
{
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
@ -32,7 +32,7 @@ class SubObject : public Object
|
||||
const std::string& m_parentPropertyName;
|
||||
|
||||
public:
|
||||
SubObject(Object& parent, const std::string& parentPropertyName);
|
||||
SubObject(Object& _parent, const std::string& parentPropertyName);
|
||||
|
||||
Object& parent() const { return m_parent; }
|
||||
std::string id() const;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -31,6 +31,7 @@
|
||||
#include "client.hpp"
|
||||
#include "world.hpp"
|
||||
#include "worldlist.hpp"
|
||||
#include "worldloader.hpp"
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
@ -202,7 +203,8 @@ void Traintastic::loadWorld(const std::filesystem::path& path)
|
||||
{
|
||||
try
|
||||
{
|
||||
world = World::load(path / "traintastic.json");
|
||||
world = WorldLoader(path / "traintastic.json").world();
|
||||
//World::load(path / "traintastic.json");
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include <boost/uuid/string_generator.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include "traintastic.hpp"
|
||||
#include "worldsaver.hpp"
|
||||
|
||||
|
||||
|
||||
@ -36,6 +37,7 @@
|
||||
|
||||
#include "../hardware/input/loconetinput.hpp"
|
||||
#include "../hardware/decoder/decoder.hpp"
|
||||
#include "../hardware/controller/z21app.hpp"
|
||||
|
||||
|
||||
using nlohmann::json;
|
||||
@ -62,6 +64,7 @@ void World::init(const std::shared_ptr<World>& world)
|
||||
world->commandStations.setValueInternal(std::make_shared<CommandStationList>(*world, world->commandStations.name()));
|
||||
world->decoders.setValueInternal(std::make_shared<DecoderList>(*world, world->decoders.name()));
|
||||
world->inputs.setValueInternal(std::make_shared<InputList>(*world, world->inputs.name()));
|
||||
world->controllers.setValueInternal(std::make_shared<ControllerList>(*world, world->controllers.name()));
|
||||
world->clock.setValueInternal(std::make_shared<Clock>(*world, world->clock.name()));
|
||||
world->luaScripts.setValueInternal(std::make_shared<Lua::ScriptList>(*world, world->luaScripts.name()));
|
||||
}
|
||||
@ -74,6 +77,7 @@ World::World() :
|
||||
commandStations{this, "command_stations", nullptr, PropertyFlags::ReadOnly | PropertyFlags::SubObject},
|
||||
decoders{this, "decoders", nullptr, PropertyFlags::ReadOnly | PropertyFlags::SubObject},
|
||||
inputs{this, "inputs", nullptr, PropertyFlags::ReadOnly | PropertyFlags::SubObject},
|
||||
controllers{this, "controllers", nullptr, PropertyFlags::ReadOnly | PropertyFlags::SubObject},
|
||||
clock{this, "clock", nullptr, PropertyFlags::ReadOnly | PropertyFlags::SubObject},
|
||||
luaScripts{this, "lua_scripts", nullptr, PropertyFlags::ReadOnly | PropertyFlags::SubObject},
|
||||
state{this, "state", WorldState::TrackPowerOff, PropertyFlags::ReadOnly},
|
||||
@ -116,6 +120,18 @@ World::World() :
|
||||
save{*this, "save",
|
||||
[this]()
|
||||
{
|
||||
try
|
||||
{
|
||||
WorldSaver saver(*this);
|
||||
Traintastic::instance->console->notice(classId, "Saved world " + name.value());
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
Traintastic::instance->console->critical(classId, std::string("Saving world failed: ").append(e.what()));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
json objects = json::array();
|
||||
for(auto& it : m_objects)
|
||||
if(ObjectPtr object = it.second.lock())
|
||||
@ -134,6 +150,7 @@ World::World() :
|
||||
}
|
||||
else
|
||||
Traintastic::instance->console->critical(classId, "Can't write to world file");
|
||||
*/
|
||||
}}
|
||||
{
|
||||
m_interfaceItems.add(name);
|
||||
@ -142,6 +159,7 @@ World::World() :
|
||||
m_interfaceItems.add(commandStations);
|
||||
m_interfaceItems.add(decoders);
|
||||
m_interfaceItems.add(inputs);
|
||||
m_interfaceItems.add(controllers);
|
||||
m_interfaceItems.add(clock);
|
||||
m_interfaceItems.add(luaScripts);
|
||||
|
||||
@ -172,14 +190,14 @@ std::string World::getUniqueId(const std::string& prefix) const
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
ObjectPtr World::createObject(const std::string& classId, const std::string& _id)
|
||||
/*
|
||||
ObjectPtr World::createObject(const std::string& classId, std::string_view _id)
|
||||
{
|
||||
if(classId == Hardware::Decoder::classId)
|
||||
return std::dynamic_pointer_cast<Object>(Hardware::Decoder::create(shared_ptr<World>(), getUniqueId("decoder")));
|
||||
else
|
||||
return ObjectPtr();
|
||||
}
|
||||
}*/
|
||||
|
||||
bool World::isObject(const std::string& _id) const
|
||||
{
|
||||
@ -202,6 +220,7 @@ ObjectPtr World::getObject(const std::string& _id) const
|
||||
void World::event(WorldEvent event)
|
||||
{
|
||||
const WorldState st = state;
|
||||
worldEvent(st, event);
|
||||
for(auto& it : m_objects)
|
||||
it.second.lock()->worldEvent(st, event);
|
||||
}
|
||||
@ -211,9 +230,12 @@ void World::load()
|
||||
std::ifstream file(m_filename);
|
||||
if(file.is_open())
|
||||
{
|
||||
json world = json::parse(file);
|
||||
m_uuid = boost::uuids::string_generator()(std::string(world["uuid"]));
|
||||
name = world[name.name()];
|
||||
json data = json::parse(file);
|
||||
m_uuid = boost::uuids::string_generator()(std::string(data["uuid"]));
|
||||
name = data[name.name()];
|
||||
|
||||
json objects = data["objects"];
|
||||
|
||||
|
||||
|
||||
|
||||
@ -227,7 +249,7 @@ void World::load()
|
||||
|
||||
std::weak_ptr<World> w = shared_ptr<World>();
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
auto cs = Hardware::CommandStation::Z21::create(w, "cs1");
|
||||
//cs->hostname = "192.168.1.2";
|
||||
cs->hostname = "192.168.16.254";
|
||||
@ -250,7 +272,7 @@ void World::load()
|
||||
#endif
|
||||
cs->xpressnet->commandStation = XpressNetCommandStation::Roco10764;
|
||||
#endif
|
||||
commandStations->add(cs);
|
||||
commandStations->addObject(cs);
|
||||
|
||||
|
||||
{
|
||||
@ -309,22 +331,22 @@ void World::load()
|
||||
dec->address = 3311;
|
||||
dec->longAddress = true;
|
||||
dec->speedSteps = 126;
|
||||
|
||||
for(int i = 0; i <= 20; i++)
|
||||
dec->functions->add();
|
||||
/*
|
||||
{
|
||||
auto f = Hardware::DecoderFunction::create(*dec, "dec_br211_f0");
|
||||
auto f = dec->functions->add();
|
||||
f->number = 0;
|
||||
f->name = "Light";
|
||||
dec->functions->add(f);
|
||||
f->m_decoder = dec.get();
|
||||
}
|
||||
|
||||
{
|
||||
auto f = Hardware::DecoderFunction::create(w, "dec_br211_f1");
|
||||
auto f = dec->functions->add();
|
||||
f->number = 1;
|
||||
f->name = "Sound";
|
||||
dec->functions->add(f);
|
||||
f->m_decoder = dec.get();
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//cs->online = true;
|
||||
@ -362,11 +384,16 @@ void World::load()
|
||||
" console.debug(event)\n"
|
||||
" console.debug(event == enum.world_event.TRACK_POWER_ON)\n"
|
||||
"end\n";
|
||||
luaScripts->add(script);
|
||||
luaScripts->addObject(script);
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
auto z21app = Hardware::Controller::Z21App::create(w, "z21app");
|
||||
z21app->commandStation = cs;
|
||||
z21app->active = true;
|
||||
controllers->addObject(z21app);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -383,6 +410,9 @@ json World::saveObject(const ObjectPtr& object)
|
||||
|
||||
objectData["class_id"] = object->getClassId();
|
||||
|
||||
if(Hardware::DecoderFunction* function = dynamic_cast<Hardware::DecoderFunction*>(object.get()))
|
||||
objectData["decoder"] = function->decoder().id.toJSON();
|
||||
|
||||
for(auto& item : object->interfaceItems())
|
||||
if(AbstractProperty* property = dynamic_cast<AbstractProperty*>(&item.second))
|
||||
{
|
||||
|
||||
@ -37,14 +37,19 @@
|
||||
#include "../hardware/commandstation/commandstationlist.hpp"
|
||||
#include "../hardware/decoder/decoderlist.hpp"
|
||||
#include "../hardware/input/inputlist.hpp"
|
||||
#include "../hardware/controller/controllerlist.hpp"
|
||||
#include "../lua/scriptlist.hpp"
|
||||
//class CommandStationList;
|
||||
//class DecoderList;
|
||||
|
||||
class WorldLoader;
|
||||
|
||||
class World : public Object
|
||||
{
|
||||
friend class IdObject;
|
||||
friend class Traintastic;
|
||||
friend class WorldLoader;
|
||||
friend class WorldSaver;
|
||||
|
||||
protected:
|
||||
static void init(const std::shared_ptr<World>& world);
|
||||
@ -70,6 +75,7 @@ class World : public Object
|
||||
ObjectProperty<CommandStationList> commandStations;
|
||||
ObjectProperty<DecoderList> decoders;
|
||||
ObjectProperty<InputList> inputs;
|
||||
ObjectProperty<ControllerList> controllers;
|
||||
ObjectProperty<Clock> clock;
|
||||
ObjectProperty<Lua::ScriptList> luaScripts;
|
||||
|
||||
@ -87,8 +93,8 @@ class World : public Object
|
||||
const boost::uuids::uuid& uuid() const { return m_uuid; }
|
||||
|
||||
std::string getUniqueId(const std::string& prefix) const;
|
||||
ObjectPtr createObject(const std::string& classId, const std::string& _id = "");
|
||||
bool isObject(const std::string& _id) const;
|
||||
//ObjectPtr createObject(const std::string& classId, std::string_view _id = "");
|
||||
bool isObject(const std::string&_id) const;
|
||||
ObjectPtr getObject(const std::string& _id) const;
|
||||
};
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
102
server/src/core/worldloader.cpp
Normale Datei
102
server/src/core/worldloader.cpp
Normale Datei
@ -0,0 +1,102 @@
|
||||
#include "worldloader.hpp"
|
||||
#include <fstream>
|
||||
#include <boost/uuid/string_generator.hpp>
|
||||
#include "world.hpp"
|
||||
|
||||
#include "../hardware/commandstation/li10x.hpp"
|
||||
#include "../hardware/commandstation/usbxpressnetinterface.hpp"
|
||||
#include "../hardware/commandstation/z21.hpp"
|
||||
#include "../hardware/controller/z21app.hpp"
|
||||
#include "../hardware/decoder/decoder.hpp"
|
||||
#include "../hardware/decoder/decoderfunction.hpp"
|
||||
#include "../lua/script.hpp"
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
WorldLoader::WorldLoader(const std::filesystem::path& filename) :
|
||||
m_world{World::create()}
|
||||
{
|
||||
std::ifstream file(filename);
|
||||
if(!file.is_open())
|
||||
throw std::runtime_error("can't open " + filename.string());
|
||||
|
||||
json data = json::parse(file);;
|
||||
|
||||
m_world->m_filename = filename;
|
||||
m_world->m_uuid = boost::uuids::string_generator()(std::string(data["uuid"]));
|
||||
m_world->name = data[m_world->name.name()];
|
||||
|
||||
// create a list of all objects
|
||||
for(json object : data["objects"])
|
||||
{
|
||||
if(auto it = object.find("id"); it != object.end())
|
||||
m_objects.insert({it.value().get<std::string>(), {object, nullptr, false}});
|
||||
else
|
||||
throw std::runtime_error("id missing");
|
||||
}
|
||||
|
||||
// then create all objects
|
||||
for(auto& it : m_objects)
|
||||
if(!it.second.object)
|
||||
createObject(it.second);
|
||||
|
||||
// and finally load their data
|
||||
for(auto& it : m_objects)
|
||||
if(!it.second.loaded)
|
||||
loadObject(it.second);
|
||||
}
|
||||
|
||||
void WorldLoader::createObject(ObjectData& objectData)
|
||||
{
|
||||
assert(!objectData.object);
|
||||
|
||||
std::string_view classId = objectData.json["class_id"];
|
||||
std::string_view id = objectData.json["id"];
|
||||
|
||||
// TODO some kind of class list !!
|
||||
if(classId == Hardware::CommandStation::LI10x::classId)
|
||||
objectData.object = Hardware::CommandStation::LI10x::create(m_world, id);
|
||||
else if(classId == Hardware::CommandStation::USBXpressNetInterface::classId)
|
||||
objectData.object = Hardware::CommandStation::USBXpressNetInterface::create(m_world, id);
|
||||
else if(classId == Hardware::CommandStation::Z21::classId)
|
||||
objectData.object = Hardware::CommandStation::Z21::create(m_world, id);
|
||||
else if(classId == Hardware::Controller::Z21App::classId)
|
||||
objectData.object = Hardware::Controller::Z21App::create(m_world, id);
|
||||
else if(classId == Hardware::Decoder::classId)
|
||||
objectData.object = Hardware::Decoder::create(m_world, id);
|
||||
else if(classId == Lua::Script::classId)
|
||||
objectData.object = Lua::Script::create(m_world, id);
|
||||
else if(classId == Hardware::DecoderFunction::classId)
|
||||
{
|
||||
//objectData.object = Hardware::Decoder::create(m_world, id);
|
||||
}
|
||||
|
||||
if(!objectData.object)
|
||||
{};//m_objects.insert(id, object);
|
||||
}
|
||||
|
||||
void WorldLoader::loadObject(ObjectData& objectData)
|
||||
{
|
||||
/*assert*/if(!objectData.object)return;
|
||||
assert(!objectData.loaded);
|
||||
|
||||
Object& object = *objectData.object;
|
||||
for(auto& [name, value] : objectData.json.items())
|
||||
if(AbstractProperty* property = object.getProperty(name))
|
||||
if(property->type() == ValueType::Object)
|
||||
{
|
||||
//hier voor objecten wat anders doen
|
||||
}
|
||||
else
|
||||
property->fromJSON(value);
|
||||
|
||||
objectData.loaded = true;
|
||||
//objectData.object->loaded();
|
||||
}
|
||||
|
||||
/*
|
||||
std::shared_ptr<Object> WorldLoader::getObject(std::string_view id)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
36
server/src/core/worldloader.hpp
Normale Datei
36
server/src/core/worldloader.hpp
Normale Datei
@ -0,0 +1,36 @@
|
||||
#ifndef WORLDLOADER_HPP
|
||||
#define WOLRDLOADER_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "stdfilesystem.hpp"
|
||||
|
||||
class Object;
|
||||
class World;
|
||||
|
||||
class WorldLoader
|
||||
{
|
||||
private:
|
||||
struct ObjectData
|
||||
{
|
||||
nlohmann::json json;
|
||||
std::shared_ptr<Object> object;
|
||||
bool loaded;
|
||||
};
|
||||
|
||||
std::shared_ptr<World> m_world;
|
||||
std::unordered_map<std::string, ObjectData> m_objects;
|
||||
|
||||
void createObject(ObjectData& objectData);
|
||||
void loadObject(ObjectData& objectData);
|
||||
|
||||
public:
|
||||
WorldLoader(const std::filesystem::path& filename);
|
||||
|
||||
std::shared_ptr<World> world() { return m_world; }
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
69
server/src/core/worldsaver.cpp
Normale Datei
69
server/src/core/worldsaver.cpp
Normale Datei
@ -0,0 +1,69 @@
|
||||
#include "worldsaver.hpp"
|
||||
#include <fstream>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include "world.hpp"
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
WorldSaver::WorldSaver(const World& world)
|
||||
{
|
||||
json objects = json::array();
|
||||
for(auto& it : world.m_objects)
|
||||
if(ObjectPtr object = it.second.lock())
|
||||
objects.push_back(saveObject(object));
|
||||
|
||||
json data;
|
||||
data["uuid"] = to_string(world.m_uuid);
|
||||
data[world.name.name()] = world.name.value();
|
||||
data[world.scale.name()] = world.scale.value();
|
||||
data["objects"] = objects;
|
||||
|
||||
std::ofstream file(world.m_filename);
|
||||
if(file.is_open())
|
||||
{
|
||||
file << data.dump(2);
|
||||
//Traintastic::instance->console->notice(classId, "Saved world " + name.value());
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("file not open");
|
||||
//Traintastic::instance->console->critical(classId, "Can't write to world file");
|
||||
}
|
||||
|
||||
json WorldSaver::saveObject(const ObjectPtr& object)
|
||||
{
|
||||
json objectData;
|
||||
|
||||
objectData["class_id"] = object->getClassId();
|
||||
|
||||
if(Hardware::DecoderFunction* function = dynamic_cast<Hardware::DecoderFunction*>(object.get()))
|
||||
objectData["decoder"] = function->decoder().id.toJSON();
|
||||
|
||||
for(auto& item : object->interfaceItems())
|
||||
if(AbstractProperty* property = dynamic_cast<AbstractProperty*>(&item.second))
|
||||
{
|
||||
if(!property->isStoreable())
|
||||
continue;
|
||||
|
||||
if(property->type() == ValueType::Object)
|
||||
{
|
||||
if(ObjectPtr value = property->toObject())
|
||||
{
|
||||
if(IdObject* idObject = dynamic_cast<IdObject*>(value.get()))
|
||||
objectData[property->name()] = idObject->id.toJSON();
|
||||
else if(SubObject* subObject = dynamic_cast<SubObject*>(value.get()))
|
||||
{
|
||||
if((property->flags() & PropertyFlags::SubObject) == PropertyFlags::SubObject)
|
||||
objectData[property->name()] = saveObject(value);
|
||||
else
|
||||
objectData[property->name()] = subObject->id();
|
||||
}
|
||||
}
|
||||
else
|
||||
objectData[property->name()] = nullptr;
|
||||
}
|
||||
else
|
||||
objectData[property->name()] = property->toJSON();
|
||||
}
|
||||
|
||||
return objectData;
|
||||
}
|
||||
23
server/src/core/worldsaver.hpp
Normale Datei
23
server/src/core/worldsaver.hpp
Normale Datei
@ -0,0 +1,23 @@
|
||||
#ifndef WORLDSAVER_HPP
|
||||
#define WOLRDSAVER_HPP
|
||||
|
||||
//#include <memory>
|
||||
//#include <string>
|
||||
//#include <unordered_map>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "objectptr.hpp"
|
||||
//#include "stdfilesystem.hpp"
|
||||
|
||||
//class Object;
|
||||
class World;
|
||||
|
||||
class WorldSaver
|
||||
{
|
||||
private:
|
||||
nlohmann::json saveObject(const ObjectPtr& object);
|
||||
|
||||
public:
|
||||
WorldSaver(const World& world);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -29,9 +29,9 @@
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(DecoderProtocol,
|
||||
{
|
||||
{DecoderProtocol::None, "none"},
|
||||
{DecoderProtocol::DCC, "dcc"},
|
||||
{DecoderProtocol::Custom, "custom"},
|
||||
{DecoderProtocol::None, "NONE"},
|
||||
{DecoderProtocol::DCC, "DCC"},
|
||||
{DecoderProtocol::Custom, "CUSTOM"},
|
||||
})
|
||||
|
||||
LUA_ENUM_VALUES(DecoderProtocol, 3,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2020 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -21,6 +21,8 @@
|
||||
*/
|
||||
|
||||
#include "commandstation.hpp"
|
||||
#include "commandstationlist.hpp"
|
||||
#include "commandstationlisttablemodel.hpp"
|
||||
#include <functional>
|
||||
#include "../../core/world.hpp"
|
||||
#include "../decoder/decoder.hpp"
|
||||
@ -28,7 +30,7 @@
|
||||
|
||||
namespace Hardware::CommandStation {
|
||||
|
||||
CommandStation::CommandStation(const std::weak_ptr<World>& world, const std::string& _id) :
|
||||
CommandStation::CommandStation(const std::weak_ptr<World>& world, std::string_view _id) :
|
||||
IdObject(world, _id),
|
||||
name{this, "name", "", PropertyFlags::ReadWrite | PropertyFlags::Store},
|
||||
online{this, "online", false, PropertyFlags::ReadWrite | PropertyFlags::StoreState,
|
||||
@ -50,9 +52,11 @@ CommandStation::CommandStation(const std::weak_ptr<World>& world, const std::str
|
||||
trackVoltageOffChanged(value);
|
||||
}},
|
||||
decoders{this, "decoders", nullptr, PropertyFlags::ReadOnly | PropertyFlags::Store | PropertyFlags::SubObject},
|
||||
controllers{this, "controllers", nullptr, PropertyFlags::ReadOnly | PropertyFlags::Store | PropertyFlags::SubObject},
|
||||
notes{this, "notes", "", PropertyFlags::ReadWrite | PropertyFlags::Store}
|
||||
{
|
||||
decoders.setValueInternal(std::make_shared<DecoderList>(*this, decoders.name()));
|
||||
controllers.setValueInternal(std::make_shared<ControllerList>(*this, controllers.name()));
|
||||
|
||||
m_interfaceItems.add(name)
|
||||
.addAttributeEnabled(false);
|
||||
@ -64,17 +68,33 @@ CommandStation::CommandStation(const std::weak_ptr<World>& world, const std::str
|
||||
.addAttributeEnabled(false)
|
||||
.addAttributeObjectEditor(false);
|
||||
m_interfaceItems.add(decoders);
|
||||
m_interfaceItems.add(controllers);
|
||||
m_interfaceItems.add(notes);
|
||||
}
|
||||
|
||||
void CommandStation::addToWorld()
|
||||
{
|
||||
IdObject::addToWorld();
|
||||
|
||||
if(auto world = m_world.lock())
|
||||
world->commandStations->addObject(shared_ptr<CommandStation>());
|
||||
}
|
||||
|
||||
void CommandStation::worldEvent(WorldState state, WorldEvent event)
|
||||
{
|
||||
IdObject::worldEvent(state, event);
|
||||
|
||||
name.setAttributeEnabled(contains(state, WorldState::Edit));
|
||||
|
||||
if(event == WorldEvent::EmergencyStop)
|
||||
emergencyStop = true;
|
||||
else if(event == WorldEvent::TrackPowerOff)
|
||||
trackVoltageOff = true;
|
||||
else if(event == WorldEvent::TrackPowerOn)
|
||||
trackVoltageOff = false;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Decoder>& CommandStation::getDecoder(DecoderProtocol protocol, uint16_t address, bool longAddress) const
|
||||
const std::shared_ptr<Hardware::Decoder>& CommandStation::getDecoder(DecoderProtocol protocol, uint16_t address, bool longAddress) const
|
||||
{
|
||||
auto it = std::find_if(decoders->begin(), decoders->end(), [=](auto& decoder){ return decoder->protocol == protocol && decoder->address == address && decoder->longAddress == longAddress; });
|
||||
if(it != decoders->end())
|
||||
@ -82,4 +102,23 @@ const std::shared_ptr<Decoder>& CommandStation::getDecoder(DecoderProtocol proto
|
||||
return Decoder::null;
|
||||
}
|
||||
|
||||
void CommandStation::emergencyStopChanged(bool value)
|
||||
{
|
||||
for(auto& controller : *controllers)
|
||||
controller->emergencyStopChanged(value);
|
||||
}
|
||||
|
||||
void CommandStation::trackVoltageOffChanged(bool value)
|
||||
{
|
||||
for(auto& controller : *controllers)
|
||||
controller->trackPowerChanged(!value);
|
||||
}
|
||||
|
||||
void CommandStation::decoderChanged(const Hardware::Decoder& decoder, Hardware::DecoderChangeFlags changes, uint32_t functionNumber)
|
||||
{
|
||||
for(auto& controller : *controllers)
|
||||
controller->decoderChanged(decoder, changes, functionNumber);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -29,6 +29,7 @@
|
||||
#include <enum/decoderprotocol.hpp>
|
||||
|
||||
class DecoderList;
|
||||
class ControllerList;
|
||||
|
||||
namespace Hardware {
|
||||
class Decoder;
|
||||
@ -42,25 +43,27 @@ class CommandStation : public IdObject
|
||||
friend class ::Hardware::Decoder;
|
||||
|
||||
protected:
|
||||
void addToWorld() final;
|
||||
void worldEvent(WorldState state, WorldEvent event) override;
|
||||
|
||||
virtual bool setOnline(bool& value) = 0;
|
||||
virtual void emergencyStopChanged(bool value) = 0;
|
||||
virtual void trackVoltageOffChanged(bool value) = 0;
|
||||
virtual void emergencyStopChanged(bool value);
|
||||
virtual void trackVoltageOffChanged(bool value);
|
||||
//virtual bool isDecoderSupported(Decoder& decoder) const = 0;
|
||||
virtual void decoderChanged(const Decoder& decoder, DecoderChangeFlags changes, uint32_t functionNumber) = 0;
|
||||
|
||||
const std::shared_ptr<Decoder>& getDecoder(DecoderProtocol protocol, uint16_t address, bool longAddress) const;
|
||||
virtual void decoderChanged(const Hardware::Decoder& decoder, DecoderChangeFlags changes, uint32_t functionNumber);
|
||||
|
||||
public:
|
||||
CommandStation(const std::weak_ptr<World>& world, const std::string& _id);
|
||||
CommandStation(const std::weak_ptr<World>& world, std::string_view _id);
|
||||
|
||||
Property<std::string> name;
|
||||
Property<bool> online;
|
||||
Property<bool> emergencyStop;
|
||||
Property<bool> trackVoltageOff;
|
||||
ObjectProperty<DecoderList> decoders;
|
||||
ObjectProperty<ControllerList> controllers;
|
||||
Property<std::string> notes;
|
||||
|
||||
const std::shared_ptr<Hardware::Decoder>& getDecoder(DecoderProtocol protocol, uint16_t address, bool longAddress) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019 Reinder Feenstra
|
||||
* 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
|
||||
@ -25,8 +25,8 @@
|
||||
|
||||
using Hardware::CommandStation::CommandStation;
|
||||
|
||||
CommandStationList::CommandStationList(Object& parent, const std::string& parentPropertyName) :
|
||||
ObjectList<CommandStation>(parent, parentPropertyName)
|
||||
CommandStationList::CommandStationList(Object& _parent, const std::string& parentPropertyName) :
|
||||
ObjectList<CommandStation>(_parent, parentPropertyName)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren