diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b50d6474ba31f7af64bd917a91285da9dc588d5..c7fa4b6e8d6b9023cef44423effb4b9183e577c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,12 @@ src/testControlModel.cpp # Add include directory target_include_directories("Test_Control_Model" PUBLIC include/) +add_executable("Test_Object_File_Handler" +src/testObjectFileHandler.cpp +) +# Add include directory +target_include_directories("Test_Object_File_Handler" PUBLIC include/) + add_executable("Class-Member-Variable-demo" src/class-member-variables.cpp diff --git a/src/CommandListOWN.h b/src/CommandListOWN.h index 4203aeb4b97390b5cb4ecf63bf131bbde9eb51f7..61cf455319b3658e4acfb5bee189417e8b8997ef 100644 --- a/src/CommandListOWN.h +++ b/src/CommandListOWN.h @@ -33,6 +33,15 @@ public: std::shared_ptr<Command> moveUp(unsigned int _pos); std::shared_ptr<Command> moveDown(unsigned int _pos); + std::shared_ptr<Command> add(std::shared_ptr<Command> _cmd) + { + std::shared_ptr<Element> newElement = std::make_shared<Element>(_cmd); + std::shared_ptr<Element> end = getElement(getSize()); + newElement->setPrev(end); + end->setNext(newElement); + return newElement->getCommand(); + } + void createCommands(); void printCommands(); }; diff --git a/src/ControlModel.h b/src/ControlModel.h index 37b54d205e4ea9b4e37d0b4b9b2b717d43c64573..0a444d7a6dd1e4876fdb10b5e83ced492abb181b 100644 --- a/src/ControlModel.h +++ b/src/ControlModel.h @@ -10,6 +10,7 @@ #include "RoverHandler.h" #include "ComHandler.h" #include "ComState.h" +#include "ObjectFileHandler.h" class ControlModel : public ControlModelRegistry, IComListener { @@ -29,6 +30,9 @@ public: bool start(); bool stop(); + void readCommands(std::string _fileName); + void writeCommands(std::string _fileName); + // Possible Lifetime concerns CommandList &getCommandList() { return list; } // Possible Lifetime concerns @@ -36,10 +40,17 @@ public: void setSelectedRover() { - //? is RoverHandler static? Where does it belong? ControlModel? std::vector<Rover> rovers = RoverHandler::getFreeRover(); if (!rovers.empty()) + { selectedRover = rovers.front(); + notifyRoverChanged(); + } + else + { + selectedRover = Rover(); //some example Rover + notifyRoverChanged(); + } } std::optional<std::string> getSelectedRoverId() @@ -108,7 +119,6 @@ bool ControlModel::start() // iterator would help greatly with of by one errors for (int i = 1; i <= size; ++i) { - //? Wie hier was sammeln und übergeben? commands.push_back(list.getCommand(i)); } @@ -118,4 +128,29 @@ bool ControlModel::start() bool ControlModel::stop() { return ComHandler::getInstance().stop(); +} + +void ControlModel::readCommands(std::string _fileName) +{ + ObjectFileHandler fH = ObjectFileHandler(_fileName); + std::vector<std::shared_ptr<Command>> v; + fH.read(v); + for (auto &&i : v) + { + list.add(i); + } +} + +void ControlModel::writeCommands(std::string _fileName) +{ + std::vector<std::shared_ptr<Command>> v; + uint size = list.getSize(); + // 0 is root element + // iterator would help greatly with of by one errors + for (int i = 1; i <= size; ++i) + { + v.push_back(list.getCommand(i)); + } + ObjectFileHandler fH = ObjectFileHandler(_fileName); + fH.write(v); } \ No newline at end of file diff --git a/src/ControlModelRegistry.h b/src/ControlModelRegistry.h index 7cb01e216fb331bd8cd6ea099b9eac23c3e16a30..dbfd41f50bb0986b0ce7c6058b9a9e4c7d57fbc5 100644 --- a/src/ControlModelRegistry.h +++ b/src/ControlModelRegistry.h @@ -7,8 +7,7 @@ class ControlModelRegistry { private: - //? maybe should be https://en.cppreference.com/w/cpp/memory/weak_ptr - std::vector<std::shared_ptr<IControlModelListener>> registry; + std::vector<std::weak_ptr<IControlModelListener>> registry; public: void addControlModelListener(std::shared_ptr<IControlModelListener> _listener); @@ -24,15 +23,23 @@ void ControlModelRegistry::addControlModelListener(std::shared_ptr<IControlModel void ControlModelRegistry::removeControlModelListener(std::shared_ptr<IControlModelListener> _listener) { - // https://en.cppreference.com/w/cpp/container/vector/erase2 - std::erase(registry, _listener); + for (auto iter = registry.begin(); iter != registry.end(); ++iter) + { + if (iter->lock().get() == _listener.get()) + { + registry.erase(iter); + } + } + } void ControlModelRegistry::notifyMessageChanged(std::string _message) { for (auto &&i : registry) { - i->messageUpdated(_message); + std::shared_ptr<IControlModelListener> l = i.lock(); + if (l) + l->messageUpdated(_message); } } @@ -40,6 +47,8 @@ void ControlModelRegistry::notifyRoverChanged() { for (auto &&i : registry) { - i->roverUpdated(); + std::shared_ptr<IControlModelListener> l = i.lock(); + if (l) + l->roverUpdated(); } } \ No newline at end of file diff --git a/src/Element.h b/src/Element.h index ea3953cf18f37ed23cd691cb2ad3359132fb6072..a9e67d019025b1e6a161ec1c5bd61149a0fcc958 100644 --- a/src/Element.h +++ b/src/Element.h @@ -23,7 +23,8 @@ public: */ template <typename Type> Element(Type _cmd) { cmd = std::make_shared<Type>(_cmd); } - + Element(std::shared_ptr<Command> _cmd) { cmd = _cmd; } + /** * @brief Construct an empty Element object. Dont use this constructor! * diff --git a/src/ObjectFileHandler.h b/src/ObjectFileHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..9fad1ceaab4e63dfcf31f87b5a1b59c3b56b04c3 --- /dev/null +++ b/src/ObjectFileHandler.h @@ -0,0 +1,113 @@ +#pragma once +#include <fstream> +#include <sstream> +#include <vector> +#include <memory> +#include "commandlib.h" +#include "Gear.h" +#include "Direction.h" +#include "Pause.h" + +class ObjectFileHandler +{ +private: + std::string fileName; + +public: + ObjectFileHandler(std::string _file); + std::string getFileName() { return fileName; } + bool read(std::vector <std::shared_ptr<Command>> &destination); + bool write(const std::vector<std::shared_ptr<Command>> &source); +}; + +ObjectFileHandler::ObjectFileHandler(std::string _file) +{ + fileName = _file; +} + +bool ObjectFileHandler::write(const std::vector <std::shared_ptr<Command>> &source) +{ + std::fstream file; + file.open(fileName, file.out); + if (!file.is_open()) + return false; + + for (std::shared_ptr<Command> i : source) + { + bool typeWasFound = false; + std::stringstream s; + + std::shared_ptr<Gear> pG = std::dynamic_pointer_cast<Gear>(i); + if (pG) + { + typeWasFound = true; + s << IGear::gear << ' '; + s << pG->getSpeed() << ' '; + s << pG->getDuration(); + } + + std::shared_ptr<Direction> pD = std::dynamic_pointer_cast<Direction>(i); + if (pD) + { + typeWasFound = true; + s << IDirection::direction << ' '; + s << pD->getDegree(); + } + + std::shared_ptr<Pause> pP = std::dynamic_pointer_cast<Pause>(i); + if (pP) + { + typeWasFound = true; + s << IPause::pause << ' '; + s << pP->getDuration(); + } + + if (!typeWasFound) + return false; + s << '\n'; + file << s.rdbuf(); + } + file << std::flush; + file.close(); + return true; +} + +bool ObjectFileHandler::read(std::vector <std::shared_ptr<Command>> &destination) +{ + std::fstream file; + file.open(fileName, file.in); + if (!file.is_open()) + return false; + + std::string name; + while (file >> name) + { + if (name == IGear::gear) + { + int speed; + file >> speed; + double duration; + file >> duration; + destination.emplace_back(std::make_shared<Gear>(speed, duration)); + } + else if (name == IDirection::direction) + { + int degree; + file >> degree; + destination.emplace_back(std::make_shared<Direction>(degree)); + } + else if (name == IPause::pause) + { + double duration; + file >> duration; + destination.emplace_back(std::make_shared<Pause>(duration)); + } + else + { + //This shouldn't happen. + } + } + + file.close(); + return true; +} \ No newline at end of file diff --git a/src/testControlModel.cpp b/src/testControlModel.cpp index 53d1957e61c4029f120916ffee9e88a2a919c50a..0f9bb27d89ba54cecf8a1c71d69aa7d71ee9d561 100644 --- a/src/testControlModel.cpp +++ b/src/testControlModel.cpp @@ -24,18 +24,26 @@ int main() std::shared_ptr<Listener> listener = std::make_shared<Listener>(); model.addControlModelListener(listener); - - std::shared_ptr<Command> a = model.getCommandTypes()[0].createInstance(); - std::cout << a->getConfig() << '\n'; - //! model.getCommandList().add(a); - // model.getCommandList().add(model.getCommandTypes()[0].createInstance()); - // model.getCommandList().add(model.getCommandTypes()[1].createInstance()); - // model.getCommandList().add(model.getCommandTypes()[2].createInstance()); + model.getCommandList().add(model.getCommandTypes()[0].createInstance()); + model.getCommandList().add(model.getCommandTypes()[1].createInstance()); + model.getCommandList().add(model.getCommandTypes()[2].createInstance()); + model.getCommandList().add(Gear(1, 1.0)); model.getCommandList().add(Direction(30)); model.getCommandList().add(Pause(0.5)); + model.readCommands("../testCommands.txt"); + model.start(); model.setSelectedRover(); + + std::cout << "Save To File?" << std::endl; + int yeanah = 0; + std::cin >> yeanah; + if (yeanah) + { + model.writeCommands("../testCommands.txt"); + std::cout << "Wrote to ../testCommands.txt" << std::endl; + } } \ No newline at end of file diff --git a/src/testObjectFileHandler.cpp b/src/testObjectFileHandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..57e2f300d3641a3d5ebffcb8f99da9d56a1dd01c --- /dev/null +++ b/src/testObjectFileHandler.cpp @@ -0,0 +1,30 @@ +#include "Command.h" +#include "Gear.h" +#include "Direction.h" +#include "Pause.h" +#include "ObjectFileHandler.h" +#include <memory> +#include <string> +#include <vector> +#include <iostream> + +int main() +{ + ObjectFileHandler f("../test.txt"); + std::cout << f.getFileName() << '\n'; + std::vector<std::shared_ptr<Command>> v; + v.emplace_back(std::make_shared<Gear>(1,2)); + v.emplace_back(std::make_shared<Direction>(3)); + v.emplace_back(std::make_shared<Pause>(4)); + std::cout << f.write(v) << std::endl; + + std::vector<std::shared_ptr<Command>> vR; + f.read(vR); + std::cout << "Now reading\n"; + for (auto &&i : vR) + { + std::cout << i->getConfig() << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/testCommands.txt b/testCommands.txt new file mode 100644 index 0000000000000000000000000000000000000000..7a8cec92454fbdd959d3087c3d3a3d274155980a --- /dev/null +++ b/testCommands.txt @@ -0,0 +1,5 @@ +Gear 1 2 +Direction 3 +Pause 4 +Direction -5 +Gear 50 3.14159 \ No newline at end of file