Intal version with working trainoverlord
This commit is contained in:
parent
a1f9fa172b
commit
872cc04a54
@ -12,11 +12,17 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Network SerialPort REQUIRE
|
||||
|
||||
set(COMMON_SOURCES
|
||||
../common/microcontroller.cpp
|
||||
../common/microcontroller.h
|
||||
../common/items/item.cpp
|
||||
../common/items/item.h
|
||||
../common/items/itemstore.cpp
|
||||
../common/items/signal.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
|
||||
)
|
||||
|
||||
include_directories(PRIVATE
|
||||
@ -32,3 +38,4 @@ set(COMMON_LINK_LIBRARYS
|
||||
|
||||
add_subdirectory(trainControllerUI)
|
||||
add_subdirectory(trainOverlord)
|
||||
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
|
||||
virtual ~Item();
|
||||
|
||||
void informValue(int8_t value);
|
||||
virtual void informValue(int8_t value);
|
||||
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,6 @@ void ItemStore::addItem(std::shared_ptr<Item> item)
|
||||
items_.push_back(std::shared_ptr<Item>(item));
|
||||
itemAdded(std::weak_ptr<Item>(items_.back()));
|
||||
}
|
||||
qDebug()<<"Got item: "<<item->id()<<" matched: "<<mached;
|
||||
}
|
||||
|
||||
void ItemStore::addItems(const std::vector<std::shared_ptr<Item>>& itemIn)
|
||||
@ -35,7 +34,7 @@ void ItemStore::addItems(const std::vector<std::shared_ptr<Item>>& itemIn)
|
||||
continue;
|
||||
if(train->getTrainId() == 0)
|
||||
{
|
||||
const uint8_t uidBytes[] = {12, 154, 110, 34};
|
||||
const uint8_t uidBytes[] = {154, 110, 34, 218};
|
||||
train->tags.push_back(NfcUid(uidBytes, sizeof(uidBytes)));
|
||||
}
|
||||
else if(train->getTrainId() == 3)
|
||||
@ -45,7 +44,7 @@ void ItemStore::addItems(const std::vector<std::shared_ptr<Item>>& itemIn)
|
||||
}
|
||||
else if(train->getTrainId() == 4)
|
||||
{
|
||||
const uint8_t uidBytes[] = {76, 55, 220, 31};
|
||||
const uint8_t uidBytes[] = {55, 220, 31, 184};
|
||||
train->tags.push_back(NfcUid(uidBytes, sizeof(uidBytes)));
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ signals:
|
||||
public slots:
|
||||
|
||||
void removeItem(const ItemData& item);
|
||||
void addItem(std::shared_ptr<Item> item);
|
||||
virtual void addItem(std::shared_ptr<Item> item);
|
||||
void addItems(const std::vector<std::shared_ptr<Item>>& itemsIn);
|
||||
void itemStateChanged(const ItemData& item);
|
||||
};
|
||||
|
@ -19,13 +19,82 @@ void Train::setFunction(uint8_t funciton, bool 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_);
|
||||
}
|
||||
|
||||
int Train::ownsTag(NfcUid uid)
|
||||
{
|
||||
for(size_t i = 0; i < tags.size(); ++i)
|
||||
{
|
||||
if(uid == tags[i])
|
||||
{
|
||||
if(i == 0)
|
||||
return getDirection() == FORWARD ? TAG_FRONT : TAG_BACK;
|
||||
else if(i == tags.size()-1)
|
||||
return getDirection() == REVERSE ? TAG_FRONT : TAG_BACK;
|
||||
else
|
||||
return TAG_CENTER;
|
||||
}
|
||||
}
|
||||
return TAG_NONE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,16 @@ class Train : public Item
|
||||
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 constexpr int TAG_BACK = 1;
|
||||
static constexpr int TAG_CENTER = 2;
|
||||
static constexpr int TAG_NONE = -1;
|
||||
|
||||
static Microcontroller *micro;
|
||||
std::vector<NfcUid> tags;
|
||||
|
||||
@ -27,6 +36,13 @@ 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();
|
||||
int ownsTag(NfcUid uid);
|
||||
bool hasBackTag();
|
||||
bool passedReader(const NfcUid &uid)
|
||||
{
|
||||
if(lastReader_ == uid.reader)
|
||||
@ -38,6 +54,9 @@ public slots:
|
||||
{
|
||||
return train_id_;
|
||||
}
|
||||
|
||||
signals:
|
||||
void unsuspended(uint32_t id, int direction);
|
||||
};
|
||||
|
||||
#endif // TRAIN_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "signal.h"
|
||||
#include "trainsignal.h"
|
||||
|
||||
Microcontroller *Signal::micro = nullptr;
|
||||
|
@ -2,13 +2,12 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "items/train.h"
|
||||
#include "items/turnout.h"
|
||||
#include "items/signal.h"
|
||||
#include "train.h"
|
||||
#include "turnout.h"
|
||||
#include "trainsignal.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());
|
||||
@ -54,18 +53,16 @@ void Microcontroller::estop()
|
||||
|
||||
void Microcontroller::write(const QByteArray& buffer)
|
||||
{
|
||||
qDebug()<<buffer;
|
||||
if(_port != nullptr)
|
||||
{
|
||||
_port->write(buffer);
|
||||
_port->waitForBytesWritten(1000);
|
||||
//_port->waitForBytesWritten(1000);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(40));
|
||||
}
|
||||
|
||||
void Microcontroller::write(char* buffer, const size_t length)
|
||||
{
|
||||
qDebug()<<buffer;
|
||||
if(_port != nullptr)
|
||||
{
|
||||
_port->write(buffer, length);
|
||||
@ -86,6 +83,7 @@ void Microcontroller::requestState()
|
||||
write("train list\n");
|
||||
write("turnout list\n");
|
||||
write("signal list\n");
|
||||
write("nfc list\n");
|
||||
}
|
||||
|
||||
//housekeeping
|
||||
@ -154,14 +152,12 @@ void Microcontroller::processNfcLine(const QString& buffer)
|
||||
uid.length = tokens.length();
|
||||
for(size_t i = 0; i < uid.length; ++i)
|
||||
uid.bytes[i] = tokens[i].toInt();
|
||||
qDebug()<<"Got Tag";
|
||||
gotTag(uid);
|
||||
}
|
||||
|
||||
void Microcontroller::processList(const QString& buffer)
|
||||
{
|
||||
QStringList bufferList = buffer.split(' ');
|
||||
qDebug()<<__func__<<" :"<<buffer<<" list mode: "<<listMode;
|
||||
if(bufferList.size() >= 10 && buffer.contains("NUMBER:"))
|
||||
{
|
||||
std::shared_ptr<Item> item;
|
||||
@ -179,7 +175,6 @@ void Microcontroller::processList(const QString& buffer)
|
||||
listMode = false;
|
||||
if(!itemList.empty())
|
||||
{
|
||||
qDebug()<<"got item list " << itemList.size();
|
||||
gotItemList(itemList);
|
||||
itemList.clear();
|
||||
}
|
||||
|
@ -10,10 +10,10 @@
|
||||
#include "microcontroller.h"
|
||||
#include "trainjs.h"
|
||||
#include "ui/mainwindow.h"
|
||||
#include "items/itemstore.h"
|
||||
#include "items/train.h"
|
||||
#include "items/turnout.h"
|
||||
#include "items/signal.h"
|
||||
#include "itemstore.h"
|
||||
#include "train.h"
|
||||
#include "turnout.h"
|
||||
#include "trainsignal.h"
|
||||
|
||||
#define BAUD QSerialPort::Baud38400
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "itemscrollbox.h"
|
||||
#include "ui_relayscrollbox.h"
|
||||
#include "ui_relayscrollbox.h"
|
||||
#include "../items/train.h"
|
||||
#include "../items/turnout.h"
|
||||
#include "../items/signal.h"
|
||||
#include "../trainjs.h"
|
||||
#include "train.h"
|
||||
#include "turnout.h"
|
||||
#include "trainsignal.h"
|
||||
#include "trainjs.h"
|
||||
#include "trainwidget.h"
|
||||
#include "signalwidget.h"
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QDebug>
|
||||
#include <QRadioButton>
|
||||
#include <memory>
|
||||
#include "../items/signal.h"
|
||||
#include "trainsignal.h"
|
||||
|
||||
SignalWidget::SignalWidget(std::weak_ptr<Item> item, QWidget *parent) :
|
||||
ItemWidget(item, parent),
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <QWidget>
|
||||
#include <memory>
|
||||
#include <QShortcut>
|
||||
#include "../items/signal.h"
|
||||
#include "../items/trainsignal.h"
|
||||
#include "itemwidget.h"
|
||||
|
||||
namespace Ui
|
||||
|
@ -1,6 +1,13 @@
|
||||
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})
|
||||
|
254
src/trainOverlord/block.cpp
Normal file
254
src/trainOverlord/block.cpp
Normal file
@ -0,0 +1,254 @@
|
||||
#include "block.h"
|
||||
#include <QJsonArray>
|
||||
#include <layout.h>
|
||||
|
||||
Block::Block(uint32_t id):
|
||||
id_(id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Block::addBorder(std::shared_ptr<BlockBorder> border)
|
||||
{
|
||||
borders_.push_back(border);
|
||||
std::shared_ptr<Block> block = border->getOtherBlock(this);
|
||||
if(!block || block.get() == this)
|
||||
{
|
||||
qWarning()<<__func__<<"no other block in border"<<border->id();
|
||||
return;
|
||||
}
|
||||
connect(block.get(), &Block::blockedChanged, this, &Block::checkWaits);
|
||||
}
|
||||
|
||||
bool Block::blocked()
|
||||
{
|
||||
if(trains_.empty() && waits_.empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Block::ownsTrain(std::weak_ptr<Train> train)
|
||||
{
|
||||
std::shared_ptr<Train> trainPtr = train.lock();
|
||||
if(!trainPtr)
|
||||
return false;
|
||||
|
||||
for(auto ownedTrain : trains_)
|
||||
{
|
||||
if(ownedTrain.lock() == trainPtr)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Block::ownsBorder(std::shared_ptr<BlockBorder> border)
|
||||
{
|
||||
if(!border)
|
||||
return false;
|
||||
for(std::shared_ptr<BlockBorder> borderTest : borders_)
|
||||
{
|
||||
if(borderTest == border)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Block::checkWaits(bool ign)
|
||||
{
|
||||
qDebug()<<__func__;
|
||||
(void)ign;
|
||||
bool wasBlocked = blocked();
|
||||
for(std::vector<TrainWait>::iterator iter = waits_.begin(); iter != waits_.end();)
|
||||
{
|
||||
std::shared_ptr<Block> block = iter->targetBlock.lock();
|
||||
std::shared_ptr<Train> train = iter->train.lock();
|
||||
qDebug()<<__func__<<"trying to push train"<<train->getTrainId()<<"to block"<<block->id();
|
||||
if(block && train && train->suspendend() && block->pushTrain(iter->train))
|
||||
{
|
||||
train->resume();
|
||||
std::shared_ptr<BlockBorder> 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);
|
||||
}
|
||||
|
||||
void Block::updateBorders()
|
||||
{
|
||||
for(std::shared_ptr<BlockBorder> broder : borders_)
|
||||
{
|
||||
broder->updateSignals();
|
||||
}
|
||||
}
|
||||
|
||||
bool Block::pushTrain(std::weak_ptr<Train> train)
|
||||
{
|
||||
if(blocked())
|
||||
return false;
|
||||
|
||||
addTrain(train);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Block::addTrain(std::weak_ptr<Train> train)
|
||||
{
|
||||
std::shared_ptr<Train> trainPtr = train.lock();
|
||||
if(!trainPtr)
|
||||
return;
|
||||
qDebug()<<"Train"<<trainPtr->getTrainId()<<"added to block"<<id_;
|
||||
bool wasBlocked = blocked();
|
||||
trains_.push_back(train);
|
||||
if(wasBlocked != blocked())
|
||||
blockedChanged(!wasBlocked);
|
||||
updateBorders();
|
||||
}
|
||||
|
||||
void Block::unsuspendedTrain(uint32_t id, int direction)
|
||||
{
|
||||
qDebug()<<"Train with item id"<<id<<"reports unsuspended";
|
||||
bool wasBlocked = blocked();
|
||||
for(std::vector<TrainWait>::iterator iter = waits_.begin(); iter != waits_.end(); ++iter)
|
||||
{
|
||||
std::shared_ptr<Train> workTrain = iter->train.lock();
|
||||
if(!workTrain)
|
||||
{
|
||||
waits_.erase(iter);
|
||||
unsuspendedTrain(id, direction);
|
||||
break;
|
||||
}
|
||||
if(workTrain->id() == id)
|
||||
{
|
||||
std::shared_ptr<Block> block = iter->targetBlock.lock();
|
||||
disconnect(workTrain.get(), &Train::unsuspended, this, &Block::unsuspendedTrain);
|
||||
if(iter->direction == direction)
|
||||
{
|
||||
if(block)
|
||||
block->addTrain(workTrain);
|
||||
}
|
||||
else
|
||||
{
|
||||
addTrain(workTrain);
|
||||
}
|
||||
waits_.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(wasBlocked != blocked())
|
||||
blockedChanged(!wasBlocked);
|
||||
updateBorders();
|
||||
}
|
||||
|
||||
void Block::removeTrain(std::weak_ptr<Train> train)
|
||||
{
|
||||
std::shared_ptr<Train> trainPtr = train.lock();
|
||||
if(!trainPtr)
|
||||
return;
|
||||
|
||||
for(std::vector<std::weak_ptr<Train>>::iterator iter = trains_.begin(); iter != trains_.end(); ++iter)
|
||||
{
|
||||
if(iter->lock() == trainPtr)
|
||||
{
|
||||
qDebug()<<"Train"<<trainPtr->getTrainId()<<"removed from to block"<<id_;
|
||||
trains_.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Block::trainArrivedAtBorder(std::weak_ptr<BlockBorder> borderIn, std::weak_ptr<Train> trainIn)
|
||||
{
|
||||
qDebug()<<__func__<<"block"<<id();
|
||||
bool wasBlocked = blocked();
|
||||
std::shared_ptr<BlockBorder> border = borderIn.lock();
|
||||
if(!border)
|
||||
{
|
||||
qWarning()<<"border has expired in"<<__func__;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ownsBorder(border))
|
||||
return;
|
||||
|
||||
qDebug()<<"Block"<<id_<<"owns subject border";
|
||||
|
||||
if(!ownsTrain(trainIn))
|
||||
return;
|
||||
|
||||
qDebug()<<"Block"<<id_<<"owns subject train";
|
||||
|
||||
std::shared_ptr block = border->getOtherBlock(this);
|
||||
if(block)
|
||||
{
|
||||
std::shared_ptr<Train> workTrain = trainIn.lock();
|
||||
if(workTrain)
|
||||
{
|
||||
if(!block->pushTrain(trainIn))
|
||||
{
|
||||
workTrain->suspend();
|
||||
TrainWait wait;
|
||||
wait.train = trainIn;
|
||||
wait.direction = workTrain->getDirection();
|
||||
wait.targetBlock = block;
|
||||
wait.border = border;
|
||||
connect(workTrain.get(), &Train::unsuspended, this, &Block::unsuspendedTrain);
|
||||
waits_.push_back(wait);
|
||||
qDebug()<<"Train"<<workTrain->getTrainId()<<"is wating at border for block"<<block->id();
|
||||
if(!block->trains_.empty() && block->trains_[0].lock())
|
||||
qDebug()<<"for train"<<block->trains_[0].lock()->getTrainId()<<"to leave";
|
||||
}
|
||||
removeTrain(workTrain);
|
||||
}
|
||||
}
|
||||
if(wasBlocked != blocked())
|
||||
blockedChanged(blocked());
|
||||
updateBorders();
|
||||
}
|
||||
|
||||
void Block::store(QJsonObject &json)
|
||||
{
|
||||
json["Id"] = static_cast<double>(id_);
|
||||
QJsonArray borders;
|
||||
for(auto& border : borders_)
|
||||
{
|
||||
QJsonObject borderObject;
|
||||
borderObject["BorderId"] = static_cast<double>(border->id());
|
||||
borders.append(borderObject);
|
||||
}
|
||||
json["Borders"] = borders;
|
||||
}
|
||||
|
||||
void Block::load(const QJsonObject &json)
|
||||
{
|
||||
id_ = static_cast<uint32_t>(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<uint32_t>(arrayObj.toObject()["BorderId"].toDouble(INT32_MAX));
|
||||
std::shared_ptr<BlockBorder> border = layout->getBorder(borderId);
|
||||
if(border)
|
||||
addBorder(border);
|
||||
else if(borderId == INT32_MAX)
|
||||
qWarning()<<"BorderId field is missing in border array for block"<<id_;
|
||||
else
|
||||
qWarning()<<"border"<<borderId<<"dosent exist but is needed by block"<<id_;
|
||||
}
|
||||
}
|
||||
}
|
65
src/trainOverlord/block.h
Normal file
65
src/trainOverlord/block.h
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef BLOCK_H
|
||||
#define BLOCK_H
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <QObject>
|
||||
#include <QRandomGenerator>
|
||||
#include <QJsonObject>
|
||||
#include "blockborder.h"
|
||||
#include "train.h"
|
||||
|
||||
class BlockBorder;
|
||||
class Layout;
|
||||
|
||||
class Block: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
static constexpr int WAIT_TYPE_BLOCK = 0;
|
||||
static constexpr int WAIT_TYPE_TRAVERSE = 1;
|
||||
|
||||
struct TrainWait
|
||||
{
|
||||
int type;
|
||||
int direction;
|
||||
std::weak_ptr<Train> train;
|
||||
std::weak_ptr<Block> targetBlock;
|
||||
std::weak_ptr<BlockBorder> border;
|
||||
};
|
||||
|
||||
std::vector< std::shared_ptr<BlockBorder> > borders_;
|
||||
std::vector< std::weak_ptr<Train> > trains_;
|
||||
std::vector<TrainWait> waits_;
|
||||
uint32_t id_;
|
||||
|
||||
protected slots:
|
||||
void unsuspendedTrain(uint32_t id, int direction);
|
||||
|
||||
protected:
|
||||
void checkWaits(bool blocked = false);
|
||||
void updateBorders();
|
||||
|
||||
public:
|
||||
Block(uint32_t id = QRandomGenerator::global()->generate());
|
||||
void addBorder(std::shared_ptr<BlockBorder> border);
|
||||
bool blocked();
|
||||
bool ownsTrain(std::weak_ptr<Train> train);
|
||||
bool ownsBorder(std::shared_ptr<BlockBorder> border);
|
||||
std::vector< std::shared_ptr<BlockBorder> > getBorders(){return borders_;}
|
||||
uint32_t id(){return id_;}
|
||||
void removeTrain(std::weak_ptr<Train> train);
|
||||
void store(QJsonObject& json);
|
||||
void load(const QJsonObject& json);
|
||||
void populate(const QJsonObject& json, Layout* layout);
|
||||
|
||||
public slots:
|
||||
bool pushTrain(std::weak_ptr<Train> train);
|
||||
void addTrain(std::weak_ptr<Train> train);
|
||||
void trainArrivedAtBorder(std::weak_ptr<BlockBorder> border, std::weak_ptr<Train> train);
|
||||
|
||||
signals:
|
||||
void blockedChanged(bool blocked);
|
||||
void trainAddedToBlock(int blockId, std::weak_ptr<Train> train);
|
||||
};
|
||||
|
||||
#endif // BLOCK_H
|
137
src/trainOverlord/blockborder.cpp
Normal file
137
src/trainOverlord/blockborder.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
#include "blockborder.h"
|
||||
#include <QJsonArray>
|
||||
#include <layout.h>
|
||||
|
||||
BlockBorder::BlockBorder(uint8_t reader, std::pair<std::weak_ptr<Block>, std::weak_ptr<Block>> blocks, uint32_t id): reader_(reader), blocks_(blocks), id_(id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool BlockBorder::isReader(uint8_t reader)
|
||||
{
|
||||
return reader == reader_;
|
||||
}
|
||||
|
||||
uint8_t BlockBorder::getReader()
|
||||
{
|
||||
return reader_;
|
||||
}
|
||||
|
||||
void BlockBorder::setSignal(std::weak_ptr<Signal> signalWeak, int8_t value)
|
||||
{
|
||||
std::shared_ptr<Signal> signal = signalWeak.lock();
|
||||
if(signal)
|
||||
{
|
||||
signal->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
void BlockBorder::updateSignals()
|
||||
{
|
||||
for(size_t i = 0; i < signals_.size(); ++i)
|
||||
{
|
||||
std::shared_ptr<Signal> signal = signals_[i].lock();
|
||||
if(signal)
|
||||
{
|
||||
std::shared_ptr<Block> block = signalDirections_[i] ? blocks_.first.lock() : blocks_.second.lock();
|
||||
if(block && block->blocked())
|
||||
{
|
||||
if(signal->getValue() != Signal::STOP)
|
||||
{
|
||||
std::weak_ptr<Signal> signalWeak = signal;
|
||||
QTimer::singleShot(500, signal.get(), [signalWeak](){BlockBorder::setSignal(signalWeak, Signal::STOP);});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(signal->getValue() != Signal::GO)
|
||||
{
|
||||
std::weak_ptr<Signal> 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> signal, std::shared_ptr<Block> block)
|
||||
{
|
||||
signals_.push_back(signal);
|
||||
signalDirections_.push_back(block == blocks_.first.lock());
|
||||
}
|
||||
|
||||
std::shared_ptr<Block> BlockBorder::getOtherBlock(Block* block)
|
||||
{
|
||||
std::shared_ptr<Block> first = blocks_.first.lock();
|
||||
std::shared_ptr<Block> second = blocks_.second.lock();
|
||||
|
||||
if(first && first.get() == block)
|
||||
return second;
|
||||
if(second && second.get() == block)
|
||||
return first;
|
||||
return std::shared_ptr<Block>();
|
||||
}
|
||||
|
||||
std::shared_ptr<Block> 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<Block>();
|
||||
}
|
||||
|
||||
void BlockBorder::store(QJsonObject& json)
|
||||
{
|
||||
json["Id"] = static_cast<double>(id_);
|
||||
json["Reader"] = static_cast<double>(reader_);
|
||||
QJsonArray signalArray;
|
||||
for(size_t i = 0; i < signals_.size(); ++i)
|
||||
{
|
||||
std::shared_ptr<Signal> signalPtr = signals_[i].lock();
|
||||
if(signalPtr)
|
||||
{
|
||||
QJsonObject signalObject;
|
||||
signalObject["SignalId"] = static_cast<double>(signalPtr->getSignalId());
|
||||
signalObject["Direction"] = static_cast<double>(signalDirections_[i]);
|
||||
signalArray.append(signalObject);
|
||||
}
|
||||
}
|
||||
json["Signals"] = signalArray;
|
||||
}
|
||||
|
||||
void BlockBorder::load(const QJsonObject& json)
|
||||
{
|
||||
id_ = static_cast<uint32_t>(json["Id"].toDouble(0));
|
||||
reader_ = json["Reader"].toDouble(0);
|
||||
const QJsonArray signalArray(json["Signals"].toArray(QJsonArray()));
|
||||
for(const auto& arrayObj : signalArray)
|
||||
{
|
||||
if(arrayObj.isObject())
|
||||
{
|
||||
signalIds_.push_back(std::pair<uint32_t, bool>(static_cast<uint32_t>(json["SignalId"].toDouble(INT32_MAX)), static_cast<bool>(json["Direction"].toDouble(0))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BlockBorder::informOfSignal(std::shared_ptr<Signal> signal)
|
||||
{
|
||||
for(const std::pair<uint32_t, bool>& signalPair : signalIds_)
|
||||
{
|
||||
if(signalPair.first == signal->getSignalId())
|
||||
{
|
||||
signals_.push_back(signal);
|
||||
signalDirections_.push_back(signalPair.second);
|
||||
}
|
||||
}
|
||||
}
|
38
src/trainOverlord/blockborder.h
Normal file
38
src/trainOverlord/blockborder.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef BLOCKBORDER_H
|
||||
#define BLOCKBORDER_H
|
||||
#include "trainsignal.h"
|
||||
#include "block.h"
|
||||
#include <QJsonObject>
|
||||
|
||||
class Block;
|
||||
class Layout;
|
||||
|
||||
class BlockBorder
|
||||
{
|
||||
private:
|
||||
uint64_t reader_;
|
||||
uint32_t id_;
|
||||
std::vector<std::pair<uint32_t, bool>> signalIds_;
|
||||
std::vector<std::weak_ptr<Signal>> signals_;
|
||||
std::vector<bool> signalDirections_;
|
||||
std::pair<std::weak_ptr<Block>, std::weak_ptr<Block>> blocks_;
|
||||
|
||||
static void setSignal(std::weak_ptr<Signal> signalWeak, int8_t value);
|
||||
|
||||
public:
|
||||
BlockBorder(uint8_t reader = 0, std::pair<std::weak_ptr<Block>, std::weak_ptr<Block>> blocks = std::pair<std::weak_ptr<Block>, std::weak_ptr<Block>>(), uint32_t id = QRandomGenerator::global()->generate());
|
||||
bool isReader(uint8_t reader);
|
||||
uint8_t getReader();
|
||||
void updateSignals();
|
||||
std::shared_ptr<Block> getOtherBlock(Block* block);
|
||||
std::pair<std::weak_ptr<Block>, std::weak_ptr<Block>> getBlocks(){return blocks_;}
|
||||
void setBlocks(std::pair<std::weak_ptr<Block>, std::weak_ptr<Block>> blocks){blocks_ = blocks;}
|
||||
void addSignal(std::weak_ptr<Signal> signal, std::shared_ptr<Block> block);
|
||||
void informOfSignal(std::shared_ptr<Signal> signal);
|
||||
std::shared_ptr<Block> getOverlap(BlockBorder* border);
|
||||
uint32_t id() {return id_;}
|
||||
void store(QJsonObject& json);
|
||||
void load(const QJsonObject& json);
|
||||
};
|
||||
|
||||
#endif // BLOCKBORDER_H
|
221
src/trainOverlord/layout.cpp
Normal file
221
src/trainOverlord/layout.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
#include "layout.h"
|
||||
#include <memory>
|
||||
#include <QJsonArray>
|
||||
|
||||
Layout::Layout(QObject *parent): QObject{parent}
|
||||
{
|
||||
}
|
||||
|
||||
void Layout::itemAdded(std::weak_ptr<Item> itemIn)
|
||||
{
|
||||
std::shared_ptr<Item> item = itemIn.lock();
|
||||
if(!item)
|
||||
return;
|
||||
std::shared_ptr<Train> train = std::dynamic_pointer_cast<Train>(item);
|
||||
std::shared_ptr<Signal> signal = std::dynamic_pointer_cast<Signal>(item);
|
||||
}
|
||||
|
||||
void Layout::removeTrainFromAllBlocks(std::shared_ptr<Train> train)
|
||||
{
|
||||
for(std::shared_ptr<Block> block : blocks_)
|
||||
block->removeTrain(train);
|
||||
}
|
||||
|
||||
void Layout::registerTrainInLimbo(std::shared_ptr<Train> train, std::shared_ptr<BlockBorder> border)
|
||||
{
|
||||
for(auto iter = trainLimbo_.begin(); iter != trainLimbo_.end(); ++iter)
|
||||
{
|
||||
std::shared_ptr<Train> limboTrain = iter->first.lock();
|
||||
std::shared_ptr<BlockBorder> limboBorder = iter->second.lock();
|
||||
if(!limboTrain || !limboBorder)
|
||||
{
|
||||
trainLimbo_.erase(iter);
|
||||
registerTrainInLimbo(train, border);
|
||||
return;
|
||||
}
|
||||
|
||||
if(*train == *limboTrain)
|
||||
{
|
||||
if(border == limboBorder)
|
||||
return;
|
||||
|
||||
std::shared_ptr<Block> overlap = border->getOverlap(limboBorder.get());
|
||||
if(overlap)
|
||||
{
|
||||
qDebug()<<"Train"<<train->getTrainId()<<"removed from limbo and added to block"<<overlap->id()<<"while crossing border"<<border->id();
|
||||
overlap->addTrain(train);
|
||||
overlap->trainArrivedAtBorder(border, train);
|
||||
trainLimbo_.erase(iter);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->second = border;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
std::shared_ptr<Block> first = border->getBlocks().first.lock();
|
||||
std::shared_ptr<Block> second = border->getBlocks().second.lock();
|
||||
|
||||
qDebug()<<"Train"<<train->getTrainId()<<"added to limbo between block"<<
|
||||
(first ? QString::number(first->id()) : "invalid")<<"and block"<<(second ? QString::number(second->id()) : "invalid");
|
||||
trainLimbo_.push_back(std::pair<std::weak_ptr<Train>, std::weak_ptr<BlockBorder>>(train, border));
|
||||
}
|
||||
|
||||
void Layout::trainArrivedAtReader(uint8_t reader, std::shared_ptr<Train> train, int tagType)
|
||||
{
|
||||
std::shared_ptr<BlockBorder> border;
|
||||
for(std::shared_ptr<BlockBorder> borderTest : borders_)
|
||||
{
|
||||
if(borderTest->getReader() == reader)
|
||||
{
|
||||
border = borderTest;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!border)
|
||||
{
|
||||
qWarning()<<"reader "<<reader<<"is not registerd with any border";
|
||||
return;
|
||||
}
|
||||
qDebug()<<"Train"<<train->getTrainId()<<"arrived at border"<<border->id();
|
||||
|
||||
bool trainHandled = false;
|
||||
for(std::shared_ptr<Block> block : blocks_)
|
||||
{
|
||||
if(block->ownsTrain(train))
|
||||
{
|
||||
trainHandled = true;
|
||||
if(block->ownsBorder(border))
|
||||
{
|
||||
block->trainArrivedAtBorder(border, train);
|
||||
}
|
||||
else
|
||||
{
|
||||
removeTrainFromAllBlocks(train);
|
||||
registerTrainInLimbo(train, border);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!trainHandled)
|
||||
registerTrainInLimbo(train, border);
|
||||
}
|
||||
|
||||
void Layout::addBlock(std::shared_ptr<Block> block)
|
||||
{
|
||||
blocks_.push_back(block);
|
||||
}
|
||||
|
||||
void Layout::addBorder(std::shared_ptr<BlockBorder> border)
|
||||
{
|
||||
borders_.push_back(border);
|
||||
}
|
||||
|
||||
std::shared_ptr<BlockBorder> Layout::getBorder(uint32_t id)
|
||||
{
|
||||
for(const std::shared_ptr<BlockBorder>& border : borders_)
|
||||
{
|
||||
if(border->id() == id)
|
||||
return border;
|
||||
}
|
||||
return std::shared_ptr<BlockBorder>();
|
||||
}
|
||||
|
||||
std::shared_ptr<Block> Layout::getBlock(uint32_t id)
|
||||
{
|
||||
for(const std::shared_ptr<Block>& block : blocks_)
|
||||
{
|
||||
if(block->id() == id)
|
||||
return block;
|
||||
}
|
||||
return std::shared_ptr<Block>();
|
||||
}
|
||||
|
||||
void Layout::store(QJsonObject& json)
|
||||
{
|
||||
QJsonArray blockArray;
|
||||
for(const std::shared_ptr<Block>& block : blocks_)
|
||||
{
|
||||
QJsonObject object;
|
||||
block->store(object);
|
||||
blockArray.append(object);
|
||||
}
|
||||
json["Blocks"] = blockArray;
|
||||
|
||||
QJsonArray borderArray;
|
||||
for(const std::shared_ptr<BlockBorder>& border : borders_)
|
||||
{
|
||||
QJsonObject object;
|
||||
border->store(object);
|
||||
borderArray.append(object);
|
||||
}
|
||||
json["Borders"] = borderArray;
|
||||
}
|
||||
|
||||
void Layout::load(const QJsonObject& json)
|
||||
{
|
||||
std::vector<QJsonObject> 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> block(new Block);
|
||||
block->load(jsonObject);
|
||||
blocks_.push_back(block);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QJsonObject> 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<BlockBorder> 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<BlockBorder>& border : borders_)
|
||||
{
|
||||
std::shared_ptr<Block> first;
|
||||
std::shared_ptr<Block> second;
|
||||
for(std::shared_ptr<Block>& block : blocks_)
|
||||
{
|
||||
if(block->ownsBorder(border))
|
||||
{
|
||||
if(!first)
|
||||
first = block;
|
||||
else if(!second)
|
||||
second = block;
|
||||
else if(!second)
|
||||
qWarning()<<"border with id"<<border->id()<<"is assigned to more than 2 blocks";
|
||||
}
|
||||
}
|
||||
if(!first || !second)
|
||||
qWarning()<<"border with id"<<border->id()<<"is assigned to less than than 2 blocks";
|
||||
border->setBlocks(std::pair<std::weak_ptr<Block>, std::weak_ptr<Block>>(first, second));
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < blocks_.size(); ++i)
|
||||
{
|
||||
blocks_[i]->populate(blockJsonObjects[i], this);
|
||||
if(blocks_[i]->getBorders().empty())
|
||||
qWarning()<<"block with id"<<blocks_[i]->id()<<"doset have at least one border";
|
||||
}
|
||||
}
|
43
src/trainOverlord/layout.h
Normal file
43
src/trainOverlord/layout.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef BLOCKSTORE_H
|
||||
#define BLOCKSTORE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "block.h"
|
||||
#include "blockborder.h"
|
||||
#include "microcontroller.h"
|
||||
#include "itemstore.h"
|
||||
|
||||
class Layout : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<Block>> blocks_;
|
||||
std::vector<std::shared_ptr<BlockBorder>> borders_;
|
||||
std::vector<std::pair<std::weak_ptr<Train>, std::weak_ptr<BlockBorder>>> trainLimbo_;
|
||||
|
||||
void removeTrainFromAllBlocks(std::shared_ptr<Train> train);
|
||||
void registerTrainInLimbo(std::shared_ptr<Train> train, std::shared_ptr<BlockBorder>);
|
||||
|
||||
public:
|
||||
explicit Layout(QObject *parent = nullptr);
|
||||
void addBlock(std::shared_ptr<Block> block);
|
||||
void addBorder(std::shared_ptr<BlockBorder> border);
|
||||
void store(QJsonObject& json);
|
||||
void load(const QJsonObject& json);
|
||||
std::shared_ptr<BlockBorder> getBorder(uint32_t id);
|
||||
std::shared_ptr<Block> getBlock(uint32_t id);
|
||||
|
||||
public slots:
|
||||
void trainArrivedAtReader(uint8_t reader, std::shared_ptr<Train> train, int tagType);
|
||||
void itemAdded(std::weak_ptr<Item> item);
|
||||
|
||||
signals:
|
||||
void trainArrivedAtBorder(std::weak_ptr<BlockBorder>, std::weak_ptr<Train> train, int tagType);
|
||||
};
|
||||
|
||||
#endif // BLOCKSTORE_H
|
@ -10,17 +10,15 @@ void OverlordItemStore::gotNfcTag(NfcUid uid)
|
||||
{
|
||||
for(std::shared_ptr<Item> item : items_)
|
||||
{
|
||||
Train* train = dynamic_cast<Train*>(item.get());
|
||||
std::shared_ptr<Train> train = std::dynamic_pointer_cast<Train>(item);
|
||||
if(!train)
|
||||
continue;
|
||||
for(const NfcUid& trainUid : train->tags)
|
||||
int owns = train->ownsTag(uid);
|
||||
if(owns == Train::TAG_FRONT || owns == Train::TAG_BACK)
|
||||
{
|
||||
if(trainUid == uid)
|
||||
{
|
||||
if(train->passedReader(uid))
|
||||
train->setValue(0-train->getValue());
|
||||
return;
|
||||
}
|
||||
qDebug()<<"Train"<<train->getTrainId()<<"arrived at reader"<<uid.reader;
|
||||
trainArrivedAtReader(uid.reader, train, owns);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
#include "itemstore.h"
|
||||
#include <QTimer>
|
||||
#include "train.h"
|
||||
|
||||
class OverlordItemStore: public ItemStore
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QTimer timer;
|
||||
public:
|
||||
OverlordItemStore(QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
|
||||
void gotNfcTag(NfcUid);
|
||||
|
||||
signals:
|
||||
void trainArrivedAtReader(uint8_t reader, std::shared_ptr<Train> train, int tagType);
|
||||
};
|
||||
|
@ -3,20 +3,87 @@
|
||||
#include <QIODevice>
|
||||
#include <QTcpSocket>
|
||||
#include <iostream>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QStandardPaths>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
#include <signal.h>
|
||||
|
||||
#include "microcontroller.h"
|
||||
#include "nfcuid.h"
|
||||
#include "overlorditemstore.h"
|
||||
#include "train.h"
|
||||
#include "turnout.h"
|
||||
#include "signal.h"
|
||||
#include "layout.h"
|
||||
|
||||
void gotTag(NfcUid uid)
|
||||
void sigHandler(int sig)
|
||||
{
|
||||
std::cout<<"Got tag from "<<uid.reader<<" uid ";
|
||||
for(size_t i = 0; i < uid.length; ++i)
|
||||
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::cout<<(int)uid.bytes[i]<<(i == uid.length-1 ? "" : ":");
|
||||
std::cerr<<"Can not open config file: "<<filePath.toLatin1().data()<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
QJsonParseError qerror;
|
||||
QJsonDocument document(QJsonDocument::fromJson(file.readAll(), &qerror));
|
||||
file.close();
|
||||
if(qerror.error != QJsonParseError::NoError)
|
||||
{
|
||||
qDebug()<<filePath<<" "<<qerror.errorString();
|
||||
if(error)
|
||||
(*error) = true;
|
||||
}
|
||||
return document.object();
|
||||
}
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
bool storeJsonObjectToDisk(const QJsonObject& json, QString filePath = QString())
|
||||
{
|
||||
if(filePath.size() == 0)
|
||||
{
|
||||
filePath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/trainoverloard.json";
|
||||
}
|
||||
QFile file(filePath + ".out");
|
||||
|
||||
qDebug()<<"config file: "<<filePath;
|
||||
file.open(QIODevice::WriteOnly);
|
||||
if(!file.isOpen())
|
||||
{
|
||||
std::cerr<<"Can not open config file: "<<filePath.toLatin1().data()<<std::endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
QJsonDocument document(json);
|
||||
file.write(document.toJson());
|
||||
file.close();
|
||||
QFile::remove(filePath);
|
||||
file.rename(filePath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void getItemsCb(QTimer* timer, ItemStore* items, Microcontroller* micro)
|
||||
{
|
||||
if(items->getItems()->empty())
|
||||
{
|
||||
micro->requestState();
|
||||
timer->start(1000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +91,8 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
signal(SIGINT, &sigHandler);
|
||||
|
||||
//set info
|
||||
QCoreApplication::setOrganizationName("UVOS");
|
||||
QCoreApplication::setOrganizationDomain("uvos.xyz");
|
||||
@ -60,9 +129,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
OverlordItemStore items;
|
||||
Layout layout;
|
||||
|
||||
QObject::connect(&items, &OverlordItemStore::itemAdded, &layout, &Layout::itemAdded);
|
||||
QObject::connect(&items, &OverlordItemStore::trainArrivedAtReader, &layout, &Layout::trainArrivedAtReader);
|
||||
|
||||
Microcontroller micro(µSocket);
|
||||
QObject::connect(µ, &Microcontroller::gotTag, gotTag);
|
||||
QObject::connect(µ, &Microcontroller::gotTag, &items, &OverlordItemStore::gotNfcTag);
|
||||
QObject::connect(µ, &Microcontroller::gotItemList, &items, &OverlordItemStore::addItems);
|
||||
QObject::connect(µ, &Microcontroller::itemChanged, &items, &OverlordItemStore::itemStateChanged);
|
||||
@ -71,5 +143,27 @@ int main(int argc, char *argv[])
|
||||
Turnout::micro = µ
|
||||
Signal::micro = µ
|
||||
|
||||
return a.exec();
|
||||
QTimer timer;
|
||||
timer.setSingleShot(false);
|
||||
QObject::connect(&timer, &QTimer::timeout, &timer, [µ, &timer, &items](){getItemsCb(&timer, &items, µ);});
|
||||
getItemsCb(&timer, &items, µ);
|
||||
|
||||
{
|
||||
bool err = false;
|
||||
QJsonObject json = getJsonObjectFromDisk(QString(), &err);
|
||||
if(err)
|
||||
{
|
||||
std::cerr<<"Could not load config file\n";
|
||||
return -1;
|
||||
}
|
||||
layout.load(json);
|
||||
}
|
||||
|
||||
int ret = a.exec();
|
||||
/*
|
||||
QJsonObject jsonStore;
|
||||
layout.store(jsonStore);
|
||||
storeJsonObjectToDisk(jsonStore);
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user