diff options
| -rw-r--r-- | Doxyfile | 1 | ||||
| -rw-r--r-- | contributing.md | 23 | ||||
| -rw-r--r-- | makefile | 3 | ||||
| -rw-r--r-- | src/crepe/api/Color.cpp | 37 | ||||
| -rw-r--r-- | src/crepe/api/Color.h | 49 | ||||
| -rw-r--r-- | src/crepe/api/Sprite.h | 3 | ||||
| -rw-r--r-- | src/crepe/facade/SDLContext.h | 6 | ||||
| -rw-r--r-- | src/crepe/system/RenderSystem.cpp | 43 | ||||
| -rw-r--r-- | src/crepe/system/RenderSystem.h | 32 | ||||
| -rw-r--r-- | src/example/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/example/components_internal.cpp | 51 | ||||
| -rw-r--r-- | src/example/ecs.cpp | 53 | ||||
| -rw-r--r-- | src/example/events.cpp | 30 | ||||
| -rw-r--r-- | src/example/game.cpp | 2 | ||||
| -rw-r--r-- | src/example/rendering.cpp | 10 | ||||
| -rw-r--r-- | src/example/scene_manager.cpp | 79 | ||||
| -rw-r--r-- | src/makefile | 7 | ||||
| -rw-r--r-- | src/test/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/test/ECSTest.cpp | 236 | ||||
| -rw-r--r-- | src/test/RenderSystemTest.cpp | 174 | ||||
| -rw-r--r-- | src/test/SceneManagerTest.cpp | 122 | 
21 files changed, 667 insertions, 299 deletions
| @@ -24,6 +24,7 @@ USE_MDFILE_AS_MAINPAGE = ./readme.md  REPEAT_BRIEF = NO  INTERNAL_DOCS = YES +EXTRACT_PRIVATE = YES  EXTRACT_STATIC = YES  HIDE_UNDOC_NAMESPACES = YES  HIDE_UNDOC_CLASSES = YES diff --git a/contributing.md b/contributing.md index 5b0c79d..9c95851 100644 --- a/contributing.md +++ b/contributing.md @@ -20,7 +20,7 @@ that you can click on to open them.  # Code style  - Formatting nitty-gritty is handled by clang-format/clang-tidy (run `make -  format` in the root folder of this repository to format all sources files) +  format` or `make lint`)  - <details><summary>    ASCII only    </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> @@ -798,6 +798,27 @@ that you can click on to open them.    resolving merge conflicts when multiple sources were added by different    people to the same CMakeLists.txt easier. +## GoogleTest-specific + +- Unit tests are not *required* to follow all code standards +- <details><summary> +  Private/protected members may be accessed using preprocessor tricks +  </summary> + +  ```cpp +  // include unrelated headers before + +  #define private public +  #define protected public + +  // headers included after *will* be affected +  ``` +  </details> +- Each test source file defines tests within a single test suite (first +  parameter of `TEST()` / `TEST_F()` macro) +- Test source files match their suite name (or test fixture name in the case of +  tests that use a fixture) +  # Structure  - Files are placed in the appropriate directory: @@ -6,5 +6,6 @@ doxygen: Doxyfile FORCE  FMT += $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp')  format: FORCE  	clang-format -i $(FMT) -	$(MAKE) -C src $@ +lint: FORCE +	$(MAKE) -C src $@ diff --git a/src/crepe/api/Color.cpp b/src/crepe/api/Color.cpp index 9e5f187..29bd77a 100644 --- a/src/crepe/api/Color.cpp +++ b/src/crepe/api/Color.cpp @@ -2,32 +2,11 @@  using namespace crepe; -Color Color::white = Color(255, 255, 255, 0); -Color Color::red = Color(255, 0, 0, 0); -Color Color::green = Color(0, 255, 0, 0); -Color Color::blue = Color(0, 0, 255, 0); -Color Color::black = Color(0, 0, 0, 0); -Color Color::cyan = Color(0, 255, 255, 0); -Color Color::yellow = Color(255, 255, 0, 0); -Color Color::magenta = Color(255, 0, 255, 0); - -Color::Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { -	this->a = alpha; -	this->r = red; -	this->g = green; -	this->b = blue; -}; - -const Color & Color::get_white() { return Color::white; }; - -const Color & Color::get_red() { return Color::red; }; -const Color & Color::get_green() { return Color::green; }; -const Color & Color::get_blue() { return Color::blue; }; - -const Color & Color::get_black() { return Color::black; }; - -const Color & Color::get_cyan() { return Color::cyan; }; - -const Color & Color::get_yellow() { return Color::yellow; }; - -const Color & Color::get_magenta() { return Color::magenta; }; +const Color Color::WHITE{0xff, 0xff, 0xff}; +const Color Color::RED{0xff, 0x00, 0x00}; +const Color Color::GREEN{0x00, 0xff, 0x00}; +const Color Color::BLUE{0x00, 0x00, 0xff}; +const Color Color::BLACK{0x00, 0x00, 0x00}; +const Color Color::CYAN{0x00, 0xff, 0xff}; +const Color Color::YELLOW{0xff, 0xff, 0x00}; +const Color Color::MAGENTA{0xff, 0x00, 0xff}; diff --git a/src/crepe/api/Color.h b/src/crepe/api/Color.h index aa47bf4..84edb5c 100644 --- a/src/crepe/api/Color.h +++ b/src/crepe/api/Color.h @@ -4,41 +4,20 @@  namespace crepe { -// TODO: make Color a struct w/o constructors/destructors -class Color { - -	// FIXME: can't these colors be defined as a `static constexpr const Color` -	// instead? - -public: -	Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); -	static const Color & get_white(); -	static const Color & get_red(); -	static const Color & get_green(); -	static const Color & get_blue(); -	static const Color & get_cyan(); -	static const Color & get_magenta(); -	static const Color & get_yellow(); -	static const Color & get_black(); - -private: -	// TODO: why are these private!? -	uint8_t r; -	uint8_t g; -	uint8_t b; -	uint8_t a; - -	static Color white; -	static Color red; -	static Color green; -	static Color blue; -	static Color cyan; -	static Color magenta; -	static Color yellow; -	static Color black; - -private: -	friend class SDLContext; +struct Color { +	uint8_t r = 0x00; +	uint8_t g = 0x00; +	uint8_t b = 0x00; +	uint8_t a = 0xff; + +	static const Color WHITE; +	static const Color RED; +	static const Color GREEN; +	static const Color BLUE; +	static const Color CYAN; +	static const Color MAGENTA; +	static const Color YELLOW; +	static const Color BLACK;  };  } // namespace crepe diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h index 0192793..74a55d4 100644 --- a/src/crepe/api/Sprite.h +++ b/src/crepe/api/Sprite.h @@ -2,8 +2,9 @@  #include <memory> +#include "../Component.h" +  #include "Color.h" -#include "Component.h"  #include "Texture.h"  namespace crepe { diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 007092b..652a83e 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -21,9 +21,6 @@ namespace crepe {  // typedef is unusable when crepe is packaged. Wouter will fix this later.  typedef SDL_Keycode CREPE_KEYCODES; -class Texture; -class LoopManager; -  /**   * \class SDLContext   * \brief Facade for the SDL library @@ -91,9 +88,6 @@ private:  	//! Will use the funtions: texture_from_path, get_width,get_height.  	friend class Texture; -	//! Will use the funtions: texture_from_path, get_width,get_height. -	friend class Animator; -  	/**  	 * \brief Loads a texture from a file path.  	 * \param path Path to the image file. diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index fa3d0de..96c5f27 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,38 +1,59 @@ +#include <algorithm> +#include <cassert>  #include <functional> +#include <stdexcept>  #include <vector>  #include "../ComponentManager.h"  #include "../api/Sprite.h"  #include "../api/Transform.h"  #include "../facade/SDLContext.h" -#include "../util/Log.h"  #include "RenderSystem.h"  using namespace crepe; +using namespace std; -void RenderSystem::clear_screen() const { SDLContext::get_instance().clear_screen(); } +void RenderSystem::clear_screen() { this->context.clear_screen(); } -void RenderSystem::present_screen() const { SDLContext::get_instance().present_screen(); } +void RenderSystem::present_screen() { this->context.present_screen(); }  void RenderSystem::update_camera() {  	ComponentManager & mgr = this->component_manager;  	std::vector<std::reference_wrapper<Camera>> cameras = mgr.get_components_by_type<Camera>(); +	if (cameras.size() == 0) throw std::runtime_error("No cameras in current scene"); +  	for (Camera & cam : cameras) { -		SDLContext::get_instance().camera(cam); -		this->curr_cam = &cam; +		this->context.camera(cam); +		this->curr_cam_ref = &cam;  	}  } -void RenderSystem::render_sprites() const { -	ComponentManager & mgr = this->component_manager; -	std::vector<std::reference_wrapper<Sprite>> sprites = mgr.get_components_by_type<Sprite>(); +bool sorting_comparison(const Sprite & a, const Sprite & b) { +	if (a.sorting_in_layer < b.sorting_in_layer) return true; +	if (a.sorting_in_layer == b.sorting_in_layer) return a.order_in_layer < b.order_in_layer; + +	return false; +} + +std::vector<std::reference_wrapper<Sprite>> +RenderSystem::sort(std::vector<std::reference_wrapper<Sprite>> & objs) { + +	std::vector<std::reference_wrapper<Sprite>> sorted_objs(objs); +	std::sort(sorted_objs.begin(), sorted_objs.end(), sorting_comparison); + +	return sorted_objs; +} + +void RenderSystem::render_sprites() { +	ComponentManager & mgr = this->component_manager; +	vector<reference_wrapper<Sprite>> sprites = mgr.get_components_by_type<Sprite>(); +	vector<reference_wrapper<Sprite>> sorted_sprites = this->sort(sprites); -	SDLContext & render = SDLContext::get_instance(); -	for (const Sprite & sprite : sprites) { +	for (const Sprite & sprite : sorted_sprites) {  		auto transforms = mgr.get_components_by_id<Transform>(sprite.game_object_id); -		render.draw(sprite, transforms[0], *curr_cam); +		this->context.draw(sprite, transforms[0], *this->curr_cam_ref);  	}  } diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 87ec494..57b9c73 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -1,18 +1,23 @@  #pragma once -#include "api/Camera.h" +#include <functional> +#include <vector> + +#include "facade/SDLContext.h"  #include "System.h"  namespace crepe { +class Camera; +class Sprite; +  /**   * \class RenderSystem   * \brief Manages rendering operations for all game objects.   * - * RenderSystem is responsible for rendering sprites, clearing and presenting the screen, and - * managing the active camera. It functions as a singleton, providing centralized rendering - * services for the application. + * RenderSystem is responsible for rendering, clearing and presenting the screen, and + * managing the active camera.    */  class RenderSystem : public System {  public: @@ -25,16 +30,25 @@ public:  private:  	//! Clears the screen in preparation for rendering. -	void clear_screen() const; +	void clear_screen();  	//! Presents the rendered frame to the display. -	void present_screen() const; +	void present_screen();  	//! Updates the active camera used for rendering.  	void update_camera();  	//! Renders all active sprites to the screen. -	void render_sprites() const; +	void render_sprites(); + +	/** +	 * \brief sort a vector sprite objects with +	 * +	 * \param objs the vector that will do a sorting algorithm on  +	 * \return returns a sorted reference vector +	 */ +	std::vector<std::reference_wrapper<Sprite>> +	sort(std::vector<std::reference_wrapper<Sprite>> & objs);  	/**  	 * \todo Include color handling for sprites. @@ -48,8 +62,10 @@ private:  private:  	//! Pointer to the current active camera for rendering -	Camera * curr_cam = nullptr; +	Camera * curr_cam_ref = nullptr;  	// TODO: needs a better solution + +	SDLContext & context = SDLContext::get_instance();  };  } // namespace crepe diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index c5cb63f..045f4d4 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) @@ -25,8 +24,6 @@ add_example(asset_manager)  add_example(savemgr)  add_example(proxy)  add_example(db) -add_example(ecs) -add_example(scene_manager)  add_example(game)  add_example(events)  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/example/events.cpp b/src/example/events.cpp index ed519ff..e6d91aa 100644 --- a/src/example/events.cpp +++ b/src/example/events.cpp @@ -2,7 +2,7 @@  #include <crepe/ComponentManager.h>  #include <crepe/system/ScriptSystem.h> -#include <crepe/util/log.h> +#include <crepe/util/Log.h>  #include <crepe/api/BehaviorScript.h>  #include <crepe/api/Config.h> @@ -65,6 +65,10 @@ public:  	}  };  int main() { +	EventManager & evmgr = EventManager::get_instance(); +	ComponentManager mgr{}; +	ScriptSystem sys{mgr}; +  	// two events to trigger  	KeyPressEvent key_press;  	key_press.key = Keycode::A; @@ -74,22 +78,19 @@ int main() {  	click_event.mouse_x = 100;  	click_event.mouse_y = 200;  	// queue events to test queue -	EventManager::get_instance().queue_event<KeyPressEvent>( -		std::move(key_press), 0); -	EventManager::get_instance().queue_event<MouseClickEvent>( -		std::move(click_event), 0); +	evmgr.queue_event<KeyPressEvent>(std::move(key_press), 0); +	evmgr.queue_event<MouseClickEvent>(std::move(click_event), 0);  	{  		TestKeyListener test_listener;  		test_listener.set_channel(1); -		auto obj = GameObject(0, "name", "tag", Vector2{1.2, 3.4}, 0, 1); +		auto obj = mgr.new_object("name", "tag", Vector2{1.2, 3.4}, 0, 1);  		obj.add_component<BehaviorScript>().set_script<MyScript>(); -		ScriptSystem sys;  		sys.update();  		// Trigger the events while `testListener` is in scope -		EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 1); -		EventManager::get_instance().trigger_event(MouseClickEvent{ +		evmgr.trigger_event<KeyPressEvent>(key_press, 1); +		evmgr.trigger_event(MouseClickEvent{      		.mouse_x = 100,      		.mouse_y = 100,      		.button = MouseButton::LEFT_MOUSE, @@ -100,14 +101,13 @@ int main() {  		std::cout << "lambda test" << std::endl;  		return false;  	}; -	EventManager::get_instance().subscribe<KeyPressEvent>( -		std::move(event_handler), 0); +	evmgr.subscribe<KeyPressEvent>(std::move(event_handler), 0);  	// testing trigger with testListener not in scope (unsubscribed) -	EventManager::get_instance().trigger_event<KeyPressEvent>(key_press, 0); -	EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, 0); +	evmgr.trigger_event<KeyPressEvent>(key_press, 0); +	evmgr.trigger_event<MouseClickEvent>(click_event, 0);  	// dispatching queued events -	EventManager::get_instance().dispatch_events(); +	evmgr.dispatch_events(); -	EventManager::get_instance().unsubscribe<KeyPressEvent>(event_handler, 0); +	evmgr.unsubscribe<KeyPressEvent>(event_handler, 0);  	return EXIT_SUCCESS;  } diff --git a/src/example/game.cpp b/src/example/game.cpp index b6a0c31..a557be7 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -74,7 +74,7 @@ public:  	game_object1.add_component<Sprite>(  	make_shared<Texture>("/home/jaro/crepe/asset/texture/green_square.png"), color,  	FlipSettings{true, true}); -	game_object1.add_component<Camera>(Color::get_white()); +	game_object1.add_component<Camera>(Color::WHITE);  	}  }; diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp index 14ecaa9..9e3c8cc 100644 --- a/src/example/rendering.cpp +++ b/src/example/rendering.cpp @@ -30,13 +30,13 @@ int main() {  	// Normal adding components  	{  		Color color(0, 0, 0, 0); -		obj.add_component<Sprite>(make_shared<Texture>("/home/jaro/crepe/asset/texture/green_square.png"), color, +		obj.add_component<Sprite>(make_shared<Texture>("../asset/texture/green_square.png"), color,  								  FlipSettings{false, false}); -		obj.add_component<Camera>(Color::get_red()); +		obj.add_component<Camera>(Color::RED);  	}  	{  		Color color(0, 0, 0, 0); -		obj1.add_component<Sprite>(make_shared<Texture>("/home/jaro/crepe/asset/texture/green_square.png"), color, +		obj1.add_component<Sprite>(make_shared<Texture>("../asset/texture/green_square.png"), color,  								   FlipSettings{true, true});  	} @@ -48,8 +48,12 @@ int main() {  	}  	*/ +	sys.update(); +	/* +  	auto start = std::chrono::steady_clock::now();  	while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) {  		sys.update();  	} +	*/  } diff --git a/src/example/scene_manager.cpp b/src/example/scene_manager.cpp deleted file mode 100644 index accec7d..0000000 --- a/src/example/scene_manager.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include <iostream> - -#include <crepe/ComponentManager.h> -#include <crepe/api/GameObject.h> -#include <crepe/api/Metadata.h> -#include <crepe/api/Scene.h> -#include <crepe/api/SceneManager.h> -#include <crepe/api/Vector2.h> - -using namespace crepe; -using namespace std; - -class ConcreteScene1 : public Scene { -public: -	using Scene::Scene; - -	void load_scene() { -		auto & mgr = this->component_manager; -		GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1); -		GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1); -		GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1); -	} -}; - -class ConcreteScene2 : public Scene { -public: -	using Scene::Scene; - -	void load_scene() { -		auto & mgr = this->component_manager; -		GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1); -		GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1); -		GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1); -		GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1); -	} -}; - -int main() { -	ComponentManager component_mgr{}; -	SceneManager scene_mgr{component_mgr}; - -	// Add the scenes to the scene manager -	scene_mgr.add_scene<ConcreteScene1>("scene1"); -	scene_mgr.add_scene<ConcreteScene2>("scene2"); - -	// There is no need to call set_next_scene() at the beginnen, because the first scene will be -	// automatically set as the next scene - -	// Load scene1 (the first scene added) -	scene_mgr.load_next_scene(); - -	// Get the Metadata components of each GameObject of Scene1 -	vector<reference_wrapper<Metadata>> metadata -		= component_mgr.get_components_by_type<Metadata>(); - -	cout << "Metadata components of Scene1:" << endl; -	// Print the Metadata -	for (auto & m : metadata) { -		cout << "Id: " << m.get().game_object_id << " Name: " << m.get().name -			 << " Tag: " << m.get().tag << endl; -	} - -	// Set scene2 as the next scene -	scene_mgr.set_next_scene("scene2"); -	// Load scene2 -	scene_mgr.load_next_scene(); - -	// Get the Metadata components of each GameObject of Scene2 -	metadata = component_mgr.get_components_by_type<Metadata>(); - -	cout << "Metadata components of Scene2:" << endl; -	// Print the Metadata -	for (auto & m : metadata) { -		cout << "Id: " << m.get().game_object_id << " Name: " << m.get().name -			 << " Tag: " << m.get().tag << endl; -	} - -	return 0; -} diff --git a/src/makefile b/src/makefile index 5f80204..a0e8f02 100644 --- a/src/makefile +++ b/src/makefile @@ -1,6 +1,9 @@  .PHONY: FORCE -FMT := $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp')  format: FORCE -	clang-tidy -p build/compile_commands.json --fix-errors $(FMT) +	$(MAKE) -C .. $@ + +LINT := $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp') +lint: FORCE +	clang-tidy -p build/compile_commands.json --fix-errors $(LINT) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index f830165..14c5123 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -4,5 +4,7 @@ target_sources(test_main PUBLIC  	PhysicsTest.cpp  	ScriptTest.cpp  	ParticleTest.cpp +	ECSTest.cpp +	SceneManagerTest.cpp  ) diff --git a/src/test/ECSTest.cpp b/src/test/ECSTest.cpp new file mode 100644 index 0000000..d5a5826 --- /dev/null +++ b/src/test/ECSTest.cpp @@ -0,0 +1,236 @@ +#include <gtest/gtest.h> + +#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> + +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); +} diff --git a/src/test/RenderSystemTest.cpp b/src/test/RenderSystemTest.cpp new file mode 100644 index 0000000..ac479d3 --- /dev/null +++ b/src/test/RenderSystemTest.cpp @@ -0,0 +1,174 @@ +#include "api/Camera.h" +#include <functional> +#include <gtest/gtest.h> +#include <memory> +#include <vector> + +#define private public +#define protected public + +#include <crepe/ComponentManager.h> +#include <crepe/api/Color.h> +#include <crepe/api/GameObject.h> +#include <crepe/api/Sprite.h> +#include <crepe/api/Texture.h> + +#include <crepe/system/RenderSystem.h> + +using namespace std; +using namespace crepe; +using namespace testing; + +class RenderSystemTest : public Test { +public: +	ComponentManager mgr{}; +	RenderSystem sys{mgr}; +	GameObject entity1 = this->mgr.new_object("name"); +	GameObject entity2 = this->mgr.new_object("name"); +	GameObject entity3 = this->mgr.new_object("name"); +	GameObject entity4 = this->mgr.new_object("name"); + +	void SetUp() override { +		auto & sprite1 +			= entity1.add_component<Sprite>(make_shared<Texture>("../asset/texture/img.png"), +											Color(0, 0, 0, 0), FlipSettings{false, false}); +		ASSERT_NE(sprite1.sprite_image.get(), nullptr); +		sprite1.order_in_layer = 5; +		sprite1.sorting_in_layer = 5; +		EXPECT_EQ(sprite1.order_in_layer, 5); +		EXPECT_EQ(sprite1.sorting_in_layer, 5); +		auto & sprite2 +			= entity2.add_component<Sprite>(make_shared<Texture>("../asset/texture/img.png"), +											Color(0, 0, 0, 0), FlipSettings{false, false}); +		ASSERT_NE(sprite2.sprite_image.get(), nullptr); +		sprite2.sorting_in_layer = 2; +		sprite2.order_in_layer = 1; + +		EXPECT_EQ(sprite2.sorting_in_layer, 2); +		EXPECT_EQ(sprite2.order_in_layer, 1); + +		auto & sprite3 +			= entity3.add_component<Sprite>(make_shared<Texture>("../asset/texture/img.png"), +											Color(0, 0, 0, 0), FlipSettings{false, false}); +		ASSERT_NE(sprite3.sprite_image.get(), nullptr); +		sprite3.sorting_in_layer = 1; +		sprite3.order_in_layer = 2; + +		EXPECT_EQ(sprite3.sorting_in_layer, 1); +		EXPECT_EQ(sprite3.order_in_layer, 2); + +		auto & sprite4 +			= entity4.add_component<Sprite>(make_shared<Texture>("../asset/texture/img.png"), +											Color(0, 0, 0, 0), FlipSettings{false, false}); +		ASSERT_NE(sprite4.sprite_image.get(), nullptr); +		sprite4.sorting_in_layer = 1; +		sprite4.order_in_layer = 1; +		EXPECT_EQ(sprite4.sorting_in_layer, 1); +		EXPECT_EQ(sprite4.order_in_layer, 1); +	} +}; + +TEST_F(RenderSystemTest, expected_throws) { +	GameObject entity1 = this->mgr.new_object("NAME"); + +	// no texture img +	EXPECT_ANY_THROW({ +		entity1.add_component<Sprite>(make_shared<Texture>("NO_IMAGE"), Color(0, 0, 0, 0), +									  FlipSettings{false, false}); +	}); + +	// No camera +	EXPECT_ANY_THROW({ this->sys.update(); }); +} + +TEST_F(RenderSystemTest, make_sprites) {} + +TEST_F(RenderSystemTest, sorting_sprites) { +	vector<reference_wrapper<Sprite>> sprites = this->mgr.get_components_by_type<Sprite>(); +	ASSERT_EQ(sprites.size(), 4); + +	vector<reference_wrapper<Sprite>> sorted_sprites = this->sys.sort(sprites); +	ASSERT_EQ(sorted_sprites.size(), 4); + +	// Expected order after sorting: +	// 1. sorting_in_layer: 1, order_in_layer: 1 (entity4) +	// 2. sorting_in_layer: 1, order_in_layer: 2 (entity3) +	// 3. sorting_in_layer: 2, order_in_layer: 1 (entity2) +	// 4. sorting_in_layer: 5, order_in_layer: 5 (entity1) + +	EXPECT_EQ(sorted_sprites[0].get().sorting_in_layer, 1); +	EXPECT_EQ(sorted_sprites[0].get().order_in_layer, 1); + +	EXPECT_EQ(sorted_sprites[1].get().sorting_in_layer, 1); +	EXPECT_EQ(sorted_sprites[1].get().order_in_layer, 2); + +	EXPECT_EQ(sorted_sprites[2].get().sorting_in_layer, 2); +	EXPECT_EQ(sorted_sprites[2].get().order_in_layer, 1); + +	EXPECT_EQ(sorted_sprites[3].get().sorting_in_layer, 5); +	EXPECT_EQ(sorted_sprites[3].get().order_in_layer, 5); + +	for (size_t i = 1; i < sorted_sprites.size(); ++i) { +		const Sprite & prev = sorted_sprites[i - 1].get(); +		const Sprite & curr = sorted_sprites[i].get(); + +		if (prev.sorting_in_layer == curr.sorting_in_layer) { +			EXPECT_LE(prev.order_in_layer, curr.order_in_layer); +		} else { +			EXPECT_LE(prev.sorting_in_layer, curr.sorting_in_layer); +		} +	} +} + +TEST_F(RenderSystemTest, Update) { +	entity1.add_component<Camera>(Color::WHITE); +	{ +		vector<reference_wrapper<Sprite>> sprites = this->mgr.get_components_by_type<Sprite>(); +		ASSERT_EQ(sprites.size(), 4); + +		EXPECT_EQ(sprites[0].get().game_object_id, 0); +		EXPECT_EQ(sprites[1].get().game_object_id, 1); +		EXPECT_EQ(sprites[2].get().game_object_id, 2); +		EXPECT_EQ(sprites[3].get().game_object_id, 3); +	} +	this->sys.update(); +	{ +		vector<reference_wrapper<Sprite>> sprites = this->mgr.get_components_by_type<Sprite>(); +		ASSERT_EQ(sprites.size(), 4); + +		EXPECT_EQ(sprites[0].get().game_object_id, 0); +		EXPECT_EQ(sprites[1].get().game_object_id, 1); +		EXPECT_EQ(sprites[2].get().game_object_id, 2); +		EXPECT_EQ(sprites[3].get().game_object_id, 3); +	} +} + +TEST_F(RenderSystemTest, Camera) { +	{ +		auto cameras = this->mgr.get_components_by_type<Camera>(); +		EXPECT_NE(cameras.size(), 1); +	} +	{ +		entity1.add_component<Camera>(Color::WHITE); +		auto cameras = this->mgr.get_components_by_type<Camera>(); +		EXPECT_EQ(cameras.size(), 1); +	} + +	//TODO improve with newer version +} +TEST_F(RenderSystemTest, Color) { +	entity1.add_component<Camera>(Color::WHITE); +	auto & sprite = this->mgr.get_components_by_id<Sprite>(entity1.id).front().get(); +	ASSERT_NE(sprite.sprite_image.get(), nullptr); + +	sprite.color = Color::GREEN; +	EXPECT_EQ(sprite.color.r, Color::GREEN.r); +	EXPECT_EQ(sprite.color.g, Color::GREEN.g); +	EXPECT_EQ(sprite.color.b, Color::GREEN.b); +	EXPECT_EQ(sprite.color.a, Color::GREEN.a); +	this->sys.update(); +	EXPECT_EQ(sprite.color.r, Color::GREEN.r); +	EXPECT_EQ(sprite.color.g, Color::GREEN.g); +	EXPECT_EQ(sprite.color.b, Color::GREEN.b); +	EXPECT_EQ(sprite.color.a, Color::GREEN.a); +} diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp new file mode 100644 index 0000000..69e1171 --- /dev/null +++ b/src/test/SceneManagerTest.cpp @@ -0,0 +1,122 @@ +#include <crepe/ComponentManager.h> +#include <crepe/api/GameObject.h> +#include <crepe/api/Metadata.h> +#include <crepe/api/Scene.h> +#include <crepe/api/SceneManager.h> +#include <crepe/api/Transform.h> +#include <crepe/api/Vector2.h> +#include <gtest/gtest.h> + +using namespace std; +using namespace crepe; + +class ConcreteScene1 : public Scene { +public: +	using Scene::Scene; + +	void load_scene() { +		auto & mgr = this->component_manager; +		GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1); +		GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1); +		GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1); +	} +}; + +class ConcreteScene2 : public Scene { +public: +	using Scene::Scene; + +	void load_scene() { +		auto & mgr = this->component_manager; +		GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1); +		GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1); +		GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1); +		GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1); +	} +}; + +class SceneManagerTest : public ::testing::Test { +public: +	ComponentManager component_mgr{}; +	SceneManager scene_mgr{component_mgr}; +}; + +TEST_F(SceneManagerTest, loadScene) { +	scene_mgr.add_scene<ConcreteScene1>("scene1"); +	scene_mgr.add_scene<ConcreteScene2>("scene2"); + +	scene_mgr.load_next_scene(); + +	vector<reference_wrapper<Metadata>> metadata +		= component_mgr.get_components_by_type<Metadata>(); +	vector<reference_wrapper<Transform>> transform +		= component_mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 3); +	EXPECT_EQ(transform.size(), 3); + +	EXPECT_EQ(metadata[0].get().game_object_id, 0); +	EXPECT_EQ(metadata[0].get().name, "scene_1"); +	EXPECT_EQ(metadata[0].get().tag, "tag_scene_1"); +	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(metadata[1].get().game_object_id, 1); +	EXPECT_EQ(metadata[1].get().name, "scene_1"); +	EXPECT_EQ(metadata[1].get().tag, "tag_scene_1"); +	EXPECT_EQ(metadata[1].get().parent, -1); +	EXPECT_EQ(metadata[1].get().children.size(), 0); +	EXPECT_EQ(transform[1].get().position.x, 1); +	EXPECT_EQ(transform[1].get().position.y, 0); + +	EXPECT_EQ(metadata[2].get().game_object_id, 2); +	EXPECT_EQ(metadata[2].get().name, "scene_1"); +	EXPECT_EQ(metadata[2].get().tag, "tag_scene_1"); +	EXPECT_EQ(metadata[2].get().parent, -1); +	EXPECT_EQ(metadata[2].get().children.size(), 0); +	EXPECT_EQ(transform[2].get().position.x, 2); +	EXPECT_EQ(transform[2].get().position.y, 0); + +	scene_mgr.set_next_scene("scene2"); +	scene_mgr.load_next_scene(); + +	metadata = component_mgr.get_components_by_type<Metadata>(); +	transform = component_mgr.get_components_by_type<Transform>(); + +	EXPECT_EQ(metadata.size(), 4); +	EXPECT_EQ(transform.size(), 4); + +	EXPECT_EQ(metadata[0].get().game_object_id, 0); +	EXPECT_EQ(metadata[0].get().name, "scene_2"); +	EXPECT_EQ(metadata[0].get().tag, "tag_scene_2"); +	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(metadata[1].get().game_object_id, 1); +	EXPECT_EQ(metadata[1].get().name, "scene_2"); +	EXPECT_EQ(metadata[1].get().tag, "tag_scene_2"); +	EXPECT_EQ(metadata[1].get().parent, -1); +	EXPECT_EQ(metadata[1].get().children.size(), 0); +	EXPECT_EQ(transform[1].get().position.x, 0); +	EXPECT_EQ(transform[1].get().position.y, 1); + +	EXPECT_EQ(metadata[2].get().game_object_id, 2); +	EXPECT_EQ(metadata[2].get().name, "scene_2"); +	EXPECT_EQ(metadata[2].get().tag, "tag_scene_2"); +	EXPECT_EQ(metadata[2].get().parent, -1); +	EXPECT_EQ(metadata[2].get().children.size(), 0); +	EXPECT_EQ(transform[2].get().position.x, 0); +	EXPECT_EQ(transform[2].get().position.y, 2); + +	EXPECT_EQ(metadata[3].get().game_object_id, 3); +	EXPECT_EQ(metadata[3].get().name, "scene_2"); +	EXPECT_EQ(metadata[3].get().tag, "tag_scene_2"); +	EXPECT_EQ(metadata[3].get().parent, -1); +	EXPECT_EQ(metadata[3].get().children.size(), 0); +	EXPECT_EQ(transform[3].get().position.x, 0); +	EXPECT_EQ(transform[3].get().position.y, 3); +} |