diff options
| -rw-r--r-- | src/crepe/Component.h | 3 | ||||
| -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 | 26 | ||||
| -rw-r--r-- | src/crepe/util/log.h | 4 | ||||
| -rw-r--r-- | src/example/script.cpp | 8 | 
21 files changed, 219 insertions, 95 deletions
| diff --git a/src/crepe/Component.h b/src/crepe/Component.h index a23de61..8a42a45 100644 --- a/src/crepe/Component.h +++ b/src/crepe/Component.h @@ -4,6 +4,9 @@  namespace crepe {  class Component { +protected: +	Component() = default; +  public:  	Component(uint32_t id);  	virtual ~Component() {} 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 f19fdcb..22dbc66 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(id,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 74788ec..063d225 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 86623de..6b337be 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -1,10 +1,12 @@  target_sources(crepe PUBLIC  	# AudioSource.cpp  	BehaviorScript.cpp +	Script.cpp  )  target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	# AudioSource.h  	BehaviorScript.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 100f028..e2cffaf 100644 --- a/src/crepe/util/CMakeLists.txt +++ b/src/crepe/util/CMakeLists.txt @@ -1,9 +1,11 @@  target_sources(crepe PUBLIC  	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 f91d52c..0c2ce1e 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"  using namespace crepe::util; @@ -14,37 +15,26 @@ static const char * const LOG_PREFIX[] = {  	[log_level::ERROR] = "[ERR] ",  }; -static void va_logf(enum log_level level, va_list args, const std::string fmt) { -	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); +static void log(enum log_level level, const std::string & msg) { +	using namespace std; +	string out = string(LOG_PREFIX[level]) + msg; +	if (!out.ends_with("\n")) out += "\n";  	// TODO: also log to file or smth -	printf("%s", msg); +	printf("%s", out.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 763b314..e2776c9 100644 --- a/src/crepe/util/log.h +++ b/src/crepe/util/log.h @@ -7,7 +7,7 @@  // utility macros  #define _crepe_logf_here(fmt, ...) \ -	crepe::util::logf(util::log_level::DEBUG, "%s%s (%s:%d)" fmt "\n", \ +	crepe::util::logf(util::log_level::DEBUG, "%s%s (%s:%d)%s" fmt "\n", \  					  crepe::util::color::FG_WHITE, __PRETTY_FUNCTION__, \  					  __FILE__, __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(": " fmt, __VA_ARGS__) -#define dbg_log(str) _crepe_logf_here(": %s", str) +#define dbg_log(str) _crepe_logf_here("%s: " str, "")  #define dbg_trace() _crepe_logf_here("%s", "")  // NOLINTEND diff --git a/src/example/script.cpp b/src/example/script.cpp index a610b83..cc585db 100644 --- a/src/example/script.cpp +++ b/src/example/script.cpp @@ -9,19 +9,21 @@  #include <crepe/util/log.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() {  	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 |