diff --git a/src/actors/actor.cpp b/src/actors/actor.cpp index 41688d7..320e5c0 100644 --- a/src/actors/actor.cpp +++ b/src/actors/actor.cpp @@ -21,7 +21,10 @@ void Actor::performAction() { if(active) { - sigValue(triggerValue); + ItemUpdateRequest request; + request.type = ITEM_UPDATE_ACTOR; + request.payload = ItemData(QRandomGenerator::global()->generate(), "Item", triggerValue); + sigItemUpdate(request); } } @@ -86,9 +89,9 @@ uint8_t Actor::getTriggerValue() return triggerValue; } -void Actor::onValueChanged(uint8_t value) +void Actor::onItemUpdated(ItemUpdateRequest update) { - (void)value; + (void) update; } std::shared_ptr Actor::createActor(const QString& type) @@ -112,9 +115,7 @@ std::shared_ptr Actor::loadActor(const QJsonObject &json) return actor; } -void Actor::setValue(uint8_t value) +void Actor::enactValue(uint8_t value) { - Item::setValue(value); setActive(value); } - diff --git a/src/actors/actor.h b/src/actors/actor.h index 7b81bde..e76bc8e 100644 --- a/src/actors/actor.h +++ b/src/actors/actor.h @@ -19,18 +19,17 @@ protected: bool exausted = false; void performAction(); + virtual void enactValue(uint8_t value) override; signals: - void sigValue(uint8_t value); + void sigItemUpdate(ItemUpdateRequest update); public slots: virtual void makeActive(); virtual void makeInactive(); virtual void setActive(uint8_t state); - virtual void onValueChanged(uint8_t state); - - virtual void setValue(uint8_t value); + virtual void onItemUpdated(ItemUpdateRequest update); public: Actor(QObject* parent = nullptr); @@ -46,8 +45,8 @@ public: static std::shared_ptr createActor(const QString& type); - virtual void store(QJsonObject& json); - virtual void load(const QJsonObject& json, const bool preserve = false); + virtual void store(QJsonObject& json) override; + virtual void load(const QJsonObject& json, const bool preserve = false) override; static std::shared_ptr loadActor(const QJsonObject& json); }; diff --git a/src/items/fixeditemsource.cpp b/src/items/fixeditemsource.cpp index d1abc21..b4459ff 100644 --- a/src/items/fixeditemsource.cpp +++ b/src/items/fixeditemsource.cpp @@ -10,5 +10,5 @@ FixedItemSource::FixedItemSource(Microcontroller* micro, QObject *parent): void FixedItemSource::refresh() { - gotItems({powerItem, rgbItem, auxItem}); + gotItems({powerItem, rgbItem, auxItem}, ITEM_UPDATE_BACKEND); } diff --git a/src/items/item.cpp b/src/items/item.cpp index 53790ae..6f88544 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -34,6 +34,11 @@ uint8_t ItemData::getValue() const return value_; } +void ItemData::setValueData(uint8_t value) +{ + value_ = value; +} + uint32_t ItemData::id() const { return itemId_; @@ -156,41 +161,27 @@ Item& Item::operator=(const ItemData& other) void Item::requestUpdate(ItemUpdateRequest update) { - if(!hasChanged(update.data)) + if(!hasChanged(update.payload)) return; - if(update.type == ITEM_UPDATE_USER || (update.type == ITEM_UPDATE_ACTOR && !override_) || update.type == ITEM_UPDATE_REMOTE) + if(update.type == ITEM_UPDATE_ACTOR && override_) + return; + + if(update.type != ITEM_UPDATE_LOADED + && (programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)) + enactValue(update.payload.getValue()); + + *this = update.payload; + update.payload = *this; + + if(update.type == ITEM_UPDATE_LOADED) { - if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY) - enactValue(update.data.getValue()); - *this = update.data; - update.data = *this; - updated(update); + actors_.clear(); + for(std::shared_ptr& actor : update.newActors) + addActor(actor); } -} -void Item::actorSetValue(uint8_t value) -{ - if(!override_ && (programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)) - setValue(value); -} - -void Item::setValue(uint8_t value) -{ - qDebug()<<__func__; - informValue(value); - updated(*this); - if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY) - enactValue(value); -} - -void Item::informValue(uint8_t value) -{ - if(value_ != value) - { - value_ = value; - valueChanged(value_); - } + updated(update); } void Item::enactValue(uint8_t value) @@ -203,8 +194,8 @@ void Item::addActor(std::shared_ptr actor) actor->setParent(this); actors_.push_back(actor); if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY) - connect(actor.get(), &Actor::sigValue, this, &Item::actorSetValue); - connect(this, &Item::valueChanged, actor.get(), &Actor::onValueChanged); + connect(actor.get(), &Actor::sigItemUpdate, this, &Item::requestUpdate); + connect(this, &Item::updated, actor.get(), &Actor::onItemUpdated); std::shared_ptr sensorActor = std::dynamic_pointer_cast(actor); if(sensorActor) @@ -263,14 +254,6 @@ void Item::setActorsActive(bool in) in ? actors_[i]->makeActive() : actors_[i]->makeInactive(); } -void Item::mergeLoaded(Item& item) -{ - name_ = item.name_; - actors_.clear(); - for(std::shared_ptr actor : item.actors_) - addActor(actor); -} - std::shared_ptr Item::loadItem(const QJsonObject& json) { std::shared_ptr newItem = nullptr; @@ -298,3 +281,14 @@ std::shared_ptr Item::loadItem(const QJsonObject& json) return newItem; } +ItemUpdateRequest Item::createValueUpdateRequest(uint8_t value, + item_update_type_t type, + bool withActors) +{ + ItemUpdateRequest update; + update.payload = *this; + update.payload.setValueData(value); + if(withActors) + update.newActors = actors_; + return update; +} diff --git a/src/items/item.h b/src/items/item.h index 4fbf23f..f88b8cf 100644 --- a/src/items/item.h +++ b/src/items/item.h @@ -17,7 +17,9 @@ typedef enum { typedef enum { ITEM_UPDATE_USER = 0, ITEM_UPDATE_ACTOR, - ITEM_UPDATE_REMOTE + ITEM_UPDATE_REMOTE, + ITEM_UPDATE_LOADED, + ITEM_UPDATE_BACKEND } item_update_type_t; class ItemData @@ -52,6 +54,7 @@ public: bool hasChanged(const ItemData& other); void setName(QString name); uint8_t getValue() const; + void setValueData(uint8_t value); bool getLoaded() const; void setLoaded(bool loaded); bool isHidden() const; @@ -65,8 +68,8 @@ public: struct ItemUpdateRequest { item_update_type_t type; - ItemData data; - bool valueOnly; + ItemData payload; + std::vector > newActors; }; @@ -81,7 +84,7 @@ signals: void updated(ItemUpdateRequest update); public slots: - void requestUpdate(ItemUpdateRequest update); + virtual void requestUpdate(ItemUpdateRequest update); public: @@ -100,7 +103,9 @@ public: void setActorsActive(bool in); void setOverride(const bool in); bool getOverride(); - void mergeLoaded(Item& item); + ItemUpdateRequest createValueUpdateRequest(uint8_t value, + item_update_type_t type, + bool withActors = false); virtual void store(QJsonObject& json); virtual void load(const QJsonObject& json, const bool preserve = false); diff --git a/src/items/itemloadersource.cpp b/src/items/itemloadersource.cpp index d5e6afa..a24e5a5 100644 --- a/src/items/itemloadersource.cpp +++ b/src/items/itemloadersource.cpp @@ -25,7 +25,7 @@ void ItemLoaderSource::refresh() qDebug()<<"Loaded item"<getName(); } } - gotItems(items); + gotItems(items, ITEM_UPDATE_LOADED); } void ItemLoaderSource::updateJson(const QJsonObject& json) diff --git a/src/items/itemsource.h b/src/items/itemsource.h index 9fee9c1..5c2bba2 100644 --- a/src/items/itemsource.h +++ b/src/items/itemsource.h @@ -17,9 +17,9 @@ public slots: virtual void refresh() = 0; signals: - void gotItems(std::vector> items, bool inform = true); + void gotItems(std::vector> items, item_update_type_t updateType); void requestReplaceItems(std::vector> items); - void updateItems(std::vector items, bool inform = true); + void updateItems(std::vector updates); }; #endif // ITEMSOURCE_H diff --git a/src/items/itemstore.cpp b/src/items/itemstore.cpp index e601aee..a14ae6f 100644 --- a/src/items/itemstore.cpp +++ b/src/items/itemstore.cpp @@ -6,7 +6,7 @@ ItemStore::ItemStore(QObject *parent): QObject(parent) { } -void ItemStore::addItem(std::shared_ptr item, bool inform) +void ItemStore::addItem(const std::shared_ptr& item, item_update_type_t updateType) { std::shared_ptr matched = nullptr; for(unsigned i = 0; i < items_.size(); i++ ) @@ -26,17 +26,18 @@ void ItemStore::addItem(std::shared_ptr item, bool inform) } else { - if(item->getLoaded()) - matched->mergeLoaded(*item); - else if(item->getValue() != matched->getValue()) - updateItem(*item, inform); + ItemUpdateRequest request = item->createValueUpdateRequest(item->getValue(), + updateType, + updateType == ITEM_UPDATE_LOADED); + updateItem(request); } } -void ItemStore::addItems(const std::vector>& itemIn, bool inform) +void ItemStore::addItems(const std::vector>& itemIn, + item_update_type_t updateType) { for(unsigned j = 0; j < itemIn.size(); j++) - addItem(itemIn[j], inform); + addItem(itemIn[j], updateType); } void ItemStore::removeItem(const ItemData& item) @@ -55,7 +56,7 @@ void ItemStore::removeItem(const ItemData& item) void ItemStore::replaceItems(const std::vector>& items) { - addItems(items, true); + addItems(items, ITEM_UPDATE_LOADED); std::vector deletedItems; for(std::shared_ptr item : items_) { @@ -72,33 +73,21 @@ void ItemStore::clear() items_.clear(); } - -void ItemStore::updateItems(std::vector items, bool inform) +void ItemStore::updateItems(const std::vector& updates) { - for(const ItemData& item : items) - updateItem(item, inform); + for(const ItemUpdateRequest& update : updates) + updateItem(update); } -void ItemStore::updateItem(const ItemData& item, bool inform) +void ItemStore::updateItem(const ItemUpdateRequest& update) { for(unsigned i = 0; i < items_.size(); i++ ) { - if(items_[i]->operator==(item)) + if(items_[i]->operator==(update.payload)) { - if(items_[i]->hasChanged(item)) - { - if(items_[i]->getValue() != item.getValue()) - { - items_[i]->setLoaded(false); - if(inform) - items_[i]->informValue(item.getValue()); - else - items_[i]->setValue(item.getValue()); - } - qDebug()<<"Item"<getName()<<"updated"<<(inform ? "with inform" : ""); - if(!inform) - itemUpdated(items_[i]); - } + items_[i]->requestUpdate(update); + qDebug() << "Item" << items_[i]->getName() << "updated"; + itemUpdated(update); } } } @@ -115,16 +104,10 @@ void ItemStore::store(QJsonObject& json) json["Items"] = itemsArray; } -void ItemStore::itemUpdateSlot(ItemData data) +void ItemStore::itemUpdateSlot(ItemUpdateRequest update) { - for(std::shared_ptr& item: items_) - { - if(*item == data) - { - qDebug()<<"Item"<(item)); - } - } + qDebug() << "Item" << update.payload.getName() << "updated from update slot"; + itemUpdated(update); } std::shared_ptr ItemStore::getItem(uint32_t id) diff --git a/src/items/itemstore.h b/src/items/itemstore.h index 830cc40..b4bdeaa 100644 --- a/src/items/itemstore.h +++ b/src/items/itemstore.h @@ -33,21 +33,21 @@ signals: void itemDeleted(ItemData item); void itemAdded(std::weak_ptr Item); - void itemUpdated(std::weak_ptr Item); + void itemUpdated(ItemUpdateRequest update); void sigRefresh(); public slots: void removeItem(const ItemData& item); - void addItem(std::shared_ptr item, bool inform = true); - void addItems(const std::vector>& itemsIn, bool inform = true); + void addItem(const std::shared_ptr& item, item_update_type_t updateType); + void addItems(const std::vector>& itemsIn, item_update_type_t updateType); void replaceItems(const std::vector>& items); - void updateItems(std::vector items, bool inform = true); - void updateItem(const ItemData& item, bool inform = true); + void updateItems(const std::vector& updates); + void updateItem(const ItemUpdateRequest& update); void refresh(); private slots: - void itemUpdateSlot(ItemData data); + void itemUpdateSlot(ItemUpdateRequest update); }; extern ItemStore globalItems; diff --git a/src/items/relay.cpp b/src/items/relay.cpp index f801e1b..14b145d 100644 --- a/src/items/relay.cpp +++ b/src/items/relay.cpp @@ -23,16 +23,6 @@ void Relay::enactValue(uint8_t value) } } -void Relay::on() -{ - setValue(true); -} - -void Relay::off() -{ - setValue(false); -} - void Relay::toggle() { value_ ? off() : on(); diff --git a/src/items/relay.h b/src/items/relay.h index 3c3c4b4..946fa87 100644 --- a/src/items/relay.h +++ b/src/items/relay.h @@ -4,7 +4,6 @@ #include #include -#include "sensors/sensor.h" #include "item.h" class Microcontroller; @@ -21,11 +20,6 @@ private: protected: virtual void enactValue(uint8_t value) override; -public slots: - void on(); - void off(); - void toggle(); - public: Relay(uint8_t id = 0, QString name = "", uint16_t address = 0, bool state = false, QObject* parent = nullptr); diff --git a/src/microcontroller.cpp b/src/microcontroller.cpp index 4833461..340bc6e 100644 --- a/src/microcontroller.cpp +++ b/src/microcontroller.cpp @@ -142,7 +142,7 @@ void Microcontroller::processList(const QString& buffer) else if(buffer.contains("EOL")) { listMode = false; - gotItems(relayList); + gotItems(relayList, ITEM_UPDATE_BACKEND); relayList.clear(); } else listMode = false; @@ -150,7 +150,10 @@ void Microcontroller::processList(const QString& buffer) void Microcontroller::processRelayState(const QString& buffer) { - updateItems({static_cast(*processRelayLine(buffer))}); + ItemUpdateRequest update; + update.type = ITEM_UPDATE_BACKEND; + update.payload = static_cast(*processRelayLine(buffer)); + updateItems({update}); } void Microcontroller::processSensorState(const QString& buffer) diff --git a/src/service/tcpclient.cpp b/src/service/tcpclient.cpp index 7d2b041..d7eb725 100644 --- a/src/service/tcpclient.cpp +++ b/src/service/tcpclient.cpp @@ -47,7 +47,7 @@ void TcpClient::processIncomeingJson(const QByteArray& jsonbytes) } } if(!items.empty()) - gotItems(items, true); + gotItems(items, ITEM_UPDATE_REMOTE); } else { diff --git a/src/ui/itemwidget.cpp b/src/ui/itemwidget.cpp index d073e50..e41fc3c 100644 --- a/src/ui/itemwidget.cpp +++ b/src/ui/itemwidget.cpp @@ -59,17 +59,27 @@ void ItemWidget::deleteItem() void ItemWidget::moveToValue(int value) { if(auto workingItem = item_.lock()) - workingItem->setValue(value); + { + ItemUpdateRequest request = workingItem->createValueUpdateRequest(value, ITEM_UPDATE_USER); + workingItem->requestUpdate(request); + } else + { disable(); + } } void ItemWidget::moveToState(bool state) { if(auto workingItem = item_.lock()) - workingItem->setValue(state); + { + ItemUpdateRequest request = workingItem->createValueUpdateRequest(state, ITEM_UPDATE_USER); + workingItem->requestUpdate(request); + } else + { disable(); + } } void ItemWidget::disable()