From 02df7de0c3f856d76ac0a1262a03797227daa8c4 Mon Sep 17 00:00:00 2001 From: blue Date: Wed, 20 Sep 2023 16:45:22 -0300 Subject: [PATCH] just some more thoughts --- src2/CMakeLists.txt | 4 +-- src2/collection.h | 25 ++++--------- src2/component.cpp | 65 ++++++++++++++++++++++++++++++++++ src2/component.h | 61 +++++++++++++++++++++++++++++++ src2/components/CMakeLists.txt | 11 ------ src2/components/component.cpp | 23 ------------ src2/components/component.h | 53 --------------------------- src2/components/file.cpp | 1 - src2/components/file.h | 14 -------- src2/taskmanager.cpp | 33 ++++++++++------- src2/taskmanager.h | 16 +++++---- 11 files changed, 163 insertions(+), 143 deletions(-) create mode 100644 src2/component.cpp create mode 100644 src2/component.h delete mode 100644 src2/components/CMakeLists.txt delete mode 100644 src2/components/component.cpp delete mode 100644 src2/components/component.h delete mode 100644 src2/components/file.cpp delete mode 100644 src2/components/file.h diff --git a/src2/CMakeLists.txt b/src2/CMakeLists.txt index b500e03..ce42eff 100644 --- a/src2/CMakeLists.txt +++ b/src2/CMakeLists.txt @@ -1,15 +1,15 @@ set(SOURCES + component.cpp collection.cpp loggable.cpp taskmanager.cpp ) set(HEADERS + component.h collection.h loggable.h taskmanager.h ) target_sources(${PROJECT_NAME} PRIVATE ${SOURCES}) - -add_subdirectory(components) diff --git a/src2/collection.h b/src2/collection.h index b6f8c1b..c35663b 100644 --- a/src2/collection.h +++ b/src2/collection.h @@ -30,30 +30,17 @@ private: std::map successSources; //would be nice to have a bimap here }; -class Collection::UnknownSource : public std::exception { +class Collection::UnknownSource : public std::runtime_error { public: - UnknownSource(const std::string& source); - - const char* what() const noexcept( true ) override; -private: - std::string source; + explicit UnknownSource(const std::string& source); }; -class Collection::DuplicateSource : public std::exception { +class Collection::DuplicateSource : public std::runtime_error { public: - DuplicateSource(const std::string& source); - - const char* what() const noexcept( true ) override; -private: - std::string source; + explicit DuplicateSource(const std::string& source); }; -class Collection::DuplicatePath : public std::exception { +class Collection::DuplicatePath : public std::runtime_error { public: - DuplicatePath(const std::string& source, const std::filesystem::path& path); - - const char* what() const noexcept( true ) override; -private: - std::string source; - std::filesystem::path path; + explicit DuplicatePath(const std::string& source, const std::filesystem::path& path); }; diff --git a/src2/component.cpp b/src2/component.cpp new file mode 100644 index 0000000..edecb21 --- /dev/null +++ b/src2/component.cpp @@ -0,0 +1,65 @@ +#include "component.h" + +#include +#include + +constexpr std::array stringStates { + "initial", + "reading", + "ready", + "building", + "done" +}; + +Component::Component( + const std::filesystem::path& path, + const std::shared_ptr& collection, + const std::shared_ptr& taskManager, + const std::shared_ptr& logger +): + Loggable(logger), + collection(collection), + taskManager(taskManager), + location(path) +{} + +void Component::read() { + if (state != initial) + throw WrongState(state, "read"); + + try { + collection->addSource(location); + } catch (const Collection::DuplicateSource e) { + state = error; + throw e; + } + state = reading; + taskManager->queue(std::bind(&Component::performRead, this)); +} + +void Component::build(const std::filesystem::path& destination, const std::string& target) { + if (state != ready) + throw WrongState(state, "build"); + + state = building; + taskManager->queue(std::bind(&Component::performBuild, this, destination, target)); +} + +void Component::performRead() { +} + +void Component::performBuild(std::filesystem::path destination, std::string target) { +} + +Component::State Component::getState() const { + return state; +} + +Component::Type Component::getType() const { + return type; +} + +Component::WrongState::WrongState(State state, const std::string& action): + std::runtime_error("An attempt to perform action \"" + action + + "\" on a wrong state \"" + stringStates[state].data() + '\"') +{} diff --git a/src2/component.h b/src2/component.h new file mode 100644 index 0000000..9fa12de --- /dev/null +++ b/src2/component.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "loggable.h" +#include "loggger.h" +#include "collection.h" +#include "taskmanager.h" + +class Component : protected Loggable { +public: + class WrongState; + enum State { + initial, + reading, + ready, + building, + error, + done + }; + + enum Type { + unknown, + file, + directory, + mason + }; + + Component( + const std::filesystem::path& path, + const std::shared_ptr& collection, + const std::shared_ptr& taskManager, + const std::shared_ptr& logger + ); + + Type getType() const; + State getState() const; + + void read(); + void build(const std::filesystem::path& destination, const std::string& target); + +private: + void performRead(); + void performBuild(std::filesystem::path destination, std::string target); + +private: + State state; + Type type; + std::shared_ptr collection; + std::shared_ptr taskManager; + std::filesystem::path location; +}; + +class Component::WrongState : public std::runtime_error { +public: + explicit WrongState(State state, const std::string& action); +}; diff --git a/src2/components/CMakeLists.txt b/src2/components/CMakeLists.txt deleted file mode 100644 index 52b35d2..0000000 --- a/src2/components/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -set(SOURCES - component.cpp - file.cpp -) - -set(HEADERS - component.h - file.h -) - -target_sources(${PROJECT_NAME} PRIVATE ${SOURCES}) diff --git a/src2/components/component.cpp b/src2/components/component.cpp deleted file mode 100644 index 41a023e..0000000 --- a/src2/components/component.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "component.h" - -Component::Component(const std::shared_ptr& collection, const std::shared_ptr& logger): - Loggable(logger), - collection(collection) -{} - -void Component::read(const std::filesystem::path& path) { - if (state != initial) - throw WrongState(state, "read"); - - location = path; - state = reading; -} - - -Component::State Component::getState() const { - return state; -} - -Component::Type Component::getType() const { - return type; -} diff --git a/src2/components/component.h b/src2/components/component.h deleted file mode 100644 index 2dcf167..0000000 --- a/src2/components/component.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "loggable.h" -#include "loggger.h" -#include "collection.h" - -class Component : protected Loggable { -public: - class WrongState; - enum State { - initial, - reading, - building, - ready - }; - - enum Type { - unknown, - file, - directory, - mason - }; - - Component(const std::shared_ptr& collection, const std::shared_ptr& logger); - virtual ~Component() override = default; - - Type getType() const; - State getState() const; - - virtual void read(const std::filesystem::path& path); - virtual void build(const std::filesystem::path& destination, const std::string& target) = 0; - -protected: - State state; - Type type; - std::shared_ptr collection; - std::filesystem::path location; -}; - -class Component::WrongState : public std::exception { -public: - WrongState(State state, const std::string& action); - - const char* what() const noexcept( true ) override; -private: - State state; - std::string action; -}; diff --git a/src2/components/file.cpp b/src2/components/file.cpp deleted file mode 100644 index 3e2f550..0000000 --- a/src2/components/file.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "file.h" diff --git a/src2/components/file.h b/src2/components/file.h deleted file mode 100644 index 31ee68d..0000000 --- a/src2/components/file.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include - -#include "component.h" - -class File : public Component { -public: - File(const std::shared_ptr& collection, const std::shared_ptr& logger); - -protected: - -}; diff --git a/src2/taskmanager.cpp b/src2/taskmanager.cpp index 03d9b3e..a6c3b0a 100644 --- a/src2/taskmanager.cpp +++ b/src2/taskmanager.cpp @@ -5,8 +5,8 @@ TaskManager::TaskManager() : stopping(false), maxThreads(std::thread::hardware_concurrency()), activeThreads(0), - queue(), - queueMutex(), + jobs(), + mutex(), loopConditional(), waitConditional(), threads() @@ -18,8 +18,15 @@ TaskManager::~TaskManager() { stop(); } +void TaskManager::queue(const Job& job) { + std::unique_lock lock(mutex); + jobs.emplace(job); + lock.unlock(); + loopConditional.notify_one(); +} + void TaskManager::start() { - std::lock_guard lock(queueMutex); + std::lock_guard lock(mutex); if (running) return; @@ -30,7 +37,7 @@ void TaskManager::start() { } void TaskManager::stop() { - std::unique_lock lock(queueMutex); + std::unique_lock lock(mutex); if (!running) return; @@ -47,19 +54,19 @@ void TaskManager::stop() { void TaskManager::loop() { while (true) { Job job; - std::unique_lock lock(queueMutex); - while (!stopping && queue.empty()) + std::unique_lock lock(mutex); + while (!stopping && jobs.empty()) loopConditional.wait(lock); if (stopping) return; ++activeThreads; - job = queue.front(); - queue.pop(); + job = jobs.front(); + jobs.pop(); lock.unlock(); - //do the job + job(); lock.lock(); --activeThreads; lock.unlock(); @@ -68,13 +75,13 @@ void TaskManager::loop() { } -bool TaskManager::busy() { - std::lock_guard lock(queueMutex); +bool TaskManager::busy() const { + std::lock_guard lock(mutex); return activeThreads == 0; } -void TaskManager::wait() { - std::unique_lock lock(queueMutex); +void TaskManager::wait() const { + std::unique_lock lock(mutex); while (activeThreads != 0) waitConditional.wait(lock); } diff --git a/src2/taskmanager.h b/src2/taskmanager.h index 87c8a6b..2d2698f 100644 --- a/src2/taskmanager.h +++ b/src2/taskmanager.h @@ -6,17 +6,19 @@ #include #include #include +#include class TaskManager { public: - typedef std::string Job; + using Job = std::function; TaskManager(); ~TaskManager(); void start(); void stop(); - void wait(); - bool busy(); + void wait() const; + void queue(const Job& job); + bool busy() const; private: void loop(); @@ -26,9 +28,9 @@ private: bool stopping; uint32_t maxThreads; uint32_t activeThreads; - std::queue queue; - std::mutex queueMutex; - std::condition_variable loopConditional; - std::condition_variable waitConditional; + std::queue jobs; + mutable std::mutex mutex; + mutable std::condition_variable loopConditional; + mutable std::condition_variable waitConditional; std::vector threads; };