// // Copyright (c) 2008-2016 the Urho3D project. // // 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 "../Precompiled.h" #include "../Audio/Audio.h" #include "../Core/Context.h" #include "../Core/CoreEvents.h" #include "../Core/EventProfiler.h" #include "../Core/ProcessUtils.h" #include "../Core/WorkQueue.h" #include "../Engine/Engine.h" #include "../Graphics/Graphics.h" #include "../Graphics/Renderer.h" #include "../Input/Input.h" #include "../IO/FileSystem.h" #include "../IO/Log.h" #include "../IO/PackageFile.h" // ATOMIC BEGIN #include "../Resource/XMLFile.h" // ATOMIC END #ifdef ATOMIC_NAVIGATION #include "../Navigation/NavigationMesh.h" #endif #ifdef ATOMIC_NETWORK #include "../Network/Network.h" #endif #ifdef ATOMIC_DATABASE #include "../Database/Database.h" #endif #ifdef ATOMIC_PHYSICS #include "../Physics/PhysicsWorld.h" #endif #include "../Resource/ResourceCache.h" #include "../Resource/Localization.h" #include "../Scene/Scene.h" #include "../Scene/SceneEvents.h" #include "../UI/UI.h" #ifdef ATOMIC_ATOMIC2D #include "../Atomic2D/Atomic2D.h" #endif #if defined(__EMSCRIPTEN__) && defined(ATOMIC_TESTING) #include #endif #include "../DebugNew.h" #if defined(_MSC_VER) && defined(_DEBUG) // From dbgint.h #define nNoMansLandSize 4 typedef struct _CrtMemBlockHeader { struct _CrtMemBlockHeader* pBlockHeaderNext; struct _CrtMemBlockHeader* pBlockHeaderPrev; char* szFileName; int nLine; size_t nDataSize; int nBlockUse; long lRequest; unsigned char gap[nNoMansLandSize]; } _CrtMemBlockHeader; #endif namespace Atomic { extern const char* logLevelPrefixes[]; Engine::Engine(Context* context) : Object(context), timeStep_(0.0f), timeStepSmoothing_(2), minFps_(10), #if defined(IOS) || defined(__ANDROID__) || defined(__arm__) || defined(__aarch64__) maxFps_(60), maxInactiveFps_(10), pauseMinimized_(true), #else maxFps_(200), maxInactiveFps_(60), pauseMinimized_(false), #endif #ifdef ATOMIC_TESTING timeOut_(0), #endif autoExit_(true), initialized_(false), exiting_(false), headless_(false), audioPaused_(false) { // Register self as a subsystem context_->RegisterSubsystem(this); // Create subsystems which do not depend on engine initialization or startup parameters context_->RegisterSubsystem(new Time(context_)); context_->RegisterSubsystem(new WorkQueue(context_)); #ifdef ATOMIC_PROFILING context_->RegisterSubsystem(new Profiler(context_)); #endif context_->RegisterSubsystem(new FileSystem(context_)); #ifdef ATOMIC_LOGGING context_->RegisterSubsystem(new Log(context_)); #endif context_->RegisterSubsystem(new ResourceCache(context_)); context_->RegisterSubsystem(new Localization(context_)); #ifdef ATOMIC_NETWORK context_->RegisterSubsystem(new Network(context_)); #endif #ifdef ATOMIC_DATABASE context_->RegisterSubsystem(new Database(context_)); #endif context_->RegisterSubsystem(new Input(context_)); context_->RegisterSubsystem(new Audio(context_)); context_->RegisterSubsystem(new UI(context_)); // Register object factories for libraries which are not automatically registered along with subsystem creation RegisterSceneLibrary(context_); #ifdef ATOMIC_PHYSICS RegisterPhysicsLibrary(context_); #endif #ifdef ATOMIC_NAVIGATION RegisterNavigationLibrary(context_); #endif SubscribeToEvent(E_EXITREQUESTED, ATOMIC_HANDLER(Engine, HandleExitRequested)); } Engine::~Engine() { } bool Engine::Initialize(const VariantMap& parameters) { if (initialized_) return true; ATOMIC_PROFILE(InitEngine); // Set headless mode headless_ = GetParameter(parameters, "Headless", false).GetBool(); // Register the rest of the subsystems if (!headless_) { context_->RegisterSubsystem(new Graphics(context_)); context_->RegisterSubsystem(new Renderer(context_)); } else { // Register graphics library objects explicitly in headless mode to allow them to work without using actual GPU resources RegisterGraphicsLibrary(context_); } #ifdef ATOMIC_ATOMIC2D // 2D graphics library is dependent on 3D graphics library RegisterAtomic2DLibrary(context_); #endif // Start logging Log* log = GetSubsystem(); if (log) { if (HasParameter(parameters, "LogLevel")) log->SetLevel(GetParameter(parameters, "LogLevel").GetInt()); log->SetQuiet(GetParameter(parameters, "LogQuiet", false).GetBool()); log->Open(GetParameter(parameters, "LogName", "Atomic.log").GetString()); } // Set maximally accurate low res timer GetSubsystem