diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 11a92ee..fae25ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Network SerialPort REQUIRED) @@ -23,6 +23,7 @@ set(COMMON_SOURCES ../common/items/train.h ../common/items/turnout.cpp ../common/items/turnout.h + ../common/nfcuid.h ) include_directories(PRIVATE diff --git a/src/common/items/itemstore.cpp b/src/common/items/itemstore.cpp index faf769a..5f0a0cb 100644 --- a/src/common/items/itemstore.cpp +++ b/src/common/items/itemstore.cpp @@ -37,10 +37,15 @@ void ItemStore::addItems(const std::vector>& itemIn) 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) { - const uint8_t uidBytes[] = {136, 83, 111, 26}; - train->tags.push_back(NfcUid(uidBytes, sizeof(uidBytes))); + train->tags.push_back(NfcUid({83, 111, 26, 174})); + train->tags.push_back(NfcUid({83, 63, 78, 170})); } else if(train->getTrainId() == 4) { diff --git a/src/common/items/train.cpp b/src/common/items/train.cpp index 38eb6b3..cfa815a 100644 --- a/src/common/items/train.cpp +++ b/src/common/items/train.cpp @@ -44,21 +44,14 @@ void Train::reverse() micro->trainReverse(train_id_); } -int Train::ownsTag(NfcUid uid) +bool 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 true; } - return TAG_NONE; + return false; } bool Train::suspend() diff --git a/src/common/items/train.h b/src/common/items/train.h index 1d63e58..3b749f0 100644 --- a/src/common/items/train.h +++ b/src/common/items/train.h @@ -3,8 +3,8 @@ #include #include "item.h" -#include "../microcontroller.h" -#include "../nfcuid.h" +#include "microcontroller.h" +#include "nfcuid.h" class Train : public Item { @@ -18,10 +18,6 @@ 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 tags; @@ -41,15 +37,8 @@ public slots: bool resume(); bool suspendend(); int getDirection(); - int ownsTag(NfcUid uid); + bool ownsTag(NfcUid uid); bool hasBackTag(); - bool passedReader(const NfcUid &uid) - { - if(lastReader_ == uid.reader) - return false; - lastReader_ = uid.reader; - return true; - } uint8_t getTrainId() { return train_id_; diff --git a/src/common/microcontroller.cpp b/src/common/microcontroller.cpp index 553e867..a650895 100644 --- a/src/common/microcontroller.cpp +++ b/src/common/microcontroller.cpp @@ -146,13 +146,16 @@ void Microcontroller::processNfcLine(const QString& buffer) if(tokens.size() < 4) return; + if(tokens[1].startsWith("NUMBER")) + return; + NfcUid uid; - uid.reader = tokens[1].toUInt(); + 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(uid); + gotTag(reader, uid); } void Microcontroller::processList(const QString& buffer) diff --git a/src/common/microcontroller.h b/src/common/microcontroller.h index 37f760a..fa28075 100644 --- a/src/common/microcontroller.h +++ b/src/common/microcontroller.h @@ -74,7 +74,7 @@ signals: void itemChanged(ItemData relay); void auxStateChanged(int value); void gotItemList(std::vector>&); - void gotTag(NfcUid uid); + void gotTag(uint8_t reader, NfcUid uid); }; #endif // MICROCONTROLLER_H diff --git a/src/common/nfcuid.h b/src/common/nfcuid.h index 8792290..90cf3fd 100644 --- a/src/common/nfcuid.h +++ b/src/common/nfcuid.h @@ -6,10 +6,9 @@ class NfcUid { public: - uint8_t reader; uint8_t bytes[10]; uint8_t length; - bool operator==(NfcUid& in) const + bool operator==(const NfcUid& in) const { if(length != in.length) return false; @@ -20,18 +19,24 @@ public: } return true; } - bool operator!=(NfcUid& in) const + bool operator!=(const NfcUid& in) const { return !operator==(in); } NfcUid(){} - NfcUid(const uint8_t* const bytesIn, uint8_t lengthIn, uint8_t readerIn = 0): - reader(readerIn), length(lengthIn) + 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() + std::string toString() const { std::string str; for(uint8_t i = 0; i < length; ++i) @@ -45,3 +50,4 @@ public: }; #endif // NFCUID_H + diff --git a/src/trainOverlord/block.cpp b/src/trainOverlord/block.cpp index 63da753..0c9b23d 100644 --- a/src/trainOverlord/block.cpp +++ b/src/trainOverlord/block.cpp @@ -1,9 +1,12 @@ #include "block.h" #include +#include #include +#include "nfcuid.h" -Block::Block(uint32_t id): - id_(id) + +Block::Block(OverlordItemStore* items, uint32_t id): + items_(items), id_(id) { } @@ -13,29 +16,36 @@ void Block::addBorder(std::shared_ptr border) borders_.push_back(border); std::shared_ptr block = border->getOtherBlock(this); if(!block || block.get() == this) - { - qWarning()<<__func__<<"no other block in border"<id(); return; - } connect(block.get(), &Block::blockedChanged, this, &Block::checkWaits); } bool Block::blocked() { - if(trains_.empty() && waits_.empty()) + if(tags_.empty() && waits_.empty()) return false; return true; } -bool Block::ownsTrain(std::weak_ptr train) +bool Block::ownsTag(const NfcUid& tag) { - std::shared_ptr trainPtr = train.lock(); - if(!trainPtr) - return false; - - for(auto ownedTrain : trains_) + for(const NfcUid& candiate : tags_) { - if(ownedTrain.lock() == trainPtr) + 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; @@ -53,17 +63,23 @@ bool Block::ownsBorder(std::shared_ptr border) return false; } -void Block::checkWaits(bool ign) +void Block::checkWaits(bool isBlocked) { - qDebug()<<__func__; - (void)ign; + if(isBlocked) + return; bool wasBlocked = blocked(); - for(std::vector::iterator iter = waits_.begin(); iter != waits_.end();) + 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->pushTrain(iter->train)) + if(block && train && train->suspendend() && block->pushTag(iter->tag)) { train->resume(); std::shared_ptr border = iter->border.lock(); @@ -84,41 +100,89 @@ void Block::checkWaits(bool ign) blockedChanged(!wasBlocked); } -void Block::updateBorders() +bool Block::pushTag(const NfcUid& tag) { - for(std::shared_ptr broder : borders_) + if(!blocked() || tagIsOfOwnedTrain(tag)) { - broder->updateSignals(); + 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"< train) +void Block::addBlockWait(const NfcUid& tag, std::shared_ptr block, std::shared_ptr border) { - if(blocked()) - return false; - - addTrain(train); - return true; + 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::addTrain(std::weak_ptr train) +void Block::addTag(const NfcUid& tag) { - std::shared_ptr trainPtr = train.lock(); - if(!trainPtr) - return; - qDebug()<<"Train"<getTrainId()<<"added to block"<::iterator iter = waits_.begin(); iter != waits_.end(); ++iter) + for(std::vector::iterator iter = waits_.begin(); iter != waits_.end(); ++iter) { std::shared_ptr workTrain = iter->train.lock(); if(!workTrain) @@ -131,45 +195,43 @@ void Block::unsuspendedTrain(uint32_t id, int direction) { std::shared_ptr block = iter->targetBlock.lock(); disconnect(workTrain.get(), &Train::unsuspended, this, &Block::unsuspendedTrain); - if(iter->direction == direction) - { - if(block) - block->addTrain(workTrain); - } - else - { - addTrain(workTrain); - } + if(block) + block->addTag(iter->tag); waits_.erase(iter); break; } } if(wasBlocked != blocked()) blockedChanged(!wasBlocked); - updateBorders(); } -void Block::removeTrain(std::weak_ptr train) +void Block::removeTag(const NfcUid& tag) { - std::shared_ptr trainPtr = train.lock(); - if(!trainPtr) - return; - - for(std::vector>::iterator iter = trains_.begin(); iter != trains_.end(); ++iter) + for(std::vector::iterator iter = tags_.begin(); iter != tags_.end(); ++iter) { - if(iter->lock() == trainPtr) + if(*iter == tag) { - qDebug()<<"Train"<getTrainId()<<"removed from to block"< borderIn, std::weak_ptr trainIn) +void Block::purgeTag(const NfcUid& tag) { - qDebug()<<__func__<<"block"< 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) { @@ -182,37 +244,28 @@ void Block::trainArrivedAtBorder(std::weak_ptr borderIn, std::weak_ qDebug()<<"Block"<getOtherBlock(this); if(block) { - std::shared_ptr workTrain = trainIn.lock(); - if(workTrain) + if(!block->pushTag(tag)) { - 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"<getTrainId()<<"is wating at border for block"<id(); - if(!block->trains_.empty() && block->trains_[0].lock()) - qDebug()<<"for train"<trains_[0].lock()->getTrainId()<<"to leave"; - } - removeTrain(workTrain); + std::shared_ptr train = items_->getTrainThatOwns(tag); + train->suspend(); + addBlockWait(tag, block, border); } + else + { + addTraverseWait(tag); + } + removeTag(tag); } if(wasBlocked != blocked()) - blockedChanged(blocked()); - updateBorders(); + blockedChanged(!wasBlocked); } void Block::store(QJsonObject &json) @@ -252,3 +305,4 @@ void Block::populate(const QJsonObject& json, Layout* layout) } } } + diff --git a/src/trainOverlord/block.h b/src/trainOverlord/block.h index dc9e9b6..4ea5d99 100644 --- a/src/trainOverlord/block.h +++ b/src/trainOverlord/block.h @@ -7,6 +7,7 @@ #include #include "blockborder.h" #include "train.h" +#include "overlorditemstore.h" class BlockBorder; class Layout; @@ -16,50 +17,59 @@ class Block: public QObject Q_OBJECT protected: static constexpr int WAIT_TYPE_BLOCK = 0; - static constexpr int WAIT_TYPE_TRAVERSE = 1; + static constexpr int WAIT_TYPE_TIMED_TRAVERSE = 1; - struct TrainWait + 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< std::weak_ptr > trains_; - std::vector waits_; + 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 updateBorders(); + 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(uint32_t id = QRandomGenerator::global()->generate()); - void addBorder(std::shared_ptr border); - bool blocked(); - bool ownsTrain(std::weak_ptr train); - bool ownsBorder(std::shared_ptr border); - std::vector< std::shared_ptr > getBorders(){return borders_;} + Block(OverlordItemStore* items, uint32_t id = QRandomGenerator::global()->generate()); uint32_t id(){return id_;} - void removeTrain(std::weak_ptr train); + + 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: - bool pushTrain(std::weak_ptr train); - void addTrain(std::weak_ptr train); - void trainArrivedAtBorder(std::weak_ptr border, std::weak_ptr train); + void tagArrivedAtBorder(NfcUid tag, std::weak_ptr border); signals: void blockedChanged(bool blocked); - void trainAddedToBlock(int blockId, std::weak_ptr train); }; #endif // BLOCK_H diff --git a/src/trainOverlord/blockborder.cpp b/src/trainOverlord/blockborder.cpp index 13d77af..f6ec684 100644 --- a/src/trainOverlord/blockborder.cpp +++ b/src/trainOverlord/blockborder.cpp @@ -2,9 +2,9 @@ #include #include -BlockBorder::BlockBorder(uint8_t reader, std::pair, std::weak_ptr> blocks, uint32_t id): reader_(reader), blocks_(blocks), id_(id) +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) @@ -17,6 +17,17 @@ 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(); @@ -26,6 +37,12 @@ void BlockBorder::setSignal(std::weak_ptr signalWeak, int8_t value) } } +void BlockBorder::blockedChanged(bool blocked) +{ + (void)blocked; + updateSignals(); +} + void BlockBorder::updateSignals() { for(size_t i = 0; i < signals_.size(); ++i) @@ -119,19 +136,37 @@ void BlockBorder::load(const QJsonObject& json) { if(arrayObj.isObject()) { - signalIds_.push_back(std::pair(static_cast(json["SignalId"].toDouble(INT32_MAX)), static_cast(json["Direction"].toDouble(0)))); + QJsonObject arrayObjObj = arrayObj.toObject(); + signalIds_.push_back(std::pair(static_cast(arrayObjObj["SignalId"].toDouble(INT32_MAX)), static_cast(arrayObjObj["Direction"].toDouble(0)))); } } } -void BlockBorder::informOfSignal(std::shared_ptr signal) +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 index 8c4bca2..8d72457 100644 --- a/src/trainOverlord/blockborder.h +++ b/src/trainOverlord/blockborder.h @@ -3,12 +3,14 @@ #include "trainsignal.h" #include "block.h" #include +#include class Block; class Layout; -class BlockBorder +class BlockBorder: public QObject { +Q_OBJECT private: uint64_t reader_; uint32_t id_; @@ -26,13 +28,17 @@ public: void updateSignals(); std::shared_ptr getOtherBlock(Block* block); std::pair, std::weak_ptr> getBlocks(){return blocks_;} - void setBlocks(std::pair, std::weak_ptr> blocks){blocks_ = blocks;} + void setBlocks(std::pair, std::weak_ptr> blocks); void addSignal(std::weak_ptr signal, std::shared_ptr block); - void informOfSignal(std::shared_ptr signal); + 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 index 39e32a9..8c27735 100644 --- a/src/trainOverlord/layout.cpp +++ b/src/trainOverlord/layout.cpp @@ -2,39 +2,32 @@ #include #include -Layout::Layout(QObject *parent): QObject{parent} +Layout::Layout(OverlordItemStore* items, QObject *parent): QObject{parent}, items_(items) { } -void Layout::itemAdded(std::weak_ptr itemIn) -{ - std::shared_ptr item = itemIn.lock(); - if(!item) - return; - std::shared_ptr train = std::dynamic_pointer_cast(item); - std::shared_ptr signal = std::dynamic_pointer_cast(item); -} - -void Layout::removeTrainFromAllBlocks(std::shared_ptr train) +void Layout::removeTagFromAllBlocks(const NfcUid& tag) { for(std::shared_ptr block : blocks_) - block->removeTrain(train); + { + block->purgeTag(tag); + } } -void Layout::registerTrainInLimbo(std::shared_ptr train, std::shared_ptr border) +void Layout::registerTagInLimbo(const NfcUid& tag, std::shared_ptr border) { - for(auto iter = trainLimbo_.begin(); iter != trainLimbo_.end(); ++iter) + for(auto iter = limbo_.begin(); iter != limbo_.end(); ++iter) { - std::shared_ptr limboTrain = iter->first.lock(); + NfcUid limboTag = iter->first; std::shared_ptr limboBorder = iter->second.lock(); - if(!limboTrain || !limboBorder) + if(!limboBorder) { - trainLimbo_.erase(iter); - registerTrainInLimbo(train, border); + limbo_.erase(iter); + registerTagInLimbo(tag, border); return; } - if(*train == *limboTrain) + if(limboTag == tag) { if(border == limboBorder) return; @@ -42,10 +35,10 @@ void Layout::registerTrainInLimbo(std::shared_ptr train, std::shared_ptr< std::shared_ptr overlap = border->getOverlap(limboBorder.get()); if(overlap) { - qDebug()<<"Train"<getTrainId()<<"removed from limbo and added to block"<id()<<"while crossing border"<id(); - overlap->addTrain(train); - overlap->trainArrivedAtBorder(border, train); - trainLimbo_.erase(iter); + qDebug()<<"Tag"<id()<<"while crossing border"<id(); + overlap->addTag(tag); + overlap->tagArrivedAtBorder(tag, border); + limbo_.erase(iter); return; } else @@ -59,12 +52,12 @@ void Layout::registerTrainInLimbo(std::shared_ptr train, std::shared_ptr< std::shared_ptr first = border->getBlocks().first.lock(); std::shared_ptr second = border->getBlocks().second.lock(); - qDebug()<<"Train"<getTrainId()<<"added to limbo between block"<< + qDebug()<<"Tag"<id()) : "invalid")<<"and block"<<(second ? QString::number(second->id()) : "invalid"); - trainLimbo_.push_back(std::pair, std::weak_ptr>(train, border)); + limbo_.push_back(std::pair>(tag, border)); } -void Layout::trainArrivedAtReader(uint8_t reader, std::shared_ptr train, int tagType) +void Layout::tagArrivedAtReader(uint8_t reader, NfcUid tag) { std::shared_ptr border; for(std::shared_ptr borderTest : borders_) @@ -80,29 +73,31 @@ void Layout::trainArrivedAtReader(uint8_t reader, std::shared_ptr train, qWarning()<<"reader "<getTrainId()<<"arrived at border"<id(); - bool trainHandled = false; - for(std::shared_ptr block : blocks_) + std::shared_ptr train = items_->getTrainThatOwns(tag); + qDebug()<<"Train"<<(train ? train->getTrainId() : -1)<<"Tag"<id(); + + bool tagHandled = false; + for(std::shared_ptr& block : blocks_) { - if(block->ownsTrain(train)) + if(block->ownsTag(tag)) { - trainHandled = true; + tagHandled = true; if(block->ownsBorder(border)) { - block->trainArrivedAtBorder(border, train); + block->tagArrivedAtBorder(tag, border); } else { - removeTrainFromAllBlocks(train); - registerTrainInLimbo(train, border); + removeTagFromAllBlocks(tag); + registerTagInLimbo(tag, border); } break; } } - if(!trainHandled) - registerTrainInLimbo(train, border); + if(!tagHandled) + registerTagInLimbo(tag, border); } void Layout::addBlock(std::shared_ptr block) @@ -166,7 +161,7 @@ void Layout::load(const QJsonObject& json) { const QJsonObject jsonObject = object.toObject(); blockJsonObjects.push_back(jsonObject); - std::shared_ptr block(new Block); + std::shared_ptr block(new Block(items_)); block->load(jsonObject); blocks_.push_back(block); } @@ -203,13 +198,18 @@ void Layout::load(const QJsonObject& json) first = block; else if(!second) second = block; - else if(!second) + 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) diff --git a/src/trainOverlord/layout.h b/src/trainOverlord/layout.h index fcb8ab3..7bbe6fe 100644 --- a/src/trainOverlord/layout.h +++ b/src/trainOverlord/layout.h @@ -6,6 +6,7 @@ #include #include "block.h" +#include "overlorditemstore.h" #include "blockborder.h" #include "microcontroller.h" #include "itemstore.h" @@ -18,13 +19,15 @@ private: private: std::vector> blocks_; std::vector> borders_; - std::vector, std::weak_ptr>> trainLimbo_; + std::vector>> limbo_; - void removeTrainFromAllBlocks(std::shared_ptr train); - void registerTrainInLimbo(std::shared_ptr train, std::shared_ptr); + void removeTagFromAllBlocks(const NfcUid& tag); + void registerTagInLimbo(const NfcUid& tag, std::shared_ptr); + + OverlordItemStore *items_; public: - explicit Layout(QObject *parent = nullptr); + explicit Layout(OverlordItemStore *items, QObject *parent = nullptr); void addBlock(std::shared_ptr block); void addBorder(std::shared_ptr border); void store(QJsonObject& json); @@ -33,11 +36,7 @@ public: std::shared_ptr getBlock(uint32_t id); public slots: - void trainArrivedAtReader(uint8_t reader, std::shared_ptr train, int tagType); - void itemAdded(std::weak_ptr item); - -signals: - void trainArrivedAtBorder(std::weak_ptr, std::weak_ptr train, int tagType); + void tagArrivedAtReader(uint8_t reader, NfcUid tag); }; #endif // BLOCKSTORE_H diff --git a/src/trainOverlord/overlorditemstore.cpp b/src/trainOverlord/overlorditemstore.cpp index 9222d9a..4e3c0f3 100644 --- a/src/trainOverlord/overlorditemstore.cpp +++ b/src/trainOverlord/overlorditemstore.cpp @@ -6,19 +6,15 @@ OverlordItemStore::OverlordItemStore(QObject *parent): ItemStore(parent) { } -void OverlordItemStore::gotNfcTag(NfcUid uid) +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; - int owns = train->ownsTag(uid); - if(owns == Train::TAG_FRONT || owns == Train::TAG_BACK) - { - qDebug()<<"Train"<getTrainId()<<"arrived at reader"<ownsTag(uid)) + return train; } + return std::shared_ptr(); } diff --git a/src/trainOverlord/overlorditemstore.h b/src/trainOverlord/overlorditemstore.h index 42123c3..92f3954 100644 --- a/src/trainOverlord/overlorditemstore.h +++ b/src/trainOverlord/overlorditemstore.h @@ -7,10 +7,5 @@ class OverlordItemStore: public ItemStore Q_OBJECT public: OverlordItemStore(QObject *parent = nullptr); - -public slots: - void gotNfcTag(NfcUid); - -signals: - void trainArrivedAtReader(uint8_t reader, std::shared_ptr train, int tagType); + std::shared_ptr getTrainThatOwns(const NfcUid& uid); }; diff --git a/src/trainOverlord/trainoverlord.cpp b/src/trainOverlord/trainoverlord.cpp index eee419a..5202293 100644 --- a/src/trainOverlord/trainoverlord.cpp +++ b/src/trainOverlord/trainoverlord.cpp @@ -129,13 +129,10 @@ 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); + Layout layout(&items); Microcontroller micro(µSocket); - QObject::connect(µ, &Microcontroller::gotTag, &items, &OverlordItemStore::gotNfcTag); + QObject::connect(µ, &Microcontroller::gotTag, &layout, &Layout::tagArrivedAtReader); QObject::connect(µ, &Microcontroller::gotItemList, &items, &OverlordItemStore::addItems); QObject::connect(µ, &Microcontroller::itemChanged, &items, &OverlordItemStore::itemStateChanged);