diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-05 16:12:47 +0100 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-05 16:12:47 +0100 |
commit | e36ea050972fcaaf3d85d672755bad4ebb2dcd80 (patch) | |
tree | 5145e0b66650eea1df301106b7d197a586be65f3 | |
parent | 333b07775be1ef20fdb5909672c1e4dcabec1b40 (diff) | |
parent | b770475741b7c33d57331f3139c55a3f237ad274 (diff) |
merge `master` into `loek/savemgr`loek/savemgr
106 files changed, 1352 insertions, 332 deletions
diff --git a/contributing.md b/contributing.md index 775119a..2fe46f7 100644 --- a/contributing.md +++ b/contributing.md @@ -1,94 +1,441 @@ -# Contributing new code +This document contains +<details><summary> +examples +</summary> +that you can click on to open them. +</details> + +# Git - Please do the following *before* sending a pull request: - Merge upstream code (if any) back into your own branch - Run formatters/linters - -# Git - - Push as often as possible - Development is done on separate branches, these follow a pattern of `name/feature` (i.e. `loek/dll-so-poc` or `jaro/class2`) - The master branch is considered stable, and should always contain a working/compiling version of the project - - TODO: tagging / versions - # Code style -- ASCII only -- Class names are always singular -- Explanatory comments are placed above the line(s) they are explaining -- Source files should only contain comments that plainly state what the code is - supposed to do -- Explanatory comments in headers may be used to clarify implementation design - decisions - 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) +- <details><summary> + ASCII only + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + // crepe startup message + std::string message = "Hello, world!"; + ``` + </td><td> + + ```cpp + // crêpe startup message + std::string message = "こんにちは世界"; + ``` + </td></tr></table></details> +- <details><summary> + Class names are always singular + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + class Foo {}; + ``` + </td><td> + + ```cpp + class Cars {}; + ``` + </td></tr></table></details> +- Source files contain the following types of comments: + - What is the code supposed to do (optional) + - Implementation details (if applicable) +- Header files contain the following types of comments: + - Usage documentation (required) + - Implementation details (if they affect the header) + - Design/data structure decisions (if applicable) +- <details><summary> + Comments are placed *above* the line(s) they are explaining + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + int add(int a, int b) { + // add numbers + int out = a + b; + return out; + } + ``` + </td><td> + + ```cpp + int add(int a, int b) { + int out = a + b; // add numbers + return out; + } + ``` + </td></tr></table></details> - Header includes are split into paragraphs separated by a blank line. The order is: 1. system headers (using `<`brackets`>`) 2. relative headers NOT in the same folder as the current file 3. relative headers in the same folder as the current file -- When using libraries of which the header include order is important, make - sure to separate the include statements using a blank line (clang-format may - sort include statements, but does not sort across empty lines). -- All engine-related code is implemented under the `crepe` namespace, - user-facing APIs under `crepe::api` (the folder structure should also reflect - this). -- `using namespace` may not be used in header files, only in source files. -- Do not (indirectly) include private *dependency* headers in API header files, - as these are no longer accessible when the engine is installed -- Getter and setter functions are appropriately prefixed with `get_` and - `set_`. -- Doxygen commands are used with a backslash instead of an at-sign (i.e. - `\brief` instead of `@brief`) -- A singleton's instance is always accessed using a getter function that - instantiates its own class as a static variable within the getter function - scope, instead of storing the instance as a member variable directly: + + > [!NOTE] + > When using libraries of which the header include order is important, make + > sure to separate the include statements using a blank line (clang-format + > may sort include statements, but does not sort across empty lines). + + <details><summary>Example</summary> + <table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + #include <SDL2/SDL.h> + #include <iostream> + + #include "api/Sprite.h" + #include "util/log.h" + + #include "SDLContext.h" + ``` + </td><td> ```cpp - class Bad { - static Bad instance; - Bad & get_instance() { return instance; } + #include <SDL2/SDL.h> + #include "SDLContext.h" + #include "util/log.h" + #include <iostream> + #include "api/Sprite.h" + ``` + </td></tr></table></details> +- <details><summary> + <code>using namespace</code> may not be used in header files, only in source files. + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + example.h: + ```cpp + namespace crepe { + void foo(); + } + ``` + + example.cpp: + ```cpp + #include "example.h" + using namespace crepe; + void foo() {} + ``` + </td><td> + + example.h: + ```cpp + namespace crepe { + template <typename T> + T foo(); + } + ``` + + example.hpp: + ```cpp + #include "example.h" + using namespace crepe; + template <typename T> + T foo(); + ``` + </td></tr></table></details> + +- <details><summary> + Getter and setter functions are appropriately prefixed with <code>get_</code> + and <code>set_</code>. + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + class Foo { + public: + int get_speed() const; + void set_speed(int speed); + private: + int speed; }; + + ``` + </td><td> - class Good { - Good & get_instance() { - static Good instance; + ```cpp + class Foo { + public: + int speed() const; + void set_speed(int speed); + private: + int speed; + }; + ``` + </td></tr></table></details> +- <details><summary> + A singleton's instance is always accessed using a getter function that + instantiates its own class as a static variable within the getter function + scope, instead of storing the instance as a member variable directly. + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + class Foo { + Foo & get_instance() { + static Foo instance; return instance; } }; ``` -- Member variable default values should be directly defined in the class + </td><td> + + ```cpp + Foo Foo::instance {}; + + class Foo { + static Foo instance; + Foo & get_instance() { return Foo::instance; } + }; + + ``` + </td></tr></table></details> +- <details><summary> + Member variable default values should be directly defined in the class/struct declaration instead of using the constructor. -- Header files declare either a single class or symbols within a single - namespace. -- Use of the `auto` type is not allowed, with the following exceptions: - - When naming the item type in a range-based for loop - - When calling template factory methods that explicitly name the return type + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + class Foo { + int speed = 0; + }; + + ``` + </td><td> + + ```cpp + class Foo { + Foo() : speed(0) {} + int speed; + }; + ``` + </td></tr></table></details> +- Use of the `auto` type is *not* allowed, with the following exceptions: + - <details><summary> + When naming the item type in a range-based for loop + </summary> + + ```cpp + for (auto & item : foo()) { + // ... + } + ``` + </details> + - <details><summary> + When calling template factory methods that explicitly name the return type in the function call signature - - When fetching a singleton instance -- Only use member initializer lists for non-trivial types. -- C++-style structs should define default values for all non-trivial fields. -- Declare incomplete classes instead of including the relevant header where - possible (i.e. if you only need a reference or pointer type). -- Template functions are only declared in a `.h` header, and defined in a - matching `.hpp` header. -- Where possible, end (initializer) lists with a trailing comma (e.g. with + </summary> + + ```cpp + auto ptr = make_unique<Foo>(); + ``` + </details> + - <details><summary> + When fetching a singleton instance + </summary> + + ```cpp + auto & mgr = crepe::api::Config::get_instance(); + ``` + </details> + +- <details><summary> + Only use member initializer lists for non-trivial types. + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + class Foo { + public: + Foo() : bar("baz") {} + private: + std::string bar; + }; + + ``` + </td><td> + + ```cpp + class Foo { + public: + Foo() : bar(0) {} + private: + int bar; + }; + ``` + </td></tr></table></details> +- <details><summary> + C++-style structs should define default values for all non-trivial fields. + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + struct Foo { + int bar; + std::string baz; + }; + ``` + </td><td> + + ```cpp + struct Foo { + int bar = 0; + std::string baz; + }; + ``` + </td></tr></table></details> +- <details><summary> + Declare incomplete classes instead of including the relevant header where + possible (i.e. if you only need a reference or raw pointer). + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + class Bar; + class Foo { + Bar & bar; + }; + + ``` + </td><td> + + ```cpp + #include "Bar.h" + class Foo { + Bar & bar; + }; + ``` + </td></tr></table></details> +- <details><summary> + Template functions are only <i>declared</i> in a <code>.h</code> header, and + <i>defined</i> in a matching <code>.hpp</code> header. + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + add.h: + ```cpp + template <typename T> + T add(T a, T b); + + #include "add.hpp" + ``` + + add.hpp: + ```cpp + #include "add.h" + + template <typename T> + T add(T a, T b) { + return a + b; + } + ``` + </td><td> + + add.h: + ```cpp + template <typename T> + T add(T a, T b) { + return a + b; + } + ``` + </td></tr></table></details> +- <details><summary> + Where possible, end (initializer) lists with a trailing comma (e.g. with structs, enums) + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + enum Color { + Red, + Green, + Blue, + }; + + ``` + </td><td> -## CMakeLists specific + ```cpp + enum Color { + Red, + Green, + Blue + }; + ``` + </td></tr></table></details> +- <details><summary> + <code>#pragma</code> should be used instead of include guards + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + #pragma once + + // ... + ``` + </td><td> + + ```cpp + #ifndef __INCLUDED_H + #define __INCLUDED_H + + // ... + + #endif + ``` + </td></tr></table></details> + +## CMakeLists-specific - Make sure list arguments (e.g. sources, libraries) given to commands (e.g. `target_sources`, `target_link_libraries`) are on separate lines. This makes resolving merge conflicts when multiple sources were added by different people to the same CMakeLists.txt easier. +# Structure + +- Files are placed in the appropriate directory: + |Path|Purpose| + |-|-| + |`crepe/`|Auxiliary, managers| + |`crepe/api/`|User-facing APIs| + |`crepe/util/`|Standalone utilities and helper functions| + |`crepe/system/`|(ECS) system classes| + |`crepe/facade/`|Library façades| +- Do not (indirectly) include private *dependency* headers in API header files, + as these are no longer accessible when the engine is installed +- All code is implemented under the `crepe` namespace. +- Header files declare either a single class or symbols within a single + namespace. + # Documentation - All documentation is written in U.S. English +- <details><summary> + Doxygen commands are used with a backslash instead of an at-sign. + </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td> + + ```cpp + /** + * \brief do something + * + * \param bar Magic number + */ + void foo(int bar); + ``` + </td><td> + + ```cpp + /** + * @brief do something + * + * @param bar Magic number + */ + void foo(); + ``` + </td></tr></table></details> # Libraries diff --git a/lib/SDL_ttf b/lib/SDL_ttf new file mode 160000 +Subproject a3d0895c1b60c41ff9e85d9203ddd7485c014da diff --git a/mwe/audio/miniaudio/main.cpp b/mwe/audio/miniaudio/main.cpp index bf31898..5c4f667 100644 --- a/mwe/audio/miniaudio/main.cpp +++ b/mwe/audio/miniaudio/main.cpp @@ -33,12 +33,10 @@ int main() { ma_sound_start(&sfx[2]); ma_sound_start(&bgm); // this actually resumes now this_thread::sleep_for(500ms); - for (unsigned i = 0; i < 3; i++) - ma_sound_seek_to_pcm_frame(&sfx[i], 0); + for (unsigned i = 0; i < 3; i++) ma_sound_seek_to_pcm_frame(&sfx[i], 0); // 5. play all samples simultaniously - for (unsigned i = 0; i < 3; i++) - ma_sound_start(&sfx[i]); + for (unsigned i = 0; i < 3; i++) ma_sound_start(&sfx[i]); this_thread::sleep_for(1000ms); ma_engine_uninit(&engine); diff --git a/mwe/events/CMakeLists.txt b/mwe/events/CMakeLists.txt index 585d869..12e45a7 100644 --- a/mwe/events/CMakeLists.txt +++ b/mwe/events/CMakeLists.txt @@ -2,30 +2,39 @@ cmake_minimum_required(VERSION 3.5) project(gameloop) # Set the C++ standard (optional, but good practice) -set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD 17) set(CMAKE_CXX_STANDARD 20) set(CMAKE_EXPORT_COMPILE_COMMANDS 1) set(CMAKE_BUILD_TYPE Debug) # Find the SDL2 package find_package(SDL2 REQUIRED) +# Find the SDL2_ttf package +find_package(SDL2_ttf REQUIRED) add_executable(gameloop - src/window.cpp - src/main.cpp - #src/eventHandler.cpp - src/eventManager.cpp - src/event.cpp - src/loopManager.cpp - src/timer.cpp - src/keyCodes.cpp - src/eventHandler.cpp + src/window.cpp + src/main.cpp + src/eventManager.cpp + src/event.cpp + src/loopManager.cpp + src/timer.cpp + src/keyCodes.cpp + src/eventHandler.cpp + src/iMouseListener.cpp + src/iKeyListener.cpp + src/mouseListenerTest.cpp + src/keyListenerTest.cpp + src/inputSystem.cpp + src/uiRenderer.cpp + src/uiObject.cpp ) -# Link the SDL2 library to your project -target_link_libraries(gameloop ${SDL2_LIBRARIES}) +target_link_libraries(gameloop ${SDL2_LIBRARIES} SDL2_ttf::SDL2_ttf) # Include SDL2 header files and project headers target_include_directories(gameloop PRIVATE ${SDL2_INCLUDE_DIRS}) target_include_directories(gameloop PRIVATE ${CMAKE_SOURCE_DIR}/include) +# Copy font files to the build directory +file(COPY ${PROJECT_SOURCE_DIR}/font DESTINATION ${CMAKE_BINARY_DIR}) diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h index 730ee4b..16c75bf 100644 --- a/mwe/events/include/event.h +++ b/mwe/events/include/event.h @@ -6,7 +6,6 @@ #include <string> #include <unordered_map> #include <variant> - class UUIDGenerator { public: static std::uint32_t getUniqueID() { @@ -63,7 +62,19 @@ public: Keycode key = 0; int repeatCount = 0; }; +class MouseClickEvent : public Event { +public: + MouseClickEvent(int x, int y, MouseButton button); + REGISTER_EVENT_TYPE("KeyClickedEvent"); + std::pair<int, int> getMousePosition() const; + MouseButton getButton() const { return button; } + +private: + int mouseX = 0; + int mouseY = 0; + MouseButton button; +}; // KeyReleasedEvent class class KeyReleasedEvent : public Event { public: @@ -89,6 +100,33 @@ public: private: int mouseX = 0; int mouseY = 0; + MouseButton button; +}; +class MouseReleasedEvent : public Event { +public: + MouseReleasedEvent(int mouseX, int mouseY, MouseButton button); + + REGISTER_EVENT_TYPE(MouseReleasedEvent) + + std::pair<int, int> getMousePosition() const; + MouseButton getMouseButton() const; + +private: + int mouseX = 0; + int mouseY = 0; + MouseButton button; +}; +class MouseMovedEvent : public Event { +public: + MouseMovedEvent(int mouseX, int mouseY); + + REGISTER_EVENT_TYPE(MouseMovedEvent) + + std::pair<int, int> getMousePosition() const; + +private: + int mouseX = 0; + int mouseY = 0; }; class CollisionEvent : public Event { public: @@ -101,3 +139,33 @@ public: private: Collision collisionData; }; +class TextSubmitEvent : public Event { +public: + TextSubmitEvent(std::string submittedText); + + REGISTER_EVENT_TYPE(TextSubmitEvent) + + std::string getText() const; + +private: + std::string text; +}; +class ShutDownEvent : public Event { +public: + ShutDownEvent() : Event("ShutDownEvent") {}; + + REGISTER_EVENT_TYPE(ShutDownEvent) + +private: +}; +// class ButtonClickEvent : public Event { +// public: +// ButtonClickEvent(int x,int y,int width,int height); + +// REGISTER_EVENT_TYPE(TextSubmitEvent) + +// std::string getText() const; + +// private: +// std::string text; +// }; diff --git a/mwe/events/include/eventHandler.h b/mwe/events/include/eventHandler.h index 7414801..aa8f63b 100644 --- a/mwe/events/include/eventHandler.h +++ b/mwe/events/include/eventHandler.h @@ -1,9 +1,8 @@ #pragma once - #include "event.h" - #include <functional> #include <iostream> + template <typename EventType> using EventHandler = std::function<void(const EventType & e)>; diff --git a/mwe/events/include/gameObject.h b/mwe/events/include/gameObject.h new file mode 100644 index 0000000..48e239b --- /dev/null +++ b/mwe/events/include/gameObject.h @@ -0,0 +1,20 @@ +#pragma once +#include <cstdint> +#include <string> +class GameObject { +public: + GameObject() {} + + // template <typename... Args> + // void addSpriteComponent(Args &&... args); + // template <typename... Args> + // void addRigidbodyComponent(Args &&... args); + // template <typename... Args> + // void addColiderComponent(Args &&... args); + + std::uint32_t mId; + std::string mName; + std::string mTag; + bool mActive; + int mLayer; +}; diff --git a/mwe/events/include/iKeyListener.h b/mwe/events/include/iKeyListener.h new file mode 100644 index 0000000..5fee2eb --- /dev/null +++ b/mwe/events/include/iKeyListener.h @@ -0,0 +1,20 @@ +#pragma once +#include "event.h" +#include "eventHandler.h" +#include "eventManager.h" +class IKeyListener { +public: + virtual ~IKeyListener(); + virtual void onKeyPressed(const KeyPressedEvent & event) = 0; + virtual void onKeyReleased(const KeyReleasedEvent & event) = 0; + +protected: + void subscribeEvents(int listenerId = 0); + void unsubscribeEvents(int listenerId = 0); + void activate(int listenerId = 0) { subscribeEvents(listenerId); } + void deactivate(int listenerId = 0) { unsubscribeEvents(listenerId); } + +private: + EventHandler<KeyPressedEvent> keyPressedHandler; + EventHandler<KeyReleasedEvent> keyReleasedHandler; +}; diff --git a/mwe/events/include/iMouseListener.h b/mwe/events/include/iMouseListener.h new file mode 100644 index 0000000..5b1181c --- /dev/null +++ b/mwe/events/include/iMouseListener.h @@ -0,0 +1,24 @@ +#pragma once +#include "event.h" +#include "eventHandler.h" +#include "eventManager.h" + +class IMouseListener { +public: + virtual ~IMouseListener(); + + virtual void onMouseClicked(const MouseClickEvent & event) = 0; + virtual void onMousePressed(const MousePressedEvent & event) = 0; + virtual void onMouseReleased(const MouseReleasedEvent & event) = 0; + virtual void onMouseMoved(const MouseMovedEvent & event) = 0; + +protected: + void subscribeEvents(int listenerId = 0); + void unsubscribeEvents(int listenerId = 0); + +private: + EventHandler<MouseClickEvent> mouseClickHandler; + EventHandler<MousePressedEvent> mousePressHandler; + EventHandler<MouseReleasedEvent> mouseReleaseHandler; + EventHandler<MouseMovedEvent> mouseMoveHandler; +}; diff --git a/mwe/events/include/inputSystem.h b/mwe/events/include/inputSystem.h new file mode 100644 index 0000000..3e53b7c --- /dev/null +++ b/mwe/events/include/inputSystem.h @@ -0,0 +1,23 @@ +#pragma once +#include "event.h" +#include "eventManager.h" +#include "keyCodes.h" +#include "uiObject.h" +#include <vector> +class InputSystem { +public: + InputSystem(); + void registerButton(Button * button); + void registerText(Text * label); + void registerTextInput(TextInput * input); + void processInput(); + +private: + std::vector<Button *> buttons; + std::vector<TextInput *> textInputs; + std::vector<Text *> texts; + void processMouseClick(int mouseX, int mouseY); + void processInputField(int mouseX, int mouseY); + void processKeyPress(Keycode); + void processTextInput(const std::string & text); +}; diff --git a/mwe/events/include/keyCodes.h b/mwe/events/include/keyCodes.h index 0879efc..73ba1cd 100644 --- a/mwe/events/include/keyCodes.h +++ b/mwe/events/include/keyCodes.h @@ -3,6 +3,16 @@ #include <cstdint> #include <unordered_map> using Keycode = uint16_t; +enum class MouseButton { + None = 0, + Left_Mouse = 1, + Right_Mouse = 2, + Middle_Mouse = 3, + X1_Mouse = 4, + X2_Mouse = 5, + Scroll_Up = 6, + Scroll_Down = 7, +}; enum : Keycode { // From glfw3.h Space = 32, @@ -136,6 +146,7 @@ enum : Keycode { RightSuper = 347, Menu = 348 }; + // Define the mapping extern const std::unordered_map<SDL_Keycode, Keycode> sdlToCustom; diff --git a/mwe/events/include/keyListenerTest.h b/mwe/events/include/keyListenerTest.h new file mode 100644 index 0000000..08f3feb --- /dev/null +++ b/mwe/events/include/keyListenerTest.h @@ -0,0 +1,12 @@ +#pragma once +#include "iKeyListener.h" +#include <iostream> + +class KeyListenerTest : public IKeyListener { +public: + KeyListenerTest(int listenerId); + ~KeyListenerTest(); + + void onKeyPressed(const KeyPressedEvent & event) override; + void onKeyReleased(const KeyReleasedEvent & event) override; +}; diff --git a/mwe/events/include/loopManager.h b/mwe/events/include/loopManager.h index baffb94..9959c94 100644 --- a/mwe/events/include/loopManager.h +++ b/mwe/events/include/loopManager.h @@ -5,7 +5,11 @@ //#include "combinedEvent.h" #include "eventHandler.h" #include "eventManager.h" +#include "inputSystem.h" #include "loopManager.h" +#include "uiObject.h" +#include "uiRenderer.h" +#include <memory> class LoopManager { public: LoopManager(); @@ -19,6 +23,7 @@ private: void lateUpdate(); void fixedUpdate(); void render(); + void onShutdown(const ShutDownEvent & e); bool gameRunning = false; WindowManager window; int timeScale = 1; @@ -26,4 +31,6 @@ private: double currentTime; double t = 0.0; double dt = 0.01; + std::unique_ptr<InputSystem> inputSystem; + EventHandler<ShutDownEvent> shutdownHandler; }; diff --git a/mwe/events/include/mouseListenerTest.h b/mwe/events/include/mouseListenerTest.h new file mode 100644 index 0000000..ca9afc5 --- /dev/null +++ b/mwe/events/include/mouseListenerTest.h @@ -0,0 +1,14 @@ +#pragma once +#include "iMouseListener.h" +#include <iostream> + +class MouseListenerTest : public IMouseListener { +public: + MouseListenerTest(int listenerId); + ~MouseListenerTest(); + + void onMouseClicked(const MouseClickEvent & event) override; + void onMousePressed(const MousePressedEvent & event) override; + void onMouseReleased(const MouseReleasedEvent & event) override; + void onMouseMoved(const MouseMovedEvent & event) override; +}; diff --git a/mwe/events/include/uiObject.h b/mwe/events/include/uiObject.h new file mode 100644 index 0000000..23efe44 --- /dev/null +++ b/mwe/events/include/uiObject.h @@ -0,0 +1,68 @@ +#pragma once +#include "event.h" +#include "eventHandler.h" +#include "gameObject.h" +#include <SDL2/SDL.h> +#include <SDL_ttf.h> +#include <functional> +struct Alignment { + enum class Horizontal { LEFT, CENTER, RIGHT }; + enum class Vertical { TOP, MIDDLE, BOTTOM }; + enum class PositioningMode { RELATIVE, STATIC, ABSOLUTE }; + + Horizontal horizontal = Horizontal::CENTER; + Vertical vertical = Vertical::MIDDLE; + PositioningMode mode = PositioningMode::RELATIVE; + + int staticX = 0; + int staticY = 0; + + int marginTop = 0; + int marginBottom = 0; + int marginLeft = 0; + int marginRight = 0; +}; +struct RGBColor { + int red; + int green; + int blue; +}; +class UIObject : public GameObject { +public: + UIObject(int width, int height); + virtual ~UIObject() {} + int width; + int height; + int x; + int y; +}; +class Button : public UIObject { +public: + Button(int width, int height); + RGBColor color; + std::function<void()> onClick; +}; +class Text : public UIObject { +public: + Text(int width, int height); + std::string text; + int size; + Alignment alignment; + //font resource + TTF_Font * font; + RGBColor color; +}; +class TextInput : public UIObject { +public: + TextInput(int width, int height); + std::string textBuffer; + std::string placeholder; + bool isActive = false; + RGBColor textColor; + RGBColor backgroundColor; + size_t maxLength = 100; + Alignment alignment; + TTF_Font * font = nullptr; + std::function<void()> onSubmit; + std::function<void()> onFocus; +}; diff --git a/mwe/events/include/uiRenderer.h b/mwe/events/include/uiRenderer.h new file mode 100644 index 0000000..8f22fdf --- /dev/null +++ b/mwe/events/include/uiRenderer.h @@ -0,0 +1,21 @@ +#pragma once +#include "uiObject.h" +#include <SDL2/SDL.h> +#include <SDL2/SDL_ttf.h> +#include <string> + +class UIRenderer { +public: + UIRenderer(SDL_Renderer * renderer); + ~UIRenderer(); + + void render(UIObject * uiObject); + +private: + SDL_Renderer * renderer; + TTF_Font * font; + + void renderButton(Button * button); + void renderText(Text * text); + void renderTextInput(TextInput * textInput); +}; diff --git a/mwe/events/include/window.h b/mwe/events/include/window.h index 9020b1a..bd75c4a 100644 --- a/mwe/events/include/window.h +++ b/mwe/events/include/window.h @@ -1,19 +1,27 @@ #pragma once +#include "uiObject.h" +#include "uiRenderer.h" #include <SDL2/SDL.h> -#include <iostream> #include <vector> + class WindowManager { public: WindowManager(); virtual ~WindowManager(); + bool initWindow(); void destroyWindow(); - SDL_Renderer * getRenderer(); + void addUIObject(UIObject * uiObject); + void renderUIObjects(); + private: const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT = 600; - SDL_Window * window = NULL; - SDL_Renderer * renderer = NULL; + SDL_Window * window = nullptr; + SDL_Renderer * renderer = nullptr; + + UIRenderer * uiRenderer; + std::vector<UIObject *> uiObjects; }; diff --git a/mwe/events/src/event.cpp b/mwe/events/src/event.cpp index c9201d0..0c9f3ed 100644 --- a/mwe/events/src/event.cpp +++ b/mwe/events/src/event.cpp @@ -50,3 +50,24 @@ CollisionEvent::CollisionEvent(Collision collision) Collision CollisionEvent::getCollisionData() const { return this->collisionData; } + +TextSubmitEvent::TextSubmitEvent(std::string text) + : text(text), Event("TextSubmitEvent") {} + +std::string TextSubmitEvent::getText() const { return this->text; } + +MouseReleasedEvent::MouseReleasedEvent(int x, int y, MouseButton button) + : mouseX(x), mouseY(y), button(button), Event("MouseReleased") {} +std::pair<int, int> MouseReleasedEvent::getMousePosition() const { + return {mouseX, mouseY}; +} +MouseClickEvent::MouseClickEvent(int x, int y, MouseButton button) + : mouseX(x), mouseY(y), button(button), Event("MouseClickEvent") {} +MouseMovedEvent::MouseMovedEvent(int x, int y) + : mouseX(x), mouseY(y), Event("MouseMovedEvent") {} +std::pair<int, int> MouseClickEvent::getMousePosition() const { + return {mouseX, mouseY}; +} +std::pair<int, int> MouseMovedEvent::getMousePosition() const { + return {mouseX, mouseY}; +} diff --git a/mwe/events/src/iKeyListener.cpp b/mwe/events/src/iKeyListener.cpp new file mode 100644 index 0000000..0235fab --- /dev/null +++ b/mwe/events/src/iKeyListener.cpp @@ -0,0 +1,19 @@ +#include "iKeyListener.h" + +IKeyListener::~IKeyListener() { unsubscribeEvents(); } + +void IKeyListener::subscribeEvents(int listenerId) { + keyPressedHandler + = [this](const KeyPressedEvent & event) { this->onKeyPressed(event); }; + keyReleasedHandler = [this](const KeyReleasedEvent & event) { + this->onKeyReleased(event); + }; + + subscribe<KeyPressedEvent>(keyPressedHandler, listenerId); + subscribe<KeyReleasedEvent>(keyReleasedHandler, listenerId); +} + +void IKeyListener::unsubscribeEvents(int listenerId) { + unsubscribe<KeyPressedEvent>(keyPressedHandler, listenerId); + unsubscribe<KeyReleasedEvent>(keyReleasedHandler, listenerId); +} diff --git a/mwe/events/src/iMouseListener.cpp b/mwe/events/src/iMouseListener.cpp new file mode 100644 index 0000000..69d8c9f --- /dev/null +++ b/mwe/events/src/iMouseListener.cpp @@ -0,0 +1,28 @@ +#include "iMouseListener.h" +IMouseListener::~IMouseListener() { unsubscribeEvents(); } + +void IMouseListener::subscribeEvents(int listenerId) { + mouseClickHandler = [this](const MouseClickEvent & event) { + this->onMouseClicked(event); + }; + mousePressHandler = [this](const MousePressedEvent & event) { + this->onMousePressed(event); + }; + mouseReleaseHandler = [this](const MouseReleasedEvent & event) { + this->onMouseReleased(event); + }; + mouseMoveHandler + = [this](const MouseMovedEvent & event) { this->onMouseMoved(event); }; + + subscribe<MouseClickEvent>(mouseClickHandler, listenerId); + subscribe<MousePressedEvent>(mousePressHandler, listenerId); + subscribe<MouseReleasedEvent>(mouseReleaseHandler, listenerId); + subscribe<MouseMovedEvent>(mouseMoveHandler, listenerId); +} + +void IMouseListener::unsubscribeEvents(int listenerId) { + unsubscribe<MouseClickEvent>(mouseClickHandler, listenerId); + unsubscribe<MousePressedEvent>(mousePressHandler, listenerId); + unsubscribe<MouseReleasedEvent>(mouseReleaseHandler, listenerId); + unsubscribe<MouseMovedEvent>(mouseMoveHandler, listenerId); +} diff --git a/mwe/events/src/inputSystem.cpp b/mwe/events/src/inputSystem.cpp new file mode 100644 index 0000000..b87b12e --- /dev/null +++ b/mwe/events/src/inputSystem.cpp @@ -0,0 +1,95 @@ +#include "inputSystem.h" + +InputSystem::InputSystem() {} + +void InputSystem::registerButton(Button * button) { buttons.push_back(button); } +void InputSystem::registerTextInput(TextInput * input) { + textInputs.push_back(input); +} +void InputSystem::registerText(Text * label) { texts.push_back(label); } + +void InputSystem::processInput() { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + triggerEvent(ShutDownEvent()); + break; + case SDL_KEYDOWN: + triggerEvent( + KeyPressedEvent(getCustomKey(event.key.keysym.sym))); + processKeyPress(event.key.keysym.sym); + break; + case SDL_TEXTINPUT: + // Process typed characters + processTextInput(event.text.text); + break; + case SDL_MOUSEBUTTONDOWN: { + int mouseX, mouseY; + SDL_GetMouseState(&mouseX, &mouseY); + processMouseClick(mouseX, mouseY); + triggerEvent(MousePressedEvent(mouseX, mouseY)); + break; + } + } + } +} + +void InputSystem::processMouseClick(int mouseX, int mouseY) { + for (auto * button : buttons) { + if (mouseX >= button->x && mouseX <= (button->x + button->width) + && mouseY >= button->y && mouseY <= (button->y + button->height)) { + button->onClick(); + } + } + for (auto * textInput : textInputs) { + if (mouseX >= textInput->x && mouseX <= textInput->x + textInput->width + && mouseY >= textInput->y + && mouseY <= textInput->y + textInput->height) { + textInput->isActive = true; + } else { + textInput->isActive = false; + } + } +} +void InputSystem::processKeyPress(Keycode key) { + // for (auto* textInput : textInputs) { + // if (textInput->isActive) { + // if (key == SDLK_RETURN || key == SDLK_KP_ENTER) { + // // Submit the text + // if (textInput->onSubmit) { + // textInput->onSubmit(); + // } + // } + // else if (key == SDLK_BACKSPACE) { + // // Handle backspace + // if (!textInput->textBuffer.empty() && textInput->caretPosition > 0) { + // textInput->textBuffer.erase(textInput->caretPosition - 1, 1); + // textInput->caretPosition--; + // } + // } + // else if (key == SDLK_LEFT) { + // // Move caret left + // if (textInput->caretPosition > 0) { + // textInput->caretPosition--; + // } + // } + // else if (key == SDLK_RIGHT) { + // // Move caret right + // if (textInput->caretPosition < textInput->textBuffer.size()) { + // textInput->caretPosition++; + // } + // } + // } + // } +} + +void InputSystem::processTextInput(const std::string & text) { + // for (auto* textInput : textInputs) { + // if (textInput->isActive) { + // // Insert text at caret position + // textInput->textBuffer.insert(textInput->caretPosition, text); + // textInput->caretPosition += text.length(); + // } + // } +} diff --git a/mwe/events/src/keyListenerTest.cpp b/mwe/events/src/keyListenerTest.cpp new file mode 100644 index 0000000..8446dfa --- /dev/null +++ b/mwe/events/src/keyListenerTest.cpp @@ -0,0 +1,15 @@ +#include "keyListenerTest.h" + +KeyListenerTest::KeyListenerTest(int listenerId) { + subscribeEvents(listenerId); +} + +KeyListenerTest::~KeyListenerTest() { unsubscribeEvents(); } + +void KeyListenerTest::onKeyPressed(const KeyPressedEvent & event) { + std::cout << "Key pressed: " << event.getKeyCode() << std::endl; +} + +void KeyListenerTest::onKeyReleased(const KeyReleasedEvent & event) { + std::cout << "Key released: " << event.getKeyCode() << std::endl; +} diff --git a/mwe/events/src/loopManager.cpp b/mwe/events/src/loopManager.cpp index 8ecb932..0b7d888 100644 --- a/mwe/events/src/loopManager.cpp +++ b/mwe/events/src/loopManager.cpp @@ -1,22 +1,27 @@ #include "loopManager.h" -LoopManager::LoopManager() {} +LoopManager::LoopManager() : inputSystem(std::make_unique<InputSystem>()) { + shutdownHandler + = [this](const ShutDownEvent & event) { this->onShutdown(event); }; + subscribe(shutdownHandler); +} void LoopManager::processInput() { - SDL_Event event; - SDL_PollEvent(&event); - switch (event.type) { - case SDL_QUIT: - gameRunning = false; - break; - case SDL_KEYDOWN: - triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); - break; - case SDL_MOUSEBUTTONDOWN: - int x, y; - SDL_GetMouseState(&x, &y); - triggerEvent(MousePressedEvent(x, y)); - break; - } + inputSystem->processInput(); + // SDL_Event event; + // SDL_PollEvent(&event); + // switch (event.type) { + // case SDL_QUIT: + // gameRunning = false; + // break; + // case SDL_KEYDOWN: + // triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); + // break; + // case SDL_MOUSEBUTTONDOWN: + // int x, y; + // SDL_GetMouseState(&x, &y); + // triggerEvent(MousePressedEvent(x, y)); + // break; + // } } void LoopManager::setRunning(bool running) { this->gameRunning = running; } void LoopManager::fixedUpdate() { @@ -28,9 +33,8 @@ void LoopManager::loop() { while (gameRunning) { timer.update(); - + processInput(); while (timer.getLag() >= timer.getFixedDeltaTime()) { - processInput(); fixedUpdate(); timer.advanceFixedUpdate(); } @@ -66,22 +70,35 @@ void LoopManager::setup() { } }; subscribe<KeyPressedEvent>(closeWindowCallback, false); + Button * testButton = new Button(200, 200); + testButton->color = {100, 0, 100}; + testButton->onClick + = []() { std::cout << "Button was clicked" << std::endl; }; + testButton->x = 200; + testButton->y = 200; + inputSystem->registerButton(testButton); + + window.addUIObject(testButton); + + TextInput * testInput = new TextInput(200, 200); + testInput->x = 100; + testInput->y = 100; + testInput->backgroundColor = {20, 50, 80}; + inputSystem->registerTextInput(testInput); + window.addUIObject(testInput); } void LoopManager::render() { //fprintf(stderr, "**********render********** \n"); if (gameRunning) { - //window.render(objectList); + window.renderUIObjects(); } } - +void LoopManager::onShutdown(const ShutDownEvent & e) { + this->gameRunning = false; +} void LoopManager::update() { //fprintf(stderr, "**********normal update********** \n"); LoopTimer & timer = LoopTimer::getInstance(); float delta = timer.getDeltaTime(); - - // for (int i = 0; i < objectList.size(); i++) { - // objectList[i]->setX(objectList[i]->getX() + 50 * delta); - // objectList[i]->setY(objectList[i]->getY() + 50 * delta); - // } } diff --git a/mwe/events/src/main.cpp b/mwe/events/src/main.cpp index f7e0766..d49cf74 100644 --- a/mwe/events/src/main.cpp +++ b/mwe/events/src/main.cpp @@ -1,6 +1,10 @@ #include "customTypes.h" #include "event.h" +#include "iKeyListener.h" +#include "iMouseListener.h" +#include "keyListenerTest.h" #include "loopManager.h" +#include "mouseListenerTest.h" #include <SDL2/SDL.h> #include <iostream> #include <memory> @@ -44,10 +48,9 @@ void testCollisionEvent() { } int main(int argc, char * args[]) { LoopManager gameLoop; - // Create an event handler for KeyPressedEvent - // EventHandler<KeyPressedEvent> callback = [](const KeyPressedEvent& e) { - // onKeyPressed(e); - // }; + int testListenerId = 0; + KeyListenerTest keyListener(testListenerId); + MouseListenerTest mouseListener(testListenerId); // custom event class poc subscribe<PlayerDamagedEvent>(onPlayerDamaged); triggerEvent(PlayerDamagedEvent(50, 1)); diff --git a/mwe/events/src/mouseListenerTest.cpp b/mwe/events/src/mouseListenerTest.cpp new file mode 100644 index 0000000..a2a7e6d --- /dev/null +++ b/mwe/events/src/mouseListenerTest.cpp @@ -0,0 +1,27 @@ +#include "mouseListenerTest.h" + +MouseListenerTest::MouseListenerTest(int listenerId) { + subscribeEvents(listenerId); +} + +MouseListenerTest::~MouseListenerTest() { unsubscribeEvents(); } + +void MouseListenerTest::onMouseClicked(const MouseClickEvent & event) { + std::cout << "Mouse clicked at: (" << event.getMousePosition().first << ", " + << event.getMousePosition().second << ")" << std::endl; +} + +void MouseListenerTest::onMousePressed(const MousePressedEvent & event) { + std::cout << "Mouse button pressed at: (" << event.getMousePosition().first + << ", " << event.getMousePosition().second << ")" << std::endl; +} + +void MouseListenerTest::onMouseReleased(const MouseReleasedEvent & event) { + std::cout << "Mouse button released at: (" << event.getMousePosition().first + << ", " << event.getMousePosition().second << ")" << std::endl; +} + +void MouseListenerTest::onMouseMoved(const MouseMovedEvent & event) { + std::cout << "Mouse moved to: (" << event.getMousePosition().first << ", " + << event.getMousePosition().second << ")" << std::endl; +} diff --git a/mwe/events/src/uiObject.cpp b/mwe/events/src/uiObject.cpp new file mode 100644 index 0000000..8405469 --- /dev/null +++ b/mwe/events/src/uiObject.cpp @@ -0,0 +1,24 @@ +#include "uiObject.h" + +// Constructor for UIObject +UIObject::UIObject(int width, int height) : width(width), height(height) {} + +// Constructor for Button +Button::Button(int width, int height) : UIObject(width, height) {} + +Text::Text(int width, int height) + : UIObject(width, height), size(12), font(nullptr), + color{255, 255, 255} { // Default size and color + alignment.horizontal = Alignment::Horizontal::CENTER; + alignment.vertical = Alignment::Vertical::MIDDLE; + alignment.mode = Alignment::PositioningMode::RELATIVE; +} + +TextInput::TextInput(int width, int height) + : UIObject(width, height), textBuffer(""), placeholder(""), isActive(false), + textColor{255, 255, 255}, backgroundColor{0, 0, 0}, maxLength(100), + font(nullptr) { + alignment.horizontal = Alignment::Horizontal::LEFT; + alignment.vertical = Alignment::Vertical::TOP; + alignment.mode = Alignment::PositioningMode::RELATIVE; +} diff --git a/mwe/events/src/uiRenderer.cpp b/mwe/events/src/uiRenderer.cpp new file mode 100644 index 0000000..9fec272 --- /dev/null +++ b/mwe/events/src/uiRenderer.cpp @@ -0,0 +1,107 @@ +#include "uiRenderer.h" + +// Constructor +UIRenderer::UIRenderer(SDL_Renderer * renderer) : renderer(renderer) {} + +// Render function +void UIRenderer::render(UIObject * uiObject) { + if (Button * button = dynamic_cast<Button *>(uiObject)) { + renderButton(button); + } else if (Text * text = dynamic_cast<Text *>(uiObject)) { + renderText(text); + } else if (TextInput * textInput = dynamic_cast<TextInput *>(uiObject)) { + renderTextInput(textInput); + } +} + +// Private helper function to render a Button +void UIRenderer::renderButton(Button * button) { + SDL_Rect buttonRect = {button->x, button->y, button->width, button->height}; + SDL_SetRenderDrawColor(renderer, 100, 100, 255, 255); // Button color + SDL_RenderFillRect(renderer, &buttonRect); +} + +// Private helper function to render a Text +void UIRenderer::renderText(Text * text) { + if (text->font != nullptr) { + SDL_Color sdlColor + = {text->color.red, text->color.green, text->color.blue, 255}; + SDL_Surface * textSurface + = TTF_RenderText_Blended(text->font, text->text.c_str(), sdlColor); + if (!textSurface) { + std::cerr << "Error creating text surface: " << TTF_GetError() + << std::endl; + return; + } + + SDL_Texture * textTexture + = SDL_CreateTextureFromSurface(renderer, textSurface); + if (!textTexture) { + std::cerr << "Error creating texture from surface: " + << SDL_GetError() << std::endl; + SDL_FreeSurface(textSurface); + return; + } + + SDL_Rect textRect = {text->x, text->y, textSurface->w, textSurface->h}; + SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); + SDL_FreeSurface(textSurface); + SDL_DestroyTexture(textTexture); + } +} + +void UIRenderer::renderTextInput(TextInput * textInput) { + // // Check if textInput or renderer is null to avoid segmentation faults + // if (!textInput || !renderer) { + // std::cerr << "Error: Null pointer detected for textInput or renderer." << std::endl; + // return; + // } + + // // Render the background rectangle for the text input + // SDL_Rect inputRect = {textInput->x, textInput->y, textInput->width, textInput->height}; + // SDL_SetRenderDrawColor(renderer, textInput->backgroundColor.red, textInput->backgroundColor.green, textInput->backgroundColor.blue, 255); + // SDL_RenderFillRect(renderer, &inputRect); + + // // Check if font is valid + // if (!textInput->font) { + // std::cerr << "Error: Font is not loaded for textInput." << std::endl; + // return; + // } + + // SDL_Color sdlColor = {textInput->textColor.red, textInput->textColor.green, textInput->textColor.blue, 255}; + + // if (!textInput->textBuffer.empty()) { + // // Render the text in the input field + // SDL_Surface* textSurface = TTF_RenderText_Blended(textInput->font, textInput->textBuffer.c_str(), sdlColor); + // if (textSurface) { + // SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); + // if (textTexture) { + // SDL_Rect textRect = {textInput->x + 5, textInput->y + 5, textSurface->w, textSurface->h}; + // SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); + // SDL_DestroyTexture(textTexture); + // } else { + // std::cerr << "Error: Unable to create texture from text surface." << std::endl; + // } + // SDL_FreeSurface(textSurface); + // } else { + // std::cerr << "Error: Unable to create text surface." << std::endl; + // } + // } else if (!textInput->placeholder.empty()) { + // // Render the placeholder text + // SDL_Color placeholderColor = {128, 128, 128, 255}; // Light gray for placeholder + // SDL_Surface* placeholderSurface = TTF_RenderText_Blended(textInput->font, textInput->placeholder.c_str(), placeholderColor); + // if (placeholderSurface) { + // SDL_Texture* placeholderTexture = SDL_CreateTextureFromSurface(renderer, placeholderSurface); + // if (placeholderTexture) { + // SDL_Rect placeholderRect = {textInput->x + 5, textInput->y + 5, placeholderSurface->w, placeholderSurface->h}; + // SDL_RenderCopy(renderer, placeholderTexture, nullptr, &placeholderRect); + // SDL_DestroyTexture(placeholderTexture); + // } else { + // std::cerr << "Error: Unable to create texture from placeholder surface." << std::endl; + // } + // SDL_FreeSurface(placeholderSurface); + // } else { + // std::cerr << "Error: Unable to create placeholder surface." << std::endl; + // } + // } +} diff --git a/mwe/events/src/window.cpp b/mwe/events/src/window.cpp index 41eb85f..f482b7f 100644 --- a/mwe/events/src/window.cpp +++ b/mwe/events/src/window.cpp @@ -1,29 +1,48 @@ #include "window.h" -WindowManager::WindowManager() {} +#include <iostream> + +WindowManager::WindowManager() { this->uiRenderer = nullptr; } + WindowManager::~WindowManager() { destroyWindow(); } -SDL_Renderer * WindowManager::getRenderer() { return renderer; } bool WindowManager::initWindow() { if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { - fprintf(stderr, "Error inititalising SDL.\n"); + std::cerr << "Error initializing SDL.\n"; return false; } + window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (!window) { - fprintf(stderr, "Error creating SDL Window. \n"); + std::cerr << "Error creating SDL Window.\n"; return false; } - renderer = SDL_CreateRenderer(window, -1, 0); + + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (!renderer) { - fprintf(stderr, "Error creating SDL renderer. \n"); + std::cerr << "Error creating SDL renderer.\n"; return false; } + + uiRenderer = new UIRenderer(renderer); return true; } + void WindowManager::destroyWindow() { SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); } + +SDL_Renderer * WindowManager::getRenderer() { return renderer; } +void WindowManager::addUIObject(UIObject * uiObject) { + uiObjects.push_back(uiObject); +} + +void WindowManager::renderUIObjects() { + for (UIObject * obj : uiObjects) { + uiRenderer->render(obj); + } + SDL_RenderPresent(this->renderer); +} diff --git a/mwe/gameloop/include/loopManager.h b/mwe/gameloop/include/loopManager.h index 1befb69..7d37253 100644 --- a/mwe/gameloop/include/loopManager.h +++ b/mwe/gameloop/include/loopManager.h @@ -1,11 +1,11 @@ #pragma once -#include "event.h" #include "gameObject.h" #include "window.h" #include <SDL2/SDL.h> class LoopManager { public: LoopManager(); + ~LoopManager(); void setup(); void loop(); @@ -17,7 +17,7 @@ private: void fixedUpdate(); void render(); bool gameRunning = false; - WindowManager window; + WindowManager * window; int timeScale = 1; float accumulator = 0.0; double currentTime; diff --git a/mwe/gameloop/include/timer.h b/mwe/gameloop/include/timer.h index 8273746..3c38594 100644 --- a/mwe/gameloop/include/timer.h +++ b/mwe/gameloop/include/timer.h @@ -25,7 +25,7 @@ private: double maximumDeltaTime = 0.25; double deltaTime; double frameTargetTime = FPS / 1000; - double fixedDeltaTime = 0.01; + double fixedDeltaTime = 0.02; double elapsedTime; double elapsedFixedTime; double time; diff --git a/mwe/gameloop/src/loopManager.cpp b/mwe/gameloop/src/loopManager.cpp index 0392853..49d65fb 100644 --- a/mwe/gameloop/src/loopManager.cpp +++ b/mwe/gameloop/src/loopManager.cpp @@ -1,6 +1,12 @@ #include "loopManager.h" #include "timer.h" -LoopManager::LoopManager() {} +LoopManager::LoopManager() { this->window = new WindowManager(); } +LoopManager::~LoopManager() { + for (GameObject * object : this->objectList) { + delete object; + } + delete this->window; +} void LoopManager::processInput() { SDL_Event event; SDL_PollEvent(&event); @@ -42,14 +48,14 @@ void LoopManager::loop() { timer.enforceFrameRate(); } - window.destroyWindow(); + window->destroyWindow(); } void LoopManager::setup() { - gameRunning = window.initWindow(); - LoopTimer::getInstance().start(); - LoopTimer::getInstance().setFPS(500); + LoopTimer::getInstance().start(); + LoopTimer::getInstance().setFPS(10); + this->gameRunning = true; for (int i = 1; i < 3; i++) { GameObject * square = new GameObject("square2", i * 60, i * 60, 20, 20, 0, 0); @@ -59,7 +65,7 @@ void LoopManager::setup() { void LoopManager::render() { fprintf(stderr, "**********render********** \n"); if (gameRunning) { - window.render(objectList); + window->render(objectList); } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index de9e990..e4922df 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,6 +37,7 @@ install( ) target_link_libraries(test_main + PRIVATE gtest PRIVATE gtest_main PUBLIC crepe ) diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt index 750a47d..3b05742 100644 --- a/src/crepe/CMakeLists.txt +++ b/src/crepe/CMakeLists.txt @@ -1,41 +1,23 @@ target_sources(crepe PUBLIC Asset.cpp - Sound.cpp - SoundContext.cpp Particle.cpp - ParticleSystem.cpp - SDLApp.cpp ComponentManager.cpp Component.cpp - ScriptSystem.cpp - PhysicsSystem.cpp - CollisionSystem.cpp Collider.cpp - SDLContext.cpp - RenderSystem.cpp - DB.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES Asset.h - Sound.h - SoundContext.h - SDLContext.h ComponentManager.h ComponentManager.hpp Component.h - System.h - ScriptSystem.h - PhysicsSystem.h - CollisionSystem.h Collider.h - SDLContext.h - RenderSystem.h ValueBroker.h ValueBroker.hpp - DB.h ) add_subdirectory(api) +add_subdirectory(facade) +add_subdirectory(system) add_subdirectory(util) diff --git a/src/crepe/api/AssetManager.cpp b/src/crepe/api/AssetManager.cpp index 560df6c..b891760 100644 --- a/src/crepe/api/AssetManager.cpp +++ b/src/crepe/api/AssetManager.cpp @@ -2,7 +2,7 @@ #include "AssetManager.h" -using namespace crepe::api; +using namespace crepe; AssetManager & AssetManager::get_instance() { static AssetManager instance; diff --git a/src/crepe/api/AssetManager.h b/src/crepe/api/AssetManager.h index 3e72a49..fefbed9 100644 --- a/src/crepe/api/AssetManager.h +++ b/src/crepe/api/AssetManager.h @@ -5,7 +5,7 @@ #include <string> #include <unordered_map> -namespace crepe::api { +namespace crepe { class AssetManager { @@ -30,6 +30,6 @@ public: bool reload = false); }; -} // namespace crepe::api +} // namespace crepe #include "AssetManager.hpp" diff --git a/src/crepe/api/AssetManager.hpp b/src/crepe/api/AssetManager.hpp index 468724c..977b4e1 100644 --- a/src/crepe/api/AssetManager.hpp +++ b/src/crepe/api/AssetManager.hpp @@ -2,7 +2,7 @@ #include "AssetManager.h" -namespace crepe::api { +namespace crepe { template <typename asset> std::shared_ptr<asset> AssetManager::cache(const std::string & file_path, @@ -21,4 +21,4 @@ std::shared_ptr<asset> AssetManager::cache(const std::string & file_path, return new_asset; } -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/AudioSource.cpp b/src/crepe/api/AudioSource.cpp index 35b8d83..63fd0d7 100644 --- a/src/crepe/api/AudioSource.cpp +++ b/src/crepe/api/AudioSource.cpp @@ -1,10 +1,10 @@ #include <memory> -#include "../Sound.h" +#include "../facade/Sound.h" #include "AudioSource.h" -using namespace crepe::api; +using namespace crepe; AudioSource::AudioSource(std::unique_ptr<Asset> audio_clip) { this->sound = std::make_unique<crepe::Sound>(std::move(audio_clip)); diff --git a/src/crepe/api/AudioSource.h b/src/crepe/api/AudioSource.h index 7980212..42add50 100644 --- a/src/crepe/api/AudioSource.h +++ b/src/crepe/api/AudioSource.h @@ -6,10 +6,8 @@ #include "../Component.h" namespace crepe { -class Sound; -} -namespace crepe::api { +class Sound; //! Audio source component class AudioSource : Component { @@ -35,7 +33,7 @@ public: float volume; private: - std::unique_ptr<crepe::Sound> sound; + std::unique_ptr<Sound> sound; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h index 6133cc8..21638f4 100644 --- a/src/crepe/api/BehaviorScript.h +++ b/src/crepe/api/BehaviorScript.h @@ -9,7 +9,7 @@ class ScriptSystem; class ComponentManager; } // namespace crepe -namespace crepe::api { +namespace crepe { class Script; @@ -30,6 +30,6 @@ protected: std::unique_ptr<Script> script = nullptr; }; -} // namespace crepe::api +} // namespace crepe #include "BehaviorScript.hpp" diff --git a/src/crepe/api/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp index 2a3502f..4751607 100644 --- a/src/crepe/api/BehaviorScript.hpp +++ b/src/crepe/api/BehaviorScript.hpp @@ -7,7 +7,7 @@ #include "BehaviorScript.h" #include "Script.h" -namespace crepe::api { +namespace crepe { template <class T> BehaviorScript & BehaviorScript::set_script() { @@ -19,4 +19,4 @@ BehaviorScript & BehaviorScript::set_script() { return *this; } -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h index 762574b..931b012 100644 --- a/src/crepe/api/CircleCollider.h +++ b/src/crepe/api/CircleCollider.h @@ -1,7 +1,7 @@ #pragma once #include "../Collider.h" -namespace crepe::api { +namespace crepe { class CircleCollider : public Collider { public: @@ -10,4 +10,4 @@ public: int radius; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Color.cpp b/src/crepe/api/Color.cpp index fb5bd1a..fc6313d 100644 --- a/src/crepe/api/Color.cpp +++ b/src/crepe/api/Color.cpp @@ -1,6 +1,6 @@ #include "Color.h" -using namespace crepe::api; +using namespace crepe; Color Color::white = Color(255, 255, 255, 0); Color Color::red = Color(255, 0, 0, 0); diff --git a/src/crepe/api/Color.h b/src/crepe/api/Color.h index e818de4..6b54888 100644 --- a/src/crepe/api/Color.h +++ b/src/crepe/api/Color.h @@ -1,6 +1,6 @@ #pragma once -namespace crepe::api { +namespace crepe { class Color { @@ -34,4 +34,4 @@ private: static Color black; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h index aef4d54..4e6d1fa 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -2,7 +2,7 @@ #include "../util/log.h" -namespace crepe::api { +namespace crepe { class Config { private: @@ -27,7 +27,7 @@ public: * Only messages with equal or higher priority than this value will be * logged. */ - util::LogLevel level = util::LogLevel::INFO; + LogLevel level = LogLevel::INFO; /** * \brief Colored log output * @@ -42,4 +42,4 @@ public: } savemgr; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Force.cpp b/src/crepe/api/Force.cpp index e359adc..3c33ad3 100644 --- a/src/crepe/api/Force.cpp +++ b/src/crepe/api/Force.cpp @@ -2,7 +2,7 @@ #include "Force.h" -namespace crepe::api { +namespace crepe { Force::Force(uint32_t game_object_id, uint32_t magnitude, uint32_t direction) : Component(game_object_id) { @@ -18,4 +18,4 @@ Force::Force(uint32_t game_object_id, uint32_t magnitude, uint32_t direction) std::round(magnitude * std::sin(radian_direction))); } -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Force.h b/src/crepe/api/Force.h index 8da9a00..c08a8b9 100644 --- a/src/crepe/api/Force.h +++ b/src/crepe/api/Force.h @@ -4,7 +4,7 @@ #include "../Component.h" -namespace crepe::api { +namespace crepe { class Force : public Component { public: @@ -14,4 +14,4 @@ public: int32_t force_y; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/GameObject.cpp b/src/crepe/api/GameObject.cpp index b167187..445a60d 100644 --- a/src/crepe/api/GameObject.cpp +++ b/src/crepe/api/GameObject.cpp @@ -1,6 +1,6 @@ #include "GameObject.h" -using namespace crepe::api; +using namespace crepe; using namespace std; GameObject::GameObject(uint32_t id, string name, string tag, int layer) diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h index 57508c5..b5d6399 100644 --- a/src/crepe/api/GameObject.h +++ b/src/crepe/api/GameObject.h @@ -3,7 +3,7 @@ #include <cstdint> #include <string> -namespace crepe::api { +namespace crepe { class GameObject { public: @@ -19,6 +19,6 @@ public: int layer; }; -} // namespace crepe::api +} // namespace crepe #include "GameObject.hpp" diff --git a/src/crepe/api/GameObject.hpp b/src/crepe/api/GameObject.hpp index 3c7e867..77cf40e 100644 --- a/src/crepe/api/GameObject.hpp +++ b/src/crepe/api/GameObject.hpp @@ -4,7 +4,7 @@ #include "GameObject.h" -namespace crepe::api { +namespace crepe { template <typename T, typename... Args> T & GameObject::add_component(Args &&... args) { @@ -12,4 +12,4 @@ T & GameObject::add_component(Args &&... args) { return mgr.add_component<T>(this->id, std::forward<Args>(args)...); } -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Point.h b/src/crepe/api/Point.h index b47b7e6..575d624 100644 --- a/src/crepe/api/Point.h +++ b/src/crepe/api/Point.h @@ -1,6 +1,6 @@ #pragma once -namespace crepe::api { +namespace crepe { class Point { public: @@ -8,4 +8,4 @@ public: double y; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Rigidbody.cpp b/src/crepe/api/Rigidbody.cpp index ebf9fb9..0a6262a 100644 --- a/src/crepe/api/Rigidbody.cpp +++ b/src/crepe/api/Rigidbody.cpp @@ -1,6 +1,6 @@ #include "Rigidbody.h" -using namespace crepe::api; +using namespace crepe; Rigidbody::Rigidbody(uint32_t game_object_id, int mass, int gravity_scale, BodyType bodyType) diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 6079a76..518ed94 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -4,7 +4,7 @@ #include "../Component.h" -namespace crepe::api { +namespace crepe { // FIXME: can't this enum be defined inside the class declaration of Rigidbody? enum class BodyType { @@ -27,4 +27,4 @@ public: BodyType body_type; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/SaveManager.cpp b/src/crepe/api/SaveManager.cpp index 87e634b..d35fc7b 100644 --- a/src/crepe/api/SaveManager.cpp +++ b/src/crepe/api/SaveManager.cpp @@ -1,4 +1,4 @@ -#include "../DB.h" +#include "../facade/DB.h" #include "../util/log.h" #include "Config.h" @@ -7,7 +7,6 @@ using namespace std; using namespace crepe; -using namespace crepe::api; template <> string SaveManager::serialize(const string & value) { diff --git a/src/crepe/api/SaveManager.h b/src/crepe/api/SaveManager.h index a1f239d..035e2b7 100644 --- a/src/crepe/api/SaveManager.h +++ b/src/crepe/api/SaveManager.h @@ -5,10 +5,8 @@ #include "../ValueBroker.h" namespace crepe { -class DB; -} -namespace crepe::api { +class DB; class SaveManager { public: diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp index 5016ed0..390cec7 100644 --- a/src/crepe/api/Script.cpp +++ b/src/crepe/api/Script.cpp @@ -1,3 +1,3 @@ #include "Script.h" -using namespace crepe::api; +using namespace crepe; diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 59e6ec0..49e625f 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -6,7 +6,7 @@ namespace crepe { class ScriptSystem; } -namespace crepe::api { +namespace crepe { class BehaviorScript; @@ -29,10 +29,10 @@ protected: std::vector<std::reference_wrapper<T>> get_components(); private: - friend class crepe::api::BehaviorScript; + friend class crepe::BehaviorScript; BehaviorScript * parent = nullptr; }; -} // namespace crepe::api +} // namespace crepe #include "Script.hpp" diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp index 8004fe3..d96c0e8 100644 --- a/src/crepe/api/Script.hpp +++ b/src/crepe/api/Script.hpp @@ -5,7 +5,7 @@ #include "BehaviorScript.h" #include "Script.h" -namespace crepe::api { +namespace crepe { template <typename T> T & Script::get_component() { @@ -22,4 +22,4 @@ std::vector<std::reference_wrapper<T>> Script::get_components() { return mgr.get_components_by_id<T>(this->parent->game_object_id); } -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp index 806f147..3dd44f2 100644 --- a/src/crepe/api/Sprite.cpp +++ b/src/crepe/api/Sprite.cpp @@ -1,15 +1,14 @@ #include <cstdint> #include <memory> -#include "api/Texture.h" -#include "util/log.h" +#include "../util/log.h" #include "Component.h" #include "Sprite.h" +#include "Texture.h" using namespace std; using namespace crepe; -using namespace crepe::api; Sprite::Sprite(uint32_t id, shared_ptr<Texture> image, const Color & color, const FlipSettings & flip) diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h index b06125e..bdb4da9 100644 --- a/src/crepe/api/Sprite.h +++ b/src/crepe/api/Sprite.h @@ -9,7 +9,7 @@ #include "Component.h" -namespace crepe::api { +namespace crepe { struct FlipSettings { bool flip_x = 1; @@ -29,4 +29,4 @@ public: uint8_t order_in_layer; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp index 481ef7c..8fc5c13 100644 --- a/src/crepe/api/Texture.cpp +++ b/src/crepe/api/Texture.cpp @@ -1,12 +1,12 @@ #include <SDL2/SDL_render.h> -#include "util/log.h" +#include "../facade/SDLContext.h" +#include "../util/log.h" #include "Asset.h" -#include "SDLContext.h" #include "Texture.h" -using namespace crepe::api; +using namespace crepe; using namespace std; Texture::Texture(unique_ptr<Asset> res) { diff --git a/src/crepe/api/Texture.h b/src/crepe/api/Texture.h index f8481e3..9a86f6f 100644 --- a/src/crepe/api/Texture.h +++ b/src/crepe/api/Texture.h @@ -12,7 +12,7 @@ namespace crepe { class SDLContext; } -namespace crepe::api { +namespace crepe { class Texture { @@ -30,4 +30,4 @@ private: friend class crepe::SDLContext; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp index 3b218bc..70b16bd 100644 --- a/src/crepe/api/Transform.cpp +++ b/src/crepe/api/Transform.cpp @@ -6,9 +6,10 @@ #include "Component.h" #include "Transform.h" -using namespace crepe::api; +using namespace crepe; -Transform::Transform(uint32_t game_id, const Point & point, double rot, double scale) +Transform::Transform(uint32_t game_id, const Point & point, double rot, + double scale) : Component(game_id), position(point), rotation(rot), scale(scale) { dbg_trace(); } diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h index c451c16..d416088 100644 --- a/src/crepe/api/Transform.h +++ b/src/crepe/api/Transform.h @@ -6,7 +6,7 @@ #include "Component.h" -namespace crepe::api { +namespace crepe { class Transform : public Component { // FIXME: What's the difference between the `Point` and `Position` @@ -24,4 +24,4 @@ public: double scale; }; -} // namespace crepe::api +} // namespace crepe diff --git a/src/crepe/facade/CMakeLists.txt b/src/crepe/facade/CMakeLists.txt new file mode 100644 index 0000000..bb52e7a --- /dev/null +++ b/src/crepe/facade/CMakeLists.txt @@ -0,0 +1,16 @@ +target_sources(crepe PUBLIC + Sound.cpp + SoundContext.cpp + SDLApp.cpp + SDLContext.cpp + DB.cpp +) + +target_sources(crepe PUBLIC FILE_SET HEADERS FILES + Sound.h + SoundContext.h + SDLContext.h + SDLContext.h + DB.h +) + diff --git a/src/crepe/DB.cpp b/src/crepe/facade/DB.cpp index bd2f089..bd2f089 100644 --- a/src/crepe/DB.cpp +++ b/src/crepe/facade/DB.cpp diff --git a/src/crepe/DB.h b/src/crepe/facade/DB.h index 06442ad..06442ad 100644 --- a/src/crepe/DB.h +++ b/src/crepe/facade/DB.h diff --git a/src/crepe/SDLApp.cpp b/src/crepe/facade/SDLApp.cpp index c6ddeaa..c6ddeaa 100644 --- a/src/crepe/SDLApp.cpp +++ b/src/crepe/facade/SDLApp.cpp diff --git a/src/crepe/SDLApp.h b/src/crepe/facade/SDLApp.h index e67947b..6d8f3f4 100644 --- a/src/crepe/SDLApp.h +++ b/src/crepe/facade/SDLApp.h @@ -2,7 +2,7 @@ #include <SDL2/SDL.h> -#include "api/ParticleEmitter.h" +#include "../api/ParticleEmitter.h" class SDLApp { public: diff --git a/src/crepe/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 8bc5bc6..8da93e9 100644 --- a/src/crepe/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -7,10 +7,10 @@ #include <cstddef> #include <iostream> -#include "api/Sprite.h" -#include "api/Texture.h" -#include "api/Transform.h" -#include "util/log.h" +#include "../api/Sprite.h" +#include "../api/Texture.h" +#include "../api/Transform.h" +#include "../util/log.h" #include "SDLContext.h" @@ -89,8 +89,7 @@ SDLContext::SDLContext() { void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer); } -void SDLContext::draw(const api::Sprite & sprite, - const api::Transform & transform) { +void SDLContext::draw(const Sprite & sprite, const Transform & transform) { static SDL_RendererFlip render_flip = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) diff --git a/src/crepe/SDLContext.h b/src/crepe/facade/SDLContext.h index 4d9c1bc..f1ba8a6 100644 --- a/src/crepe/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -3,17 +3,13 @@ #include <SDL2/SDL_render.h> #include <SDL2/SDL_video.h> -#include "api/Sprite.h" -#include "api/Transform.h" - -#include "RenderSystem.h" - -namespace crepe::api { -class Texture; -} +#include "../api/Sprite.h" +#include "../api/Transform.h" +#include "../system/RenderSystem.h" namespace crepe { +class Texture; class SDLContext { public: @@ -34,13 +30,13 @@ private: virtual ~SDLContext(); private: - friend class api::Texture; + friend class Texture; SDL_Texture * texture_from_path(const char *); //SDL_Texture* setTextureFromPath(const char*, SDL_Rect& clip, const int row, const int col); private: friend class RenderSystem; - void draw(const api::Sprite &, const api::Transform &); + void draw(const Sprite &, const Transform &); void clear_screen(); void present_screen(); diff --git a/src/crepe/Sound.cpp b/src/crepe/facade/Sound.cpp index 64fa281..648ec81 100644 --- a/src/crepe/Sound.cpp +++ b/src/crepe/facade/Sound.cpp @@ -1,4 +1,4 @@ -#include "util/log.h" +#include "../util/log.h" #include "Sound.h" #include "SoundContext.h" diff --git a/src/crepe/Sound.h b/src/crepe/facade/Sound.h index 917b57e..183bd7c 100644 --- a/src/crepe/Sound.h +++ b/src/crepe/facade/Sound.h @@ -4,7 +4,7 @@ #include <soloud/soloud.h> #include <soloud/soloud_wav.h> -#include "Asset.h" +#include "../Asset.h" namespace crepe { diff --git a/src/crepe/SoundContext.cpp b/src/crepe/facade/SoundContext.cpp index 72047d2..5e5a3a9 100644 --- a/src/crepe/SoundContext.cpp +++ b/src/crepe/facade/SoundContext.cpp @@ -1,4 +1,4 @@ -#include "util/log.h" +#include "../util/log.h" #include "SoundContext.h" diff --git a/src/crepe/SoundContext.h b/src/crepe/facade/SoundContext.h index d3123d2..d3123d2 100644 --- a/src/crepe/SoundContext.h +++ b/src/crepe/facade/SoundContext.h diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt new file mode 100644 index 0000000..ff6f66f --- /dev/null +++ b/src/crepe/system/CMakeLists.txt @@ -0,0 +1,15 @@ +target_sources(crepe PUBLIC + ParticleSystem.cpp + ScriptSystem.cpp + PhysicsSystem.cpp + CollisionSystem.cpp + RenderSystem.cpp +) + +target_sources(crepe PUBLIC FILE_SET HEADERS FILES + System.h + ScriptSystem.h + PhysicsSystem.h + CollisionSystem.h + RenderSystem.h +) diff --git a/src/crepe/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 55e0fdc..55e0fdc 100644 --- a/src/crepe/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp diff --git a/src/crepe/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 1e9f1aa..1e9f1aa 100644 --- a/src/crepe/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h diff --git a/src/crepe/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp index af6c550..397b586 100644 --- a/src/crepe/ParticleSystem.cpp +++ b/src/crepe/system/ParticleSystem.cpp @@ -1,9 +1,9 @@ #include <cmath> #include <ctime> -#include "api/ParticleEmitter.h" +#include "../ComponentManager.h" +#include "../api/ParticleEmitter.h" -#include "ComponentManager.h" #include "ParticleSystem.h" using namespace crepe; diff --git a/src/crepe/ParticleSystem.h b/src/crepe/system/ParticleSystem.h index ad96eb0..3ac1d3f 100644 --- a/src/crepe/ParticleSystem.h +++ b/src/crepe/system/ParticleSystem.h @@ -1,6 +1,6 @@ #pragma once -#include "api/ParticleEmitter.h" +#include "../api/ParticleEmitter.h" namespace crepe { diff --git a/src/crepe/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp index 16f4c10..cea8062 100644 --- a/src/crepe/PhysicsSystem.cpp +++ b/src/crepe/system/PhysicsSystem.cpp @@ -1,14 +1,13 @@ #include <iostream> -#include "api/Force.h" -#include "api/Rigidbody.h" -#include "api/Transform.h" +#include "../ComponentManager.h" +#include "../api/Force.h" +#include "../api/Rigidbody.h" +#include "../api/Transform.h" -#include "ComponentManager.h" #include "PhysicsSystem.h" using namespace crepe; -using namespace crepe::api; PhysicsSystem::PhysicsSystem() {} diff --git a/src/crepe/PhysicsSystem.h b/src/crepe/system/PhysicsSystem.h index 33b4072..33b4072 100644 --- a/src/crepe/PhysicsSystem.h +++ b/src/crepe/system/PhysicsSystem.h diff --git a/src/crepe/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index fae93f0..96c94e9 100644 --- a/src/crepe/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,16 +1,15 @@ #include <functional> #include <vector> -#include "api/Sprite.h" -#include "api/Transform.h" -#include "util/log.h" +#include "../ComponentManager.h" +#include "../facade/SDLContext.h" +#include "../api/Sprite.h" +#include "../api/Transform.h" +#include "../util/log.h" -#include "ComponentManager.h" #include "RenderSystem.h" -#include "SDLContext.h" using namespace crepe; -using namespace crepe::api; RenderSystem::RenderSystem() { dbg_trace(); } diff --git a/src/crepe/RenderSystem.h b/src/crepe/system/RenderSystem.h index 4b910a4..4b910a4 100644 --- a/src/crepe/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h diff --git a/src/crepe/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp index 171b490..f1fae4d 100644 --- a/src/crepe/ScriptSystem.cpp +++ b/src/crepe/system/ScriptSystem.cpp @@ -2,16 +2,15 @@ #include <functional> #include <vector> -#include "api/BehaviorScript.h" -#include "api/Script.h" -#include "util/log.h" +#include "../ComponentManager.h" +#include "../api/BehaviorScript.h" +#include "../api/Script.h" +#include "../util/log.h" -#include "ComponentManager.h" #include "ScriptSystem.h" using namespace std; using namespace crepe; -using namespace crepe::api; ScriptSystem::ScriptSystem() { dbg_trace(); } ScriptSystem::~ScriptSystem() { dbg_trace(); } diff --git a/src/crepe/ScriptSystem.h b/src/crepe/system/ScriptSystem.h index 1f472a0..32e793c 100644 --- a/src/crepe/ScriptSystem.h +++ b/src/crepe/system/ScriptSystem.h @@ -4,12 +4,10 @@ #include "System.h" -namespace crepe::api { -class Script; -} - namespace crepe { +class Script; + class ScriptSystem : public System { public: static ScriptSystem & get_instance(); @@ -20,7 +18,8 @@ private: ~ScriptSystem(); private: - std::forward_list<api::Script *> get_scripts(); + // TODO: to forward_list<reference_wrapper> + std::forward_list<Script *> get_scripts(); }; } // namespace crepe diff --git a/src/crepe/System.h b/src/crepe/system/System.h index ecbb7f5..ecbb7f5 100644 --- a/src/crepe/System.h +++ b/src/crepe/system/System.h diff --git a/src/crepe/util/CMakeLists.txt b/src/crepe/util/CMakeLists.txt index 01d8f22..0fa4343 100644 --- a/src/crepe/util/CMakeLists.txt +++ b/src/crepe/util/CMakeLists.txt @@ -1,11 +1,11 @@ target_sources(crepe PUBLIC - color.cpp + LogColor.cpp log.cpp fmt.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES - color.h + LogColor.h log.h fmt.h Proxy.h diff --git a/src/crepe/util/color.cpp b/src/crepe/util/LogColor.cpp index a7bbc81..b5fe3ea 100644 --- a/src/crepe/util/color.cpp +++ b/src/crepe/util/LogColor.cpp @@ -1,16 +1,17 @@ #include <cstdarg> #include "../api/Config.h" -#include "color.h" +#include "LogColor.h" + #include "fmt.h" -using namespace crepe::util; +using namespace crepe; using namespace std; static constexpr const char * RESET_CODE = "\e[0m"; const string LogColor::str(const string & content) { - auto & cfg = api::Config::get_instance(); + auto & cfg = Config::get_instance(); string out = content; if (cfg.log.color) out = this->code + out; if (content.size() == 0) return out; diff --git a/src/crepe/util/color.h b/src/crepe/util/LogColor.h index 91e1abe..c1170cb 100644 --- a/src/crepe/util/color.h +++ b/src/crepe/util/LogColor.h @@ -2,7 +2,7 @@ #include <string> -namespace crepe::util { +namespace crepe { class LogColor { public: @@ -48,4 +48,4 @@ private: std::string final = ""; }; -} // namespace crepe::util +} // namespace crepe diff --git a/src/crepe/util/Proxy.h b/src/crepe/util/Proxy.h index 89cb3c3..65db04d 100644 --- a/src/crepe/util/Proxy.h +++ b/src/crepe/util/Proxy.h @@ -2,13 +2,13 @@ #include "ValueBroker.h" -namespace crepe::util { +namespace crepe { template <typename T> class Proxy { public: Proxy & operator = (const T &); - operator const T & () const; + operator const T & (); public: Proxy(ValueBroker<T>); diff --git a/src/crepe/util/Proxy.hpp b/src/crepe/util/Proxy.hpp index c2cae93..4aec9e9 100644 --- a/src/crepe/util/Proxy.hpp +++ b/src/crepe/util/Proxy.hpp @@ -2,7 +2,7 @@ #include "Proxy.h" -namespace crepe::util { +namespace crepe { template <typename T> Proxy<T>::Proxy(ValueBroker<T> broker) : broker(broker) { } @@ -14,7 +14,7 @@ Proxy<T> & Proxy<T>::operator = (const T & val) { } template <typename T> -Proxy<T>::operator const T & () const { +Proxy<T>::operator const T & () { return this->broker.get(); } diff --git a/src/crepe/util/fmt.cpp b/src/crepe/util/fmt.cpp index 8ef1164..4b50da8 100644 --- a/src/crepe/util/fmt.cpp +++ b/src/crepe/util/fmt.cpp @@ -6,25 +6,27 @@ using namespace std; -string crepe::util::va_stringf(va_list args, const char * fmt) { +string crepe::va_stringf(va_list args, const char * fmt) { + string out; + va_list args_copy; va_copy(args_copy, args); - - size_t sz = vsnprintf(NULL, 0, fmt, args_copy) + 1; - char * msg = (char *) malloc(sz); + size_t length = vsnprintf(NULL, 0, fmt, args_copy); + // resize to include terminating null byte + out.resize(length + 1); va_end(args_copy); - vsnprintf(msg, sz, fmt, args); - - string out = msg; - free(msg); + // vsnprintf adds terminating null byte + vsnprintf(out.data(), out.size(), fmt, args); + // resize to actual length + out.resize(length); va_end(args); return out; } -string crepe::util::stringf(const char * fmt, ...) { +string crepe::stringf(const char * fmt, ...) { va_list args; va_start(args, fmt); string out = va_stringf(args, fmt); diff --git a/src/crepe/util/fmt.h b/src/crepe/util/fmt.h index 44c426f..e319e6e 100644 --- a/src/crepe/util/fmt.h +++ b/src/crepe/util/fmt.h @@ -2,9 +2,9 @@ #include <string> -namespace crepe::util { +namespace crepe { std::string va_stringf(va_list args, const char * fmt); std::string stringf(const char * fmt, ...); -} // namespace crepe::util +} // namespace crepe diff --git a/src/crepe/util/log.cpp b/src/crepe/util/log.cpp index 6bcc4ae..4a8f8e8 100644 --- a/src/crepe/util/log.cpp +++ b/src/crepe/util/log.cpp @@ -7,7 +7,7 @@ #include "fmt.h" #include "log.h" -using namespace crepe::util; +using namespace crepe; using namespace std; string log_prefix(LogLevel level) { @@ -27,25 +27,25 @@ string log_prefix(LogLevel level) { } static void log(LogLevel level, const string msg) { - auto & cfg = crepe::api::Config::get_instance(); + auto & cfg = Config::get_instance(); if (level < cfg.log.level) return; string out = log_prefix(level) + msg; if (!out.ends_with("\n")) out += "\n"; // TODO: also log to file or smth - printf("%s", out.c_str()); + fwrite(out.c_str(), 1, out.size(), stdout); fflush(stdout); } -void crepe::util::logf(const char * fmt, ...) { +void crepe::logf(const char * fmt, ...) { va_list args; va_start(args, fmt); log(LogLevel::DEBUG, va_stringf(args, fmt)); va_end(args); } -void crepe::util::logf(LogLevel level, const char * fmt, ...) { +void crepe::logf(LogLevel level, const char * fmt, ...) { va_list args; va_start(args, fmt); log(level, va_stringf(args, fmt)); diff --git a/src/crepe/util/log.h b/src/crepe/util/log.h index 308ba96..5a1cf00 100644 --- a/src/crepe/util/log.h +++ b/src/crepe/util/log.h @@ -3,28 +3,27 @@ // allow user to disable debug macros #ifndef CREPE_DISABLE_MACROS -#include "color.h" +#include "LogColor.h" // utility macros #define _crepe_logf_here(level, format, ...) \ - crepe::util::logf( \ + crepe::logf( \ level, "%s" format, \ - crepe::util::LogColor().fg_white(false).fmt( \ + crepe::LogColor().fg_white(false).fmt( \ "%s (%s:%d)", __PRETTY_FUNCTION__, __FILE_NAME__, __LINE__), \ __VA_ARGS__) // very illegal global function-style macros // NOLINTBEGIN #define dbg_logf(fmt, ...) \ - _crepe_logf_here(crepe::util::LogLevel::DEBUG, ": " fmt, __VA_ARGS__) -#define dbg_log(str) \ - _crepe_logf_here(crepe::util::LogLevel::DEBUG, "%s: " str, "") -#define dbg_trace() _crepe_logf_here(crepe::util::LogLevel::TRACE, "%s", "") + _crepe_logf_here(crepe::LogLevel::DEBUG, ": " fmt, __VA_ARGS__) +#define dbg_log(str) _crepe_logf_here(crepe::LogLevel::DEBUG, "%s: " str, "") +#define dbg_trace() _crepe_logf_here(crepe::LogLevel::TRACE, "%s", "") // NOLINTEND #endif -namespace crepe::util { +namespace crepe { enum LogLevel { TRACE, @@ -37,4 +36,4 @@ enum LogLevel { void logf(const char * fmt, ...); void logf(enum LogLevel level, const char * fmt, ...); -} // namespace crepe::util +} // namespace crepe diff --git a/src/example/asset_manager.cpp b/src/example/asset_manager.cpp index 7e15d1f..ba18b62 100644 --- a/src/example/asset_manager.cpp +++ b/src/example/asset_manager.cpp @@ -1,11 +1,9 @@ - - -#include <crepe/Sound.h> +#include <crepe/facade/Sound.h> #include <crepe/api/AssetManager.h> #include <crepe/api/Texture.h> using namespace crepe; -using namespace crepe::api; + int main() { // this needs to be called before the asset manager otherwise the destructor diff --git a/src/example/audio_internal.cpp b/src/example/audio_internal.cpp index f35ad9d..0b36daa 100644 --- a/src/example/audio_internal.cpp +++ b/src/example/audio_internal.cpp @@ -3,29 +3,26 @@ * Standalone example for usage of the internal \c Sound class. */ -#include <crepe/Sound.h> -#include <crepe/util/log.h> +#include <crepe/facade/Sound.h> #include <crepe/api/Config.h> +#include <crepe/util/log.h> #include <thread> using namespace crepe; -using namespace crepe::api; using namespace std; using namespace std::chrono_literals; using std::make_unique; // Unrelated stuff that is not part of this POC -int _ = [] () { +int _ = []() { // Show dbg_trace() output - auto & cfg = api::Config::get_instance(); - cfg.log.level = util::LogLevel::TRACE; + auto & cfg = Config::get_instance(); + cfg.log.level = LogLevel::TRACE; return 0; // satisfy compiler }(); - - int main() { // Load a background track (Ogg Vorbis) auto bgm = Sound("../mwe/audio/bgm.ogg"); diff --git a/src/example/components_internal.cpp b/src/example/components_internal.cpp index 3c68974..ea1eaad 100644 --- a/src/example/components_internal.cpp +++ b/src/example/components_internal.cpp @@ -15,7 +15,6 @@ #include <crepe/util/log.h> -using namespace crepe::api; using namespace crepe; using namespace std; diff --git a/src/example/db.cpp b/src/example/db.cpp index b1ab196..c046421 100644 --- a/src/example/db.cpp +++ b/src/example/db.cpp @@ -1,4 +1,4 @@ -#include <crepe/DB.h> +#include <crepe/facade/DB.h> #include <crepe/api/Config.h> #include <crepe/util/log.h> @@ -7,8 +7,8 @@ using namespace std; // run before main static auto _ = [] () { - auto & cfg = api::Config::get_instance(); - cfg.log.level = util::LogLevel::TRACE; + auto & cfg = Config::get_instance(); + cfg.log.level = LogLevel::TRACE; return 0; }(); diff --git a/src/example/log.cpp b/src/example/log.cpp index 04ab9cd..db8aa48 100644 --- a/src/example/log.cpp +++ b/src/example/log.cpp @@ -7,16 +7,15 @@ #include <crepe/util/log.h> using namespace crepe; -using namespace crepe::util; // unrelated setup code -int _ = [] () { +int _ = []() { // make sure all log messages get printed - auto & cfg = api::Config::get_instance(); - cfg.log.level = util::LogLevel::TRACE; + auto & cfg = Config::get_instance(); + cfg.log.level = LogLevel::TRACE; return 0; // satisfy compiler -} (); +}(); int main() { dbg_trace(); diff --git a/src/example/particle.cpp b/src/example/particle.cpp index 53fa213..83b1e8a 100644 --- a/src/example/particle.cpp +++ b/src/example/particle.cpp @@ -1,15 +1,15 @@ -#include "Particle.h" -#include "ParticleSystem.h" -#include "SDLApp.h" -#include "api/ParticleEmitter.h" #include <chrono> +#include <iostream> +#include <thread> + #include <crepe/Component.h> #include <crepe/ComponentManager.h> +#include <crepe/Particle.h> +#include <crepe/facade/SDLApp.h> #include <crepe/api/GameObject.h> -#include <iostream> -#include <thread> +#include <crepe/api/ParticleEmitter.h> +#include <crepe/system/ParticleSystem.h> -using namespace crepe::api; using namespace crepe; using namespace std; diff --git a/src/example/physics.cpp b/src/example/physics.cpp index db69b9b..2dbddc2 100644 --- a/src/example/physics.cpp +++ b/src/example/physics.cpp @@ -1,15 +1,15 @@ -#include "PhysicsSystem.h" #include <chrono> +#include <iostream> +#include <thread> + #include <crepe/Component.h> #include <crepe/ComponentManager.h> #include <crepe/api/Force.h> #include <crepe/api/GameObject.h> #include <crepe/api/Rigidbody.h> #include <crepe/api/Transform.h> -#include <iostream> -#include <thread> +#include <crepe/system/PhysicsSystem.h> -using namespace crepe::api; using namespace crepe; using namespace std; diff --git a/src/example/proxy.cpp b/src/example/proxy.cpp index 0be4fac..9f54f96 100644 --- a/src/example/proxy.cpp +++ b/src/example/proxy.cpp @@ -3,22 +3,21 @@ * Standalone example for usage of the proxy type */ -#include "ValueBroker.h" +#include <crepe/ValueBroker.h> #include <crepe/api/Config.h> #include <crepe/util/log.h> #include <crepe/util/Proxy.h> using namespace std; using namespace crepe; -using namespace crepe::util; void test_ro_ref(const int & val) { } void test_rw_ref(int & val) { } void test_ro_val(int val) { } int main() { - auto & cfg = api::Config::get_instance(); - cfg.log.level = util::LogLevel::DEBUG; + auto & cfg = Config::get_instance(); + cfg.log.level = LogLevel::DEBUG; int real_value = 0; diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp index 1bf448c..b0ab60a 100644 --- a/src/example/rendering.cpp +++ b/src/example/rendering.cpp @@ -1,8 +1,6 @@ - - #include <crepe/ComponentManager.h> -#include <crepe/RenderSystem.h> #include <crepe/api/GameObject.h> +#include <crepe/system/RenderSystem.h> #include <crepe/util/log.h> #include <crepe/api/AssetManager.h> @@ -17,7 +15,6 @@ using namespace std; using namespace crepe; -using namespace crepe::api; int main() { diff --git a/src/example/savemgr.cpp b/src/example/savemgr.cpp index 6d011e5..c8dd2bc 100644 --- a/src/example/savemgr.cpp +++ b/src/example/savemgr.cpp @@ -10,14 +10,12 @@ #include <crepe/api/Config.h> using namespace crepe; -using namespace crepe::api; -using namespace crepe::util; // unrelated setup code int _ = [] () { // make sure all log messages get printed auto & cfg = Config::get_instance(); - cfg.log.level = util::LogLevel::TRACE; + cfg.log.level = LogLevel::TRACE; return 0; // satisfy compiler } (); diff --git a/src/example/script.cpp b/src/example/script.cpp index cda9591..dac7af3 100644 --- a/src/example/script.cpp +++ b/src/example/script.cpp @@ -4,7 +4,7 @@ */ #include <crepe/ComponentManager.h> -#include <crepe/ScriptSystem.h> +#include <crepe/system/ScriptSystem.h> #include <crepe/util/log.h> #include <crepe/api/BehaviorScript.h> @@ -14,20 +14,17 @@ #include <crepe/api/Transform.h> using namespace crepe; -using namespace crepe::api; using namespace std; // Unrelated stuff that is not part of this POC -int _ = [] () { +int _ = []() { // Show dbg_trace() output - auto & cfg = api::Config::get_instance(); - cfg.log.level = util::LogLevel::TRACE; + auto & cfg = Config::get_instance(); + cfg.log.level = LogLevel::TRACE; return 0; // satisfy compiler }(); - - // User-defined script: class MyScript : public Script { void update() { @@ -40,7 +37,12 @@ class MyScript : public Script { int main() { // Create game object with Transform and BehaviorScript components auto obj = GameObject(0, "name", "tag", 0); - obj.add_component<Transform>(Point { .x = 1.2, .y = 3.4, }, 0, 0); + obj.add_component<Transform>( + Point{ + .x = 1.2, + .y = 3.4, + }, + 0, 0); obj.add_component<BehaviorScript>().set_script<MyScript>(); // Get ScriptSystem singleton instance (this would normally be done from the @@ -51,4 +53,3 @@ int main() { return EXIT_SUCCESS; } - |