diff options
| author | max-001 <maxsmits21@kpnmail.nl> | 2024-11-20 10:41:01 +0100 | 
|---|---|---|
| committer | max-001 <maxsmits21@kpnmail.nl> | 2024-11-20 10:41:01 +0100 | 
| commit | 85a15e4f43941b5d47fc4be2fee754f0a3d88d15 (patch) | |
| tree | 3fdddf3b6699266360123d701dcc7b0ddaa07f9b /src | |
| parent | 0476a8e9dbe7afb422862f7b1c15aaed7f3c416e (diff) | |
Added ECS tests
Diffstat (limited to 'src')
| -rw-r--r-- | src/example/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/example/components_internal.cpp | 51 | ||||
| -rw-r--r-- | src/example/ecs.cpp | 53 | ||||
| -rw-r--r-- | src/test/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/test/ECSTest.cpp | 236 | 
5 files changed, 237 insertions, 106 deletions
| diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 3a5b543..bbeec09 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -17,7 +17,6 @@ function(add_example target_name)  endfunction()  add_example(audio_internal) -# add_example(components_internal)  add_example(script)  add_example(log)  add_example(rendering) @@ -26,7 +25,6 @@ add_example(physics)  add_example(savemgr)  add_example(proxy)  add_example(db) -add_example(ecs)  add_example(scene_manager)  add_example(particles)  add_example(gameloop) diff --git a/src/example/components_internal.cpp b/src/example/components_internal.cpp deleted file mode 100644 index 2a232a9..0000000 --- a/src/example/components_internal.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/** \file - *  - * Standalone example for usage of the internal ECS - */ - -#include <cassert> -#include <chrono> - -#include <crepe/Component.h> -#include <crepe/ComponentManager.h> - -#include <crepe/api/GameObject.h> -#include <crepe/api/Rigidbody.h> -#include <crepe/api/Sprite.h> - -#include <crepe/util/Log.h> - -using namespace crepe; -using namespace std; - -#define OBJ_COUNT 100000 - -int main() { -	dbg_trace(); - -	ComponentManager mgr{}; - -	auto start_adding = chrono::high_resolution_clock::now(); - -	for (int i = 0; i < OBJ_COUNT; ++i) { -		GameObject obj = mgr.new_object("Name", "Tag"); -		obj.add_component<Sprite>("test"); -		obj.add_component<Rigidbody>(0, 0, i); -	} - -	auto stop_adding = chrono::high_resolution_clock::now(); - -	auto sprites = mgr.get_components_by_type<Sprite>(); -	for (auto sprite : sprites) { -		assert(true); -	} - -	auto stop_looping = chrono::high_resolution_clock::now(); - -	auto add_time = chrono::duration_cast<chrono::microseconds>(stop_adding - start_adding); -	auto loop_time = chrono::duration_cast<chrono::microseconds>(stop_looping - stop_adding); -	printf("add time:  %ldus\n", add_time.count()); -	printf("loop time: %ldus\n", loop_time.count()); - -	return 0; -} diff --git a/src/example/ecs.cpp b/src/example/ecs.cpp deleted file mode 100644 index d5ba51b..0000000 --- a/src/example/ecs.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include <iostream> - -#include <crepe/ComponentManager.h> -#include <crepe/api/GameObject.h> -#include <crepe/api/Metadata.h> -#include <crepe/api/Transform.h> - -using namespace crepe; -using namespace std; - -int main() { -	ComponentManager mgr{}; - -	// Create a few GameObjects -	try { -		GameObject body = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); -		GameObject right_leg = mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1); -		GameObject left_leg = mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1); -		GameObject right_foot = mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1); -		GameObject left_foot = mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1); - -		// Set the parent of each GameObject -		right_foot.set_parent(right_leg); -		left_foot.set_parent(left_leg); -		right_leg.set_parent(body); -		left_leg.set_parent(body); - -		// Adding a second Transform component is not allowed and will invoke an exception -		body.add_component<Transform>(Vector2{10, 10}, 0, 1); -	} catch (const exception & e) { -		cerr << e.what() << endl; -	} - -	// Get the Metadata and Transform components of each GameObject -	vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>(); -	vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>(); - -	// Print the Metadata and Transform components -	for (auto & m : metadata) { -		cout << "Id: " << m.get().game_object_id << " Name: " << m.get().name -			 << " Tag: " << m.get().tag << " Parent: " << m.get().parent << " Children: "; -		for (auto & c : m.get().children) { -			cout << c << " "; -		} -		cout << endl; -	} -	for (auto & t : transform) { -		cout << "Id: " << t.get().game_object_id << " Position: [" << t.get().position.x -			 << ", " << t.get().position.y << "]" << endl; -	} - -	return 0; -} diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 49c8151..0849b98 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -3,5 +3,6 @@ target_sources(test_main PUBLIC  	PhysicsTest.cpp  	ScriptTest.cpp  	ParticleTest.cpp +	ECSTest.cpp  ) diff --git a/src/test/ECSTest.cpp b/src/test/ECSTest.cpp new file mode 100644 index 0000000..a245879 --- /dev/null +++ b/src/test/ECSTest.cpp @@ -0,0 +1,236 @@ +#include <climits> +#include <cstdint> +#define protected public + +#include <crepe/ComponentManager.h> +#include <crepe/api/GameObject.h> +#include <crepe/api/Metadata.h> +#include <crepe/api/Transform.h> +#include <crepe/api/Vector2.h> +#include <crepe/api/Rigidbody.h> +#include <gtest/gtest.h> + +using namespace std; +using namespace crepe; + +class ECSTest : public ::testing::Test { +public: +	ComponentManager mgr{}; +}; + +TEST_F(ECSTest, createGameObject) { +	GameObject obj = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + +	vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>(); +	vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 1); +	EXPECT_EQ(transform.size(), 1); + +	EXPECT_EQ(metadata[0].get().name, "body"); +	EXPECT_EQ(metadata[0].get().tag, "person"); +	EXPECT_EQ(metadata[0].get().parent, -1); +	EXPECT_EQ(metadata[0].get().children.size(), 0); + +	EXPECT_EQ(transform[0].get().position.x, 0); +	EXPECT_EQ(transform[0].get().position.y, 0); +	EXPECT_EQ(transform[0].get().rotation, 0); +	EXPECT_EQ(transform[0].get().scale, 1); +} + +TEST_F(ECSTest, deleteAllGameObjects) { +	GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); +	GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + +	mgr.delete_all_components(); + +	vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>(); +	vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 0); +	EXPECT_EQ(transform.size(), 0); + +	GameObject obj2 = mgr.new_object("body2", "person2", Vector2{1, 0}, 5, 1); + +	metadata = mgr.get_components_by_type<Metadata>(); +	transform = mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 1); +	EXPECT_EQ(transform.size(), 1); + +	EXPECT_EQ(metadata[0].get().game_object_id, 0); +	EXPECT_EQ(metadata[0].get().name, "body2"); +	EXPECT_EQ(metadata[0].get().tag, "person2"); +	EXPECT_EQ(metadata[0].get().parent, -1); +	EXPECT_EQ(metadata[0].get().children.size(), 0); + +	EXPECT_EQ(transform[0].get().game_object_id, 0); +	EXPECT_EQ(transform[0].get().position.x, 1); +	EXPECT_EQ(transform[0].get().position.y, 0); +	EXPECT_EQ(transform[0].get().rotation, 5); +	EXPECT_EQ(transform[0].get().scale, 1); +} + +TEST_F(ECSTest, deleteGameObject) { +	GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); +	GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + +	mgr.delete_all_components_of_id(0); + +	vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>(); +	vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 1); +	EXPECT_EQ(transform.size(), 1); + +	EXPECT_EQ(metadata[0].get().game_object_id, 1); +	EXPECT_EQ(metadata[0].get().name, "body"); +	EXPECT_EQ(metadata[0].get().tag, "person"); +	EXPECT_EQ(metadata[0].get().parent, -1); +	EXPECT_EQ(metadata[0].get().children.size(), 0); + +	EXPECT_EQ(transform[0].get().game_object_id, 1); +	EXPECT_EQ(transform[0].get().position.x, 0); +	EXPECT_EQ(transform[0].get().position.y, 0); +	EXPECT_EQ(transform[0].get().rotation, 0); +	EXPECT_EQ(transform[0].get().scale, 1); +} + +TEST_F(ECSTest, manyGameObjects) { +	for(int i = 0; i < 5000; i++) { +		GameObject obj = mgr.new_object("body", "person", Vector2{0, 0}, 0, i); +	} + +	vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>(); +	vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 5000); +	EXPECT_EQ(transform.size(), 5000); +	for(int i = 0; i < 5000; i++) { +		EXPECT_EQ(metadata[i].get().game_object_id, i); +		EXPECT_EQ(metadata[i].get().name, "body"); +		EXPECT_EQ(metadata[i].get().tag, "person"); +		EXPECT_EQ(metadata[i].get().parent, -1); +		EXPECT_EQ(metadata[i].get().children.size(), 0); + +		EXPECT_EQ(transform[i].get().game_object_id, i); +		EXPECT_EQ(transform[i].get().position.x, 0); +		EXPECT_EQ(transform[i].get().position.y, 0); +		EXPECT_EQ(transform[i].get().rotation, 0); +		EXPECT_EQ(transform[i].get().scale, i); +	} + +	mgr.delete_components<Metadata>(); + +	metadata = mgr.get_components_by_type<Metadata>(); +	transform = mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 0); +	EXPECT_EQ(transform.size(), 5000); + +	for(int i = 0; i < 10000 - 5000; i++) { +		string tag = "person" + to_string(i); +		GameObject obj = mgr.new_object("body", tag, Vector2{0, 0}, i, 0); +	} + +	metadata = mgr.get_components_by_type<Metadata>(); +	transform = mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 10000 - 5000); +	EXPECT_EQ(transform.size(), 10000); +} + +TEST_F(ECSTest, getComponentsByID) { +	GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); +	GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); + +	vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_id<Metadata>(0); +	vector<reference_wrapper<Transform>> transform = mgr.get_components_by_id<Transform>(1); + +	EXPECT_EQ(metadata.size(), 1); +	EXPECT_EQ(transform.size(), 1); + +	EXPECT_EQ(metadata[0].get().game_object_id, 0); +	EXPECT_EQ(metadata[0].get().name, "body"); +	EXPECT_EQ(metadata[0].get().tag, "person"); +	EXPECT_EQ(metadata[0].get().parent, -1); +	EXPECT_EQ(metadata[0].get().children.size(), 0); + +	EXPECT_EQ(transform[0].get().game_object_id, 1); +	EXPECT_EQ(transform[0].get().position.x, 0); +	EXPECT_EQ(transform[0].get().position.y, 0); +	EXPECT_EQ(transform[0].get().rotation, 0); +	EXPECT_EQ(transform[0].get().scale, 1); +} + +TEST_F(ECSTest, tooMuchComponents) { +	try { +		GameObject obj0 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); +		obj0.add_component<Transform>(Vector2{10, 10}, 0, 1); +	} catch (const exception & e) { +		EXPECT_EQ(e.what(), string("Exceeded maximum number of instances for this component type")); +	} + +	try { +		GameObject obj1 = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); +		obj1.add_component<Metadata>("body", "person"); +	} catch (const exception & e) { +		EXPECT_EQ(e.what(), string("Exceeded maximum number of instances for this component type")); +	} + +	vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>(); + +	EXPECT_EQ(metadata.size(), 2); +	EXPECT_EQ(metadata[0].get().name, "body"); +	EXPECT_EQ(metadata[1].get().name, "body"); +} + +TEST_F(ECSTest, partentChild) { +	{ +		GameObject body = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1); +		GameObject right_leg = mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1); +		GameObject left_leg = mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1); +		GameObject right_foot = mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1); +		GameObject left_foot = mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1); + +		// Set the parent of each GameObject +		right_foot.set_parent(right_leg); +		left_foot.set_parent(left_leg); +		right_leg.set_parent(body); +		left_leg.set_parent(body); +	} + +	// Get the Metadata and Transform components of each GameObject +	vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>(); + +	// Check IDs +	EXPECT_EQ(metadata[0].get().game_object_id, 0); +	EXPECT_EQ(metadata[1].get().game_object_id, 1); +	EXPECT_EQ(metadata[2].get().game_object_id, 2); +	EXPECT_EQ(metadata[3].get().game_object_id, 3); +	EXPECT_EQ(metadata[4].get().game_object_id, 4); + +	// Check the parent-child relationships +	EXPECT_EQ(metadata[0].get().name, "body"); +	EXPECT_EQ(metadata[1].get().name, "rightLeg"); +	EXPECT_EQ(metadata[2].get().name, "leftLeg"); +	EXPECT_EQ(metadata[3].get().name, "rightFoot"); +	EXPECT_EQ(metadata[4].get().name, "leftFoot"); + +	EXPECT_EQ(metadata[0].get().parent, -1); +	EXPECT_EQ(metadata[1].get().parent, 0); +	EXPECT_EQ(metadata[2].get().parent, 0); +	EXPECT_EQ(metadata[3].get().parent, 1); +	EXPECT_EQ(metadata[4].get().parent, 2); + +	EXPECT_EQ(metadata[0].get().children.size(), 2); +	EXPECT_EQ(metadata[1].get().children.size(), 1); +	EXPECT_EQ(metadata[2].get().children.size(), 1); +	EXPECT_EQ(metadata[3].get().children.size(), 0); +	EXPECT_EQ(metadata[4].get().children.size(), 0); + +	EXPECT_EQ(metadata[0].get().children[0], 1); +	EXPECT_EQ(metadata[0].get().children[1], 2); +	EXPECT_EQ(metadata[1].get().children[0], 3); +	EXPECT_EQ(metadata[2].get().children[0], 4); +} |