diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index b71f98e..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - -project(trainController LANGUAGES CXX) - -add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index fae25ab..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Network SerialPort REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Network SerialPort REQUIRED) - -set(COMMON_SOURCES - ../common/microcontroller.cpp - ../common/microcontroller.h - ../common/items/item.cpp - ../common/items/item.h - ../common/items/itemstore.cpp - ../common/items/itemstore.h - ../common/items/trainsignal.cpp - ../common/items/trainsignal.h - ../common/items/train.cpp - ../common/items/train.h - ../common/items/turnout.cpp - ../common/items/turnout.h - ../common/nfcuid.h -) - -include_directories(PRIVATE - ./common/items/ - ./common - -) - -set(COMMON_LINK_LIBRARYS - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::SerialPort -) - -add_subdirectory(trainControllerUI) -add_subdirectory(trainOverlord) - diff --git a/src/QJoysticks.cpp b/src/QJoysticks.cpp new file mode 100644 index 0000000..2deb989 --- /dev/null +++ b/src/QJoysticks.cpp @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2015-2017 Alex Spataru + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include "QJoysticks.h" +#include "jsbackend/SDL_Joysticks.h" +#include "jsbackend/VirtualJoystick.h" + +QJoysticks::QJoysticks() +{ + /* Initialize input methods */ + m_sdlJoysticks = new SDL_Joysticks(this); + m_virtualJoystick = new VirtualJoystick(this); + + /* Configure SDL joysticks */ + connect(sdlJoysticks(), &SDL_Joysticks::POVEvent, this, &QJoysticks::POVEvent); + connect(sdlJoysticks(), &SDL_Joysticks::axisEvent, this, &QJoysticks::axisEvent); + connect(sdlJoysticks(), &SDL_Joysticks::buttonEvent, this, &QJoysticks::buttonEvent); + connect(sdlJoysticks(), &SDL_Joysticks::countChanged, this, &QJoysticks::updateInterfaces); + + /* Configure virtual joysticks */ + connect(virtualJoystick(), &VirtualJoystick::povEvent, this, &QJoysticks::POVEvent); + connect(virtualJoystick(), &VirtualJoystick::axisEvent, this, &QJoysticks::axisEvent); + connect(virtualJoystick(), &VirtualJoystick::buttonEvent, this, &QJoysticks::buttonEvent); + connect(virtualJoystick(), &VirtualJoystick::enabledChanged, this, &QJoysticks::updateInterfaces); + + /* React to own signals to create QML signals */ + connect(this, &QJoysticks::POVEvent, this, &QJoysticks::onPOVEvent); + connect(this, &QJoysticks::axisEvent, this, &QJoysticks::onAxisEvent); + connect(this, &QJoysticks::buttonEvent, this, &QJoysticks::onButtonEvent); + + /* Configure the settings */ + m_sortJoyticks = 0; + m_settings = new QSettings(qApp->organizationName(), qApp->applicationName()); + m_settings->beginGroup("Blacklisted Joysticks"); +} + +QJoysticks::~QJoysticks() +{ + delete m_settings; + delete m_sdlJoysticks; + delete m_virtualJoystick; +} + +/** + * Returns the one and only instance of this class + */ +QJoysticks *QJoysticks::getInstance() +{ + static QJoysticks joysticks; + return &joysticks; +} + +/** + * Returns the number of joysticks that are attached to the computer and/or + * registered with the \c QJoysticks system. + * + * \note This count also includes the virtual joystick (if its enabled) + */ +int QJoysticks::count() const +{ + return inputDevices().count(); +} + +/** + * Returns the number of joysticks that are not blacklisted. + * This can be considered the "effective" number of joysticks. + */ +int QJoysticks::nonBlacklistedCount() +{ + int cnt = count(); + + for (int i = 0; i < count(); ++i) + if (isBlacklisted(i)) + --cnt; + + return cnt; +} + +/** + * Returns a list with the names of all registered joystick. + * + * \note This list also includes the blacklisted joysticks + * \note This list also includes the virtual joystick (if its enabled) + */ +QStringList QJoysticks::deviceNames() const +{ + QStringList names; + + foreach (QJoystickDevice *joystick, inputDevices()) + names.append(joystick->name); + + return names; +} + +/** + * Returns the POV value for the given joystick \a index and \a pov ID + */ +int QJoysticks::getPOV(const int index, const int pov) +{ + if (joystickExists(index)) + return getInputDevice(index)->povs.at(pov); + + return -1; +} + +/** + * Returns the axis value for the given joystick \a index and \a axis ID + */ +double QJoysticks::getAxis(const int index, const int axis) +{ + if (joystickExists(index)) + return getInputDevice(index)->axes.at(axis); + + return 0; +} + +/** + * Returns the button value for the given joystick \a index and \a button ID + */ +bool QJoysticks::getButton(const int index, const int button) +{ + if (joystickExists(index)) + return getInputDevice(index)->buttons.at(button); + + return false; +} + +/** + * Returns the number of axes that the joystick at the given \a index has. + */ +int QJoysticks::getNumAxes(const int index) +{ + if (joystickExists(index)) + return getInputDevice(index)->axes.count(); + + return -1; +} + +/** + * Returns the number of POVs that the joystick at the given \a index has. + */ +int QJoysticks::getNumPOVs(const int index) +{ + if (joystickExists(index)) + return getInputDevice(index)->povs.count(); + + return -1; +} + +/** + * Returns the number of buttons that the joystick at the given \a index has. + */ +int QJoysticks::getNumButtons(const int index) +{ + if (joystickExists(index)) + return getInputDevice(index)->buttons.count(); + + return -1; +} + +/** + * Returns \c true if the joystick at the given \a index is blacklisted. + */ +bool QJoysticks::isBlacklisted(const int index) +{ + if (joystickExists(index)) + return inputDevices().at(index)->blacklisted; + + return true; +} + +/** + * Returns \c true if the joystick at the given \a index is valid, otherwise, + * the function returns \c false and warns the user through the console. + */ +bool QJoysticks::joystickExists(const int index) +{ + return (index >= 0) && (count() > index); +} + +/** + * Returns the name of the given joystick + */ +QString QJoysticks::getName(const int index) +{ + if (joystickExists(index)) + return m_devices.at(index)->name; + + return "Invalid Joystick"; +} + +/** + * Returns a pointer to the SDL joysticks system. + * This can be used if you need to get more information regarding the joysticks + * registered and managed with SDL. + */ +SDL_Joysticks *QJoysticks::sdlJoysticks() const +{ + return m_sdlJoysticks; +} + +/** + * Returns a pointer to the virtual joystick system. + * This can be used if you need to get more information regarding the virtual + * joystick or want to change its properties directly. + * + * \note You can also change the properties of the virtual joysticks using the + * functions of the \c QJoysticks system class + */ +VirtualJoystick *QJoysticks::virtualJoystick() const +{ + return m_virtualJoystick; +} + +/** + * Returns a pointer to the device at the given \a index. + */ +QJoystickDevice *QJoysticks::getInputDevice(const int index) +{ + if (joystickExists(index)) + return inputDevices().at(index); + + return Q_NULLPTR; +} + +/** + * Returns a pointer to a list containing all registered joysticks. + * This can be used for advanced hacks or just to get all properties of each + * joystick. + */ +QList QJoysticks::inputDevices() const +{ + return m_devices; +} + +/** + * If \a sort is set to true, then the device list will put all blacklisted + * joysticks at the end of the list + */ +void QJoysticks::setSortJoysticksByBlacklistState(bool sort) +{ + if (m_sortJoyticks != sort) + { + m_sortJoyticks = sort; + updateInterfaces(); + } +} + +/** + * Blacklists or whitelists the joystick at the given \a index. + * + * \note This function does not have effect if the given joystick does not exist + * \note Once the joystick is blacklisted, the joystick list will be updated + */ +void QJoysticks::setBlacklisted(const int index, bool blacklisted) +{ + Q_ASSERT(joystickExists(index)); + + /* Netrualize the joystick */ + if (blacklisted) + { + for (int i = 0; i < getNumAxes(index); ++i) + emit axisChanged(index, i, 0); + + for (int i = 0; i < getNumButtons(index); ++i) + emit buttonChanged(index, i, false); + + for (int i = 0; i < getNumPOVs(index); ++i) + emit povChanged(index, i, 0); + } + + /* See if blacklist value was actually changed */ + bool changed = m_devices.at(index)->blacklisted != blacklisted; + + /* Save settings */ + m_devices.at(index)->blacklisted = blacklisted; + m_settings->setValue(getName(index), blacklisted); + + /* Re-scan joysticks if blacklist value has changed */ + if (changed) + updateInterfaces(); +} + +/** + * 'Rescans' for new/removed joysticks and registers them again. + */ +void QJoysticks::updateInterfaces() +{ + m_devices.clear(); + + /* Put blacklisted joysticks at the bottom of the list */ + if (m_sortJoyticks) + { + /* Register non-blacklisted SDL joysticks */ + foreach (QJoystickDevice *joystick, sdlJoysticks()->joysticks()) + { + joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); + if (!joystick->blacklisted) + addInputDevice(joystick); + } + + /* Register the virtual joystick (if its not blacklisted) */ + if (virtualJoystick()->joystickEnabled()) + { + QJoystickDevice *joystick = virtualJoystick()->joystick(); + joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); + + if (!joystick->blacklisted) + { + addInputDevice(joystick); + virtualJoystick()->setJoystickID(inputDevices().count() - 1); + } + } + + /* Register blacklisted SDL joysticks */ + foreach (QJoystickDevice *joystick, sdlJoysticks()->joysticks()) + { + joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); + if (joystick->blacklisted) + addInputDevice(joystick); + } + + /* Register the virtual joystick (if its blacklisted) */ + if (virtualJoystick()->joystickEnabled()) + { + QJoystickDevice *joystick = virtualJoystick()->joystick(); + joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); + + if (joystick->blacklisted) + { + addInputDevice(joystick); + virtualJoystick()->setJoystickID(inputDevices().count() - 1); + } + } + } + + /* Sort normally */ + else + { + /* Register SDL joysticks */ + foreach (QJoystickDevice *joystick, sdlJoysticks()->joysticks()) + { + addInputDevice(joystick); + joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); + } + + /* Register virtual joystick */ + if (virtualJoystick()->joystickEnabled()) + { + QJoystickDevice *joystick = virtualJoystick()->joystick(); + joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); + + addInputDevice(joystick); + virtualJoystick()->setJoystickID(inputDevices().count() - 1); + } + } + + emit countChanged(); +} + +/** + * Changes the axis value range of the virtual joystick. + * + * Take into account that maximum axis values supported by the \c QJoysticks + * system is from \c -1 to \c 1. + */ +void QJoysticks::setVirtualJoystickRange(qreal range) +{ + virtualJoystick()->setAxisRange(range); +} + +/** + * Enables or disables the virtual joystick + */ +void QJoysticks::setVirtualJoystickEnabled(bool enabled) +{ + virtualJoystick()->setJoystickEnabled(enabled); +} + +void QJoysticks::setVirtualJoystickAxisSensibility(qreal sensibility) +{ + virtualJoystick()->setAxisSensibility(sensibility); +} + +/** + * Removes all the registered joysticks and emits appropriate signals. + */ +void QJoysticks::resetJoysticks() +{ + m_devices.clear(); + emit countChanged(); +} + +/** + * Registers the given \a device to the \c QJoysticks system + */ +void QJoysticks::addInputDevice(QJoystickDevice *device) +{ + Q_ASSERT(device); + m_devices.append(device); +} + +/** + * Configures the QML-friendly signal based on the information given by the + * \a event data and updates the joystick values + */ +void QJoysticks::onPOVEvent(const QJoystickPOVEvent &e) +{ + if (e.joystick == nullptr) + return; + + if (!isBlacklisted(e.joystick->id)) + { + if (e.pov < getInputDevice(e.joystick->id)->povs.count()) + { + getInputDevice(e.joystick->id)->povs[e.pov] = e.angle; + emit povChanged(e.joystick->id, e.pov, e.angle); + } + } +} + +/** + * Configures the QML-friendly signal based on the information given by the + * \a event data and updates the joystick values + */ +void QJoysticks::onAxisEvent(const QJoystickAxisEvent &e) +{ + if (e.joystick == nullptr) + return; + + if (!isBlacklisted(e.joystick->id)) + { + if (e.axis < getInputDevice(e.joystick->id)->axes.count()) + { + getInputDevice(e.joystick->id)->axes[e.axis] = e.value; + emit axisChanged(e.joystick->id, e.axis, e.value); + } + } +} + +/** + * Configures the QML-friendly signal based on the information given by the + * \a event data and updates the joystick values + */ +void QJoysticks::onButtonEvent(const QJoystickButtonEvent &e) +{ + if (e.joystick == nullptr) + return; + + if (!isBlacklisted(e.joystick->id)) + { + if (e.button < getInputDevice(e.joystick->id)->buttons.count()) + { + getInputDevice(e.joystick->id)->buttons[e.button] = e.pressed; + emit buttonChanged(e.joystick->id, e.button, e.pressed); + } + } +} diff --git a/src/trainControllerUI/QJoysticks.h b/src/QJoysticks.h similarity index 50% rename from src/trainControllerUI/QJoysticks.h rename to src/QJoysticks.h index 6988a82..819e092 100644 --- a/src/trainControllerUI/QJoysticks.h +++ b/src/QJoysticks.h @@ -50,73 +50,73 @@ class VirtualJoystick; */ class QJoysticks : public QObject { - Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) - Q_PROPERTY(int nonBlacklistedCount READ nonBlacklistedCount NOTIFY countChanged) - Q_PROPERTY(QStringList deviceNames READ deviceNames NOTIFY countChanged) + Q_OBJECT + Q_PROPERTY(int count READ count NOTIFY countChanged) + Q_PROPERTY(int nonBlacklistedCount READ nonBlacklistedCount NOTIFY countChanged) + Q_PROPERTY(QStringList deviceNames READ deviceNames NOTIFY countChanged) - friend class Test_QJoysticks; + friend class Test_QJoysticks; signals: - void countChanged(); - void enabledChanged(const bool enabled); - void POVEvent(const QJoystickPOVEvent &event); - void axisEvent(const QJoystickAxisEvent &event); - void buttonEvent(const QJoystickButtonEvent &event); - void povChanged(const int js, const int pov, const int angle); - void axisChanged(const int js, const int axis, const qreal value); - void buttonChanged(const int js, const int button, const bool pressed); + void countChanged(); + void enabledChanged(const bool enabled); + void POVEvent(const QJoystickPOVEvent &event); + void axisEvent(const QJoystickAxisEvent &event); + void buttonEvent(const QJoystickButtonEvent &event); + void povChanged(const int js, const int pov, const int angle); + void axisChanged(const int js, const int axis, const qreal value); + void buttonChanged(const int js, const int button, const bool pressed); public: - static QJoysticks *getInstance(); + static QJoysticks *getInstance(); - int count() const; - int nonBlacklistedCount(); - QStringList deviceNames() const; + int count() const; + int nonBlacklistedCount(); + QStringList deviceNames() const; - Q_INVOKABLE int getPOV(const int index, const int pov); - Q_INVOKABLE double getAxis(const int index, const int axis); - Q_INVOKABLE bool getButton(const int index, const int button); + Q_INVOKABLE int getPOV(const int index, const int pov); + Q_INVOKABLE double getAxis(const int index, const int axis); + Q_INVOKABLE bool getButton(const int index, const int button); - Q_INVOKABLE int getNumAxes(const int index); - Q_INVOKABLE int getNumPOVs(const int index); - Q_INVOKABLE int getNumButtons(const int index); - Q_INVOKABLE bool isBlacklisted(const int index); - Q_INVOKABLE bool joystickExists(const int index); - Q_INVOKABLE QString getName(const int index); + Q_INVOKABLE int getNumAxes(const int index); + Q_INVOKABLE int getNumPOVs(const int index); + Q_INVOKABLE int getNumButtons(const int index); + Q_INVOKABLE bool isBlacklisted(const int index); + Q_INVOKABLE bool joystickExists(const int index); + Q_INVOKABLE QString getName(const int index); - SDL_Joysticks *sdlJoysticks() const; - VirtualJoystick *virtualJoystick() const; - QJoystickDevice *getInputDevice(const int index); - QList inputDevices() const; + SDL_Joysticks *sdlJoysticks() const; + VirtualJoystick *virtualJoystick() const; + QJoystickDevice *getInputDevice(const int index); + QList inputDevices() const; public slots: - void updateInterfaces(); - void setVirtualJoystickRange(qreal range); - void setVirtualJoystickEnabled(bool enabled); - void setVirtualJoystickAxisSensibility(qreal sensibility); - void setSortJoysticksByBlacklistState(bool sort); - void setBlacklisted(int index, bool blacklisted); + void updateInterfaces(); + void setVirtualJoystickRange(qreal range); + void setVirtualJoystickEnabled(bool enabled); + void setVirtualJoystickAxisSensibility(qreal sensibility); + void setSortJoysticksByBlacklistState(bool sort); + void setBlacklisted(int index, bool blacklisted); protected: - explicit QJoysticks(); - ~QJoysticks(); + explicit QJoysticks(); + ~QJoysticks(); private slots: - void resetJoysticks(); - void addInputDevice(QJoystickDevice *device); - void onPOVEvent(const QJoystickPOVEvent &e); - void onAxisEvent(const QJoystickAxisEvent &e); - void onButtonEvent(const QJoystickButtonEvent &e); + void resetJoysticks(); + void addInputDevice(QJoystickDevice *device); + void onPOVEvent(const QJoystickPOVEvent &e); + void onAxisEvent(const QJoystickAxisEvent &e); + void onButtonEvent(const QJoystickButtonEvent &e); private: - bool m_sortJoyticks; + bool m_sortJoyticks; - QSettings *m_settings; - SDL_Joysticks *m_sdlJoysticks; - VirtualJoystick *m_virtualJoystick; + QSettings *m_settings; + SDL_Joysticks *m_sdlJoysticks; + VirtualJoystick *m_virtualJoystick; - QList m_devices; + QList m_devices; }; #endif diff --git a/src/auxitem.cpp b/src/auxitem.cpp new file mode 100644 index 0000000..8f104c5 --- /dev/null +++ b/src/auxitem.cpp @@ -0,0 +1,18 @@ +#include "auxitem.h" + +AuxItem::AuxItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): Item(itemIdIn, name, value, parent), micro_(micro) +{ + +} + +void AuxItem::setValue(uint8_t value) +{ + Item::setValue(value); + micro_->setAuxPwm(value); +} + +void AuxItem::store(QJsonObject &json) +{ + json["Type"] = "Aux"; + Item::store(json); +} diff --git a/src/auxitem.h b/src/auxitem.h new file mode 100644 index 0000000..a1e6765 --- /dev/null +++ b/src/auxitem.h @@ -0,0 +1,20 @@ +#pragma once + +#include "item.h" +#include "../microcontroller.h" + +class AuxItem: public Item +{ + Q_OBJECT +private: + Microcontroller* micro_; + +public slots: + + virtual void setValue(uint8_t value); + +public: + AuxItem(Microcontroller* micro, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "", uint8_t value = 0, QObject* parent = nullptr); + + virtual void store(QJsonObject& json); +}; diff --git a/src/common/items/itemstore.cpp b/src/common/items/itemstore.cpp deleted file mode 100644 index 5f0a0cb..0000000 --- a/src/common/items/itemstore.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "itemstore.h" -#include -#include -#include "train.h" - -ItemStore::ItemStore(QObject *parent): QObject(parent) -{ -} - -void ItemStore::addItem(std::shared_ptr item) -{ - if(!item) - { - qWarning()<<"invalid item"; - return; - } - bool mached = false; - for(unsigned i = 0; i < items_.size(); i++ ) - if(*items_[i] == *item) mached = true; - if(!mached) - { - items_.push_back(std::shared_ptr(item)); - itemAdded(std::weak_ptr(items_.back())); - } -} - -void ItemStore::addItems(const std::vector>& itemIn) -{ - for(unsigned j = 0; j < itemIn.size(); j++) - { - addItem(itemIn[j]); - Train* train = dynamic_cast(itemIn[j].get()); - if(!train) - continue; - if(train->getTrainId() == 0) - { - const uint8_t uidBytes[] = {154, 110, 34, 218}; - train->tags.push_back(NfcUid(uidBytes, sizeof(uidBytes))); - } - else if(train->getTrainId() == 1) - { - const uint8_t uidBytes[] = {83, 118, 122, 215}; - train->tags.push_back(NfcUid(uidBytes, sizeof(uidBytes))); - } - else if(train->getTrainId() == 3) - { - train->tags.push_back(NfcUid({83, 111, 26, 174})); - train->tags.push_back(NfcUid({83, 63, 78, 170})); - } - else if(train->getTrainId() == 4) - { - const uint8_t uidBytes[] = {55, 220, 31, 184}; - train->tags.push_back(NfcUid(uidBytes, sizeof(uidBytes))); - } - } -} - -void ItemStore::removeItem(const ItemData& item) -{ - for(unsigned j = 0; j < items_.size(); j++) - { - if(item == *items_[j]) - { - items_.erase(items_.begin()+j); - --j; - } - } -} - -void ItemStore::clear() -{ - for(size_t i = 0; i < items_.size(); ++i) itemDeleted(*items_[i]); - items_.clear(); -} - -void ItemStore::itemStateChanged(const ItemData& item) -{ - for(unsigned i = 0; i < items_.size(); i++ ) - { - if(items_[i]->operator==(item)) - { - if(items_[i]->getValue() != item.getValue()) - items_[i]->informValue(item.getValue()); - } - } -} - diff --git a/src/common/items/itemstore.h b/src/common/items/itemstore.h deleted file mode 100644 index ff2ce79..0000000 --- a/src/common/items/itemstore.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include -#include -#include "item.h" -#include "../nfcuid.h" - -class ItemStore: public QObject -{ - Q_OBJECT -protected: - std::vector< std::shared_ptr > items_; - -public: - - ItemStore(QObject *parent = nullptr); - virtual ~ItemStore() {} - - inline std::vector< std::shared_ptr >* getItems() - { - return &items_; - } - - void clear(); - -signals: - - void itemDeleted(ItemData item); - void itemAdded(std::weak_ptr Item); - -public slots: - - void removeItem(const ItemData& item); - virtual void addItem(std::shared_ptr item); - void addItems(const std::vector>& itemsIn); - void itemStateChanged(const ItemData& item); -}; diff --git a/src/common/items/train.cpp b/src/common/items/train.cpp deleted file mode 100644 index cfa815a..0000000 --- a/src/common/items/train.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "train.h" - -Train::Train(uint8_t id, uint8_t address, uint8_t functionMask, int8_t initalValue): - Item(address, QString("Train ")+QString::number(id), initalValue), - functionMask_(functionMask), - train_id_(id) -{ -} - -Microcontroller *Train::micro = nullptr; - -void Train::setFunction(uint8_t funciton, bool value) -{ - Item::setFunction(funciton, value); - if(micro) - micro->trainSetFunction(train_id_, funciton, value); -} - -void Train::setValue(int8_t value) -{ - Item::setValue(value); - if(suspended_ && value != 0) - { - suspended_ = false; - unsuspended(id(), getDirection()); - } - if(micro) - micro->trainSetSpeed(train_id_, value); -} - -void Train::informValue(int8_t value) -{ - if(suspended_ && value != 0) - { - suspended_ = false; - unsuspended(id(), getDirection()); - } - Item::informValue(value); -} - -void Train::reverse() -{ - if(micro) - micro->trainReverse(train_id_); -} - -bool Train::ownsTag(NfcUid uid) -{ - for(size_t i = 0; i < tags.size(); ++i) - { - if(uid == tags[i]) - return true; - } - return false; -} - -bool Train::suspend() -{ - if(suspended_) - return false; - suspendedSpeed_ = value_; - setValue(0); - suspended_ = true; - return true; -} - -bool Train::resume() -{ - if(!suspended_) - return false; - suspended_ = false; - setValue(suspendedSpeed_); - return true; -} - -bool Train::hasBackTag() -{ - return tags.size() > 1; -} - -bool Train::suspendend() -{ - return suspended_; -} - -int Train::getDirection() -{ - if(!suspended_) - return value_ < 0 ? REVERSE : FORWARD; - else - return suspendedSpeed_ < 0 ? REVERSE : FORWARD; -} - diff --git a/src/common/items/train.h b/src/common/items/train.h deleted file mode 100644 index 3b749f0..0000000 --- a/src/common/items/train.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef TRAIN_H -#define TRAIN_H - -#include -#include "item.h" -#include "microcontroller.h" -#include "nfcuid.h" - -class Train : public Item -{ - Q_OBJECT - uint8_t functionMask_; - uint8_t train_id_; - int lastReader_ = -1; - int8_t suspendedSpeed_; - bool suspended_ = false; -public: - static constexpr int FORWARD = 1; - static constexpr int REVERSE = -1; - static constexpr int TAG_FRONT = 0; - static Microcontroller *micro; - std::vector tags; - - Train(uint8_t id = 0, uint8_t address = 0, uint8_t functionMask = 0, int8_t initalValue = 0); - - uint8_t getFunctionMask() - { - return functionMask_; - } - -public slots: - void reverse(); - virtual void setFunction(uint8_t function, bool on); - virtual void setValue(int8_t value); - virtual void informValue(int8_t value); - bool suspend(); - bool resume(); - bool suspendend(); - int getDirection(); - bool ownsTag(NfcUid uid); - bool hasBackTag(); - uint8_t getTrainId() - { - return train_id_; - } - -signals: - void unsuspended(uint32_t id, int direction); -}; - -#endif // TRAIN_H diff --git a/src/common/items/trainsignal.cpp b/src/common/items/trainsignal.cpp deleted file mode 100644 index c8178ec..0000000 --- a/src/common/items/trainsignal.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "trainsignal.h" - -Microcontroller *Signal::micro = nullptr; - -Signal::Signal(uint8_t id, uint8_t address, uint8_t subaddress, uint8_t type, int8_t initalValue) - : Item(address | (subaddress << 8), QString("Turnout ")+QString::number(id), initalValue), - subaddress_(subaddress), signalId_(id), type_(type) -{ - itemId_ = address | (subaddress << 8); - name_ = QString("Signal ")+QString::number(id); -} - -void Signal::setValue(int8_t value) -{ - Item::setValue(value); - if(micro) - micro->signalSetValue(signalId_, value); -} - -bool Signal::hasSlow() -{ - return type_ & TYPE_HAS_SLOW; -} - -bool Signal::hasExpect() -{ - return type_ & TYPE_HAS_EXPECT; -} diff --git a/src/common/items/trainsignal.h b/src/common/items/trainsignal.h deleted file mode 100644 index 876437f..0000000 --- a/src/common/items/trainsignal.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SIGNAL_H -#define SIGNAL_H - -#include "item.h" -#include "../microcontroller.h" - -class Signal : public Item -{ -public: - static constexpr int GO = 0; - static constexpr int STOP = 1; - static constexpr int SLOW = 2; - static constexpr int EXPECT_GO = 1 << 3; - static constexpr int EXPECT_STOP = 2 << 3; - static constexpr int EXPECT_SLOW = 3 << 3; - - static constexpr uint8_t TYPE_NORMAL = 0; - static constexpr uint8_t TYPE_RELAY = 1; - static constexpr uint8_t TYPE_HAS_SLOW = 1 << 1; - static constexpr uint8_t TYPE_HAS_EXPECT = 1 << 2; -private: - uint8_t subaddress_; - uint8_t signalId_; - uint8_t type_; -public: - static Microcontroller *micro; - - explicit Signal(uint8_t id = 0, uint8_t address = 0, uint8_t subaddress = 0, uint8_t type = 0, int8_t initalValue = 0); - virtual void setValue(int8_t value); - bool hasSlow(); - bool hasExpect(); - uint8_t getSignalId() - { - return signalId_; - } -}; - -#endif // SIGNAL_H diff --git a/src/common/microcontroller.cpp b/src/common/microcontroller.cpp deleted file mode 100644 index a650895..0000000 --- a/src/common/microcontroller.cpp +++ /dev/null @@ -1,253 +0,0 @@ -#include "microcontroller.h" - -#include -#include -#include "train.h" -#include "turnout.h" -#include "trainsignal.h" - -void Microcontroller::trainSetSpeed(uint8_t id, int8_t speed) -{ - std::stringstream ss; - ss<<"train "<<(unsigned)id<<" speed "<<(int)speed<<'\n'; - write(ss.str().c_str()); -} - -void Microcontroller::trainReverse(uint8_t id) -{ - std::stringstream ss; - ss<<"train "<<(unsigned)id<<" reverse\n"; - write(ss.str().c_str()); -} - -void Microcontroller::trainSetFunction(uint8_t id, uint8_t function, bool on) -{ - std::stringstream ss; - ss<<"train "<<(unsigned)id<<" function "<<(unsigned)function<<' '<<(on ? "on" : "off")<<'\n'; - write(ss.str().c_str()); -} - -void Microcontroller::tunoutSetDirection(uint8_t id, bool direction) -{ - std::stringstream ss; - ss<<"turnout "<<(unsigned)id<<" set "<<(!direction ? "left" : "right")<<'\n'; - write(ss.str().c_str()); -} - -void Microcontroller::signalSetValue(uint8_t id, uint8_t state) -{ - std::stringstream ss; - ss<<"signal "<<(unsigned)id<<" set "<<(unsigned)state<<'\n'; - write(ss.str().c_str()); -} - -void Microcontroller::setPower(bool on) -{ - write(on ? "power on\n" : "power off\n"); -} - -void Microcontroller::estop() -{ - write("stop\n"); -} - -void Microcontroller::write(const QByteArray& buffer) -{ - if(_port != nullptr) - { - _port->write(buffer); - //_port->waitForBytesWritten(1000); - } - std::this_thread::sleep_for(std::chrono::milliseconds(40)); -} - -void Microcontroller::write(char* buffer, const size_t length) -{ - if(_port != nullptr) - { - _port->write(buffer, length); - //_port->waitForBytesWritten(1000); - } - std::this_thread::sleep_for(std::chrono::milliseconds(40)); -} - -bool Microcontroller::connected() -{ - if(_port != nullptr) - return _port->isOpen(); - else return false; -} - -void Microcontroller::requestState() -{ - write("train list\n"); - write("turnout list\n"); - write("signal list\n"); - write("nfc list\n"); -} - -//housekeeping - -Microcontroller::Microcontroller(QIODevice* port) -{ - setIODevice(port); -} - -Microcontroller::Microcontroller() -{ -} - -Microcontroller::~Microcontroller() -{ -} - -void Microcontroller::setIODevice(QIODevice* port) -{ - _port = port; - QObject::connect(_port, &QIODevice::readyRead, this, &Microcontroller::isReadyRead); -} - -std::shared_ptr Microcontroller::processTrainLine(const QString& buffer) -{ - QStringList bufferList = buffer.split(' '); - if(bufferList.size() >= 14 && buffer.startsWith("TRAIN NUMBER:")) - { - return std::shared_ptr(new Train(bufferList[2].toInt(), bufferList[4].toInt(), bufferList[13].toInt(nullptr, 2), - bufferList[9].toInt())); - } - return nullptr; -} - -std::shared_ptr Microcontroller::processTurnoutLine(const QString& buffer) -{ - QStringList bufferList = buffer.split(' '); - if(bufferList.size() >= 11 && buffer.startsWith("TURNOUT NUMBER:")) - { - return std::shared_ptr(new Turnout(bufferList[2].toInt(), bufferList[4].toInt(), bufferList[6].toInt(), - bufferList[11].toInt())); - } - return nullptr; -} - -std::shared_ptr Microcontroller::processSignalLine(const QString& buffer) -{ - QStringList bufferList = buffer.split(' '); - if(bufferList.size() >= 13 && buffer.startsWith("SIGNAL NUMBER:")) - { - return std::shared_ptr(new Signal(bufferList[2].toInt(), bufferList[4].toInt(), bufferList[6].toInt(), - bufferList[8].toInt(), bufferList[13].toInt())); - } - return nullptr; -} - -void Microcontroller::processNfcLine(const QString& buffer) -{ - QStringList tokens = buffer.split(" "); - if(tokens.size() < 4) - return; - - if(tokens[1].startsWith("NUMBER")) - return; - - NfcUid uid; - uint8_t reader = tokens[1].toUInt(); - tokens = tokens[3].split(':'); - uid.length = tokens.length(); - for(size_t i = 0; i < uid.length; ++i) - uid.bytes[i] = tokens[i].toInt(); - gotTag(reader, uid); -} - -void Microcontroller::processList(const QString& buffer) -{ - QStringList bufferList = buffer.split(' '); - if(bufferList.size() >= 10 && buffer.contains("NUMBER:")) - { - std::shared_ptr item; - if(listMode == TRAIN_LIST) - item = processTrainLine(buffer); - else if(listMode == TURNOUT_LIST) - item = processTurnoutLine(buffer); - else if(listMode == SIGNAL_LIST) - item = processSignalLine(buffer); - if(item) - itemList.push_back(item); - } - else - { - listMode = false; - if(!itemList.empty()) - { - gotItemList(itemList); - itemList.clear(); - } - } -} - -void Microcontroller::processItemState(const QString& buffer) -{ - std::shared_ptr item = processTrainLine(buffer); - if(_buffer.startsWith("TRAIN NUMBER:")) - item = processTrainLine(buffer); - else if(_buffer.startsWith("TURNOUT NUMBER:")) - item = processTurnoutLine(buffer); - else if(_buffer.startsWith("SIGNAL NUMBER:")) - item = processSignalLine(buffer); - if(item) - itemChanged(static_cast(*item)); - else - qWarning()<<__func__<<"failed to process status line"; -} - - -void Microcontroller::processMicroReturn() -{ - if(listMode) - processList(_buffer); - else - { - if(_buffer.startsWith("Trains:")) - { - listMode = TRAIN_LIST; - itemList.clear(); - } - else if(_buffer.startsWith("Turnouts:")) - { - listMode = TURNOUT_LIST; - } - else if(_buffer.startsWith("Signals:")) - { - listMode = SIGNAL_LIST; - } - else if(_buffer.startsWith("TRAIN NUMBER:") || _buffer.startsWith("TURNOUT NUMBER:") || - _buffer.startsWith("SIGNAL NUMBER:")) - { - processItemState(_buffer); - } - else if(_buffer.startsWith("NFC")) - { - processNfcLine(_buffer); - } - else if(_buffer.startsWith("TrainController")) - { - requestState(); - } - } - -} - -void Microcontroller::isReadyRead() -{ - char charBuf; - while(_port->getChar(&charBuf)) - { - _buffer.push_back(charBuf); - if( _buffer.endsWith('\n') ) - { - _buffer.remove('\n'); - processMicroReturn(); - textRecived(_buffer); - _buffer.clear(); - } - } -} diff --git a/src/common/microcontroller.h b/src/common/microcontroller.h deleted file mode 100644 index fa28075..0000000 --- a/src/common/microcontroller.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef MICROCONTROLLER_H -#define MICROCONTROLLER_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "items/item.h" -#include "nfcuid.h" - -class Microcontroller : public QObject -{ - Q_OBJECT - -private: - - static constexpr int TRAIN_LIST = 1; - static constexpr int TURNOUT_LIST = 2; - static constexpr int SIGNAL_LIST = 3; - - int listMode = 0; - - //uint8_t _auxState = 0; - - QIODevice* _port = nullptr; - - std::vector< std::shared_ptr > itemList; - - QScopedPointer loop; - QString _buffer; - - void processMicroReturn(); - void processList(const QString& buffer); - void processItemState(const QString& buffer); - std::shared_ptr processTrainLine(const QString& buffer); - std::shared_ptr processTurnoutLine(const QString& buffer); - std::shared_ptr processSignalLine(const QString& buffer); - void processNfcLine(const QString& buffer); - - void write(char *buffer, const size_t length); - void write(const QByteArray& buffer); - -public: - Microcontroller(QIODevice* port); - Microcontroller(); - ~Microcontroller(); - bool connected(); - void setIODevice(QIODevice* port); - -public slots: - void requestState(); - - void trainSetSpeed(uint8_t id, int8_t speed); - void trainReverse(uint8_t id); - void trainSetFunction(uint8_t id, uint8_t function, bool on); - void tunoutSetDirection(uint8_t id, bool direction); - void signalSetValue(uint8_t id, uint8_t state); - void estop(); - void setPower(bool on); - -private slots: - void isReadyRead(); - -signals: - void textRecived(const QString string); - void itemChanged(ItemData relay); - void auxStateChanged(int value); - void gotItemList(std::vector>&); - void gotTag(uint8_t reader, NfcUid uid); -}; - -#endif // MICROCONTROLLER_H diff --git a/src/common/nfcuid.h b/src/common/nfcuid.h deleted file mode 100644 index 90cf3fd..0000000 --- a/src/common/nfcuid.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef NFCUID_H -#define NFCUID_H -#include -#include - -class NfcUid -{ -public: - uint8_t bytes[10]; - uint8_t length; - bool operator==(const NfcUid& in) const - { - if(length != in.length) - return false; - for(uint8_t i = 0; i < length; ++i) - { - if(bytes[i] != in.bytes[i]) - return false; - } - return true; - } - bool operator!=(const NfcUid& in) const - { - return !operator==(in); - } - NfcUid(){} - NfcUid(const std::initializer_list list) - { - length = list.size(); - uint8_t i = 0; - for(std::initializer_list::iterator iter = list.begin(); iter != list.end(); ++iter) - bytes[i++] = *iter; - } - NfcUid(const uint8_t* const bytesIn, uint8_t lengthIn): length(lengthIn) - { - for(uint8_t i = 0; i < length; ++i) - bytes[i] = bytesIn[i]; - } - std::string toString() const - { - std::string str; - for(uint8_t i = 0; i < length; ++i) - { - str.append(std::to_string((int)bytes[i])); - if(i != length-1) - str.push_back(':'); - } - return str; - } -}; - -#endif // NFCUID_H - diff --git a/src/items/auxitem.cpp b/src/items/auxitem.cpp new file mode 100644 index 0000000..8f104c5 --- /dev/null +++ b/src/items/auxitem.cpp @@ -0,0 +1,18 @@ +#include "auxitem.h" + +AuxItem::AuxItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): Item(itemIdIn, name, value, parent), micro_(micro) +{ + +} + +void AuxItem::setValue(uint8_t value) +{ + Item::setValue(value); + micro_->setAuxPwm(value); +} + +void AuxItem::store(QJsonObject &json) +{ + json["Type"] = "Aux"; + Item::store(json); +} diff --git a/src/items/auxitem.h b/src/items/auxitem.h new file mode 100644 index 0000000..a1e6765 --- /dev/null +++ b/src/items/auxitem.h @@ -0,0 +1,20 @@ +#pragma once + +#include "item.h" +#include "../microcontroller.h" + +class AuxItem: public Item +{ + Q_OBJECT +private: + Microcontroller* micro_; + +public slots: + + virtual void setValue(uint8_t value); + +public: + AuxItem(Microcontroller* micro, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "", uint8_t value = 0, QObject* parent = nullptr); + + virtual void store(QJsonObject& json); +}; diff --git a/src/common/items/item.cpp b/src/items/item.cpp similarity index 73% rename from src/common/items/item.cpp rename to src/items/item.cpp index 6a8dd2f..36756b9 100644 --- a/src/common/items/item.cpp +++ b/src/items/item.cpp @@ -10,29 +10,28 @@ ItemData::ItemData(uint32_t itemIdIn, QString name, int8_t value): name_(name), QString ItemData::getName() const { - return name_; + return name_; } void ItemData::setName(QString name) { - name_ = name; + name_ = name; } int8_t ItemData::getValue() const { - return value_; + return value_; } uint32_t ItemData::id() const { - return itemId_; + return itemId_; } //item -Item::Item(uint32_t itemIdIn, QString name, int8_t value, QObject *parent): QObject(parent), ItemData (itemIdIn, name, - value) +Item::Item(uint32_t itemIdIn, QString name, int8_t value, QObject *parent): QObject(parent), ItemData (itemIdIn, name, value) { } @@ -48,16 +47,16 @@ Item::~Item() void Item::setFunction(uint8_t function, bool on) { - functionChanged(function, on); + functionChanged(function, on); } void Item::setValue(int8_t value) { - value_ = value; - valueChanged(value_); + value_ = value; + valueChanged(value_); } void Item::informValue(int8_t value) { - Item::setValue(value); + Item::setValue(value); } diff --git a/src/common/items/item.h b/src/items/item.h similarity index 53% rename from src/common/items/item.h rename to src/items/item.h index 54c843a..be563d7 100644 --- a/src/common/items/item.h +++ b/src/items/item.h @@ -11,34 +11,28 @@ class Actor; class ItemData { protected: - QString name_; + QString name_; int8_t value_; - uint32_t itemId_; + uint32_t itemId_; public: ItemData(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", int8_t value = 0); - inline bool operator==(const ItemData& in) const - { - return itemId_==in.itemId_; - } - inline bool operator!=(const ItemData& in) const - { - return itemId_!=in.itemId_; - } + inline bool operator==(const ItemData& in) const{ return itemId_==in.itemId_; } + inline bool operator!=(const ItemData& in) const{ return itemId_!=in.itemId_; } - uint32_t id() const; + uint32_t id() const; - void setName(QString name); + void setName(QString name); int8_t getValue() const; - virtual QString getName() const; + virtual QString getName() const; }; class Item: public QObject, public ItemData { - Q_OBJECT + Q_OBJECT private: signals: @@ -49,17 +43,16 @@ signals: public slots: virtual void setValue(int8_t value); - virtual void setFunction(uint8_t funciton, bool value); + virtual void setFunction(uint8_t funciton, bool value); public: - Item(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", int8_t value = 0, - QObject *parent = nullptr); - Item(const ItemData& itemData, QObject *parent = nullptr); + Item(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", int8_t value = 0, QObject *parent = nullptr); + Item(const ItemData& itemData, QObject *parent = nullptr); - virtual ~Item(); + virtual ~Item(); - virtual void informValue(int8_t value); + void informValue(int8_t value); }; diff --git a/src/items/itemstore.cpp b/src/items/itemstore.cpp new file mode 100644 index 0000000..61b41eb --- /dev/null +++ b/src/items/itemstore.cpp @@ -0,0 +1,111 @@ +#include "itemstore.h" +#include +#include +#include "train.h" +#include "../trainjs.h" + +ItemStore::ItemStore(QObject *parent): QObject(parent) +{ +} + +void ItemStore::addItem(std::shared_ptr item) +{ + if(!item) + { + qWarning()<<"invalid item"; + return; + } + bool mached = false; + for(unsigned i = 0; i < items_.size(); i++ ) + if(*items_[i] == *item) mached = true; + if(!mached) + { + items_.push_back(std::shared_ptr(item)); + + if(dynamic_cast(item.get())) + { + std::vector> joysticks = TrainJs::getJsDevices(); + for(auto joystick: joysticks) + { + if(!joystick->itemIsSet()) + { + joystick->setItem(item); + connect(joystick.get(), &TrainJs::reqNewItem, this, &ItemStore::jsReqNewItem); + break; + } + } + } + + itemAdded(std::weak_ptr(items_.back())); + } + qDebug()<<"Got item: "<id()<<" matched: "<> joysticks = TrainJs::getJsDevices(); + for(auto joystick: joysticks) + { + if(joystick->getWantsNewItem()) + { + std::shared_ptr oldItem = joystick->getItem().lock(); + for(size_t i = 0; i < items_.size(); ++i) + { + if(!oldItem || *items_[i] == *oldItem) + { + if(i+1 < items_.size()) + joystick->setItem(items_[i+1]); + else + joystick->setItem(items_[0]); + break; + } + } + } + } +} + +void ItemStore::addItems(const std::vector>& itemIn) +{ + for(unsigned j = 0; j < itemIn.size(); j++) + addItem(itemIn[j]); + +} + +void ItemStore::removeItem(const ItemData& item) +{ + for(unsigned j = 0; j < items_.size(); j++) + { + if(item == *items_[j]) + { + items_.erase(items_.begin()+j); + --j; + } + } +} + + +void ItemStore::clear() +{ + for(size_t i = 0; i < items_.size(); ++i) itemDeleted(*items_[i]); + items_.clear(); +} + + +void ItemStore::itemStateChanged(const ItemData& item) +{ + + for(unsigned i = 0; i < items_.size(); i++ ) + { + if(items_[i]->operator==(item)) + { + + if(items_[i]->getValue() != item.getValue())items_[i]->informValue(item.getValue()); + } + + } + +} + diff --git a/src/items/itemstore.h b/src/items/itemstore.h new file mode 100644 index 0000000..6148027 --- /dev/null +++ b/src/items/itemstore.h @@ -0,0 +1,38 @@ +#pragma once +#include +#include +#include "item.h" + +#include + +class ItemStore: public QObject +{ + Q_OBJECT +private: + std::vector< std::shared_ptr > items_; + +public: + + ItemStore(QObject *parent = nullptr); + virtual ~ItemStore(){} + + inline std::vector< std::shared_ptr >* getItems(){ return &items_; } + + void clear(); + +private slots: + + void jsReqNewItem(); + +signals: + + void itemDeleted(ItemData item); + void itemAdded(std::weak_ptr Item); + +public slots: + + void removeItem(const ItemData& item); + void addItem(std::shared_ptr item); + void addItems(const std::vector>& itemsIn); + void itemStateChanged(const ItemData& item); +}; diff --git a/src/items/train.cpp b/src/items/train.cpp new file mode 100644 index 0000000..09266de --- /dev/null +++ b/src/items/train.cpp @@ -0,0 +1,31 @@ +#include "train.h" + +Train::Train(uint8_t id, uint8_t address, uint8_t functionMask, int8_t initalValue): + Item(address, QString("Train ")+QString::number(id), initalValue), + functionMask_(functionMask), + train_id_(id) +{ +} + +Microcontroller *Train::micro = nullptr; + +void Train::setFunction(uint8_t funciton, bool value) +{ + Item::setFunction(funciton, value); + if(micro) + micro->trainSetFunction(train_id_, funciton, value); +} + +void Train::setValue(int8_t value) +{ + Item::setValue(value); + if(micro) + micro->trainSetSpeed(train_id_, value); +} + +void Train::reverse() +{ + if(micro) + micro->trainReverse(train_id_); +} + diff --git a/src/items/train.h b/src/items/train.h new file mode 100644 index 0000000..41bbf0e --- /dev/null +++ b/src/items/train.h @@ -0,0 +1,26 @@ +#ifndef TRAIN_H +#define TRAIN_H + +#include "item.h" +#include "../microcontroller.h" + +class Train : public Item +{ + Q_OBJECT + uint8_t functionMask_; + uint8_t train_id_; +public: + static Microcontroller *micro; + + Train(uint8_t id = 0, uint8_t address = 0, uint8_t functionMask = 0, int8_t initalValue = 0); + + uint8_t getFunctionMask() {return functionMask_;} + +public slots: + void reverse(); + virtual void setFunction(uint8_t function, bool on); + virtual void setValue(int8_t value); + uint8_t getTrainId(){return train_id_;} +}; + +#endif // TRAIN_H diff --git a/src/common/items/turnout.cpp b/src/items/turnout.cpp similarity index 73% rename from src/common/items/turnout.cpp rename to src/items/turnout.cpp index df82938..a2d3133 100644 --- a/src/common/items/turnout.cpp +++ b/src/items/turnout.cpp @@ -6,13 +6,13 @@ Turnout::Turnout(uint8_t id, uint8_t address, uint8_t subaddress, int8_t initalV : Item(address | (subaddress << 8), QString("Turnout ")+QString::number(id), initalValue), subaddress_(subaddress), turnoutId_(id) { - itemId_ = address | (subaddress << 8); - name_ = QString("Turnout ")+QString::number(id); + itemId_ = address | (subaddress << 8); + name_ = QString("Turnout ")+QString::number(id); } void Turnout::setValue(int8_t value) { - Item::setValue(value); - if(micro) + Item::setValue(value); + if(micro) micro->tunoutSetDirection(turnoutId_, value > 0); } diff --git a/src/common/items/turnout.h b/src/items/turnout.h similarity index 69% rename from src/common/items/turnout.h rename to src/items/turnout.h index 6f203c2..27cd975 100644 --- a/src/common/items/turnout.h +++ b/src/items/turnout.h @@ -6,17 +6,14 @@ class Turnout : public Item { - uint8_t subaddress_; - uint8_t turnoutId_; + uint8_t subaddress_; + uint8_t turnoutId_; public: - static Microcontroller *micro; + static Microcontroller *micro; explicit Turnout(uint8_t id = 0, uint8_t address = 0, uint8_t subaddress = 0, int8_t initalValue = 0); virtual void setValue(int8_t value); - uint8_t getTurnoutId() - { - return turnoutId_; - } + uint8_t getTurnoutId(){return turnoutId_;} }; #endif // TURNOUT_H diff --git a/src/trainControllerUI/jsbackend/JoysticksCommon.h b/src/jsbackend/JoysticksCommon.h similarity index 100% rename from src/trainControllerUI/jsbackend/JoysticksCommon.h rename to src/jsbackend/JoysticksCommon.h diff --git a/src/trainControllerUI/jsbackend/JoysticksCommon.h.orig b/src/jsbackend/JoysticksCommon.h.orig similarity index 100% rename from src/trainControllerUI/jsbackend/JoysticksCommon.h.orig rename to src/jsbackend/JoysticksCommon.h.orig diff --git a/src/trainControllerUI/jsbackend/SDL_Joysticks.cpp b/src/jsbackend/SDL_Joysticks.cpp similarity index 95% rename from src/trainControllerUI/jsbackend/SDL_Joysticks.cpp rename to src/jsbackend/SDL_Joysticks.cpp index b78c4ef..4b2bdd0 100644 --- a/src/trainControllerUI/jsbackend/SDL_Joysticks.cpp +++ b/src/jsbackend/SDL_Joysticks.cpp @@ -44,7 +44,7 @@ SDL_Joysticks::SDL_Joysticks(QObject *parent) for (int i = 0; i < count; ++i) configureJoystick(i); - QTimer::singleShot(10, Qt::PreciseTimer, this, SLOT(update())); + QTimer::singleShot(100, Qt::PreciseTimer, this, SLOT(update())); } SDL_Joysticks::~SDL_Joysticks() diff --git a/src/trainControllerUI/jsbackend/SDL_Joysticks.cpp.orig b/src/jsbackend/SDL_Joysticks.cpp.orig similarity index 100% rename from src/trainControllerUI/jsbackend/SDL_Joysticks.cpp.orig rename to src/jsbackend/SDL_Joysticks.cpp.orig diff --git a/src/trainControllerUI/jsbackend/SDL_Joysticks.h b/src/jsbackend/SDL_Joysticks.h similarity index 100% rename from src/trainControllerUI/jsbackend/SDL_Joysticks.h rename to src/jsbackend/SDL_Joysticks.h diff --git a/src/trainControllerUI/jsbackend/SDL_Joysticks.h.orig b/src/jsbackend/SDL_Joysticks.h.orig similarity index 100% rename from src/trainControllerUI/jsbackend/SDL_Joysticks.h.orig rename to src/jsbackend/SDL_Joysticks.h.orig diff --git a/src/trainControllerUI/jsbackend/VirtualJoystick.cpp b/src/jsbackend/VirtualJoystick.cpp similarity index 100% rename from src/trainControllerUI/jsbackend/VirtualJoystick.cpp rename to src/jsbackend/VirtualJoystick.cpp diff --git a/src/trainControllerUI/jsbackend/VirtualJoystick.cpp.orig b/src/jsbackend/VirtualJoystick.cpp.orig similarity index 100% rename from src/trainControllerUI/jsbackend/VirtualJoystick.cpp.orig rename to src/jsbackend/VirtualJoystick.cpp.orig diff --git a/src/trainControllerUI/jsbackend/VirtualJoystick.h b/src/jsbackend/VirtualJoystick.h similarity index 100% rename from src/trainControllerUI/jsbackend/VirtualJoystick.h rename to src/jsbackend/VirtualJoystick.h diff --git a/src/trainControllerUI/jsbackend/VirtualJoystick.h.orig b/src/jsbackend/VirtualJoystick.h.orig similarity index 100% rename from src/trainControllerUI/jsbackend/VirtualJoystick.h.orig rename to src/jsbackend/VirtualJoystick.h.orig diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..4464629 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "microcontroller.h" +#include "trainjs.h" +#include "ui/mainwindow.h" +#include "items/itemstore.h" +#include "items/train.h" +#include "items/turnout.h" + +#define BAUD QSerialPort::Baud38400 + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + //set info + QCoreApplication::setOrganizationName("UVOS"); + QCoreApplication::setOrganizationDomain("uvos.xyz"); + QCoreApplication::setApplicationName("traincontrollerui"); + QCoreApplication::setApplicationVersion("0.1"); + + QDir::setCurrent(a.applicationDirPath()); + + //parse comand line + QCommandLineParser parser; + parser.setApplicationDescription("Smart Home Interface"); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption tcpOption(QStringList() << "t" << "tcp", QCoreApplication::translate("main", "Use Tcp connection")); + parser.addOption(tcpOption); + QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", "Set server host ip addres"), "adress"); + parser.addOption(hostOption); + QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", "Set server Port in TCP mode or Serial port in serial mode"), "port"); + parser.addOption(portOption); + QCommandLineOption serialOption(QStringList() << "s" << "serial", QCoreApplication::translate("main", "Use serial connection")); + parser.addOption(serialOption); + QCommandLineOption baudOption(QStringList() << "b" << "baud", QCoreApplication::translate("main", "Set Baud Rate")); + parser.addOption(baudOption); + parser.process(a); + + QIODevice* masterIODevice = nullptr; + + if(parser.isSet(tcpOption)) + { + QTcpSocket* microSocket = new QTcpSocket; + + int port = 6856; + if(parser.isSet(portOption)) port = parser.value(portOption).toInt(); + + QString host("127.0.0.1"); + if(parser.isSet(hostOption)) host = parser.value(hostOption); + std::cout<<"connecting to "<connectToHost(host, port, QIODevice::ReadWrite); + if(!microSocket->waitForConnected(3000)) + { + std::cout<<"Can not connect to to Server.\n"; + QMessageBox::critical(nullptr, "Error", "Can not connect to to Server"); + return 1; + } + masterIODevice = microSocket; + } + else + { + QSerialPort* microPort = new QSerialPort; + if(parser.isSet(portOption)) microPort->setPortName(parser.value(portOption)); + else microPort->setPortName("ttyUSB0"); + + if(parser.isSet(portOption)) microPort->setBaudRate(parser.value(baudOption).toInt()); + else microPort->setBaudRate(BAUD); + + if(!microPort->open(QIODevice::ReadWrite)) + { + QMessageBox::critical(nullptr, "Error", QString("Can not open serial port ")+microPort->portName()); + std::cout<<"Can not open serial port "<portName().toStdString()<<". Continueing in demo mode"<<'\n'; + return 1; + } + masterIODevice = microPort; + } + + Microcontroller micro(masterIODevice); + micro.setPower(true); + + TrainJs::init(); + + Train::micro = µ + Turnout::micro = µ + ItemStore items; + + QObject::connect(µ, &Microcontroller::gotItemList, &items, &ItemStore::addItems); + QObject::connect(µ, &Microcontroller::itemChanged, &items, &ItemStore::itemStateChanged); + + //mainwindow + MainWindow w(µ, &items); + + w.show(); + + int retVal = a.exec(); + micro.setPower(false); + + if(masterIODevice) + delete masterIODevice; + return retVal; +} + diff --git a/src/mainobject.cpp b/src/mainobject.cpp new file mode 100644 index 0000000..4af15c0 --- /dev/null +++ b/src/mainobject.cpp @@ -0,0 +1,14 @@ +#include "mainobject.h" + +MainObject::MainObject(QIODevice* ioDevice) : + masterIODevice(ioDevice), + micro(masterIODevice) +{ + //connect item store + QObject::connect(µ, &Microcontroller::gotItemList, &items, &ItemStore::addItems); +} + +MainObject::~MainObject() +{ +} + diff --git a/src/trainControllerUI/mainobject.h b/src/mainobject.h similarity index 59% rename from src/trainControllerUI/mainobject.h rename to src/mainobject.h index 9c00769..234bd16 100644 --- a/src/trainControllerUI/mainobject.h +++ b/src/mainobject.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include @@ -19,25 +22,26 @@ #include "microcontroller.h" #include "ui/mainwindow.h" #include "items/itemstore.h" +#include "items/auxitem.h" class MainObject : public QObject { - Q_OBJECT + Q_OBJECT public: - //io - QIODevice * const masterIODevice = nullptr; + //io + QIODevice * const masterIODevice = nullptr; - Microcontroller micro; + Microcontroller micro; - const QString settingsPath; + const QString settingsPath; - //items - ItemStore items; + //items + ItemStore items; public: - explicit MainObject(QIODevice* ioDevice); - ~MainObject(); + explicit MainObject(QIODevice* ioDevice); + ~MainObject(); }; #endif // MAINOBJECT_H diff --git a/src/microcontroller.cpp b/src/microcontroller.cpp new file mode 100644 index 0000000..093be50 --- /dev/null +++ b/src/microcontroller.cpp @@ -0,0 +1,199 @@ +#include "microcontroller.h" + +#include +#include +#include "items/train.h" +#include "items/turnout.h" + +void Microcontroller::trainSetSpeed(uint8_t id, int8_t speed) +{ + qDebug()<<__func__; + std::stringstream ss; + ss<<"train "<<(unsigned)id<<" speed "<<(int)speed<<'\n'; + write(ss.str().c_str()); +} + +void Microcontroller::trainReverse(uint8_t id) +{ + std::stringstream ss; + ss<<"train "<<(unsigned)id<<" reverse\n"; + write(ss.str().c_str()); +} + +void Microcontroller::trainSetFunction(uint8_t id, uint8_t function, bool on) +{ + std::stringstream ss; + ss<<"train "<<(unsigned)id<<" function "<<(unsigned)function<<' '<<(on ? "on" : "off")<<'\n'; + write(ss.str().c_str()); +} + +void Microcontroller::tunoutSetDirection(uint8_t id, bool direction) +{ + std::stringstream ss; + ss<<"turnout "<<(unsigned)id<<" set "<<(!direction ? "left" : "right")<<'\n'; + write(ss.str().c_str()); +} + +void Microcontroller::setPower(bool on) +{ + write(on ? "power on\n" : "power off\n"); +} + +void Microcontroller::estop() +{ + write("stop\n"); +} + +void Microcontroller::write(const QByteArray& buffer) +{ + qDebug()<write(buffer); + _port->waitForBytesWritten(1000); + } + std::this_thread::sleep_for(std::chrono::milliseconds(40)); +} + +void Microcontroller::write(char* buffer, const size_t length) +{ + qDebug()<write(buffer, length); + //_port->waitForBytesWritten(1000); + } + std::this_thread::sleep_for(std::chrono::milliseconds(40)); +} + +bool Microcontroller::connected() +{ + if(_port != nullptr) + return _port->isOpen(); + else return false; +} + +void Microcontroller::requestState() +{ + write("train list\n"); + write("turnout list\n"); +} + +//housekeeping + +Microcontroller::Microcontroller(QIODevice* port) +{ + setIODevice(port); +} + +Microcontroller::Microcontroller() +{ +} + +Microcontroller::~Microcontroller() +{ +} + +void Microcontroller::setIODevice(QIODevice *port) +{ + _port = port; + QObject::connect(_port, &QIODevice::readyRead, this, &Microcontroller::isReadyRead); +} + +std::shared_ptr Microcontroller::processTrainLine(const QString& buffer) +{ + QStringList bufferList = buffer.split(' '); + if(bufferList.size() >= 14 && buffer.startsWith("TRAIN NUMBER:")) + { + return std::shared_ptr(new Train(bufferList[2].toInt(), bufferList[4].toInt(), bufferList[13].toInt(nullptr, 2), bufferList[9].toInt())); + } + return nullptr; +} + +std::shared_ptr Microcontroller::processTurnoutLine(const QString& buffer) +{ + QStringList bufferList = buffer.split(' '); + if(bufferList.size() >= 11 && buffer.startsWith("TURNOUT NUMBER:")) + { + return std::shared_ptr(new Turnout(bufferList[2].toInt(), bufferList[4].toInt(), bufferList[6].toInt(), bufferList[11].toInt())); + } + return nullptr; +} + +void Microcontroller::processList(const QString& buffer) +{ + QStringList bufferList = buffer.split(' '); + qDebug()<<__func__<<" :"<= 10 && buffer.contains("NUMBER:")) + { + std::shared_ptr item; + if(listMode == TRAIN_LIST) + item = processTrainLine(buffer); + else if(listMode == TURNOUT_LIST) + item = processTurnoutLine(buffer); + if(item) + itemList.push_back(item); + } + else + { + listMode = false; + if(!itemList.empty()) + { + qDebug()<<"got item list " << itemList.size(); + gotItemList(itemList); + itemList.clear(); + } + } +} + +void Microcontroller::processItemState(const QString& buffer) +{ + if(_buffer.startsWith("TRAIN NUMBER:")) + itemChanged(static_cast(*processTrainLine(buffer))); + else if(_buffer.startsWith("TURNOUT NUMBER:")) + itemChanged(static_cast(*processTurnoutLine(buffer))); +} + + +void Microcontroller::processMicroReturn() +{ + if(listMode) + processList(_buffer); + else + { + if(_buffer.startsWith("Trains:")) + { + listMode = TRAIN_LIST; + itemList.clear(); + } + else if(_buffer.startsWith("Turnouts:")) + { + listMode = TURNOUT_LIST; + } + else if(_buffer.startsWith("TRAIN NUMBER:") || _buffer.startsWith("TURNOUT NUMBER:")) + { + processItemState(_buffer); + } + else if(_buffer.startsWith("TrainController")) + { + requestState(); + } + } + +} + +void Microcontroller::isReadyRead() +{ + char charBuf; + while(_port->getChar(&charBuf)) + { + _buffer.push_back(charBuf); + if( _buffer.endsWith('\n') ) + { + _buffer.remove('\n'); + processMicroReturn(); + textRecived(_buffer); + _buffer.clear(); + } + } +} diff --git a/src/microcontroller.h b/src/microcontroller.h new file mode 100644 index 0000000..cddfe2e --- /dev/null +++ b/src/microcontroller.h @@ -0,0 +1,83 @@ +#ifndef MICROCONTROLLER_H +#define MICROCONTROLLER_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "items/item.h" + +class Microcontroller : public QObject +{ + + Q_OBJECT + +public: + + static constexpr char AMP_RELAY = 0; + static constexpr char SENSOR_TEMPERATURE = 1; + static constexpr char SENSOR_DOOR = 0 ; + +private: + + static constexpr int TRAIN_LIST = 1; + static constexpr int TURNOUT_LIST = 2; + + int listMode = 0; + + //uint8_t _auxState = 0; + + QIODevice* _port = nullptr; + + std::vector< std::shared_ptr > itemList; + + QScopedPointer loop; + QString _buffer; + + void processMicroReturn(); + void processList(const QString& buffer); + void processItemState(const QString& buffer); + std::shared_ptr processTrainLine(const QString& buffer); + std::shared_ptr processTurnoutLine(const QString& buffer); + + void write(char *buffer, const size_t length); + void write(const QByteArray& buffer); + +public: + Microcontroller(QIODevice* port); + Microcontroller(); + ~Microcontroller(); + bool connected(); + void setIODevice(QIODevice* port); + +public slots: + void requestState(); + + void trainSetSpeed(uint8_t id, int8_t speed); + void trainReverse(uint8_t id); + void trainSetFunction(uint8_t id, uint8_t function, bool on); + void tunoutSetDirection(uint8_t id, bool direction); + void estop(); + void setPower(bool on); + +private slots: + void isReadyRead(); + +signals: + void textRecived(const QString string); + void itemChanged(ItemData relay); + void auxStateChanged(int value); + void gotItemList(std::vector< std::shared_ptr >&); +}; + +#endif // MICROCONTROLLER_H diff --git a/src/trainControllerUI/CMakeLists.txt b/src/trainControllerUI/CMakeLists.txt deleted file mode 100644 index b201225..0000000 --- a/src/trainControllerUI/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -set(UI_SOURCES - traincontrollerui.cpp - mainobject.cpp - QJoysticks.cpp - trainjs.cpp - ui/itemscrollbox.cpp - ui/itemscrollbox.h - ui/itemwidget.cpp - ui/itemwidget.h - ui/mainwindow.cpp - ui/mainwindow.h - ui/mainwindow.ui - ui/relayscrollbox.ui - ui/signalwidget.cpp - ui/signalwidget.h - ui/signalwidget.ui - ui/trainwidget.cpp - ui/trainwidget.h - ui/trainwidget.ui - jsbackend/SDL_Joysticks.cpp - jsbackend/VirtualJoystick.cpp -) - -find_package(SDL2 REQUIRED) - -add_executable(traincontrollerui ${UI_SOURCES} ${COMMON_SOURCES}) -target_link_libraries(traincontrollerui PRIVATE ${COMMON_LINK_LIBRARYS} Qt${QT_VERSION_MAJOR}::Widgets ${SDL2_LIBRARIES}) -target_include_directories(traincontrollerui PRIVATE ./ ./ui ./jsbackend ${SDL2_INCLUDE_DIRS}) diff --git a/src/trainControllerUI/QJoysticks.cpp b/src/trainControllerUI/QJoysticks.cpp deleted file mode 100644 index 2d6e964..0000000 --- a/src/trainControllerUI/QJoysticks.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (c) 2015-2017 Alex Spataru - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include "QJoysticks.h" -#include "jsbackend/SDL_Joysticks.h" -#include "jsbackend/VirtualJoystick.h" - -QJoysticks::QJoysticks() -{ - /* Initialize input methods */ - m_sdlJoysticks = new SDL_Joysticks(this); - m_virtualJoystick = new VirtualJoystick(this); - - /* Configure SDL joysticks */ - connect(sdlJoysticks(), &SDL_Joysticks::POVEvent, this, &QJoysticks::POVEvent); - connect(sdlJoysticks(), &SDL_Joysticks::axisEvent, this, &QJoysticks::axisEvent); - connect(sdlJoysticks(), &SDL_Joysticks::buttonEvent, this, &QJoysticks::buttonEvent); - connect(sdlJoysticks(), &SDL_Joysticks::countChanged, this, &QJoysticks::updateInterfaces); - - /* Configure virtual joysticks */ - connect(virtualJoystick(), &VirtualJoystick::povEvent, this, &QJoysticks::POVEvent); - connect(virtualJoystick(), &VirtualJoystick::axisEvent, this, &QJoysticks::axisEvent); - connect(virtualJoystick(), &VirtualJoystick::buttonEvent, this, &QJoysticks::buttonEvent); - connect(virtualJoystick(), &VirtualJoystick::enabledChanged, this, &QJoysticks::updateInterfaces); - - /* React to own signals to create QML signals */ - connect(this, &QJoysticks::POVEvent, this, &QJoysticks::onPOVEvent); - connect(this, &QJoysticks::axisEvent, this, &QJoysticks::onAxisEvent); - connect(this, &QJoysticks::buttonEvent, this, &QJoysticks::onButtonEvent); - - /* Configure the settings */ - m_sortJoyticks = 0; - m_settings = new QSettings(qApp->organizationName(), qApp->applicationName()); - m_settings->beginGroup("Blacklisted Joysticks"); -} - -QJoysticks::~QJoysticks() -{ - delete m_settings; - delete m_sdlJoysticks; - delete m_virtualJoystick; -} - -/** - * Returns the one and only instance of this class - */ -QJoysticks *QJoysticks::getInstance() -{ - static QJoysticks joysticks; - return &joysticks; -} - -/** - * Returns the number of joysticks that are attached to the computer and/or - * registered with the \c QJoysticks system. - * - * \note This count also includes the virtual joystick (if its enabled) - */ -int QJoysticks::count() const -{ - return inputDevices().count(); -} - -/** - * Returns the number of joysticks that are not blacklisted. - * This can be considered the "effective" number of joysticks. - */ -int QJoysticks::nonBlacklistedCount() -{ - int cnt = count(); - - for (int i = 0; i < count(); ++i) - if (isBlacklisted(i)) - --cnt; - - return cnt; -} - -/** - * Returns a list with the names of all registered joystick. - * - * \note This list also includes the blacklisted joysticks - * \note This list also includes the virtual joystick (if its enabled) - */ -QStringList QJoysticks::deviceNames() const -{ - QStringList names; - - foreach (QJoystickDevice *joystick, inputDevices()) - names.append(joystick->name); - - return names; -} - -/** - * Returns the POV value for the given joystick \a index and \a pov ID - */ -int QJoysticks::getPOV(const int index, const int pov) -{ - if (joystickExists(index)) - return getInputDevice(index)->povs.at(pov); - - return -1; -} - -/** - * Returns the axis value for the given joystick \a index and \a axis ID - */ -double QJoysticks::getAxis(const int index, const int axis) -{ - if (joystickExists(index)) - return getInputDevice(index)->axes.at(axis); - - return 0; -} - -/** - * Returns the button value for the given joystick \a index and \a button ID - */ -bool QJoysticks::getButton(const int index, const int button) -{ - if (joystickExists(index)) - return getInputDevice(index)->buttons.at(button); - - return false; -} - -/** - * Returns the number of axes that the joystick at the given \a index has. - */ -int QJoysticks::getNumAxes(const int index) -{ - if (joystickExists(index)) - return getInputDevice(index)->axes.count(); - - return -1; -} - -/** - * Returns the number of POVs that the joystick at the given \a index has. - */ -int QJoysticks::getNumPOVs(const int index) -{ - if (joystickExists(index)) - return getInputDevice(index)->povs.count(); - - return -1; -} - -/** - * Returns the number of buttons that the joystick at the given \a index has. - */ -int QJoysticks::getNumButtons(const int index) -{ - if (joystickExists(index)) - return getInputDevice(index)->buttons.count(); - - return -1; -} - -/** - * Returns \c true if the joystick at the given \a index is blacklisted. - */ -bool QJoysticks::isBlacklisted(const int index) -{ - if (joystickExists(index)) - return inputDevices().at(index)->blacklisted; - - return true; -} - -/** - * Returns \c true if the joystick at the given \a index is valid, otherwise, - * the function returns \c false and warns the user through the console. - */ -bool QJoysticks::joystickExists(const int index) -{ - return (index >= 0) && (count() > index); -} - -/** - * Returns the name of the given joystick - */ -QString QJoysticks::getName(const int index) -{ - if (joystickExists(index)) - return m_devices.at(index)->name; - - return "Invalid Joystick"; -} - -/** - * Returns a pointer to the SDL joysticks system. - * This can be used if you need to get more information regarding the joysticks - * registered and managed with SDL. - */ -SDL_Joysticks *QJoysticks::sdlJoysticks() const -{ - return m_sdlJoysticks; -} - -/** - * Returns a pointer to the virtual joystick system. - * This can be used if you need to get more information regarding the virtual - * joystick or want to change its properties directly. - * - * \note You can also change the properties of the virtual joysticks using the - * functions of the \c QJoysticks system class - */ -VirtualJoystick *QJoysticks::virtualJoystick() const -{ - return m_virtualJoystick; -} - -/** - * Returns a pointer to the device at the given \a index. - */ -QJoystickDevice *QJoysticks::getInputDevice(const int index) -{ - if (joystickExists(index)) - return inputDevices().at(index); - - return Q_NULLPTR; -} - -/** - * Returns a pointer to a list containing all registered joysticks. - * This can be used for advanced hacks or just to get all properties of each - * joystick. - */ -QList QJoysticks::inputDevices() const -{ - return m_devices; -} - -/** - * If \a sort is set to true, then the device list will put all blacklisted - * joysticks at the end of the list - */ -void QJoysticks::setSortJoysticksByBlacklistState(bool sort) -{ - if (m_sortJoyticks != sort) - { - m_sortJoyticks = sort; - updateInterfaces(); - } -} - -/** - * Blacklists or whitelists the joystick at the given \a index. - * - * \note This function does not have effect if the given joystick does not exist - * \note Once the joystick is blacklisted, the joystick list will be updated - */ -void QJoysticks::setBlacklisted(const int index, bool blacklisted) -{ - Q_ASSERT(joystickExists(index)); - - /* Netrualize the joystick */ - if (blacklisted) - { - for (int i = 0; i < getNumAxes(index); ++i) - emit axisChanged(index, i, 0); - - for (int i = 0; i < getNumButtons(index); ++i) - emit buttonChanged(index, i, false); - - for (int i = 0; i < getNumPOVs(index); ++i) - emit povChanged(index, i, 0); - } - - /* See if blacklist value was actually changed */ - bool changed = m_devices.at(index)->blacklisted != blacklisted; - - /* Save settings */ - m_devices.at(index)->blacklisted = blacklisted; - m_settings->setValue(getName(index), blacklisted); - - /* Re-scan joysticks if blacklist value has changed */ - if (changed) - updateInterfaces(); -} - -/** - * 'Rescans' for new/removed joysticks and registers them again. - */ -void QJoysticks::updateInterfaces() -{ - m_devices.clear(); - - /* Put blacklisted joysticks at the bottom of the list */ - if (m_sortJoyticks) - { - /* Register non-blacklisted SDL joysticks */ - foreach (QJoystickDevice *joystick, sdlJoysticks()->joysticks()) - { - joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); - if (!joystick->blacklisted) - addInputDevice(joystick); - } - - /* Register the virtual joystick (if its not blacklisted) */ - if (virtualJoystick()->joystickEnabled()) - { - QJoystickDevice *joystick = virtualJoystick()->joystick(); - joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); - - if (!joystick->blacklisted) - { - addInputDevice(joystick); - virtualJoystick()->setJoystickID(inputDevices().count() - 1); - } - } - - /* Register blacklisted SDL joysticks */ - foreach (QJoystickDevice *joystick, sdlJoysticks()->joysticks()) - { - joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); - if (joystick->blacklisted) - addInputDevice(joystick); - } - - /* Register the virtual joystick (if its blacklisted) */ - if (virtualJoystick()->joystickEnabled()) - { - QJoystickDevice *joystick = virtualJoystick()->joystick(); - joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); - - if (joystick->blacklisted) - { - addInputDevice(joystick); - virtualJoystick()->setJoystickID(inputDevices().count() - 1); - } - } - } - - /* Sort normally */ - else - { - /* Register SDL joysticks */ - foreach (QJoystickDevice *joystick, sdlJoysticks()->joysticks()) - { - addInputDevice(joystick); - joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); - } - - /* Register virtual joystick */ - if (virtualJoystick()->joystickEnabled()) - { - QJoystickDevice *joystick = virtualJoystick()->joystick(); - joystick->blacklisted = m_settings->value(joystick->name, false).toBool(); - - addInputDevice(joystick); - virtualJoystick()->setJoystickID(inputDevices().count() - 1); - } - } - - emit countChanged(); -} - -/** - * Changes the axis value range of the virtual joystick. - * - * Take into account that maximum axis values supported by the \c QJoysticks - * system is from \c -1 to \c 1. - */ -void QJoysticks::setVirtualJoystickRange(qreal range) -{ - virtualJoystick()->setAxisRange(range); -} - -/** - * Enables or disables the virtual joystick - */ -void QJoysticks::setVirtualJoystickEnabled(bool enabled) -{ - virtualJoystick()->setJoystickEnabled(enabled); -} - -void QJoysticks::setVirtualJoystickAxisSensibility(qreal sensibility) -{ - virtualJoystick()->setAxisSensibility(sensibility); -} - -/** - * Removes all the registered joysticks and emits appropriate signals. - */ -void QJoysticks::resetJoysticks() -{ - m_devices.clear(); - emit countChanged(); -} - -/** - * Registers the given \a device to the \c QJoysticks system - */ -void QJoysticks::addInputDevice(QJoystickDevice *device) -{ - Q_ASSERT(device); - m_devices.append(device); -} - -/** - * Configures the QML-friendly signal based on the information given by the - * \a event data and updates the joystick values - */ -void QJoysticks::onPOVEvent(const QJoystickPOVEvent &e) -{ - if (e.joystick == nullptr) - return; - - if (!isBlacklisted(e.joystick->id)) - { - if (e.pov < getInputDevice(e.joystick->id)->povs.count()) - { - getInputDevice(e.joystick->id)->povs[e.pov] = e.angle; - emit povChanged(e.joystick->id, e.pov, e.angle); - } - } -} - -/** - * Configures the QML-friendly signal based on the information given by the - * \a event data and updates the joystick values - */ -void QJoysticks::onAxisEvent(const QJoystickAxisEvent &e) -{ - if (e.joystick == nullptr) - return; - - if (!isBlacklisted(e.joystick->id)) - { - if (e.axis < getInputDevice(e.joystick->id)->axes.count()) - { - getInputDevice(e.joystick->id)->axes[e.axis] = e.value; - emit axisChanged(e.joystick->id, e.axis, e.value); - } - } -} - -/** - * Configures the QML-friendly signal based on the information given by the - * \a event data and updates the joystick values - */ -void QJoysticks::onButtonEvent(const QJoystickButtonEvent &e) -{ - if (e.joystick == nullptr) - return; - - if (!isBlacklisted(e.joystick->id)) - { - if (e.button < getInputDevice(e.joystick->id)->buttons.count()) - { - getInputDevice(e.joystick->id)->buttons[e.button] = e.pressed; - emit buttonChanged(e.joystick->id, e.button, e.pressed); - } - } -} diff --git a/src/trainControllerUI/mainobject.cpp b/src/trainControllerUI/mainobject.cpp deleted file mode 100644 index 3a0558b..0000000 --- a/src/trainControllerUI/mainobject.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "mainobject.h" - -MainObject::MainObject(QIODevice* ioDevice) : - masterIODevice(ioDevice), - micro(masterIODevice) -{ - //connect item store - QObject::connect(µ, &Microcontroller::gotItemList, &items, &ItemStore::addItems); -} - -MainObject::~MainObject() -{ -} - diff --git a/src/trainControllerUI/traincontrollerui.cpp b/src/trainControllerUI/traincontrollerui.cpp deleted file mode 100644 index 6541439..0000000 --- a/src/trainControllerUI/traincontrollerui.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "microcontroller.h" -#include "trainjs.h" -#include "ui/mainwindow.h" -#include "itemstore.h" -#include "train.h" -#include "turnout.h" -#include "trainsignal.h" - -#define BAUD QSerialPort::Baud38400 - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - - //set info - QCoreApplication::setOrganizationName("UVOS"); - QCoreApplication::setOrganizationDomain("uvos.xyz"); - QCoreApplication::setApplicationName("traincontrollerui"); - QCoreApplication::setApplicationVersion("0.1"); - - QDir::setCurrent(a.applicationDirPath()); - - //parse comand line - QCommandLineParser parser; - parser.setApplicationDescription("Train control gui"); - parser.addHelpOption(); - parser.addVersionOption(); - QCommandLineOption tcpOption(QStringList() << "t" << "tcp", QCoreApplication::translate("main", "Use Tcp connection")); - parser.addOption(tcpOption); - QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", - "Set server host ip addres"), "adress"); - parser.addOption(hostOption); - QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", - "Set server Port in TCP mode or Serial port in serial mode"), "port"); - parser.addOption(portOption); - QCommandLineOption serialOption(QStringList() << "s" << "serial", QCoreApplication::translate("main", - "Use serial connection")); - parser.addOption(serialOption); - QCommandLineOption baudOption(QStringList() << "b" << "baud", QCoreApplication::translate("main", "Set Baud Rate")); - parser.addOption(baudOption); - parser.process(a); - - QIODevice* masterIODevice = nullptr; - - if(parser.isSet(tcpOption)) - { - QTcpSocket* microSocket = new QTcpSocket; - - int port = 6856; - if(parser.isSet(portOption)) port = parser.value(portOption).toInt(); - - QString host("127.0.0.1"); - if(parser.isSet(hostOption)) host = parser.value(hostOption); - std::cout<<"connecting to "<connectToHost(host, port, QIODevice::ReadWrite); - if(!microSocket->waitForConnected(3000)) - { - std::cout<<"Can not connect to to Server.\n"; - QMessageBox::critical(nullptr, "Error", "Can not connect to to Server"); - return 1; - } - masterIODevice = microSocket; - } - else - { - QSerialPort* microPort = new QSerialPort; - if(parser.isSet(portOption)) microPort->setPortName(parser.value(portOption)); - else microPort->setPortName("ttyUSB0"); - - if(parser.isSet(portOption)) microPort->setBaudRate(parser.value(baudOption).toInt()); - else microPort->setBaudRate(BAUD); - - if(!microPort->open(QIODevice::ReadWrite)) - { - QMessageBox::critical(nullptr, "Error", QString("Can not open serial port ")+microPort->portName()); - std::cout<<"Can not open serial port "<portName().toStdString()<<". Continueing in demo mode"<<'\n'; - return 1; - } - masterIODevice = microPort; - } - - Microcontroller micro(masterIODevice); - micro.setPower(true); - - TrainJs::init(); - - Train::micro = µ - Turnout::micro = µ - Signal::micro = µ - ItemStore items; - - QObject::connect(µ, &Microcontroller::gotItemList, &items, &ItemStore::addItems); - QObject::connect(µ, &Microcontroller::itemChanged, &items, &ItemStore::itemStateChanged); - - //mainwindow - MainWindow w(µ, &items); - - w.show(); - - int retVal = a.exec(); - micro.setPower(false); - - if(masterIODevice) - delete masterIODevice; - return retVal; -} - diff --git a/src/trainControllerUI/ui/itemscrollbox.cpp b/src/trainControllerUI/ui/itemscrollbox.cpp deleted file mode 100644 index 50f4d7b..0000000 --- a/src/trainControllerUI/ui/itemscrollbox.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "itemscrollbox.h" -#include "ui_relayscrollbox.h" -#include "ui_relayscrollbox.h" -#include "train.h" -#include "turnout.h" -#include "trainsignal.h" -#include "trainjs.h" -#include "trainwidget.h" -#include "signalwidget.h" - -ItemScrollBox::ItemScrollBox(QWidget *parent) : - QWidget(parent), - ui(new Ui::RelayScrollBox) -{ - ui->setupUi(this); - QScroller::grabGesture(ui->scrollArea, QScroller::TouchGesture); - QScroller::grabGesture(ui->scrollArea, QScroller::LeftMouseButtonGesture); -} - -ItemScrollBox::~ItemScrollBox() -{ - delete ui; -} - -void ItemScrollBox::addItem(std::weak_ptr item) -{ - if(auto workItem = item.lock()) - { - Train* train = dynamic_cast(workItem.get()); - Turnout* turnout = dynamic_cast(workItem.get()); - Signal* signal = dynamic_cast(workItem.get()); - if(train) - { - TrainWidget *widget = new TrainWidget(item, this); - widgets_.push_back(widget); - if(train->getTrainId() == 0) - widget->setShortcuts(QKeySequence(Qt::Key_Q), QKeySequence(Qt::Key_A), QKeySequence(Qt::Key_Z)); - else if(train->getTrainId() == 1) - widget->setShortcuts(QKeySequence(Qt::Key_W), QKeySequence(Qt::Key_S), QKeySequence(Qt::Key_X)); - else if(train->getTrainId() == 2) - widget->setShortcuts(QKeySequence(Qt::Key_E), QKeySequence(Qt::Key_D), QKeySequence(Qt::Key_C)); - else if(train->getTrainId() == 3) - widget->setShortcuts(QKeySequence(Qt::Key_R), QKeySequence(Qt::Key_F), QKeySequence(Qt::Key_V)); - else if(train->getTrainId() == 4) - widget->setShortcuts(QKeySequence(Qt::Key_T), QKeySequence(Qt::Key_G), QKeySequence(Qt::Key_B)); - - std::vector> joysticks = TrainJs::getJsDevices(); - for(auto joystick: joysticks) - { - if(!joystick->itemIsSet()) - { - joystick->setItem(item); - connect(joystick.get(), &TrainJs::reqNewItem, this, &ItemScrollBox::jsReqNewItem); - break; - } - } - } - else if(turnout) - { - TrainWidget *widget = new TrainWidget(item, this); - widgets_.push_back(widget); - if(turnout->getTurnoutId() == 0) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_1)); - else if(turnout->getTurnoutId() == 1) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_2)); - else if(turnout->getTurnoutId() == 2) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_3)); - else if(turnout->getTurnoutId() == 3) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_4)); - else if(turnout->getTurnoutId() == 4) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_5)); - else if(turnout->getTurnoutId() == 5) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_6)); - else if(turnout->getTurnoutId() == 6) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_7)); - else if(turnout->getTurnoutId() == 7) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_8)); - else if(turnout->getTurnoutId() == 8) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_9)); - else if(turnout->getTurnoutId() == 9) - widget->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_0)); - } - else if(signal) - { - SignalWidget *widget = new SignalWidget(item, this); - widgets_.push_back(widget); - } - ui->relayWidgetVbox->addWidget(widgets_.back()); - connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest); - connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem); - } -} - -void ItemScrollBox::jsReqNewItem() -{ - if(widgets_.empty()) - return; - - std::vector> joysticks = TrainJs::getJsDevices(); - for(auto joystick: joysticks) - { - if(joystick->getWantsNewItem()) - { - std::shared_ptr oldItem = joystick->getItem().lock(); - for(size_t i = 0; i < widgets_.size(); ++i) - { - std::shared_ptr item = widgets_[i]->getItem().lock(); - if(item && (!oldItem || *item == *oldItem)) - { - for(size_t j = 1; j < widgets_.size(); ++j) - { - ItemWidget* widget = widgets_[(i+j) % widgets_.size()]; - std::shared_ptr item = widgets_[i]->getItem().lock(); - if(item && dynamic_cast(item.get())) - { - joystick->setItem(item); - break; - } - } - break; - } - } - } - } -} - -void ItemScrollBox::removeItem(const ItemData& item) -{ - for(unsigned i = 0; i < widgets_.size(); i++) - { - if(widgets_[i]->controles(item)) - { - ui->relayWidgetVbox->removeWidget(widgets_[i]); - delete widgets_[i]; - widgets_.erase(widgets_.begin()+i); - } - } -} - - diff --git a/src/trainControllerUI/ui/itemwidget.cpp b/src/trainControllerUI/ui/itemwidget.cpp deleted file mode 100644 index b780b09..0000000 --- a/src/trainControllerUI/ui/itemwidget.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "itemwidget.h" - -#include -#include -#include -#include "../items/train.h" -#include "../items/turnout.h" - -ItemWidget::ItemWidget(std::weak_ptr item, QWidget *parent) : - QWidget(parent), - item_(item) -{ - qDebug()<<__func__<<" "<<(bool)item_.lock(); - -} - -bool ItemWidget::controles(const ItemData& relay) -{ - if(auto workingRelay = item_.lock()) - { - if(relay == *workingRelay) - return true; - else - return false; - } - return true; -} - -std::weak_ptr ItemWidget::getItem() -{ - return item_; -} - -ItemWidget::~ItemWidget() -{ -} diff --git a/src/trainControllerUI/ui/itemwidget.h b/src/trainControllerUI/ui/itemwidget.h deleted file mode 100644 index f4093d9..0000000 --- a/src/trainControllerUI/ui/itemwidget.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include -#include "../items/item.h" - -class ItemWidget : public QWidget -{ - Q_OBJECT -protected: - std::weak_ptr item_; - - virtual void disable(){} - -signals: - - void deleteRequest(const ItemData& item); - -public: - explicit ItemWidget(std::weak_ptr item, QWidget *parent); - std::weak_ptr getItem(); - bool controles(const ItemData& relay); - ~ItemWidget(); - -public slots: - - virtual void stateChanged(int state){(void)state;} -}; - diff --git a/src/trainControllerUI/ui/mainwindow.cpp b/src/trainControllerUI/ui/mainwindow.cpp deleted file mode 100644 index b2d6b13..0000000 --- a/src/trainControllerUI/ui/mainwindow.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "mainwindow.h" -#include "ui_mainwindow.h" -#include "itemscrollbox.h" - -MainWindow::MainWindow(Microcontroller * const micro, ItemStore* items, QWidget *parent) : - QMainWindow(parent), - stopShort(QKeySequence(Qt::Key_Space), this), - ui(new Ui::MainWindow), - _micro(micro) -{ - ui->setupUi(this); - - connect(&stopShort, &QShortcut::activated, _micro, &Microcontroller::estop); - connect(ui->pushButton_stop, &QPushButton::clicked, _micro, &Microcontroller::estop); - connect(ui->pushButton_refesh, &QPushButton::clicked, _micro, &Microcontroller::requestState); - - connect(items, &ItemStore::itemAdded, ui->relayList, &ItemScrollBox::addItem); - connect(items, &ItemStore::itemDeleted, ui->relayList, &ItemScrollBox::removeItem); - - for(size_t i = 0; i < items->getItems()->size(); ++i) - { - ui->relayList->addItem(items->getItems()->at(i)); - } - - connect(ui->relayList, &ItemScrollBox::deleteRequest, items, &ItemStore::removeItem); - - ui->pushButton_addItem->hide(); -} - -MainWindow::~MainWindow() -{ - delete ui; -} - -/* -void MainWindow::showItemCreationDialog() -{ - ItemCreationDialog diag(this); - diag.show(); - if(diag.exec()) - { - createdItem(diag.item); - } -} -*/ diff --git a/src/trainControllerUI/ui/signalwidget.cpp b/src/trainControllerUI/ui/signalwidget.cpp deleted file mode 100644 index 6bb722b..0000000 --- a/src/trainControllerUI/ui/signalwidget.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "signalwidget.h" -#include "ui_signalwidget.h" - -#include -#include -#include -#include "trainsignal.h" - -SignalWidget::SignalWidget(std::weak_ptr item, QWidget *parent) : - ItemWidget(item, parent), - ui(new Ui::SignalWidget) -{ - ui->setupUi(this); - - if(auto workingItem = item_.lock()) - { - std::shared_ptr signal = std::dynamic_pointer_cast(workingItem); - if(signal) - { - - ui->label->setText(workingItem->getName()); - - connect(ui->radioButton_go, &QRadioButton::clicked, this, [this]() - { - setValue(Signal::GO); - }); - connect(ui->radioButton_slow, &QRadioButton::clicked, this, [this]() - { - setValue(Signal::SLOW); - }); - connect(ui->radioButton_stop, &QRadioButton::clicked, this, [this]() - { - setValue(Signal::STOP); - }); - - connect(signal.get(), &Item::valueChanged, this, &SignalWidget::moveToValue); - - if(!signal->hasSlow()) - ui->radioButton_slow->hide(); - } - } - else - { - qWarning("SignalWidget got invalid item"); - SignalWidget::disable(); - } -} - -void SignalWidget::deleteItem() -{ - if(auto workingItem = item_.lock()) - { - deleteRequest(*workingItem); - } -} - -void SignalWidget::setValue(int8_t value) -{ - if(auto workingItem = item_.lock()) - workingItem->setValue(value); - else - disable(); -} - -void SignalWidget::moveToValue(int8_t value) -{ - qDebug()<<"got value"<radioButton_go->blockSignals(true); - ui->radioButton_slow->blockSignals(true); - ui->radioButton_stop->blockSignals(true); - - ui->radioButton_go->setChecked(value == Signal::GO); - ui->radioButton_slow->setChecked(value == Signal::SLOW); - ui->radioButton_stop->setChecked(value == Signal::STOP); - - ui->radioButton_go->blockSignals(false); - ui->radioButton_slow->blockSignals(false); - ui->radioButton_stop->blockSignals(false); -} - -void SignalWidget::disable() -{ - ui->radioButton_go->setEnabled(false); - ui->radioButton_slow->setEnabled(false); - ui->radioButton_stop->setEnabled(false); -} - -void SignalWidget::stateChanged(int state) -{ - moveToValue(state); -} - -SignalWidget::~SignalWidget() -{ - delete ui; -} diff --git a/src/trainControllerUI/ui/signalwidget.h b/src/trainControllerUI/ui/signalwidget.h deleted file mode 100644 index 6cc36f3..0000000 --- a/src/trainControllerUI/ui/signalwidget.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include -#include -#include "../items/trainsignal.h" -#include "itemwidget.h" - -namespace Ui -{ -class SignalWidget; -} - -class SignalWidget : public ItemWidget -{ - Q_OBJECT -protected: - - virtual void disable(); - -private slots: - void moveToValue(int8_t value); - void setValue(int8_t value); - void deleteItem(); - -public: - explicit SignalWidget(std::weak_ptr item, QWidget *parent); - ~SignalWidget(); - -public slots: - - virtual void stateChanged(int state); - -private: - Ui::SignalWidget *ui; -}; diff --git a/src/trainControllerUI/ui/signalwidget.ui b/src/trainControllerUI/ui/signalwidget.ui deleted file mode 100644 index 2f6a4ed..0000000 --- a/src/trainControllerUI/ui/signalwidget.ui +++ /dev/null @@ -1,98 +0,0 @@ - - - SignalWidget - - - - 0 - 0 - 312 - 78 - - - - - 0 - 0 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - TextLabel - - - - - - - - - - - Go - - - true - - - - - - - Slow - - - false - - - - - - - Stop - - - - - - - - - - - - - Qt::Horizontal - - - - - - - - diff --git a/src/trainControllerUI/ui/trainwidget.cpp b/src/trainControllerUI/ui/trainwidget.cpp deleted file mode 100644 index 59bd65c..0000000 --- a/src/trainControllerUI/ui/trainwidget.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "trainwidget.h" -#include "ui_trainwidget.h" - -#include -#include -#include -#include "../items/train.h" -#include "../items/turnout.h" - -TrainWidget::TrainWidget(std::weak_ptr item, QWidget *parent) : - ItemWidget(item, parent), - ui(new Ui::TrainWidget) -{ - ui->setupUi(this); - if(auto workingItem = item_.lock()) - { - ui->label->setText(workingItem->getName()); - - connect(ui->slider, &QSlider::valueChanged, this, &TrainWidget::setValue); - connect(ui->checkBox_f1, &QCheckBox::stateChanged, this, &TrainWidget::f1); - connect(ui->checkBox_f2, &QCheckBox::stateChanged, this, &TrainWidget::f2); - connect(ui->checkBox_f3, &QCheckBox::stateChanged, this, &TrainWidget::f3); - connect(ui->checkBox_f4, &QCheckBox::stateChanged, this, &TrainWidget::f4); - connect(ui->pushButton_reverse, &QPushButton::clicked, this, &TrainWidget::reverse); - connect(ui->radioButton_left, &QRadioButton::clicked, this, [this]() - { - setValue(0); - }); - connect(ui->radioButton_right, &QRadioButton::clicked, this, [this]() - { - setValue(1); - }); - - connect(workingItem.get(), &Item::valueChanged, this, &TrainWidget::moveToValue); - - Train* train = dynamic_cast(workingItem.get()); - Turnout* turnout = dynamic_cast(workingItem.get()); - - if(turnout) - { - ui->checkBox_f1->hide(); - ui->checkBox_f2->hide(); - ui->checkBox_f3->hide(); - ui->checkBox_f4->hide(); - ui->slider->hide(); - } - - if(!train) - { - ui->pushButton_reverse->hide(); - } - else - { - ui->radioButton_left->hide(); - ui->radioButton_right->hide(); - uint8_t functionMask = train->getFunctionMask(); - qDebug()<<"functionMask: "<<(int)functionMask; - if(!(functionMask & (1 << 0))) - ui->checkBox_f1->hide(); - if(!(functionMask & (1 << 1))) - ui->checkBox_f2->hide(); - if(!(functionMask & (1 << 2))) - ui->checkBox_f3->hide(); - if(!(functionMask & (1 << 3))) - ui->checkBox_f4->hide(); - } - } - else - { - qWarning("TrainWidget got invalid item"); - TrainWidget::disable(); - } -} - -void TrainWidget::deleteItem() -{ - if(auto workingItem = item_.lock()) - { - deleteRequest(*workingItem); - } -} - -void TrainWidget::setValue(int8_t value) -{ - if(auto workingItem = item_.lock()) - workingItem->setValue(value); - else - disable(); -} - -void TrainWidget::moveToValue(int8_t value) -{ - ui->slider->blockSignals(true); - ui->radioButton_left->blockSignals(true); - ui->radioButton_right->blockSignals(true); - - ui->pushButton_reverse->setText(value == 0 ? "Reverse" : "Stop"); - ui->slider->setValue(value); - ui->radioButton_left->setChecked(!value); - ui->radioButton_right->setChecked(value); - - ui->slider->blockSignals(false); - ui->radioButton_left->blockSignals(false); - ui->radioButton_right->blockSignals(false); -} - -void TrainWidget::f1(int value) -{ - if(auto workingItem = item_.lock()) - workingItem->setFunction(0, value == Qt::Checked); - else disable(); -} - -void TrainWidget::f2(int value) -{ - if(auto workingItem = item_.lock()) - workingItem->setFunction(1, value == Qt::Checked); - else disable(); -} - - -void TrainWidget::f3(int value) -{ - if(auto workingItem = item_.lock()) - workingItem->setFunction(2, value == Qt::Checked); - else disable(); -} - -void TrainWidget::f4(int value) -{ - if(auto workingItem = item_.lock()) - workingItem->setFunction(3, value == Qt::Checked); - else disable(); -} - -void TrainWidget::reverse() -{ - if(auto workingItem = item_.lock()) - { - Train* train = dynamic_cast(workingItem.get()); - if(train && workingItem->getValue() == 0) - train->reverse(); - else - { - setValue(!((bool)workingItem->getValue())); - } - } - else disable(); -} - -void TrainWidget::disable() -{ - ui->checkBox_f1->setEnabled(false); - ui->checkBox_f2->setEnabled(false); - ui->checkBox_f3->setEnabled(false); - ui->checkBox_f4->setEnabled(false); - ui->label->setEnabled(false); - ui->slider->setEnabled(false); - ui->pushButton_reverse->setEnabled(false); -} - -void TrainWidget::stepUp() -{ - setValue(ui->slider->value()+1); -} - -void TrainWidget::stepDown() -{ - setValue(ui->slider->value()-1); -} - -void TrainWidget::setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev) -{ - shortcuts_.clear(); - shortcuts_.push_back(std::unique_ptr(new QShortcut(up, this))); - connect(shortcuts_.back().get(), &QShortcut::activated, this, &TrainWidget::stepUp); - shortcuts_.push_back(std::unique_ptr(new QShortcut(down, this))); - connect(shortcuts_.back().get(), &QShortcut::activated, this, &TrainWidget::stepDown); - shortcuts_.push_back(std::unique_ptr(new QShortcut(rev, this))); - connect(shortcuts_.back().get(), &QShortcut::activated, this, &TrainWidget::reverse); -} - -void TrainWidget::stateChanged(int state) -{ - qDebug()<<"widget got state "<slider->blockSignals(true); - ui->slider->setValue(state); - ui->slider->blockSignals(false); -} - -TrainWidget::~TrainWidget() -{ - delete ui; -} diff --git a/src/trainControllerUI/ui/trainwidget.h b/src/trainControllerUI/ui/trainwidget.h deleted file mode 100644 index d2edca4..0000000 --- a/src/trainControllerUI/ui/trainwidget.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include -#include -#include "../items/item.h" -#include "itemwidget.h" - -namespace Ui -{ -class TrainWidget; -} - -class TrainWidget : public ItemWidget -{ - Q_OBJECT -protected: - std::vector< std::unique_ptr > shortcuts_; - - void disable(); - -private slots: - void setValue(int8_t value); - void moveToValue(int8_t value); - void deleteItem(); - - void stepUp(); - void stepDown(); - - void f1(int state); - void f2(int state); - void f3(int state); - void f4(int state); - void reverse(); - -public: - explicit TrainWidget(std::weak_ptr item, QWidget *parent); - ~TrainWidget(); - void setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev); - -public slots: - - virtual void stateChanged(int state); - -private: - Ui::TrainWidget *ui; -}; - diff --git a/src/trainOverlord/CMakeLists.txt b/src/trainOverlord/CMakeLists.txt deleted file mode 100644 index ce7f463..0000000 --- a/src/trainOverlord/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(UI_SOURCES - trainoverlord.cpp - overlorditemstore.cpp - overlorditemstore.h - blockborder.cpp - blockborder.h - block.cpp - block.h - layout.h - layout.cpp -) - -add_executable(trainoverlord ${UI_SOURCES} ${COMMON_SOURCES}) -target_link_libraries(trainoverlord PRIVATE ${COMMON_LINK_LIBRARYS}) -target_include_directories(trainoverlord PRIVATE ./) diff --git a/src/trainOverlord/block.cpp b/src/trainOverlord/block.cpp deleted file mode 100644 index 0c9b23d..0000000 --- a/src/trainOverlord/block.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#include "block.h" -#include -#include -#include -#include "nfcuid.h" - - -Block::Block(OverlordItemStore* items, uint32_t id): - items_(items), id_(id) -{ - -} - -void Block::addBorder(std::shared_ptr border) -{ - borders_.push_back(border); - std::shared_ptr block = border->getOtherBlock(this); - if(!block || block.get() == this) - return; - connect(block.get(), &Block::blockedChanged, this, &Block::checkWaits); -} - -bool Block::blocked() -{ - if(tags_.empty() && waits_.empty()) - return false; - return true; -} - -bool Block::ownsTag(const NfcUid& tag) -{ - for(const NfcUid& candiate : tags_) - { - if(candiate == tag) - return true; - } - return false; -} - -bool Block::tagIsOfOwnedTrain(const NfcUid& tag) -{ - std::shared_ptr train = items_->getTrainThatOwns(tag); - if(!train) - return false; - for(const NfcUid& canidate : tags_) - { - std::shared_ptr canidateTrain = items_->getTrainThatOwns(canidate); - if(*canidateTrain == *train) - return true; - } - return false; -} - -bool Block::ownsBorder(std::shared_ptr border) -{ - if(!border) - return false; - for(std::shared_ptr borderTest : borders_) - { - if(borderTest == border) - return true; - } - return false; -} - -void Block::checkWaits(bool isBlocked) -{ - if(isBlocked) - return; - bool wasBlocked = blocked(); - for(std::vector::iterator iter = waits_.begin(); iter != waits_.end();) - { - if(iter->type != WAIT_TYPE_BLOCK) - { - ++iter; - continue; - } - - std::shared_ptr block = iter->targetBlock.lock(); - std::shared_ptr train = iter->train.lock(); - qDebug()<<__func__<<"trying to push train"<getTrainId()<<"to block"<id(); - if(block && train && train->suspendend() && block->pushTag(iter->tag)) - { - train->resume(); - std::shared_ptr border = iter->border.lock(); - if(border) - border->updateSignals(); - iter = waits_.erase(iter); - } - else if(!block || !train || !train->suspendend()) - { - iter = waits_.erase(iter); - } - else - { - ++iter; - } - } - if(wasBlocked != blocked()) - blockedChanged(!wasBlocked); -} - -bool Block::pushTag(const NfcUid& tag) -{ - if(!blocked() || tagIsOfOwnedTrain(tag)) - { - addTag(tag); - return true; - } - return false; -} - -void Block::removeTraverse(std::shared_ptr train) -{ - bool wasBlocked = blocked(); - for(std::vector::iterator iter = waits_.begin(); iter != waits_.end();) - { - if(iter->type == WAIT_TYPE_TIMED_TRAVERSE) - { - std::shared_ptr iterTrain = iter->train.lock(); - if(!iterTrain) - { - iter = waits_.erase(iter); - continue; - } - if(*iterTrain == *train) - { - qDebug()<<"Train"<getTrainId()<<"removed from traverse wait for block"< train = items_->getTrainThatOwns(tag); - if(!train) - return; - if(!train->hasBackTag()) - { - qDebug()<<"Train"<getTrainId()<<"added as timed traverse wait for block"< block, std::shared_ptr border) -{ - std::shared_ptr train = items_->getTrainThatOwns(tag); - if(!train) - return; - Wait wait; - wait.type = WAIT_TYPE_BLOCK; - wait.train = train; - wait.direction = train->getDirection(); - wait.targetBlock = block; - wait.border = border; - wait.tag = tag; - connect(train.get(), &Train::unsuspended, this, &Block::unsuspendedTrain); - waits_.push_back(wait); - qDebug()<<"Train"<getTrainId()<<"is wating at border for block"<id(); -} - -void Block::addTag(const NfcUid& tag) -{ - bool wasBlocked = blocked(); - tags_.push_back(tag); - if(wasBlocked != blocked()) - blockedChanged(!wasBlocked); -} - -void Block::unsuspendedTrain(uint32_t id, int direction) -{ - qDebug()<<"Train with item id"<::iterator iter = waits_.begin(); iter != waits_.end(); ++iter) - { - std::shared_ptr workTrain = iter->train.lock(); - if(!workTrain) - { - waits_.erase(iter); - unsuspendedTrain(id, direction); - break; - } - if(workTrain->id() == id) - { - std::shared_ptr block = iter->targetBlock.lock(); - disconnect(workTrain.get(), &Train::unsuspended, this, &Block::unsuspendedTrain); - if(block) - block->addTag(iter->tag); - waits_.erase(iter); - break; - } - } - if(wasBlocked != blocked()) - blockedChanged(!wasBlocked); -} - -void Block::removeTag(const NfcUid& tag) -{ - for(std::vector::iterator iter = tags_.begin(); iter != tags_.end(); ++iter) - { - if(*iter == tag) - { - tags_.erase(iter); - break; - } - } -} - -void Block::purgeTag(const NfcUid& tag) -{ - bool wasBlocked = blocked(); - removeTag(tag); - std::shared_ptr train = items_->getTrainThatOwns(tag); - if(train) - removeTraverse(train); - if(wasBlocked != blocked()) - blockedChanged(!wasBlocked); -} - -void Block::tagArrivedAtBorder(NfcUid tag, std::weak_ptr borderIn) -{ - bool wasBlocked = blocked(); - qDebug()<<__func__<<"block"< border = borderIn.lock(); - if(!border) - { - qWarning()<<"border has expired in"<<__func__; - return; - } - - if(!ownsBorder(border)) - return; - - qDebug()<<"Block"<getOtherBlock(this); - if(block) - { - if(!block->pushTag(tag)) - { - std::shared_ptr train = items_->getTrainThatOwns(tag); - train->suspend(); - addBlockWait(tag, block, border); - } - else - { - addTraverseWait(tag); - } - removeTag(tag); - } - if(wasBlocked != blocked()) - blockedChanged(!wasBlocked); -} - -void Block::store(QJsonObject &json) -{ - json["Id"] = static_cast(id_); - QJsonArray borders; - for(auto& border : borders_) - { - QJsonObject borderObject; - borderObject["BorderId"] = static_cast(border->id()); - borders.append(borderObject); - } - json["Borders"] = borders; -} - -void Block::load(const QJsonObject &json) -{ - id_ = static_cast(json["Id"].toDouble(0)); -} - -void Block::populate(const QJsonObject& json, Layout* layout) -{ - borders_.clear(); - const QJsonArray bordersArray(json["Borders"].toArray(QJsonArray())); - for(const auto& arrayObj : bordersArray) - { - if(arrayObj.isObject()) - { - uint32_t borderId = static_cast(arrayObj.toObject()["BorderId"].toDouble(INT32_MAX)); - std::shared_ptr border = layout->getBorder(borderId); - if(border) - addBorder(border); - else if(borderId == INT32_MAX) - qWarning()<<"BorderId field is missing in border array for block"< -#include -#include -#include -#include -#include "blockborder.h" -#include "train.h" -#include "overlorditemstore.h" - -class BlockBorder; -class Layout; - -class Block: public QObject -{ - Q_OBJECT -protected: - static constexpr int WAIT_TYPE_BLOCK = 0; - static constexpr int WAIT_TYPE_TIMED_TRAVERSE = 1; - - struct Wait - { - int type; - int direction; - NfcUid tag; - std::weak_ptr train; - std::weak_ptr targetBlock; - std::weak_ptr border; - }; - - std::vector< std::shared_ptr > borders_; - std::vector tags_; - std::vector waits_; - uint32_t id_; - OverlordItemStore* items_; - -protected slots: - void unsuspendedTrain(uint32_t id, int direction); - void removeTraverse(std::shared_ptr train); - -protected: - void checkWaits(bool blocked = false); - void addTraverseWait(const NfcUid& tag); - void addBlockWait(const NfcUid& tag, std::shared_ptr block, std::shared_ptr border); - void removeTag(const NfcUid& tag); - bool tagIsOfOwnedTrain(const NfcUid& tag); - -public: - Block(OverlordItemStore* items, uint32_t id = QRandomGenerator::global()->generate()); - uint32_t id(){return id_;} - - void addBorder(std::shared_ptr border); - std::vector< std::shared_ptr > getBorders(){return borders_;} - bool ownsBorder(std::shared_ptr border); - - bool pushTag(const NfcUid& tag); - void addTag(const NfcUid& tag); - void purgeTag(const NfcUid& tag); - bool ownsTag(const NfcUid& tag); - - bool blocked(); - - void store(QJsonObject& json); - void load(const QJsonObject& json); - void populate(const QJsonObject& json, Layout* layout); - -public slots: - void tagArrivedAtBorder(NfcUid tag, std::weak_ptr border); - -signals: - void blockedChanged(bool blocked); -}; - -#endif // BLOCK_H diff --git a/src/trainOverlord/blockborder.cpp b/src/trainOverlord/blockborder.cpp deleted file mode 100644 index f6ec684..0000000 --- a/src/trainOverlord/blockborder.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include "blockborder.h" -#include -#include - -BlockBorder::BlockBorder(uint8_t reader, std::pair, std::weak_ptr> blocks, uint32_t id): reader_(reader), id_(id) -{ - setBlocks(blocks); -} - -bool BlockBorder::isReader(uint8_t reader) -{ - return reader == reader_; -} - -uint8_t BlockBorder::getReader() -{ - return reader_; -} - -void BlockBorder::setBlocks(std::pair, std::weak_ptr> blocks) -{ - blocks_ = blocks; - std::shared_ptr first = blocks.first.lock(); - if(first) - connect(first.get(), &Block::blockedChanged, this, &BlockBorder::blockedChanged); - std::shared_ptr second = blocks.second.lock(); - if(second) - connect(second.get(), &Block::blockedChanged, this, &BlockBorder::blockedChanged); -} - -void BlockBorder::setSignal(std::weak_ptr signalWeak, int8_t value) -{ - std::shared_ptr signal = signalWeak.lock(); - if(signal) - { - signal->setValue(value); - } -} - -void BlockBorder::blockedChanged(bool blocked) -{ - (void)blocked; - updateSignals(); -} - -void BlockBorder::updateSignals() -{ - for(size_t i = 0; i < signals_.size(); ++i) - { - std::shared_ptr signal = signals_[i].lock(); - if(signal) - { - std::shared_ptr block = signalDirections_[i] ? blocks_.first.lock() : blocks_.second.lock(); - if(block && block->blocked()) - { - if(signal->getValue() != Signal::STOP) - { - std::weak_ptr signalWeak = signal; - QTimer::singleShot(500, signal.get(), [signalWeak](){BlockBorder::setSignal(signalWeak, Signal::STOP);}); - } - } - else - { - if(signal->getValue() != Signal::GO) - { - std::weak_ptr signalWeak = signal; - QTimer::singleShot(500, signal.get(), [signalWeak](){BlockBorder::setSignal(signalWeak, Signal::GO);}); - } - } - } - else - { - signals_.erase(signals_.begin()+i); - updateSignals(); - break; - } - } -} - -void BlockBorder::addSignal(std::weak_ptr signal, std::shared_ptr block) -{ - signals_.push_back(signal); - signalDirections_.push_back(block == blocks_.first.lock()); -} - -std::shared_ptr BlockBorder::getOtherBlock(Block* block) -{ - std::shared_ptr first = blocks_.first.lock(); - std::shared_ptr second = blocks_.second.lock(); - - if(first && first.get() == block) - return second; - if(second && second.get() == block) - return first; - return std::shared_ptr(); -} - -std::shared_ptr BlockBorder::getOverlap(BlockBorder* border) -{ - if(border->getBlocks().first.lock() == blocks_.first.lock() || border->getBlocks().first.lock() == blocks_.second.lock()) - { - return border->getBlocks().first.lock(); - } - else if(border->getBlocks().second.lock() == blocks_.first.lock() || border->getBlocks().second.lock() == blocks_.second.lock()) - { - return border->getBlocks().second.lock(); - } - return std::shared_ptr(); -} - -void BlockBorder::store(QJsonObject& json) -{ - json["Id"] = static_cast(id_); - json["Reader"] = static_cast(reader_); - QJsonArray signalArray; - for(size_t i = 0; i < signals_.size(); ++i) - { - std::shared_ptr signalPtr = signals_[i].lock(); - if(signalPtr) - { - QJsonObject signalObject; - signalObject["SignalId"] = static_cast(signalPtr->getSignalId()); - signalObject["Direction"] = static_cast(signalDirections_[i]); - signalArray.append(signalObject); - } - } - json["Signals"] = signalArray; -} - -void BlockBorder::load(const QJsonObject& json) -{ - id_ = static_cast(json["Id"].toDouble(0)); - reader_ = json["Reader"].toDouble(0); - const QJsonArray signalArray(json["Signals"].toArray(QJsonArray())); - for(const auto& arrayObj : signalArray) - { - if(arrayObj.isObject()) - { - QJsonObject arrayObjObj = arrayObj.toObject(); - signalIds_.push_back(std::pair(static_cast(arrayObjObj["SignalId"].toDouble(INT32_MAX)), static_cast(arrayObjObj["Direction"].toDouble(0)))); - } - } -} - -bool BlockBorder::hasMissingSingal() -{ - for(auto& signal : signalIds_) - { - qDebug()<<"Missing signal id:"< item) -{ - std::shared_ptr workItem = item.lock(); - if(!workItem) - return; - std::shared_ptr signal = std::dynamic_pointer_cast(workItem); - if(!signal) - return; - for(const std::pair& signalPair : signalIds_) - { - if(signalPair.first == signal->getSignalId()) - { - signals_.push_back(signal); - signalDirections_.push_back(signalPair.second); - qDebug()<<"Border"<getSignalId(); - } - } - std::erase_if(signalIds_, [signal](std::pair pair) -> bool{return pair.first == signal->getSignalId();}); -} diff --git a/src/trainOverlord/blockborder.h b/src/trainOverlord/blockborder.h deleted file mode 100644 index 8d72457..0000000 --- a/src/trainOverlord/blockborder.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef BLOCKBORDER_H -#define BLOCKBORDER_H -#include "trainsignal.h" -#include "block.h" -#include -#include - -class Block; -class Layout; - -class BlockBorder: public QObject -{ -Q_OBJECT -private: - uint64_t reader_; - uint32_t id_; - std::vector> signalIds_; - std::vector> signals_; - std::vector signalDirections_; - std::pair, std::weak_ptr> blocks_; - - static void setSignal(std::weak_ptr signalWeak, int8_t value); - -public: - BlockBorder(uint8_t reader = 0, std::pair, std::weak_ptr> blocks = std::pair, std::weak_ptr>(), uint32_t id = QRandomGenerator::global()->generate()); - bool isReader(uint8_t reader); - uint8_t getReader(); - void updateSignals(); - std::shared_ptr getOtherBlock(Block* block); - std::pair, std::weak_ptr> getBlocks(){return blocks_;} - void setBlocks(std::pair, std::weak_ptr> blocks); - void addSignal(std::weak_ptr signal, std::shared_ptr block); - void informOfItem(std::weak_ptr item); - bool hasMissingSingal(); - std::shared_ptr getOverlap(BlockBorder* border); - uint32_t id() {return id_;} - void store(QJsonObject& json); - void load(const QJsonObject& json); - -public slots: - void blockedChanged(bool blocked); -}; - -#endif // BLOCKBORDER_H diff --git a/src/trainOverlord/layout.cpp b/src/trainOverlord/layout.cpp deleted file mode 100644 index 8c27735..0000000 --- a/src/trainOverlord/layout.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "layout.h" -#include -#include - -Layout::Layout(OverlordItemStore* items, QObject *parent): QObject{parent}, items_(items) -{ -} - -void Layout::removeTagFromAllBlocks(const NfcUid& tag) -{ - for(std::shared_ptr block : blocks_) - { - block->purgeTag(tag); - } -} - -void Layout::registerTagInLimbo(const NfcUid& tag, std::shared_ptr border) -{ - for(auto iter = limbo_.begin(); iter != limbo_.end(); ++iter) - { - NfcUid limboTag = iter->first; - std::shared_ptr limboBorder = iter->second.lock(); - if(!limboBorder) - { - limbo_.erase(iter); - registerTagInLimbo(tag, border); - return; - } - - if(limboTag == tag) - { - if(border == limboBorder) - return; - - std::shared_ptr overlap = border->getOverlap(limboBorder.get()); - if(overlap) - { - qDebug()<<"Tag"<id()<<"while crossing border"<id(); - overlap->addTag(tag); - overlap->tagArrivedAtBorder(tag, border); - limbo_.erase(iter); - return; - } - else - { - iter->second = border; - return; - } - - } - } - std::shared_ptr first = border->getBlocks().first.lock(); - std::shared_ptr second = border->getBlocks().second.lock(); - - qDebug()<<"Tag"<id()) : "invalid")<<"and block"<<(second ? QString::number(second->id()) : "invalid"); - limbo_.push_back(std::pair>(tag, border)); -} - -void Layout::tagArrivedAtReader(uint8_t reader, NfcUid tag) -{ - std::shared_ptr border; - for(std::shared_ptr borderTest : borders_) - { - if(borderTest->getReader() == reader) - { - border = borderTest; - break; - } - } - if(!border) - { - qWarning()<<"reader "< train = items_->getTrainThatOwns(tag); - qDebug()<<"Train"<<(train ? train->getTrainId() : -1)<<"Tag"<id(); - - bool tagHandled = false; - for(std::shared_ptr& block : blocks_) - { - if(block->ownsTag(tag)) - { - tagHandled = true; - if(block->ownsBorder(border)) - { - block->tagArrivedAtBorder(tag, border); - } - else - { - removeTagFromAllBlocks(tag); - registerTagInLimbo(tag, border); - } - break; - } - } - - if(!tagHandled) - registerTagInLimbo(tag, border); -} - -void Layout::addBlock(std::shared_ptr block) -{ - blocks_.push_back(block); -} - -void Layout::addBorder(std::shared_ptr border) -{ - borders_.push_back(border); -} - -std::shared_ptr Layout::getBorder(uint32_t id) -{ - for(const std::shared_ptr& border : borders_) - { - if(border->id() == id) - return border; - } - return std::shared_ptr(); -} - -std::shared_ptr Layout::getBlock(uint32_t id) -{ - for(const std::shared_ptr& block : blocks_) - { - if(block->id() == id) - return block; - } - return std::shared_ptr(); -} - -void Layout::store(QJsonObject& json) -{ - QJsonArray blockArray; - for(const std::shared_ptr& block : blocks_) - { - QJsonObject object; - block->store(object); - blockArray.append(object); - } - json["Blocks"] = blockArray; - - QJsonArray borderArray; - for(const std::shared_ptr& border : borders_) - { - QJsonObject object; - border->store(object); - borderArray.append(object); - } - json["Borders"] = borderArray; -} - -void Layout::load(const QJsonObject& json) -{ - std::vector blockJsonObjects; - const QJsonArray blockArray(json["Blocks"].toArray(QJsonArray())); - for(const auto& object : blockArray) - { - if(object.isObject()) - { - const QJsonObject jsonObject = object.toObject(); - blockJsonObjects.push_back(jsonObject); - std::shared_ptr block(new Block(items_)); - block->load(jsonObject); - blocks_.push_back(block); - } - } - - std::vector borderJsonObjects; - const QJsonArray borderArray(json["Borders"].toArray(QJsonArray())); - for(const auto& object : borderArray) - { - if(object.isObject()) - { - const QJsonObject jsonObject = object.toObject(); - borderJsonObjects.push_back(jsonObject); - std::shared_ptr border(new BlockBorder); - border->load(object.toObject()); - borders_.push_back(border); - } - } - - for(size_t i = 0; i < blocks_.size(); ++i) - { - blocks_[i]->populate(blockJsonObjects[i], this); - } - - for(std::shared_ptr& border : borders_) - { - std::shared_ptr first; - std::shared_ptr second; - for(std::shared_ptr& block : blocks_) - { - if(block->ownsBorder(border)) - { - if(!first) - first = block; - else if(!second) - second = block; - else - qWarning()<<"border with id"<id()<<"is assigned to more than 2 blocks"; - } - } - if(!first || !second) - qWarning()<<"border with id"<id()<<"is assigned to less than than 2 blocks"; - border->setBlocks(std::pair, std::weak_ptr>(first, second)); - - for(std::shared_ptr& item : *items_->getItems()) - border->informOfItem(item); - - connect(items_, &ItemStore::itemAdded, border.get(), &BlockBorder::informOfItem); - } - - for(size_t i = 0; i < blocks_.size(); ++i) - { - blocks_[i]->populate(blockJsonObjects[i], this); - if(blocks_[i]->getBorders().empty()) - qWarning()<<"block with id"<id()<<"doset have at least one border"; - } -} diff --git a/src/trainOverlord/layout.h b/src/trainOverlord/layout.h deleted file mode 100644 index 7bbe6fe..0000000 --- a/src/trainOverlord/layout.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef BLOCKSTORE_H -#define BLOCKSTORE_H - -#include -#include -#include - -#include "block.h" -#include "overlorditemstore.h" -#include "blockborder.h" -#include "microcontroller.h" -#include "itemstore.h" - -class Layout : public QObject -{ - Q_OBJECT -private: - -private: - std::vector> blocks_; - std::vector> borders_; - std::vector>> limbo_; - - void removeTagFromAllBlocks(const NfcUid& tag); - void registerTagInLimbo(const NfcUid& tag, std::shared_ptr); - - OverlordItemStore *items_; - -public: - explicit Layout(OverlordItemStore *items, QObject *parent = nullptr); - void addBlock(std::shared_ptr block); - void addBorder(std::shared_ptr border); - void store(QJsonObject& json); - void load(const QJsonObject& json); - std::shared_ptr getBorder(uint32_t id); - std::shared_ptr getBlock(uint32_t id); - -public slots: - void tagArrivedAtReader(uint8_t reader, NfcUid tag); -}; - -#endif // BLOCKSTORE_H diff --git a/src/trainOverlord/overlorditemstore.cpp b/src/trainOverlord/overlorditemstore.cpp deleted file mode 100644 index 4e3c0f3..0000000 --- a/src/trainOverlord/overlorditemstore.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "overlorditemstore.h" -#include -#include "train.h" - -OverlordItemStore::OverlordItemStore(QObject *parent): ItemStore(parent) -{ -} - -std::shared_ptr OverlordItemStore::getTrainThatOwns(const NfcUid& uid) -{ - for(std::shared_ptr item : items_) - { - std::shared_ptr train = std::dynamic_pointer_cast(item); - if(!train) - continue; - if(train->ownsTag(uid)) - return train; - } - return std::shared_ptr(); -} diff --git a/src/trainOverlord/overlorditemstore.h b/src/trainOverlord/overlorditemstore.h deleted file mode 100644 index 92f3954..0000000 --- a/src/trainOverlord/overlorditemstore.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "itemstore.h" -#include "train.h" - -class OverlordItemStore: public ItemStore -{ - Q_OBJECT -public: - OverlordItemStore(QObject *parent = nullptr); - std::shared_ptr getTrainThatOwns(const NfcUid& uid); -}; diff --git a/src/trainOverlord/trainoverlord.cpp b/src/trainOverlord/trainoverlord.cpp deleted file mode 100644 index 5202293..0000000 --- a/src/trainOverlord/trainoverlord.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "microcontroller.h" -#include "nfcuid.h" -#include "overlorditemstore.h" -#include "train.h" -#include "turnout.h" -#include "layout.h" - -void sigHandler(int sig) -{ - QCoreApplication::quit(); -} - -QJsonObject getJsonObjectFromDisk(const QString& filePath, bool* error) -{ - QFile file; - - if(filePath.size() > 0) - file.setFileName(filePath); - else - file.setFileName(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/trainoverloard.json"); - - file.open(QIODevice::ReadOnly); - if(!file.isOpen()) - { - std::cerr<<"Can not open config file: "<getItems()->empty()) - { - micro->requestState(); - timer->start(1000); - } -} - -int main(int argc, char *argv[]) -{ - QCoreApplication a(argc, argv); - - signal(SIGINT, &sigHandler); - - //set info - QCoreApplication::setOrganizationName("UVOS"); - QCoreApplication::setOrganizationDomain("uvos.xyz"); - QCoreApplication::setApplicationName("TrainOverlord"); - QCoreApplication::setApplicationVersion("0.1"); - - //parse comand line - QCommandLineParser parser; - parser.setApplicationDescription("Train control application"); - parser.addHelpOption(); - parser.addVersionOption(); - QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", - "Set server host ip addres"), "adress"); - parser.addOption(hostOption); - QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", - "Set server Port in TCP mode or Serial port in serial mode"), "port"); - parser.addOption(portOption); - parser.process(a); - - QTcpSocket microSocket; - - int port = 6856; - if(parser.isSet(portOption)) - port = parser.value(portOption).toInt(); - - QString host("127.0.0.1"); - if(parser.isSet(hostOption)) host = parser.value(hostOption); - std::cout<<"connecting to "< getItem(); void setItem(std::weak_ptr); bool itemIsSet(); - bool getWantsNewItem() - { - return wantsNewItem; - } + bool getWantsNewItem() {return wantsNewItem;} }; #endif // TRAINJS_H diff --git a/src/ui/alarmsettingsdialog.ui.orig b/src/ui/alarmsettingsdialog.ui.orig new file mode 100644 index 0000000..55297a9 --- /dev/null +++ b/src/ui/alarmsettingsdialog.ui.orig @@ -0,0 +1,142 @@ + + + AlarmSettingsDialog + + + + 0 + 0 + 423 + 281 + + + + Dialog + + + + + + Sound File: + + + + + + + 0 + + + 0 + + + + + false + + + + + + + Change + + + + + + + + + 0 + + + + + Sunrise + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Enable + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AlarmSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AlarmSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/itemcreationdialog.cpp b/src/ui/itemcreationdialog.cpp new file mode 100644 index 0000000..55b26ca --- /dev/null +++ b/src/ui/itemcreationdialog.cpp @@ -0,0 +1,30 @@ +#include "itemcreationdialog.h" +#include "ui_itemcreationdialog.h" + +ItemCreationDialog::ItemCreationDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ItemCreationDialog) +{ + ui->setupUi(this); + connect(ui->comboBox, &QComboBox::currentTextChanged, this, &ItemCreationDialog::itemTypeChanged); + connect(ui->lineEdit, &QLineEdit::textChanged, this, &ItemCreationDialog::itemNameChanged); +} + +ItemCreationDialog::~ItemCreationDialog() +{ + delete ui; +} + +void ItemCreationDialog::itemTypeChanged(const QString& type) +{ + ui->verticalLayout->removeWidget(widget); +} + +void ItemCreationDialog::itemNameChanged(const QString& name) +{ + if(item) + { + item->setName(name); + } +} + diff --git a/src/ui/itemcreationdialog.h b/src/ui/itemcreationdialog.h new file mode 100644 index 0000000..57421ae --- /dev/null +++ b/src/ui/itemcreationdialog.h @@ -0,0 +1,33 @@ +#ifndef ITEMCREATIONDIALOG_H +#define ITEMCREATIONDIALOG_H + +#include +#include +#include "../items/item.h" + +namespace Ui { +class ItemCreationDialog; +} + +class ItemCreationDialog : public QDialog +{ + Q_OBJECT + + QWidget* widget; + +public: + explicit ItemCreationDialog(QWidget *parent = nullptr); + ~ItemCreationDialog(); + + std::shared_ptr item; + +private slots: + + void itemTypeChanged(const QString& type); + void itemNameChanged(const QString& name); + +private: + Ui::ItemCreationDialog *ui; +}; + +#endif // ITEMCREATIONDIALOG_H diff --git a/src/ui/itemcreationdialog.ui b/src/ui/itemcreationdialog.ui new file mode 100644 index 0000000..4b55d6d --- /dev/null +++ b/src/ui/itemcreationdialog.ui @@ -0,0 +1,116 @@ + + + ItemCreationDialog + + + + 0 + 0 + 400 + 140 + + + + Create Item + + + + :/images/UVOSicon.bmp:/images/UVOSicon.bmp + + + + + + + + Type + + + + + + + + Message + + + + + System + + + + + + + + + + + + Name + + + + + + + Item + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + ItemCreationDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ItemCreationDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/itemscrollbox.cpp b/src/ui/itemscrollbox.cpp new file mode 100644 index 0000000..a83b7e0 --- /dev/null +++ b/src/ui/itemscrollbox.cpp @@ -0,0 +1,84 @@ +#include "itemscrollbox.h" +#include "ui_relayscrollbox.h" +#include "ui_relayscrollbox.h" +#include "../items/train.h" +#include "../items/turnout.h" +#include "../trainjs.h" + +ItemScrollBox::ItemScrollBox(QWidget *parent) : + QWidget(parent), + ui(new Ui::RelayScrollBox) +{ + ui->setupUi(this); + QScroller::grabGesture(ui->scrollArea, QScroller::TouchGesture); + QScroller::grabGesture(ui->scrollArea, QScroller::LeftMouseButtonGesture); +} + +ItemScrollBox::~ItemScrollBox() +{ + delete ui; +} + +void ItemScrollBox::addItem(std::weak_ptr item) +{ + if(auto workItem = item.lock()) + { + widgets_.push_back(new ItemWidget(item, this)); + Train* train = dynamic_cast(workItem.get()); + Turnout* turnout = dynamic_cast(workItem.get()); + if(train) + { + if(train->getTrainId() == 0) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_Q), QKeySequence(Qt::Key_A), QKeySequence(Qt::Key_Z)); + else if(train->getTrainId() == 1) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_W), QKeySequence(Qt::Key_S), QKeySequence(Qt::Key_X)); + else if(train->getTrainId() == 2) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_E), QKeySequence(Qt::Key_D), QKeySequence(Qt::Key_C)); + else if(train->getTrainId() == 3) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_R), QKeySequence(Qt::Key_F), QKeySequence(Qt::Key_V)); + else if(train->getTrainId() == 4) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_T), QKeySequence(Qt::Key_G), QKeySequence(Qt::Key_B)); + } + else if(turnout) + { + if(turnout->getTurnoutId() == 0) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_1)); + else if(turnout->getTurnoutId() == 1) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_2)); + else if(turnout->getTurnoutId() == 2) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_3)); + else if(turnout->getTurnoutId() == 3) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_4)); + else if(turnout->getTurnoutId() == 4) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_5)); + else if(turnout->getTurnoutId() == 5) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_6)); + else if(turnout->getTurnoutId() == 6) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_7)); + else if(turnout->getTurnoutId() == 7) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_8)); + else if(turnout->getTurnoutId() == 8) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_9)); + else if(turnout->getTurnoutId() == 9) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_0)); + } + ui->relayWidgetVbox->addWidget(widgets_.back()); + connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest); + connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem); + } +} + +void ItemScrollBox::removeItem(const ItemData& item) +{ + for(unsigned i = 0; i < widgets_.size(); i++) + { + if(widgets_[i]->controles(item)) + { + ui->relayWidgetVbox->removeWidget(widgets_[i]); + delete widgets_[i]; + widgets_.erase(widgets_.begin()+i); + } + } +} + + diff --git a/src/trainControllerUI/ui/itemscrollbox.h b/src/ui/itemscrollbox.h similarity index 50% rename from src/trainControllerUI/ui/itemscrollbox.h rename to src/ui/itemscrollbox.h index 444e608..2d78f2a 100644 --- a/src/trainControllerUI/ui/itemscrollbox.h +++ b/src/ui/itemscrollbox.h @@ -10,32 +10,32 @@ #include "../items/itemstore.h" -namespace Ui -{ +namespace Ui { class RelayScrollBox; } class ItemScrollBox : public QWidget { - Q_OBJECT + Q_OBJECT private: - std::vector< ItemWidget* > widgets_; + std::vector< ItemWidget* > widgets_; signals: - void deleteRequest(const ItemData& item); + void deleteRequest(const ItemData& item); public: - explicit ItemScrollBox(QWidget *parent = nullptr); - ~ItemScrollBox(); + explicit ItemScrollBox(QWidget *parent = nullptr); + ~ItemScrollBox(); + + void setItemStore(ItemStore* itemStore); public slots: - void addItem(std::weak_ptr item); - void removeItem(const ItemData& item); - void jsReqNewItem(); + void addItem(std::weak_ptr item); + void removeItem(const ItemData& item); private: - Ui::RelayScrollBox *ui; + Ui::RelayScrollBox *ui; }; #endif // RELAYSCROLLBOX_H diff --git a/src/ui/itemsettingsdialog.cpp b/src/ui/itemsettingsdialog.cpp new file mode 100644 index 0000000..179ce19 --- /dev/null +++ b/src/ui/itemsettingsdialog.cpp @@ -0,0 +1,176 @@ + #include "itemsettingsdialog.h" +#include "ui_itemsettingsdialog.h" +#include + +ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr item, QWidget *parent) : + QDialog(parent), + item_(item), + ui(new Ui::ItemSettingsDialog) +{ + ui->setupUi(this); + + setModal(false); + + ui->label_name->setText(item_->getName()); + ui->checkBox_Override->setChecked(item_->getOverride()); + + + if(std::shared_ptr relay = std::dynamic_pointer_cast(item_)) + { + itemSpecificWidget_ = new RelayItemSettingsWidget(relay); + } + else if(std::shared_ptr msgItem = std::dynamic_pointer_cast(item_)) + { + itemSpecificWidget_ = new MessageItemSettingsWidget(msgItem); + } + else if(std::shared_ptr sysItem = std::dynamic_pointer_cast(item_)) + { + itemSpecificWidget_ = new SystemItemSettingsWidget(sysItem); + } + + if(itemSpecificWidget_) + { + ui->verticalLayout_2->addWidget(itemSpecificWidget_); + } + + connect(ui->pushButton_add, &QPushButton::clicked, this, &ItemSettingsDialog::addActor); + connect(ui->pushButton_remove, &QPushButton::clicked, this, &ItemSettingsDialog::removeActor); + connect(ui->pushButton_edit, &QPushButton::clicked, this, &ItemSettingsDialog::editActor); + connect(ui->checkBox_Override, &QPushButton::clicked, this, &ItemSettingsDialog::changeOverride); + + + ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("Actor")); + ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("Action")); + ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("Enabled")); + ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + ui->tableWidget->horizontalHeader()->resizeSection(1, 60); + ui->tableWidget->horizontalHeader()->resizeSection(2, 75); + loadActorList(); +} + +ItemSettingsDialog::~ItemSettingsDialog() +{ + if(itemSpecificWidget_) delete itemSpecificWidget_; + delete ui; +} + +void ItemSettingsDialog::changeOverride() +{ + item_->setOverride(ui->checkBox_Override->isChecked()); +} + +void ItemSettingsDialog::loadActorList() +{ + //ui->listWidget->clear(); + ui->tableWidget->setRowCount(item_->getActors().size()); + + for(unsigned i = 0; i < item_->getActors().size(); i++) + { + ui->tableWidget->setItem(i, 0, new QTableWidgetItem(item_->getActors()[i]->getName())); + ui->tableWidget->setItem(i, 1, new QTableWidgetItem(item_->getActors()[i]->actionName())); + ui->tableWidget->setItem(i, 2, new QTableWidgetItem(item_->getActors()[i]->isActive() ? "Y" : "N")); + } +} + +void ItemSettingsDialog::addActor() +{ + ActorSettingsDialog* dialog = nullptr; + std::shared_ptr actor = nullptr; + + if(ui->comboBox->currentText() == "Alarm") + { + std::shared_ptr alarm = std::shared_ptr(new AlarmTime); + actor = alarm; + dialog = new ActorSettingsDialog(alarm, this); + } + else if(ui->comboBox->currentText() == "Sensor") + { + std::shared_ptr sensorActor = std::shared_ptr(new SensorActor); + actor = sensorActor; + dialog = new ActorSettingsDialog(sensorActor, this); + } + else if(ui->comboBox->currentText() == "Timer" ) + { + std::shared_ptr timerActor = std::shared_ptr(new TimerActor); + actor = timerActor; + dialog = new ActorSettingsDialog(timerActor, this); + } + else if(ui->comboBox->currentText() == "Regulator") + { + std::shared_ptr regulator = std::shared_ptr(new Regulator); + actor = regulator; + dialog = new ActorSettingsDialog(regulator, this); + } + + else if(ui->comboBox->currentText() == "Polynomal") + { + std::shared_ptr polynomalActor = std::shared_ptr(new PolynomalActor); + actor = polynomalActor; + dialog = new ActorSettingsDialog(polynomalActor, this); + } + + else if(ui->comboBox->currentText() == "Multi Factor") + { + std::shared_ptr polynomalActor = std::shared_ptr(new MultiFactorActor); + actor = polynomalActor; + dialog = new ActorSettingsDialog(polynomalActor, this); + } + + + if(dialog != nullptr) + { + dialog->setParent(this); + dialog->show(); + if(dialog->exec() == QDialog::Accepted) + { + item_->addActor(actor); + loadActorList(); + } + delete dialog; + } + +} + +void ItemSettingsDialog::removeActor() +{ + if(item_->getActors().size() > ui->tableWidget->currentRow()) + { + item_->removeActor(item_->getActors().at(ui->tableWidget->currentRow())); + loadActorList(); + } +} + +void ItemSettingsDialog::editActor() +{ + if(item_->getActors().size() > ui->tableWidget->currentRow()) + { + std::shared_ptr actor = item_->getActors()[ui->tableWidget->currentRow()]; + + std::shared_ptr alarmTime = std::dynamic_pointer_cast(actor); + std::shared_ptr regulator = std::dynamic_pointer_cast(actor); + std::shared_ptr sensorActor = std::dynamic_pointer_cast(actor); + std::shared_ptr timerActor = std::dynamic_pointer_cast(actor); + std::shared_ptr polynomalActor = std::dynamic_pointer_cast(actor); + std::shared_ptr factorActor = std::dynamic_pointer_cast(actor); + + ActorSettingsDialog* dialog; + + if(alarmTime) dialog = new ActorSettingsDialog(alarmTime, this); + else if(regulator) dialog = new ActorSettingsDialog(regulator, this); + else if(sensorActor) dialog = new ActorSettingsDialog(sensorActor, this); + else if(timerActor) dialog = new ActorSettingsDialog(timerActor, this); + else if(polynomalActor) dialog = new ActorSettingsDialog(polynomalActor, this); + else if(factorActor) dialog = new ActorSettingsDialog(factorActor, this); + else dialog = new ActorSettingsDialog(actor, this); + dialog->setParent(this); + dialog->show(); + dialog->exec(); + + for(int i = 0; i < ui->tableWidget->rowCount() && i < item_->getActors().size(); ++i) + { + ui->tableWidget->item(i, 0)->setText(item_->getActors()[i]->getName()); + ui->tableWidget->item(i, 1)->setText(item_->getActors()[i]->actionName()); + ui->tableWidget->item(i, 2)->setText(item_->getActors()[i]->isActive() ? "Y" : "N"); + } + } +} diff --git a/src/ui/itemsettingsdialog.h b/src/ui/itemsettingsdialog.h new file mode 100644 index 0000000..ca12f21 --- /dev/null +++ b/src/ui/itemsettingsdialog.h @@ -0,0 +1,37 @@ +#ifndef RELAYSETTINGSDIALOG_H +#define RELAYSETTINGSDIALOG_H + +#include +#include +#include +#include "../items/item.h" + +namespace Ui { +class ItemSettingsDialog; +} + +class ItemSettingsDialog : public QDialog +{ + Q_OBJECT + std::shared_ptr item_; + QWidget* itemSpecificWidget_ = nullptr; + +private: + void loadActorList(); + +public: + explicit ItemSettingsDialog(std::shared_ptr item, QWidget *parent = nullptr); + ~ItemSettingsDialog(); + +private slots: + + void removeActor(); + void addActor(); + void editActor(); + void changeOverride(); + +private: + Ui::ItemSettingsDialog *ui; +}; + +#endif // RELAYSETTINGSDIALOG_H diff --git a/src/ui/itemsettingsdialog.ui b/src/ui/itemsettingsdialog.ui new file mode 100644 index 0000000..871bb9f --- /dev/null +++ b/src/ui/itemsettingsdialog.ui @@ -0,0 +1,274 @@ + + + ItemSettingsDialog + + + + 0 + 0 + 577 + 390 + + + + Item Settings + + + + :/images/UVOSicon.bmp:/images/UVOSicon.bmp + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + 0 + + + 10 + + + + + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 5 + 0 + + + + Qt::LeftToRight + + + TextLabel + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + Override + + + + + + + QFrame::StyledPanel + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + false + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + false + + + QAbstractItemView::SelectRows + + + false + + + Qt::SolidLine + + + false + + + 0 + + + 3 + + + false + + + 32 + + + true + + + false + + + 32 + + + + + + + + + + 0 + + + 0 + + + + + Remove + + + + + + + Edit + + + + + + + + + + + + 0 + 0 + + + + Act on + + + + + + + + Sensor + + + + + Polynomal + + + + + Regulator + + + + + Alarm + + + + + Timer + + + + + Multi Factor + + + + + + + + + 0 + 0 + + + + Add + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + ItemSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ItemSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/itemwidget.cpp b/src/ui/itemwidget.cpp new file mode 100644 index 0000000..af6426e --- /dev/null +++ b/src/ui/itemwidget.cpp @@ -0,0 +1,203 @@ +#include "itemwidget.h" +#include "ui_itemwidget.h" + +#include +#include +#include +#include "../items/train.h" +#include "../items/turnout.h" + +ItemWidget::ItemWidget(std::weak_ptr item, QWidget *parent) : + QWidget(parent), + item_(item), + ui(new Ui::ItemWidget) +{ + ui->setupUi(this); + + if(auto workingItem = item_.lock()) + { + ui->label->setText(workingItem->getName()); + + connect(ui->slider, &QSlider::valueChanged, this, &ItemWidget::setValue); + connect(ui->checkBox_f1, &QCheckBox::stateChanged, this, &ItemWidget::f1); + connect(ui->checkBox_f2, &QCheckBox::stateChanged, this, &ItemWidget::f2); + connect(ui->checkBox_f3, &QCheckBox::stateChanged, this, &ItemWidget::f3); + connect(ui->checkBox_f4, &QCheckBox::stateChanged, this, &ItemWidget::f4); + connect(ui->pushButton_reverse, &QPushButton::clicked, this, &ItemWidget::reverse); + connect(ui->radioButton_left, &QRadioButton::clicked, this, [this](){setValue(0);}); + connect(ui->radioButton_right, &QRadioButton::clicked, this, [this](){setValue(1);}); + + connect(workingItem.get(), &Item::valueChanged, this, &ItemWidget::moveToValue); + + Train* train = dynamic_cast(workingItem.get()); + Turnout* turnout = dynamic_cast(workingItem.get()); + + if(turnout) + { + ui->checkBox_f1->hide(); + ui->checkBox_f2->hide(); + ui->checkBox_f3->hide(); + ui->checkBox_f4->hide(); + ui->slider->hide(); + } + + if(!train) + { + ui->pushButton_reverse->hide(); + } + else + { + ui->radioButton_left->hide(); + ui->radioButton_right->hide(); + uint8_t functionMask = train->getFunctionMask(); + qDebug()<<"functionMask: "<<(int)functionMask; + if(!(functionMask & (1 << 0))) + ui->checkBox_f1->hide(); + if(!(functionMask & (1 << 1))) + ui->checkBox_f2->hide(); + if(!(functionMask & (1 << 2))) + ui->checkBox_f3->hide(); + if(!(functionMask & (1 << 3))) + ui->checkBox_f4->hide(); + } + } + else disable(); +} + +void ItemWidget::deleteItem() +{ + if(auto workingItem = item_.lock()) + { + deleteRequest(*workingItem); + } +} + +void ItemWidget::setValue(int8_t value) +{ + if(auto workingItem = item_.lock()) + workingItem->setValue(value); + else + disable(); +} + +void ItemWidget::moveToValue(int8_t value) +{ + ui->slider->blockSignals(true); + ui->radioButton_left->blockSignals(true); + ui->radioButton_right->blockSignals(true); + + ui->pushButton_reverse->setText(value == 0 ? "Reverse" : "Stop"); + ui->slider->setValue(value); + ui->radioButton_left->setChecked(!value); + ui->radioButton_right->setChecked(value); + + ui->slider->blockSignals(false); + ui->radioButton_left->blockSignals(false); + ui->radioButton_right->blockSignals(false); +} + +void ItemWidget::f1(int value) +{ + if(auto workingItem = item_.lock()) + workingItem->setFunction(0, value == Qt::Checked); + else disable(); +} + +void ItemWidget::f2(int value) +{ + if(auto workingItem = item_.lock()) + workingItem->setFunction(1, value == Qt::Checked); + else disable(); +} + + +void ItemWidget::f3(int value) +{ + if(auto workingItem = item_.lock()) + workingItem->setFunction(2, value == Qt::Checked); + else disable(); +} + +void ItemWidget::f4(int value) +{ + if(auto workingItem = item_.lock()) + workingItem->setFunction(3, value == Qt::Checked); + else disable(); +} + +void ItemWidget::reverse() +{ + if(auto workingItem = item_.lock()) + { + Train* train = dynamic_cast(workingItem.get()); + if(train && workingItem->getValue() == 0) + train->reverse(); + else + { + setValue(!((bool)workingItem->getValue())); + } + } + else disable(); +} + +void ItemWidget::disable() +{ + ui->checkBox_f1->setEnabled(false); + ui->checkBox_f2->setEnabled(false); + ui->checkBox_f3->setEnabled(false); + ui->checkBox_f4->setEnabled(false); + ui->label->setEnabled(false); + ui->slider->setEnabled(false); + ui->pushButton_reverse->setEnabled(false); +} + +bool ItemWidget::controles(const ItemData& relay) +{ + if(auto workingRelay = item_.lock()) + { + if(relay == *workingRelay) + return true; + else + return false; + } + return true; +} + +void ItemWidget::stepUp() +{ + setValue(ui->slider->value()+1); +} + +void ItemWidget::stepDown() +{ + setValue(ui->slider->value()-1); +} + +void ItemWidget::setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev) +{ + shortcuts_.clear(); + shortcuts_.push_back(std::unique_ptr(new QShortcut(up, this))); + connect(shortcuts_.back().get(), &QShortcut::activated, this, &ItemWidget::stepUp); + shortcuts_.push_back(std::unique_ptr(new QShortcut(down, this))); + connect(shortcuts_.back().get(), &QShortcut::activated, this, &ItemWidget::stepDown); + shortcuts_.push_back(std::unique_ptr(new QShortcut(rev, this))); + connect(shortcuts_.back().get(), &QShortcut::activated, this, &ItemWidget::reverse); +} + +std::weak_ptr ItemWidget::getItem() +{ + return item_; +} + +void ItemWidget::stateChanged(int state) +{ + qDebug()<<"widget got state "<slider->blockSignals(true); + ui->slider->setValue(state); + ui->slider->blockSignals(false); +} + +ItemWidget::~ItemWidget() +{ + delete ui; +} diff --git a/src/ui/itemwidget.h b/src/ui/itemwidget.h new file mode 100644 index 0000000..c0eb45b --- /dev/null +++ b/src/ui/itemwidget.h @@ -0,0 +1,57 @@ +#ifndef RELAYWIDGET_H +#define RELAYWIDGET_H + +#include +#include +#include +#include "itemsettingsdialog.h" +#include "../items/item.h" + +namespace Ui { +class ItemWidget; +} + +class ItemWidget : public QWidget +{ + Q_OBJECT +private: + std::weak_ptr item_; + + std::vector< std::unique_ptr > shortcuts_; + + void disable(); + +signals: + + void deleteRequest(const ItemData& item); + +private slots: + void setValue(int8_t value); + void moveToValue(int8_t value); + void deleteItem(); + + void stepUp(); + void stepDown(); + + void f1(int state); + void f2(int state); + void f3(int state); + void f4(int state); + void reverse(); + +public: + explicit ItemWidget(std::weak_ptr item, QWidget *parent); + std::weak_ptr getItem(); + bool controles(const ItemData& relay); + ~ItemWidget(); + void setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev); + +public slots: + + void stateChanged(int state); + +private: + Ui::ItemWidget *ui; +}; + +#endif // RELAYWIDGET_H diff --git a/src/trainControllerUI/ui/trainwidget.ui b/src/ui/itemwidget.ui similarity index 98% rename from src/trainControllerUI/ui/trainwidget.ui rename to src/ui/itemwidget.ui index eec9954..8fb7574 100644 --- a/src/trainControllerUI/ui/trainwidget.ui +++ b/src/ui/itemwidget.ui @@ -1,7 +1,7 @@ - TrainWidget - + ItemWidget + 0 diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp new file mode 100644 index 0000000..93187a4 --- /dev/null +++ b/src/ui/mainwindow.cpp @@ -0,0 +1,45 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "itemscrollbox.h" +#include "itemsettingsdialog.h" +#include "itemcreationdialog.h" + +MainWindow::MainWindow(Microcontroller * const micro, ItemStore* items, QWidget *parent) : + QMainWindow(parent), + stopShort(QKeySequence(Qt::Key_Space), this), + ui(new Ui::MainWindow), + _micro(micro) +{ + ui->setupUi(this); + + connect(&stopShort, &QShortcut::activated, _micro, &Microcontroller::estop); + connect(ui->pushButton_stop, &QPushButton::clicked, _micro, &Microcontroller::estop); + connect(ui->pushButton_refesh, &QPushButton::clicked, _micro, &Microcontroller::requestState); + + connect(items, &ItemStore::itemAdded, ui->relayList, &ItemScrollBox::addItem); + connect(items, &ItemStore::itemDeleted, ui->relayList, &ItemScrollBox::removeItem); + + for(size_t i = 0; i < items->getItems()->size(); ++i) + { + ui->relayList->addItem(items->getItems()->at(i)); + } + + connect(ui->relayList, &ItemScrollBox::deleteRequest, items, &ItemStore::removeItem); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +/* +void MainWindow::showItemCreationDialog() +{ + ItemCreationDialog diag(this); + diag.show(); + if(diag.exec()) + { + createdItem(diag.item); + } +} +*/ diff --git a/src/trainControllerUI/ui/mainwindow.h b/src/ui/mainwindow.h similarity index 57% rename from src/trainControllerUI/ui/mainwindow.h rename to src/ui/mainwindow.h index 17a9071..890b84b 100644 --- a/src/trainControllerUI/ui/mainwindow.h +++ b/src/ui/mainwindow.h @@ -20,25 +20,25 @@ class MainWindow; class MainWindow : public QMainWindow { - Q_OBJECT - QShortcut stopShort; + Q_OBJECT + QShortcut stopShort; public: - explicit MainWindow(Microcontroller * const micro, ItemStore* items, QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(Microcontroller * const micro, ItemStore* items, QWidget *parent = nullptr); + ~MainWindow(); private: - Ui::MainWindow *ui; + Ui::MainWindow *ui; - Microcontroller *_micro; + Microcontroller *_micro; signals: - void createdItem(std::shared_ptr item); + void createdItem(std::shared_ptr item); private slots: - //void showItemCreationDialog(); + //void showItemCreationDialog(); }; diff --git a/src/trainControllerUI/ui/mainwindow.ui b/src/ui/mainwindow.ui similarity index 100% rename from src/trainControllerUI/ui/mainwindow.ui rename to src/ui/mainwindow.ui diff --git a/src/trainControllerUI/ui/relayscrollbox.ui b/src/ui/relayscrollbox.ui similarity index 100% rename from src/trainControllerUI/ui/relayscrollbox.ui rename to src/ui/relayscrollbox.ui diff --git a/trainControllerUI.pro b/trainControllerUI.pro new file mode 100644 index 0000000..992cae3 --- /dev/null +++ b/trainControllerUI.pro @@ -0,0 +1,65 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-06-01T22:31:38 +# +#------------------------------------------------- + +QT += core gui widgets network serialport + +TARGET = traincontrollerui +TEMPLATE = app + +INCLUDEPATH += /usr/include/libnl3/ +INCLUDEPATH += /usr/include/SDL2/ + +LIBS += -lnl-3 -lnl-genl-3 -lSDL2 + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS +DEFINES += SDL_SUPPORTED + +QMAKE_CXXFLAGS += -std=c++17 -O2 + +SOURCES += \ + src/items/train.cpp \ + src/items/turnout.cpp \ + src/mainobject.cpp \ + src/trainjs.cpp \ + src/QJoysticks.cpp \ + src/jsbackend/SDL_Joysticks.cpp \ + src/jsbackend/VirtualJoystick.cpp \ + src/ui/itemwidget.cpp \ + src/ui/itemscrollbox.cpp \ + src/ui/mainwindow.cpp \ + src/items/item.cpp \ + src/items/itemstore.cpp\ + src/main.cpp \ + src/microcontroller.cpp + +HEADERS += \ + src/items/train.h \ + src/items/turnout.h \ + src/mainobject.h \ + src/trainjs.h \ + src/QJoysticks.h \ + src/jsbackend/SDL_Joysticks.h \ + src/jsbackend/VirtualJoystick.h \ + src/jsbackend/JoysticksCommon.h \ + src/ui/itemwidget.h \ + src/ui/itemscrollbox.h \ + src/ui/mainwindow.h \ + src/items/item.h \ + src/items/itemstore.h + +HEADERS += \ + src/microcontroller.h \ + +INCLUDEPATH += src/ui/ + +FORMS += \ + src/ui/mainwindow.ui \ + src/ui/relayscrollbox.ui \ + src/ui/itemwidget.ui