diff options
-rw-r--r-- | src/crepe/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/crepe/Component.cpp | 2 | ||||
-rw-r--r-- | src/crepe/Component.h | 7 | ||||
-rw-r--r-- | src/crepe/ComponentManager.cpp | 7 | ||||
-rw-r--r-- | src/crepe/ComponentManager.h | 5 | ||||
-rw-r--r-- | src/crepe/ComponentManager.hpp | 92 | ||||
-rw-r--r-- | src/crepe/GameObject.h | 2 | ||||
-rw-r--r-- | src/crepe/GameObject.hpp | 4 | ||||
-rw-r--r-- | src/crepe/Script.cpp | 6 | ||||
-rw-r--r-- | src/crepe/ScriptSystem.cpp | 34 | ||||
-rw-r--r-- | src/crepe/ScriptSystem.h | 11 | ||||
-rw-r--r-- | src/crepe/api/BehaviorScript.cpp | 1 | ||||
-rw-r--r-- | src/crepe/api/BehaviorScript.h | 30 | ||||
-rw-r--r-- | src/crepe/api/BehaviorScript.hpp | 19 | ||||
-rw-r--r-- | src/crepe/api/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/crepe/api/Script.cpp | 3 | ||||
-rw-r--r-- | src/crepe/api/Script.h (renamed from src/crepe/Script.h) | 12 | ||||
-rw-r--r-- | src/crepe/util/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/crepe/util/fmt.cpp | 33 | ||||
-rw-r--r-- | src/crepe/util/fmt.h | 10 | ||||
-rw-r--r-- | src/crepe/util/log.cpp | 27 | ||||
-rw-r--r-- | src/crepe/util/log.h | 4 | ||||
-rw-r--r-- | src/example/script.cpp | 8 |
23 files changed, 222 insertions, 100 deletions
diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt index d85aef0..8323490 100644 --- a/src/crepe/CMakeLists.txt +++ b/src/crepe/CMakeLists.txt @@ -9,7 +9,6 @@ target_sources(crepe PUBLIC Rigidbody.cpp Sprite.cpp ScriptSystem.cpp - Script.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp index d14159c..bce90f1 100644 --- a/src/crepe/Component.cpp +++ b/src/crepe/Component.cpp @@ -1,5 +1,3 @@ #include "Component.h" using namespace crepe; - -Component::Component() : active(true) {} diff --git a/src/crepe/Component.h b/src/crepe/Component.h index 16a4ce5..d9a01ac 100644 --- a/src/crepe/Component.h +++ b/src/crepe/Component.h @@ -3,12 +3,15 @@ namespace crepe { class Component { +protected: + Component() = default; + public: - Component(); + virtual ~Component() = default; // TODO: shouldn't this constructor be deleted because this class will never // directly be instantiated? - bool active; + bool active = true; }; } // namespace crepe diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp index 9a3fec7..8bde33a 100644 --- a/src/crepe/ComponentManager.cpp +++ b/src/crepe/ComponentManager.cpp @@ -1,4 +1,5 @@ #include "ComponentManager.h" +#include "util/log.h" using namespace crepe; @@ -20,5 +21,9 @@ void ComponentManager::delete_all_components_of_id(uint32_t id) { void ComponentManager::delete_all_components() { // Clear the whole unordered_map<> - components.clear(); + this->components.clear(); } + +ComponentManager::ComponentManager() { dbg_trace(); } + +ComponentManager::~ComponentManager() { dbg_trace(); } diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h index 2ab9dc8..38f32e4 100644 --- a/src/crepe/ComponentManager.h +++ b/src/crepe/ComponentManager.h @@ -23,7 +23,7 @@ public: public: //! Add a component of a specific type template <typename T, typename... Args> - void add_component(uint32_t id, Args &&... args); + T & add_component(uint32_t id, Args &&... args); //! Deletes all components of a specific type and id template <typename T> void delete_components_by_id(uint32_t id); @@ -44,7 +44,8 @@ public: std::vector<std::reference_wrapper<T>> get_components_by_type() const; private: - ComponentManager() = default; + ComponentManager(); + virtual ~ComponentManager(); /* * The std::unordered_map<std::type_index, std::vector<std::vector<std::unique_ptr<Component>>>> below might seem a bit strange, let me explain this structure: diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp index 2ea0c70..2377a94 100644 --- a/src/crepe/ComponentManager.hpp +++ b/src/crepe/ComponentManager.hpp @@ -7,7 +7,7 @@ namespace crepe { template <class T, typename... Args> -void ComponentManager::add_component(uint32_t id, Args &&... args) { +T & ComponentManager::add_component(uint32_t id, Args &&... args) { using namespace std; static_assert(is_base_of<Component, T>::value, @@ -33,6 +33,8 @@ void ComponentManager::add_component(uint32_t id, Args &&... args) { T * instance = new T(forward<Args>(args)...); // store its unique_ptr in the vector<> components[type][id].push_back(unique_ptr<T>(instance)); + + return *instance; } template <typename T> @@ -61,11 +63,9 @@ void ComponentManager::delete_components() { // Determine the type of T (this is used as the key of the unordered_map<>) std::type_index type = typeid(T); - // Find the type (in the unordered_map<>) - if (components.find(type) != components.end()) { - // Clear the whole vector<> of this specific type - components[type].clear(); - } + if (components.find(type) == components.end()) return; + + components[type].clear(); } template <typename T> @@ -79,30 +79,26 @@ ComponentManager::get_components_by_id(uint32_t id) const { // Create an empty vector<> vector<reference_wrapper<T>> component_vector; - // Find the type (in the unordered_map<>) - if (components.find(type) != components.end()) { - // Get the correct vector<> - const vector<vector<unique_ptr<Component>>> & component_array - = components.at(type); + if (components.find(type) == components.end()) return component_vector; - // Make sure that the id (that we are looking for) is within the boundaries of the vector<> - if (id < component_array.size()) { - // Loop trough the whole vector<> - for (const unique_ptr<Component> & component_ptr : - component_array[id]) { - // Cast the unique_ptr to a raw pointer - T * casted_component = static_cast<T *>(component_ptr.get()); - - // Ensure that the cast was successful - if (casted_component) { - // Add the dereferenced raw pointer to the vector<> - component_vector.push_back(*casted_component); - } - } - } + // Get the correct vector<> + const vector<vector<unique_ptr<Component>>> & component_array + = components.at(type); + + // Make sure that the id (that we are looking for) is within the boundaries of the vector<> + if (id >= component_array.size()) return component_vector; + + // Loop trough the whole vector<> + for (const unique_ptr<Component> & component_ptr : component_array[id]) { + // Cast the unique_ptr to a raw pointer + T * casted_component = static_cast<T *>(component_ptr.get()); + + if (casted_component == nullptr) continue; + + // Add the dereferenced raw pointer to the vector<> + component_vector.push_back(*casted_component); } - // Return the vector<> return component_vector; } @@ -120,30 +116,28 @@ ComponentManager::get_components_by_type() const { // uint32_t id = 0; // Find the type (in the unordered_map<>) - if (components.find(type) != components.end()) { + if (components.find(type) == components.end()) return component_vector; - // Get the correct vector<> - const vector<vector<unique_ptr<Component>>> & component_array - = components.at(type); - - // Loop through the whole vector<> - for (const vector<unique_ptr<Component>> & component : - component_array) { - // Loop trough the whole vector<> - for (const unique_ptr<Component> & component_ptr : component) { - // Cast the unique_ptr to a raw pointer - T * casted_component = static_cast<T *>(component_ptr.get()); - - // Ensure that the cast was successful - if (casted_component) { - // Pair the dereferenced raw pointer and the id and add it to the vector<> - component_vector.emplace_back(ref(*casted_component)); - } - } - - // Increase the id (the id will also be stored in the returned vector<>) - //++id; + // Get the correct vector<> + const vector<vector<unique_ptr<Component>>> & component_array + = components.at(type); + + // Loop through the whole vector<> + for (const vector<unique_ptr<Component>> & component : component_array) { + // Loop trough the whole vector<> + for (const unique_ptr<Component> & component_ptr : component) { + // Cast the unique_ptr to a raw pointer + T * casted_component = static_cast<T *>(component_ptr.get()); + + // Ensure that the cast was successful + if (casted_component == nullptr) continue; + + // Pair the dereferenced raw pointer and the id and add it to the vector<> + component_vector.emplace_back(ref(*casted_component)); } + + // Increase the id (the id will also be stored in the returned vector<>) + //++id; } // Return the vector<> diff --git a/src/crepe/GameObject.h b/src/crepe/GameObject.h index 3588d9a..b5d6399 100644 --- a/src/crepe/GameObject.h +++ b/src/crepe/GameObject.h @@ -10,7 +10,7 @@ public: GameObject(uint32_t id, std::string name, std::string tag, int layer); template <typename T, typename... Args> - void add_component(Args &&... args); + T & add_component(Args &&... args); uint32_t id; std::string name; diff --git a/src/crepe/GameObject.hpp b/src/crepe/GameObject.hpp index 5966fbf..8cd1abe 100644 --- a/src/crepe/GameObject.hpp +++ b/src/crepe/GameObject.hpp @@ -7,9 +7,9 @@ namespace crepe { template <typename T, typename... Args> -void GameObject::add_component(Args &&... args) { +T & GameObject::add_component(Args &&... args) { auto & mgr = ComponentManager::get_instance(); - mgr.add_component<T>(id, std::forward<Args>(args)...); + return mgr.add_component<T>(id, std::forward<Args>(args)...); } } // namespace crepe diff --git a/src/crepe/Script.cpp b/src/crepe/Script.cpp deleted file mode 100644 index 3b83b7c..0000000 --- a/src/crepe/Script.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "Script.h" - -using namespace crepe; - -void Script::init() {} -void Script::update() {} diff --git a/src/crepe/ScriptSystem.cpp b/src/crepe/ScriptSystem.cpp index 988bb71..5d882be 100644 --- a/src/crepe/ScriptSystem.cpp +++ b/src/crepe/ScriptSystem.cpp @@ -1,8 +1,16 @@ -#include "util/log.h" +#include <forward_list> +#include <functional> +#include <vector> +#include "ComponentManager.h" #include "ScriptSystem.h" +#include "api/BehaviorScript.h" +#include "api/Script.h" +#include "util/log.h" +using namespace std; using namespace crepe; +using namespace crepe::api; ScriptSystem::ScriptSystem() { dbg_trace(); } ScriptSystem::~ScriptSystem() { dbg_trace(); } @@ -12,4 +20,26 @@ ScriptSystem & ScriptSystem::get_instance() { return instance; } -void ScriptSystem::update() { dbg_trace(); } +void ScriptSystem::update() { + using namespace std; + dbg_trace(); + + forward_list<Script *> scripts = this->get_scripts(); + for (Script * script : scripts) script->update(); +} + +forward_list<Script *> ScriptSystem::get_scripts() { + forward_list<Script *> scripts = {}; + ComponentManager & mgr = ComponentManager::get_instance(); + vector<reference_wrapper<BehaviorScript>> behavior_scripts + = mgr.get_components_by_type<BehaviorScript>(); + + for (auto behavior_script_ref : behavior_scripts) { + BehaviorScript & behavior_script = behavior_script_ref.get(); + Script * script = behavior_script.script.get(); + if (script == nullptr) continue; + scripts.push_front(script); + } + + return scripts; +} diff --git a/src/crepe/ScriptSystem.h b/src/crepe/ScriptSystem.h index 72e360b..1f472a0 100644 --- a/src/crepe/ScriptSystem.h +++ b/src/crepe/ScriptSystem.h @@ -1,17 +1,26 @@ #pragma once +#include <forward_list> + #include "System.h" +namespace crepe::api { +class Script; +} + namespace crepe { class ScriptSystem : public System { public: static ScriptSystem & get_instance(); - virtual void update(); + void update(); private: ScriptSystem(); ~ScriptSystem(); + +private: + std::forward_list<api::Script *> get_scripts(); }; } // namespace crepe diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp index 84bfd4c..1f236b4 100644 --- a/src/crepe/api/BehaviorScript.cpp +++ b/src/crepe/api/BehaviorScript.cpp @@ -1,6 +1,7 @@ #include "../util/log.h" #include "BehaviorScript.h" +#include "Script.h" using namespace crepe::api; diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h index 1d05a75..6ce6798 100644 --- a/src/crepe/api/BehaviorScript.h +++ b/src/crepe/api/BehaviorScript.h @@ -1,16 +1,36 @@ #pragma once -#include "../Component.h" -#include "../Script.h" +#include <memory> + +#include "Component.h" +#include "Script.h" + +namespace crepe { +class ScriptSystem; +class ComponentManager; +} // namespace crepe namespace crepe::api { -class BehaviorScript : public Script, public Component { - // only allow ComponentManager to instantiate scripts - friend class ComponentManager; +class Script; +class BehaviorScript : public Component { protected: + friend class crepe::ComponentManager; BehaviorScript(); + +public: + virtual ~BehaviorScript() = default; + +public: + template <class T> + BehaviorScript & set_script(); + +protected: + friend class crepe::ScriptSystem; + std::unique_ptr<Script> script = nullptr; }; } // namespace crepe::api + +#include "BehaviorScript.hpp" diff --git a/src/crepe/api/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp new file mode 100644 index 0000000..a6bd81c --- /dev/null +++ b/src/crepe/api/BehaviorScript.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include <type_traits> + +#include "../util/log.h" +#include "BehaviorScript.h" + +namespace crepe::api { + +template <class T> +BehaviorScript & BehaviorScript::set_script() { + static_assert(std::is_base_of<Script, T>::value); + dbg_trace(); + Script * s = new T(); + this->script = std::unique_ptr<Script>(s); + return *this; +} + +} // namespace crepe::api diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 68c4b72..2181b30 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -1,11 +1,13 @@ target_sources(crepe PUBLIC # AudioSource.cpp BehaviorScript.cpp + Script.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES # AudioSource.h BehaviorScript.h Config.h + Script.h ) diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp new file mode 100644 index 0000000..5016ed0 --- /dev/null +++ b/src/crepe/api/Script.cpp @@ -0,0 +1,3 @@ +#include "Script.h" + +using namespace crepe::api; diff --git a/src/crepe/Script.h b/src/crepe/api/Script.h index cdd6814..0036d1f 100644 --- a/src/crepe/Script.h +++ b/src/crepe/api/Script.h @@ -1,15 +1,21 @@ #pragma once namespace crepe { +class ScriptSystem; +} + +namespace crepe::api { class Script { + friend class crepe::ScriptSystem; + protected: - virtual void init(); - virtual void update(); + virtual void init() {} + virtual void update() {} // NOTE: additional *events* (like unity's OnDisable and OnEnable) should be // implemented as member methods in derivative user script classes and // registered in init(), otherwise this class will balloon in size with each // added event. }; -} // namespace crepe +} // namespace crepe::api diff --git a/src/crepe/util/CMakeLists.txt b/src/crepe/util/CMakeLists.txt index d5dbd9f..bbeaad9 100644 --- a/src/crepe/util/CMakeLists.txt +++ b/src/crepe/util/CMakeLists.txt @@ -1,10 +1,12 @@ target_sources(crepe PUBLIC color.cpp log.cpp + fmt.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES color.h log.h + fmt.h ) diff --git a/src/crepe/util/fmt.cpp b/src/crepe/util/fmt.cpp new file mode 100644 index 0000000..8ef1164 --- /dev/null +++ b/src/crepe/util/fmt.cpp @@ -0,0 +1,33 @@ +#include <cstdarg> +#include <cstdio> +#include <string> + +#include "fmt.h" + +using namespace std; + +string crepe::util::va_stringf(va_list args, const char * fmt) { + va_list args_copy; + va_copy(args_copy, args); + + size_t sz = vsnprintf(NULL, 0, fmt, args_copy) + 1; + char * msg = (char *) malloc(sz); + va_end(args_copy); + + vsnprintf(msg, sz, fmt, args); + + string out = msg; + free(msg); + + va_end(args); + + return out; +} + +string crepe::util::stringf(const char * fmt, ...) { + va_list args; + va_start(args, fmt); + string out = va_stringf(args, fmt); + va_end(args); + return out; +} diff --git a/src/crepe/util/fmt.h b/src/crepe/util/fmt.h new file mode 100644 index 0000000..44c426f --- /dev/null +++ b/src/crepe/util/fmt.h @@ -0,0 +1,10 @@ +#pragma once + +#include <string> + +namespace crepe::util { + +std::string va_stringf(va_list args, const char * fmt); +std::string stringf(const char * fmt, ...); + +} // namespace crepe::util diff --git a/src/crepe/util/log.cpp b/src/crepe/util/log.cpp index ba12ba5..e3e9f1f 100644 --- a/src/crepe/util/log.cpp +++ b/src/crepe/util/log.cpp @@ -3,6 +3,7 @@ #include <cstdlib> #include <string> +#include "fmt.h" #include "log.h" #include "../api/Config.h" @@ -16,40 +17,30 @@ static const char * const LOG_PREFIX[] = { [log_level::ERROR] = "[ERROR] ", }; -static void va_logf(enum log_level level, va_list args, const std::string fmt) { +static void log(enum log_level level, const std::string msg) { auto & cfg = crepe::api::Config::get_instance(); if (level < cfg.log.level) return; - va_list args_copy; - va_copy(args_copy, args); - - // prepend log level and ensure newline - std::string format_fixed = LOG_PREFIX[level] + fmt; - if (!format_fixed.ends_with("\n")) format_fixed += "\n"; - - size_t sz = vsnprintf(NULL, 0, format_fixed.c_str(), args_copy) + 1; - char * msg = (char *) malloc(sz); - va_end(args_copy); - - vsnprintf(msg, sz, format_fixed.c_str(), args); + using namespace std; + string final = string(LOG_PREFIX[level]) + msg; + if (!final.ends_with("\n")) final += "\n"; // TODO: also log to file or smth - printf("%s", msg); + printf("%s", final.c_str()); fflush(stdout); - - free(msg); } void crepe::util::logf(const char * fmt, ...) { va_list args; va_start(args, fmt); - va_logf(crepe::util::log_level::DEBUG, args, fmt); + log(log_level::DEBUG, va_stringf(args, fmt)); va_end(args); } void crepe::util::logf(log_level level, const char * fmt, ...) { va_list args; va_start(args, fmt); - va_logf(level, args, fmt); + log(level, va_stringf(args, fmt)); va_end(args); } + diff --git a/src/crepe/util/log.h b/src/crepe/util/log.h index d5494c7..c5d8665 100644 --- a/src/crepe/util/log.h +++ b/src/crepe/util/log.h @@ -7,7 +7,7 @@ // utility macros #define _crepe_logf_here(lvl, fmt, ...) \ - crepe::util::logf(lvl, "%s%s (%s:%d)" fmt "\n", \ + crepe::util::logf(lvl, "%s%s (%s:%d)%s" fmt "\n", \ crepe::util::color::FG_WHITE, __PRETTY_FUNCTION__, \ __FILE_NAME__, __LINE__, crepe::util::color::RESET, \ __VA_ARGS__) @@ -15,7 +15,7 @@ // very illegal global function-style macros // NOLINTBEGIN #define dbg_logf(fmt, ...) _crepe_logf_here(util::log_level::DEBUG, ": " fmt, __VA_ARGS__) -#define dbg_log(str) _crepe_logf_here(util::log_level::DEBUG, ": %s", str) +#define dbg_log(str) _crepe_logf_here(util::log_level::DEBUG, "%s: " str, "") #define dbg_trace() _crepe_logf_here(util::log_level::TRACE, "%s", "") // NOLINTEND diff --git a/src/example/script.cpp b/src/example/script.cpp index 44e2922..91e4713 100644 --- a/src/example/script.cpp +++ b/src/example/script.cpp @@ -10,12 +10,14 @@ #include <crepe/api/Config.h> #include <crepe/api/BehaviorScript.h> +#include <crepe/api/Script.h> using namespace crepe; +using namespace crepe::api; using namespace std; -class MyScript : public api::BehaviorScript { - void update() { dbg_trace(); } +class MyScript : public Script { + void update() { dbg_log("MY SCRIPT UPDATE"); } }; int main() { @@ -25,7 +27,7 @@ int main() { dbg_trace(); auto obj = GameObject(0, "name", "tag", 0); - obj.add_component<MyScript>(); + obj.add_component<BehaviorScript>().set_script<MyScript>(); auto & sys = ScriptSystem::get_instance(); sys.update(); // -> MyScript::update |