diff options
Diffstat (limited to 'src/crepe')
28 files changed, 515 insertions, 25 deletions
| diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt index 208ba1f..d85aef0 100644 --- a/src/crepe/CMakeLists.txt +++ b/src/crepe/CMakeLists.txt @@ -2,12 +2,30 @@ target_sources(crepe PUBLIC  	Asset.cpp  	Sound.cpp  	SoundContext.cpp +	ComponentManager.cpp +	Component.cpp +	GameObject.cpp +	Collider.cpp +	Rigidbody.cpp +	Sprite.cpp +	ScriptSystem.cpp +	Script.cpp  )  target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	Asset.h  	Sound.h  	SoundContext.h +	ComponentManager.h +	ComponentManager.hpp +	Component.h +	GameObject.h +	GameObject.hpp +	Collider.h +	Rigidbody.h +	Sprite.h +	System.h +	ScriptSystem.h  )  add_subdirectory(api) diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp new file mode 100644 index 0000000..3f12afd --- /dev/null +++ b/src/crepe/Collider.cpp @@ -0,0 +1,5 @@ +#include "Collider.h" + +using namespace crepe; + +Collider::Collider(int size) : size(size) {} diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h new file mode 100644 index 0000000..120da05 --- /dev/null +++ b/src/crepe/Collider.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Component.h" + +namespace crepe { + +class Collider : public Component { +public: +	Collider(int size); + +	int size; +}; + +} // namespace crepe diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp new file mode 100644 index 0000000..d14159c --- /dev/null +++ b/src/crepe/Component.cpp @@ -0,0 +1,5 @@ +#include "Component.h" + +using namespace crepe; + +Component::Component() : active(true) {} diff --git a/src/crepe/Component.h b/src/crepe/Component.h new file mode 100644 index 0000000..16a4ce5 --- /dev/null +++ b/src/crepe/Component.h @@ -0,0 +1,14 @@ +#pragma once + +namespace crepe { + +class Component { +public: +	Component(); +	// TODO: shouldn't this constructor be deleted because this class will never +	// directly be instantiated? + +	bool active; +}; + +} // namespace crepe diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp new file mode 100644 index 0000000..9a3fec7 --- /dev/null +++ b/src/crepe/ComponentManager.cpp @@ -0,0 +1,24 @@ +#include "ComponentManager.h" + +using namespace crepe; + +ComponentManager & ComponentManager::get_instance() { +	static ComponentManager instance; +	return instance; +} + +void ComponentManager::delete_all_components_of_id(uint32_t id) { +	// Loop through all the types (in the unordered_map<>) +	for (auto & [type, componentArray] : components) { +		// Make sure that the id (that we are looking for) is within the boundaries of the vector<> +		if (id < componentArray.size()) { +			// Clear the components at this specific id +			componentArray[id].clear(); +		} +	} +} + +void ComponentManager::delete_all_components() { +	// Clear the whole unordered_map<> +	components.clear(); +} diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h new file mode 100644 index 0000000..2ab9dc8 --- /dev/null +++ b/src/crepe/ComponentManager.h @@ -0,0 +1,62 @@ +#pragma once + +#include <cstdint> +#include <memory> +#include <typeindex> +#include <unordered_map> +#include <utility> +#include <vector> + +#include "Component.h" + +namespace crepe { + +class ComponentManager { +public: +	// Singleton +	static ComponentManager & get_instance(); +	ComponentManager(const ComponentManager &) = delete; +	ComponentManager(ComponentManager &&) = delete; +	ComponentManager & operator=(const ComponentManager &) = delete; +	ComponentManager & operator=(ComponentManager &&) = delete; + +public: +	//! Add a component of a specific type +	template <typename T, typename... Args> +	void 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); +	//! Deletes all components of a specific type +	template <typename T> +	void delete_components(); +	//! Deletes all components of a specific id +	void delete_all_components_of_id(uint32_t id); +	//! Deletes all components +	void delete_all_components(); + +	//! Get a vector<> of all components at specific type and id +	template <typename T> +	std::vector<std::reference_wrapper<T>> +	get_components_by_id(uint32_t id) const; +	//! Get a vector<> of all components of a specific type +	template <typename T> +	std::vector<std::reference_wrapper<T>> get_components_by_type() const; + +private: +	ComponentManager() = default; + +	/* +	 * 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: +	 * The std::unordered_map<> has a key and value. The key is a std::type_index and the value is a std::vector. So, a new std::vector will be created for each new std::type_index. +	 * The first std::vector<> stores another vector<>. This first vector<> is to bind the entity's id to a component. +	 * The second std::vector<> stores unique_ptrs. Each component can be gathered via an unique_ptr. This second vector<> allows multiple components of the same std::type_index for one entity (id). +	 */ +	std::unordered_map<std::type_index, +					   std::vector<std::vector<std::unique_ptr<Component>>>> +		components; +}; + +} // namespace crepe + +#include "ComponentManager.hpp" diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp new file mode 100644 index 0000000..084cd33 --- /dev/null +++ b/src/crepe/ComponentManager.hpp @@ -0,0 +1,152 @@ +#pragma once + +#include <type_traits> + +#include "ComponentManager.h" + +namespace crepe { + +template <class T, typename... Args> +void ComponentManager::add_component(uint32_t id, Args &&... args) { +	using namespace std; + +	static_assert(is_base_of<Component, T>::value, "add_component must recieve a derivative class of Component"); + +	// Determine the type of T (this is used as the key of the unordered_map<>) +	type_index type = typeid(T); + +	// Check if this component type is already in the unordered_map<> +	if (components.find(type) == components.end()) { +		//If not, create a new (empty) vector<> of vector<unique_ptr<Component>> +		components[type] = vector<vector<unique_ptr<Component>>>(); +	} + +	// Resize the vector<> if the id is greater than the current size +	if (id >= components[type].size()) { +		// Initialize new slots to nullptr (resize does automatically init to nullptr) +		components[type].resize(id + 1); +	} + +	// Create a new component of type T (arguments directly forwarded). The +	// constructor must be called by ComponentManager. +	T * instance = new T(forward<Args>(args)...); +	// store its unique_ptr in the vector<> +	components[type][id].push_back(unique_ptr<T>(instance)); +} + +template <typename T> +void ComponentManager::delete_components_by_id(uint32_t id) { +	using namespace std; + +	// Determine the type of T (this is used as the key of the unordered_map<>) +	type_index type = typeid(T); + +	// Find the type (in the unordered_map<>) +	if (components.find(type) != components.end()) { +		// Get the correct vector<> +		vector<vector<unique_ptr<Component>>> & component_array +			= components[type]; + +		// Make sure that the id (that we are looking for) is within the boundaries of the vector<> +		if (id < component_array.size()) { +			// Clear the whole vector<> of this specific type and id +			component_array[id].clear(); +		} +	} +} + +template <typename T> +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(); +	} +} + +template <typename T> +std::vector<std::reference_wrapper<T>> +ComponentManager::get_components_by_id(uint32_t id) const { +	using namespace std; + +	// Determine the type of T (this is used as the key of the unordered_map<>) +	type_index type = typeid(T); + +	// 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); + +		// 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); +				} +			} +		} +	} + +	// Return the vector<> +	return component_vector; +} + +template <typename T> +std::vector<std::reference_wrapper<T>> +ComponentManager::get_components_by_type() const { +	using namespace std; + +	// Determine the type of T (this is used as the key of the unordered_map<>) +	type_index type = typeid(T); + +	// Create an empty vector<> +	vector<reference_wrapper<T>> component_vector; +	// Set the id to 0 (the id will also be stored in the returned vector<>) +	// uint32_t id = 0; + +	// 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); + +		// 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; +		} +	} + +	// Return the vector<> +	return component_vector; +} + +} // namespace crepe diff --git a/src/crepe/GameObject.cpp b/src/crepe/GameObject.cpp new file mode 100644 index 0000000..de3beb6 --- /dev/null +++ b/src/crepe/GameObject.cpp @@ -0,0 +1,7 @@ +#include "GameObject.h" + +using namespace crepe; + +GameObject::GameObject(uint32_t id, std::string name, std::string tag, +					   int layer) +	: id(id), name(name), tag(tag), active(true), layer(layer) {} diff --git a/src/crepe/GameObject.h b/src/crepe/GameObject.h new file mode 100644 index 0000000..3588d9a --- /dev/null +++ b/src/crepe/GameObject.h @@ -0,0 +1,24 @@ +#pragma once + +#include <cstdint> +#include <string> + +namespace crepe { + +class GameObject { +public: +	GameObject(uint32_t id, std::string name, std::string tag, int layer); + +	template <typename T, typename... Args> +	void add_component(Args &&... args); + +	uint32_t id; +	std::string name; +	std::string tag; +	bool active; +	int layer; +}; + +} // namespace crepe + +#include "GameObject.hpp" diff --git a/src/crepe/GameObject.hpp b/src/crepe/GameObject.hpp new file mode 100644 index 0000000..5966fbf --- /dev/null +++ b/src/crepe/GameObject.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "GameObject.h" + +#include "ComponentManager.h" + +namespace crepe { + +template <typename T, typename... Args> +void GameObject::add_component(Args &&... args) { +	auto & mgr = ComponentManager::get_instance(); +	mgr.add_component<T>(id, std::forward<Args>(args)...); +} + +} // namespace crepe diff --git a/src/crepe/Rigidbody.cpp b/src/crepe/Rigidbody.cpp new file mode 100644 index 0000000..495d908 --- /dev/null +++ b/src/crepe/Rigidbody.cpp @@ -0,0 +1,6 @@ +#include "Rigidbody.h" + +using namespace crepe; + +Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType) +	: mass(mass), gravity_scale(gravityScale), body_type(bodyType) {} diff --git a/src/crepe/Rigidbody.h b/src/crepe/Rigidbody.h new file mode 100644 index 0000000..63a8877 --- /dev/null +++ b/src/crepe/Rigidbody.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Component.h" + +namespace crepe { + +class Rigidbody : public Component { +public: +	Rigidbody(int mass, int gravityScale, int bodyType); + +	int mass; +	int gravity_scale; +	int body_type; +}; + +} // namespace crepe diff --git a/src/crepe/Script.cpp b/src/crepe/Script.cpp new file mode 100644 index 0000000..42e3666 --- /dev/null +++ b/src/crepe/Script.cpp @@ -0,0 +1,7 @@ +#include "Script.h" + +using namespace crepe; + +void Script::init() { } +void Script::update() { } + diff --git a/src/crepe/Script.h b/src/crepe/Script.h new file mode 100644 index 0000000..ba4073a --- /dev/null +++ b/src/crepe/Script.h @@ -0,0 +1,16 @@ +#pragma once + +namespace crepe { + +class Script { +protected: +	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. +}; + +} + diff --git a/src/crepe/ScriptSystem.cpp b/src/crepe/ScriptSystem.cpp new file mode 100644 index 0000000..e301c71 --- /dev/null +++ b/src/crepe/ScriptSystem.cpp @@ -0,0 +1,22 @@ +#include "util/log.h" + +#include "ScriptSystem.h" + +using namespace crepe; + +ScriptSystem::ScriptSystem() { +	dbg_trace(); +} +ScriptSystem::~ScriptSystem() { +	dbg_trace(); +} + +ScriptSystem & ScriptSystem::get_instance() { +	static ScriptSystem instance; +	return instance; +} + +void ScriptSystem::update() { +	dbg_trace(); +} + diff --git a/src/crepe/ScriptSystem.h b/src/crepe/ScriptSystem.h new file mode 100644 index 0000000..e1ed290 --- /dev/null +++ b/src/crepe/ScriptSystem.h @@ -0,0 +1,18 @@ +#pragma once + +#include "System.h" + +namespace crepe { + +class ScriptSystem : public System { +public: +	static ScriptSystem & get_instance(); +	virtual void update(); + +private: +	ScriptSystem(); +	~ScriptSystem(); +}; + +} + diff --git a/src/crepe/Sound.h b/src/crepe/Sound.h index 1ac20a7..b7cfbb8 100644 --- a/src/crepe/Sound.h +++ b/src/crepe/Sound.h @@ -1,7 +1,7 @@  #pragma once -#include <soloud.h> -#include <soloud_wav.h> +#include <soloud/soloud.h> +#include <soloud/soloud_wav.h>  #include <memory> diff --git a/src/crepe/SoundContext.h b/src/crepe/SoundContext.h index 090966d..d3123d2 100644 --- a/src/crepe/SoundContext.h +++ b/src/crepe/SoundContext.h @@ -1,6 +1,6 @@  #pragma once -#include <soloud.h> +#include <soloud/soloud.h>  #include "Sound.h" diff --git a/src/crepe/Sprite.cpp b/src/crepe/Sprite.cpp new file mode 100644 index 0000000..a5a5e68 --- /dev/null +++ b/src/crepe/Sprite.cpp @@ -0,0 +1,8 @@ +#include <string> + +#include "Sprite.h" + +using namespace crepe; +using namespace std; + +Sprite::Sprite(string path) : path(path) {} diff --git a/src/crepe/Sprite.h b/src/crepe/Sprite.h new file mode 100644 index 0000000..143e702 --- /dev/null +++ b/src/crepe/Sprite.h @@ -0,0 +1,16 @@ +#pragma once + +#include <string> + +#include "Component.h" + +namespace crepe { + +class Sprite : public Component { +public: +	Sprite(std::string path); + +	std::string path; +}; + +} // namespace crepe diff --git a/src/crepe/System.h b/src/crepe/System.h new file mode 100644 index 0000000..3fe3d66 --- /dev/null +++ b/src/crepe/System.h @@ -0,0 +1,23 @@ +#pragma once + +namespace crepe { + +class System { +public: +	static System & get_instance(); +	virtual void update() = 0; + +protected: +	System() { }; +	virtual ~System() { }; + +private: +	// singleton +	System(const System &) = delete; +	System(System &&) = delete; +	System & operator=(const System &) = delete; +	System & operator=(System &&) = delete; +}; + +} + diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp new file mode 100644 index 0000000..2dd933e --- /dev/null +++ b/src/crepe/api/BehaviorScript.cpp @@ -0,0 +1,10 @@ +#include "../util/log.h" + +#include "BehaviorScript.h" + +using namespace crepe::api; + +BehaviorScript::BehaviorScript() { +	dbg_trace(); +} + diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h new file mode 100644 index 0000000..e9542c1 --- /dev/null +++ b/src/crepe/api/BehaviorScript.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../Script.h" +#include "../Component.h" + +namespace crepe::api { + +class BehaviorScript : public Script, public Component { +	// only allow ComponentManager to instantiate scripts +	friend class ComponentManager; + +protected: +	BehaviorScript(); +}; + +} + diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 9548594..86623de 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -1,9 +1,10 @@  target_sources(crepe PUBLIC  	# AudioSource.cpp +	BehaviorScript.cpp  )  target_sources(crepe PUBLIC FILE_SET HEADERS FILES -	AudioSource.h -	Component.h +	# AudioSource.h +	BehaviorScript.h  ) diff --git a/src/crepe/api/Component.h b/src/crepe/api/Component.h deleted file mode 100644 index d5e0499..0000000 --- a/src/crepe/api/Component.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace crepe::api { - -class Component { -public: -	bool active; -}; - -} // namespace crepe::api diff --git a/src/crepe/util/log.cpp b/src/crepe/util/log.cpp index 6829ec3..f91d52c 100644 --- a/src/crepe/util/log.cpp +++ b/src/crepe/util/log.cpp @@ -8,10 +8,10 @@  using namespace crepe::util;  static const char * const LOG_PREFIX[] = { -	[log_level::debug] = "[DBG] ", -	[log_level::info] = "[INFO] ", -	[log_level::warning] = "[WARN] ", -	[log_level::error] = "[ERR] ", +	[log_level::DEBUG] = "[DBG] ", +	[log_level::INFO] = "[INFO] ", +	[log_level::WARNING] = "[WARN] ", +	[log_level::ERROR] = "[ERR] ",  };  static void va_logf(enum log_level level, va_list args, const std::string fmt) { @@ -38,7 +38,7 @@ static void va_logf(enum log_level level, va_list args, const std::string fmt) {  void crepe::util::logf(const char * fmt, ...) {  	va_list args;  	va_start(args, fmt); -	va_logf(crepe::util::log_level::debug, args, fmt); +	va_logf(crepe::util::log_level::DEBUG, args, fmt);  	va_end(args);  } diff --git a/src/crepe/util/log.h b/src/crepe/util/log.h index bfe7291..2b0fbe1 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)" fmt "\n", \  					  crepe::util::color::FG_WHITE, __PRETTY_FUNCTION__, \  					  __FILE_NAME__, __LINE__, crepe::util::color::RESET, \  					  __VA_ARGS__) @@ -24,10 +24,10 @@  namespace crepe::util {  enum log_level { -	debug, -	info, -	warning, -	error, +	DEBUG, +	INFO, +	WARNING, +	ERROR,  };  void logf(const char * fmt, ...); |