diff --git a/contrib/assimp b/contrib/assimp index f81ea6986..10df90ec1 160000 --- a/contrib/assimp +++ b/contrib/assimp @@ -1 +1 @@ -Subproject commit f81ea6986ccd30a016ec44a1fd46e2e5c3ff9d4c +Subproject commit 10df90ec144179f97803a382e4f07c0570665864 diff --git a/src/Engine/Animation/AnimatorComponent.h b/src/Engine/Animation/AnimatorComponent.h index eeaf84525..6bcc65904 100644 --- a/src/Engine/Animation/AnimatorComponent.h +++ b/src/Engine/Animation/AnimatorComponent.h @@ -49,12 +49,12 @@ struct AnimationTrack { //------------------------------------------------------------------------------------------------- /// @ingroup Engine /// -/// @brief Describes the base class for all components. +/// @brief //------------------------------------------------------------------------------------------------- class AnimatorComponent : public App::Component { public: AnimatorComponent(App::Entity *owner, App::ComponentType type); - ~AnimatorComponent(); + ~AnimatorComponent() override; void addTrack(AnimationTrack *track); AnimationTrack *getTrackAt(size_t index) const; bool selectTrack(size_t index); diff --git a/src/Engine/App/AppBase.cpp b/src/Engine/App/AppBase.cpp index 885a861a4..07b20879d 100644 --- a/src/Engine/App/AppBase.cpp +++ b/src/Engine/App/AppBase.cpp @@ -27,7 +27,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "App/ResourceCacheService.h" #include "App/ServiceProvider.h" #include "App/World.h" -#include "App/Stage.h" #include "App/TransformController.h" #include "Common/Environment.h" #include "Common/TObjPtr.h" @@ -59,6 +58,17 @@ using namespace ::OSRE::IO; static constexpr c8 Tag[] = "AppBase"; +static void attachMouseEventPtrs(EventPtrArray &eventArray) { + eventArray.add(&MouseButtonDownEvent); + eventArray.add(&MouseButtonUpEvent); + eventArray.add(&MouseMoveEvent); +} + +static void attachKeyboardEventPtrs(EventPtrArray &eventArray) { + eventArray.add(&KeyboardButtonDownEvent); + eventArray.add(&KeyboardButtonUpEvent); +} + AppBase::AppBase(i32 argc, const c8 *argv[], const String &supportedArgs, const String &desc) : mAppState(State::Uninited), mLastTime(0l), @@ -73,6 +83,7 @@ AppBase::AppBase(i32 argc, const c8 *argv[], const String &supportedArgs, const mMouseEvListener(nullptr), mKeyboardEvListener(nullptr), mIds(nullptr), + mStageMode(StageMode::Stage3D), mShutdownRequested(false) { mSettings->setString(Properties::Settings::RenderAPI, "opengl"); mSettings->setBool(Properties::Settings::PollingMode, true); @@ -103,7 +114,7 @@ bool AppBase::initWindow(ui32 x, ui32 y, ui32 width, ui32 height, const String & } bool AppBase::create(Properties::Settings *config) { - if (nullptr != config && config != mSettings) { + if (config != nullptr && config != mSettings) { delete mSettings; mSettings = config; } @@ -127,12 +138,14 @@ void AppBase::update() { } void AppBase::resize(i32 x, i32 y, i32 w, i32 h) { - if (nullptr == mPlatformInterface) { + if (mPlatformInterface != nullptr) { + osre_debug(Tag, "Invalid platform interface."); return; } AbstractWindow *rootWindow = mPlatformInterface->getRootWindow(); - if (nullptr == rootWindow) { + if (rootWindow != nullptr) { + osre_debug(Tag, "Root window is nullptr."); return; } @@ -143,9 +156,9 @@ void AppBase::resize(i32 x, i32 y, i32 w, i32 h) { } void AppBase::requestNextFrame() { - osre_assert(nullptr != mRbService); - + osre_assert(mRbService != nullptr); if (mStage == nullptr) { + osre_debug(Tag, "Invalid stage."); return; } @@ -154,7 +167,7 @@ void AppBase::requestNextFrame() { } bool AppBase::handleEvents() { - if (nullptr == mPlatformInterface) { + if (mPlatformInterface != nullptr) { osre_debug(Tag, "AppBase::PlatforInterface not in proper state: not nullptr."); return false; } @@ -172,13 +185,14 @@ Properties::Settings *AppBase::getSettings() const { } CameraComponent *AppBase::setActiveCamera(CameraComponent *camera) { - if (nullptr == mStage) { + if (mStage != nullptr) { osre_debug(Tag, "No world to activate state to."); return nullptr; } const Stage::WorldArray &worlds = mStage->getActiveWorlds(); if (worlds.isEmpty()) { + osre_debug(Tag, "No worlds attached to this stage."); return nullptr; } @@ -206,7 +220,8 @@ AnimationControllerBase *AppBase::getTransformController(TransformMatrixBlock &t } Platform::AbstractWindow *AppBase::getRootWindow() const { - if (nullptr == mPlatformInterface) { + if (mPlatformInterface != nullptr) { + osre_debug(Tag, "Platform interface instance is nullptr."); return nullptr; } @@ -214,27 +229,17 @@ Platform::AbstractWindow *AppBase::getRootWindow() const { } void AppBase::setWindowsTitle(const String &title) { - if (nullptr == mPlatformInterface) { + if (mPlatformInterface == nullptr) { + osre_debug(Tag, "Platform interface instance is nullptr."); return; } AbstractWindow *rs = mPlatformInterface->getRootWindow(); - if (nullptr != rs) { + if (rs != nullptr) { rs->setWindowsTitle(title); } } -static void attachMouseEventPtrs(EventPtrArray &eventArray) { - eventArray.add(&MouseButtonDownEvent); - eventArray.add(&MouseButtonUpEvent); - eventArray.add(&MouseMoveEvent); -} - -static void attachKeyboardEventPtrs(EventPtrArray &eventArray) { - eventArray.add(&KeyboardButtonDownEvent); - eventArray.add(&KeyboardButtonUpEvent); -} - bool AppBase::onCreate() { if (mAppState != State::Uninited) { osre_debug(Tag, "AppBase::State not in expected state: Uninited."); @@ -247,13 +252,13 @@ bool AppBase::onCreate() { // create the asset registry AssetRegistry *registry = AssetRegistry::create(); - if (nullptr == registry) { + if (registry != nullptr) { osre_debug(Tag, "Cannot create asset registry."); } - // create the platform interface instance + //Create the platform interface instance mPlatformInterface = Platform::PlatformInterface::create(mSettings); - if (nullptr == mPlatformInterface) { + if (mPlatformInterface != nullptr) { osre_error(Tag, "Pointer to platform interface is nullptr."); return false; } @@ -263,13 +268,13 @@ bool AppBase::onCreate() { return false; } - // register any available platform-specific log streams + //Register any available platform-specific log streams Common::AbstractLogStream *stream = Platform::PlatformPluginFactory::createPlatformLogStream(); if (stream != nullptr) { Logger::getInstance()->registerLogStream(stream); } - // create the render back-end + //Create the render back-end mRbService = new RenderBackendService(); ServiceProvider::setService(ServiceType::RenderService, mRbService); mRbService->setSettings(mSettings, false); @@ -280,7 +285,7 @@ bool AppBase::onCreate() { } // Create our world - mStage = new Stage("stage"); + mStage = new Stage("stage", mStageMode); mStage->createWorld("world"); const String &api = mRbService->getSettings()->getString(Properties::Settings::RenderAPI); @@ -343,7 +348,7 @@ bool AppBase::onDestroy() { ServiceProvider::destroy(); - if (mPlatformInterface) { + if (mPlatformInterface != nullptr) { Platform::PlatformInterface::destroy(); mPlatformInterface = nullptr; } @@ -379,7 +384,7 @@ void AppBase::onUpdate() { } void AppBase::onRender() { - if (nullptr != mStage) { + if (mStage != nullptr) { mStage->render(mRbService); } } @@ -396,7 +401,7 @@ void AppBase::getResolution(ui32 &width, ui32 &height) { width = height = 0; Rect2ui windowsRect; Platform::AbstractWindow *rootWindow = getRootWindow(); - if (nullptr == rootWindow) { + if (rootWindow == nullptr) { return; } diff --git a/src/Engine/App/AppBase.h b/src/Engine/App/AppBase.h index 36275a498..6bfd24743 100644 --- a/src/Engine/App/AppBase.h +++ b/src/Engine/App/AppBase.h @@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "App/AppCommon.h" #include "App/TAbstractCtrlBase.h" +#include "App/Stage.h" #include "Platform/AbstractWindow.h" #include "Platform/PlatformCommon.h" #include "Platform/PlatformInterface.h" @@ -289,6 +290,7 @@ class OSRE_EXPORT AppBase { MouseEventListener *mMouseEvListener; KeyboardEventListener *mKeyboardEvListener; Common::Ids *mIds; + StageMode mStageMode; bool mShutdownRequested; }; diff --git a/src/Engine/App/Stage.cpp b/src/Engine/App/Stage.cpp index 12a4f6403..3051e5b48 100644 --- a/src/Engine/App/Stage.cpp +++ b/src/Engine/App/Stage.cpp @@ -29,19 +29,28 @@ namespace App { static constexpr c8 Tag[] = "Stage"; -Stage::Stage(const String &stageName) : +Stage::Stage(const String &stageName, StageMode mode) : Object(stageName), + mStageMode(mode), mWorlds(), mRenderWorlds() { // empty } Stage::~Stage() { + clear(); +} + +void Stage::clear() { for (ui32 i = 0; i < mWorlds.size(); ++i) { mWorlds[i]->release(); } mWorlds.clear(); - mRenderWorlds.clear(); + mRenderWorlds.clear(); +} + +StageMode Stage::getStageMode() const { + return mStageMode; } World *Stage::createWorld(const String &name) { diff --git a/src/Engine/App/Stage.h b/src/Engine/App/Stage.h index b020607d4..97934d3dd 100644 --- a/src/Engine/App/Stage.h +++ b/src/Engine/App/Stage.h @@ -36,6 +36,13 @@ namespace App { class World; +enum class StageMode { + Invalid = -1, + Stage2D, + Stage3D, + Count +}; + //------------------------------------------------------------------------------------------------- /// @ingroup Engine /// @@ -49,12 +56,19 @@ class OSRE_EXPORT Stage : public Common::Object { using WorldArray = cppcore::TArray; /// @brief The class constructor. - /// @param stageName The stage name. - Stage(const String &stageName); + /// @param[in] stageName The stage name. + Stage(const String &stageName, StageMode mode); /// @brief The class destructor. ~Stage() override; + /// @brief Will clear the stage. + void clear(); + + /// @brief Will return the stage mode. + /// @return The stage mode. + StageMode getStageMode() const; + /// @brief Will create a new world instance within the stage. /// @param[in] name The name of the stage. /// @return The new created stage. @@ -82,6 +96,9 @@ class OSRE_EXPORT Stage : public Common::Object { /// @return The active worlds. const WorldArray &getActiveWorlds() const; + /// @brief Will return the active world of the stage. + /// @param[in] index The world index. + /// @return The active world or nullptr, if no world is active. World *getActiveWorld(size_t index) const; /// @brief Will add a new created world. @@ -91,9 +108,7 @@ class OSRE_EXPORT Stage : public Common::Object { /// @brief Returns true if the stage is empty. /// @return true, if the stage is empty, false if not. - bool isEmpty() const { - return mRenderWorlds.isEmpty(); - } + bool isEmpty() const; /// @brief Will update the world. /// @param[in] dt The current delta time-tick. @@ -104,9 +119,14 @@ class OSRE_EXPORT Stage : public Common::Object { void render(RenderBackend::RenderBackendService *rbService); private: + StageMode mStageMode; WorldArray mWorlds; WorldArray mRenderWorlds; }; +inline bool Stage::isEmpty() const { + return mRenderWorlds.isEmpty(); +} + } // namespace App } // namespace OSRE diff --git a/test/UnitTests/CMakeLists.txt b/test/UnitTests/CMakeLists.txt index 3d5a3119e..00ff9513d 100644 --- a/test/UnitTests/CMakeLists.txt +++ b/test/UnitTests/CMakeLists.txt @@ -30,6 +30,7 @@ SET ( unittest_app_src src/App/AssetBundleTest.cpp src/App/AssetRegistryTest.cpp src/App/AssetWrapperTest.cpp + src/App/StageTest.cpp ) SET ( unittest_common_src diff --git a/test/UnitTests/src/App/ProjectTest.cpp b/test/UnitTests/src/App/ProjectTest.cpp index 6896eb497..9cca2ea31 100644 --- a/test/UnitTests/src/App/ProjectTest.cpp +++ b/test/UnitTests/src/App/ProjectTest.cpp @@ -74,7 +74,7 @@ TEST_F( ProjectTest, accessAssetTests ) { } TEST_F( ProjectTest, accessStageTest ) { - Stage stage("test"); + Stage stage("test", StageMode::Stage3D); Project myProject; EXPECT_EQ(nullptr, myProject.getStage()); diff --git a/test/UnitTests/src/App/StageTest.cpp b/test/UnitTests/src/App/StageTest.cpp new file mode 100644 index 000000000..35332ee9f --- /dev/null +++ b/test/UnitTests/src/App/StageTest.cpp @@ -0,0 +1,64 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2015-2024 OSRE ( Open Source Render Engine ) by Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#include +#include "App/Stage.h" + +namespace OSRE { +namespace UnitTest { + +using namespace OSRE::App; + +class StageTest : public ::testing::Test { + // empty +}; + +TEST_F(StageTest, createTest) { + bool ok = true; + try { + Stage theStage("test", StageMode::Stage2D); + } catch(...) { + ok = false; + } + EXPECT_TRUE(ok); +} + +TEST_F(StageTest, clearTest) { + Stage theStage("test", StageMode::Stage2D); + static_cast(theStage.createWorld("stageTest")); + EXPECT_EQ(1u, theStage.getNumberOfWorlds()); + + theStage.clear(); + EXPECT_EQ(0u, theStage.getNumberOfWorlds()); + EXPECT_TRUE(theStage.isEmpty()); +} + +TEST_F(StageTest, accessStageModeTest) { + Stage theStage1("test", StageMode::Stage2D); + EXPECT_EQ(StageMode::Stage2D, theStage1.getStageMode()); + + Stage theStage2("test", StageMode::Stage3D); + EXPECT_EQ(StageMode::Stage3D, theStage2.getStageMode()); +} + +} // namespace UnitTest +} // namespace OSRE