aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/crepe/api/CMakeLists.txt1
-rw-r--r--src/crepe/api/Config.h13
-rw-r--r--src/crepe/api/LoopManager.cpp2
-rw-r--r--src/crepe/api/LoopTimer.cpp2
-rw-r--r--src/crepe/api/LoopTimer.h4
-rw-r--r--src/crepe/api/Scene.cpp5
-rw-r--r--src/crepe/api/Scene.h23
-rw-r--r--src/crepe/api/SceneManager.h4
-rw-r--r--src/crepe/api/SceneManager.hpp12
-rw-r--r--src/crepe/api/Texture.cpp13
-rw-r--r--src/crepe/api/Texture.h12
-rw-r--r--src/doc/feature/scene.dox6
-rw-r--r--src/test/AssetTest.cpp13
-rw-r--r--src/test/RenderSystemTest.cpp8
-rw-r--r--src/test/SceneManagerTest.cpp46
-rw-r--r--src/test/main.cpp23
16 files changed, 113 insertions, 74 deletions
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index c3e0b37..50c51ed 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -12,7 +12,6 @@ target_sources(crepe PUBLIC
SaveManager.cpp
Config.cpp
Metadata.cpp
- Scene.cpp
SceneManager.cpp
Camera.cpp
Animator.cpp
diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h
index 13eabd1..0c9d116 100644
--- a/src/crepe/api/Config.h
+++ b/src/crepe/api/Config.h
@@ -11,19 +11,18 @@ namespace crepe {
* modified *before* execution is handed over from the game programmer to the engine (i.e. the
* main loop is started).
*/
-class Config {
+class Config final {
public:
//! Retrieve handle to global Config instance
static Config & get_instance();
private:
Config() = default;
-
- // singleton
- Config(const Config &) = delete;
- Config(Config &&) = delete;
- Config & operator=(const Config &) = delete;
- Config & operator=(Config &&) = delete;
+ ~Config() = default;
+ Config(const Config &) = default;
+ Config(Config &&) = default;
+ Config & operator=(const Config &) = default;
+ Config & operator=(Config &&) = default;
public:
//! Logging-related settings
diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp
index a64366f..7edf4d1 100644
--- a/src/crepe/api/LoopManager.cpp
+++ b/src/crepe/api/LoopManager.cpp
@@ -57,7 +57,7 @@ void LoopManager::loop() {
void LoopManager::setup() {
this->game_running = true;
LoopTimer::get_instance().start();
- LoopTimer::get_instance().set_fps(60);
+ LoopTimer::get_instance().set_fps(200);
}
void LoopManager::render() {
diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp
index a9800b7..15a0e3a 100644
--- a/src/crepe/api/LoopTimer.cpp
+++ b/src/crepe/api/LoopTimer.cpp
@@ -47,7 +47,7 @@ double LoopTimer::get_fixed_delta_time() const { return this->fixed_delta_time.c
void LoopTimer::set_fps(int fps) {
this->fps = fps;
// target time per frame in seconds
- this->frame_target_time = std::chrono::seconds(1) / fps;
+ this->frame_target_time = std::chrono::duration<double>(1.0) / fps;
}
int LoopTimer::get_fps() const { return this->fps; }
diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h
index f277d7b..9393439 100644
--- a/src/crepe/api/LoopTimer.h
+++ b/src/crepe/api/LoopTimer.h
@@ -130,9 +130,9 @@ private:
//! Delta time for the current frame in seconds
std::chrono::duration<double> delta_time{0.0};
//! Target time per frame in seconds
- std::chrono::duration<double> frame_target_time = std::chrono::seconds(1) / fps;
+ std::chrono::duration<double> frame_target_time = std::chrono::duration<double>(1.0) / fps;
//! Fixed delta time for fixed updates in seconds
- std::chrono::duration<double> fixed_delta_time = std::chrono::seconds(1) / 50;
+ std::chrono::duration<double> fixed_delta_time = std::chrono::duration<double>(1.0) / 50.0;
//! Total elapsed game time in seconds
std::chrono::duration<double> elapsed_time{0.0};
//! Total elapsed time for fixed updates in seconds
diff --git a/src/crepe/api/Scene.cpp b/src/crepe/api/Scene.cpp
deleted file mode 100644
index 849945e..0000000
--- a/src/crepe/api/Scene.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "Scene.h"
-
-using namespace crepe;
-
-Scene::Scene(ComponentManager & mgr) : component_manager(mgr) {}
diff --git a/src/crepe/api/Scene.h b/src/crepe/api/Scene.h
index 869bf6f..f6fdb2a 100644
--- a/src/crepe/api/Scene.h
+++ b/src/crepe/api/Scene.h
@@ -2,6 +2,8 @@
#include <string>
+#include "../util/OptionalRef.h"
+
namespace crepe {
class SceneManager;
@@ -15,11 +17,8 @@ class ComponentManager;
*/
class Scene {
protected:
- //TODO: Use Loek's custom reference class to set ComponentManger via SceneManager instead of via constructor
- /**
- * \param mgr Reference to the ComponentManager
- */
- Scene(ComponentManager & mgr);
+ // NOTE: This must be the only constructor on Scene, see "Late references" below
+ Scene() = default;
//! SceneManager instances Scene
friend class SceneManager;
@@ -36,8 +35,20 @@ public:
virtual std::string get_name() const = 0;
protected:
+ /**
+ * \name Late references
+ *
+ * These references are set by SceneManager immediately after calling the constructor of Scene.
+ *
+ * \note Scene must have a constructor without arguments so the game programmer doesn't need to
+ * manually add `using Scene::Scene` to their concrete scene class, if they want to add a
+ * constructor with arguments (e.g. for passing references to their own concrete Scene classes).
+ *
+ * \{
+ */
//! Reference to the ComponentManager
- ComponentManager & component_manager;
+ OptionalRef<ComponentManager> component_manager;
+ //! \}
};
} // namespace crepe
diff --git a/src/crepe/api/SceneManager.h b/src/crepe/api/SceneManager.h
index 45ba668..f6f62cd 100644
--- a/src/crepe/api/SceneManager.h
+++ b/src/crepe/api/SceneManager.h
@@ -26,8 +26,8 @@ public:
*
* \tparam T Type of concrete scene
*/
- template <typename T>
- void add_scene();
+ template <typename T, typename... Args>
+ void add_scene(Args &&... args);
/**
* \brief Set the next scene
*
diff --git a/src/crepe/api/SceneManager.hpp b/src/crepe/api/SceneManager.hpp
index 94e5946..5c8e417 100644
--- a/src/crepe/api/SceneManager.hpp
+++ b/src/crepe/api/SceneManager.hpp
@@ -4,13 +4,17 @@
namespace crepe {
-template <typename T>
-void SceneManager::add_scene() {
+template <typename T, typename... Args>
+void SceneManager::add_scene(Args &&... args) {
using namespace std;
static_assert(is_base_of<Scene, T>::value, "T must be derived from Scene");
- Scene * scene = new T(this->component_manager);
- this->scenes.emplace_back(unique_ptr<Scene>(scene));
+ Scene * scene = new T(std::forward<Args>(args)...);
+ unique_ptr<Scene> unique_scene(scene);
+
+ unique_scene->component_manager = this->component_manager;
+
+ this->scenes.emplace_back(std::move(unique_scene));
// The first scene added, is the one that will be loaded at the beginning
if (next_scene.empty()) {
diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp
index 9be9421..264d7b1 100644
--- a/src/crepe/api/Texture.cpp
+++ b/src/crepe/api/Texture.cpp
@@ -9,14 +9,9 @@
using namespace crepe;
using namespace std;
-Texture::Texture(unique_ptr<Asset> res) {
+Texture::Texture(const Asset & src) {
dbg_trace();
- this->load(std::move(res));
-}
-
-Texture::Texture(const char * src) {
- dbg_trace();
- this->load(make_unique<Asset>(src));
+ this->load(src);
}
Texture::~Texture() {
@@ -24,9 +19,9 @@ Texture::~Texture() {
this->texture.reset();
}
-void Texture::load(unique_ptr<Asset> res) {
+void Texture::load(const Asset & res) {
SDLContext & ctx = SDLContext::get_instance();
- this->texture = std::move(ctx.texture_from_path(res->get_path()));
+ this->texture = ctx.texture_from_path(res.get_path());
}
int Texture::get_width() const {
diff --git a/src/crepe/api/Texture.h b/src/crepe/api/Texture.h
index 6965223..b4f7d07 100644
--- a/src/crepe/api/Texture.h
+++ b/src/crepe/api/Texture.h
@@ -25,16 +25,10 @@ class Texture {
public:
/**
- * \brief Constructs a Texture from a file path.
- * \param src Path to the image file to be loaded as a texture.
- */
- Texture(const char * src);
-
- /**
* \brief Constructs a Texture from an Asset resource.
- * \param res Unique pointer to an Asset resource containing texture data.
+ * \param src Asset with texture data to load.
*/
- Texture(std::unique_ptr<Asset> res);
+ Texture(const Asset & src);
/**
* \brief Destroys the Texture instance, freeing associated resources.
@@ -59,7 +53,7 @@ private:
* \brief Loads the texture from an Asset resource.
* \param res Unique pointer to an Asset resource to load the texture from.
*/
- void load(std::unique_ptr<Asset> res);
+ void load(const Asset & res);
private:
//! The texture of the class from the library
diff --git a/src/doc/feature/scene.dox b/src/doc/feature/scene.dox
index eedc69a..d81df4c 100644
--- a/src/doc/feature/scene.dox
+++ b/src/doc/feature/scene.dox
@@ -36,16 +36,14 @@ concrete scene to be added.
#include <crepe/api/LoopManager.h>
#include <crepe/api/GameObject.h>
#include <crepe/api/Scene.h>
-#include <crepe/api/Vector2.h>
+#include <crepe/types.h>
using namespace crepe;
class MyScene : public Scene {
public:
- using Scene::Scene;
-
void load_scene() {
- auto & mgr = this->component_manager;
+ ComponentManager & mgr = this->component_manager;
GameObject object1 = mgr.new_object("object1", "tag_my_scene", vec2{0, 0}, 0, 1);
GameObject object2 = mgr.new_object("object2", "tag_my_scene", vec2{1, 0}, 0, 1);
}
diff --git a/src/test/AssetTest.cpp b/src/test/AssetTest.cpp
index 8aa7629..93fd6a9 100644
--- a/src/test/AssetTest.cpp
+++ b/src/test/AssetTest.cpp
@@ -7,17 +7,12 @@ using namespace std;
using namespace crepe;
using namespace testing;
-class AssetTest : public Test {
-public:
- Config & cfg = Config::get_instance();
- void SetUp() override { this->cfg.asset.root_pattern = ".crepe-root"; }
-};
-
-TEST_F(AssetTest, Existant) { ASSERT_NO_THROW(Asset{"asset/texture/img.png"}); }
+TEST(AssetTest, Existant) { ASSERT_NO_THROW(Asset{"asset/texture/img.png"}); }
-TEST_F(AssetTest, Nonexistant) { ASSERT_ANY_THROW(Asset{"asset/nonexistant"}); }
+TEST(AssetTest, Nonexistant) { ASSERT_ANY_THROW(Asset{"asset/nonexistant"}); }
-TEST_F(AssetTest, Rootless) {
+TEST(AssetTest, Rootless) {
+ Config & cfg = Config::get_instance();
cfg.asset.root_pattern.clear();
string arbitrary = "\\/this is / /../passed through as-is";
diff --git a/src/test/RenderSystemTest.cpp b/src/test/RenderSystemTest.cpp
index ac479d3..f37fb56 100644
--- a/src/test/RenderSystemTest.cpp
+++ b/src/test/RenderSystemTest.cpp
@@ -30,7 +30,7 @@ public:
void SetUp() override {
auto & sprite1
- = entity1.add_component<Sprite>(make_shared<Texture>("../asset/texture/img.png"),
+ = 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;
@@ -38,7 +38,7 @@ public:
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"),
+ = 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;
@@ -48,7 +48,7 @@ public:
EXPECT_EQ(sprite2.order_in_layer, 1);
auto & sprite3
- = entity3.add_component<Sprite>(make_shared<Texture>("../asset/texture/img.png"),
+ = 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;
@@ -58,7 +58,7 @@ public:
EXPECT_EQ(sprite3.order_in_layer, 2);
auto & sprite4
- = entity4.add_component<Sprite>(make_shared<Texture>("../asset/texture/img.png"),
+ = 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;
diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp
index f3d2387..62b7d33 100644
--- a/src/test/SceneManagerTest.cpp
+++ b/src/test/SceneManagerTest.cpp
@@ -1,3 +1,4 @@
+#include "types.h"
#include <crepe/ComponentManager.h>
#include <crepe/api/GameObject.h>
#include <crepe/api/Metadata.h>
@@ -12,10 +13,8 @@ using namespace crepe;
class ConcreteScene1 : public Scene {
public:
- using Scene::Scene;
-
void load_scene() {
- auto & mgr = this->component_manager;
+ ComponentManager & mgr = this->component_manager;
GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", vec2{0, 0}, 0, 1);
GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", vec2{1, 0}, 0, 1);
GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", vec2{2, 0}, 0, 1);
@@ -26,10 +25,8 @@ public:
class ConcreteScene2 : public Scene {
public:
- using Scene::Scene;
-
void load_scene() {
- auto & mgr = this->component_manager;
+ ComponentManager & mgr = this->component_manager;
GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 0}, 0, 1);
GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 1}, 0, 1);
GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 2}, 0, 1);
@@ -39,6 +36,21 @@ public:
string get_name() const { return "scene2"; }
};
+class ConcreteScene3 : public Scene {
+public:
+ ConcreteScene3(const string & name) : name(name) {}
+
+ void load_scene() {
+ ComponentManager & mgr = this->component_manager;
+ GameObject object1 = mgr.new_object("scene_3", "tag_scene_3", vec2{0, 0}, 0, 1);
+ }
+
+ string get_name() const { return name; }
+
+private:
+ const string name;
+};
+
class SceneManagerTest : public ::testing::Test {
public:
ComponentManager component_mgr{};
@@ -124,3 +136,25 @@ TEST_F(SceneManagerTest, loadScene) {
EXPECT_EQ(transform[3].get().position.x, 0);
EXPECT_EQ(transform[3].get().position.y, 3);
}
+
+TEST_F(SceneManagerTest, perfectForwarding) {
+ scene_mgr.add_scene<ConcreteScene3>("scene3");
+
+ 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(), 1);
+ EXPECT_EQ(transform.size(), 1);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 0);
+ EXPECT_EQ(metadata[0].get().name, "scene_3");
+ EXPECT_EQ(metadata[0].get().tag, "tag_scene_3");
+ 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);
+}
diff --git a/src/test/main.cpp b/src/test/main.cpp
index 241015d..aece72d 100644
--- a/src/test/main.cpp
+++ b/src/test/main.cpp
@@ -1,15 +1,30 @@
-#include <crepe/api/Config.h>
-
#include <gtest/gtest.h>
+#define protected public
+#define private public
+
+#include <crepe/api/Config.h>
+
using namespace crepe;
using namespace testing;
+class GlobalConfigReset : public EmptyTestEventListener {
+public:
+ Config & cfg = Config::get_instance();
+ Config cfg_default = Config();
+
+ // This function is called before each test
+ void OnTestStart(const TestInfo &) override {
+ cfg = cfg_default;
+ cfg.log.level = Log::Level::WARNING;
+ }
+};
+
int main(int argc, char ** argv) {
InitGoogleTest(&argc, argv);
- auto & cfg = Config::get_instance();
- cfg.log.level = Log::Level::ERROR;
+ UnitTest & ut = *UnitTest::GetInstance();
+ ut.listeners().Append(new GlobalConfigReset);
return RUN_ALL_TESTS();
}