no message
This commit is contained in:
37
cocos/engine/BaseEngine.cpp
Normal file
37
cocos/engine/BaseEngine.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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 "cocos/engine/BaseEngine.h"
|
||||
#include "cocos/engine/Engine.h"
|
||||
#include "cocos/platform/BasePlatform.h"
|
||||
#include "cocos/platform/interfaces/modules/ISystemWindow.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
// static
|
||||
BaseEngine::Ptr BaseEngine::createEngine() {
|
||||
return std::make_shared<Engine>();
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
109
cocos/engine/BaseEngine.h
Normal file
109
cocos/engine/BaseEngine.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "base/Scheduler.h"
|
||||
#include "base/TypeDef.h"
|
||||
#include "core/event/EventTarget.h"
|
||||
#include "platform/BasePlatform.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
class CC_DLL BaseEngine : public std::enable_shared_from_this<BaseEngine> {
|
||||
public:
|
||||
enum EngineStatus {
|
||||
ON_START,
|
||||
ON_PAUSE,
|
||||
ON_RESUME,
|
||||
ON_CLOSE,
|
||||
UNKNOWN,
|
||||
};
|
||||
~BaseEngine() = default;
|
||||
using Ptr = std::shared_ptr<BaseEngine>;
|
||||
|
||||
IMPL_EVENT_TARGET(BaseEngine)
|
||||
|
||||
DECLARE_TARGET_EVENT_BEGIN(BaseEngine)
|
||||
TARGET_EVENT_ARG1(EngineStatusChange, EngineStatus)
|
||||
DECLARE_TARGET_EVENT_END()
|
||||
/**
|
||||
@brief Get operating system interface template.
|
||||
*/
|
||||
template <class T>
|
||||
T *getInterface() const {
|
||||
BasePlatform *platform = BasePlatform::getPlatform();
|
||||
return platform->getInterface<T>();
|
||||
}
|
||||
/**
|
||||
@brief Create default engine.
|
||||
*/
|
||||
static BaseEngine::Ptr createEngine();
|
||||
|
||||
/**
|
||||
@brief Initialization engine interface.
|
||||
*/
|
||||
virtual int32_t init() = 0;
|
||||
/**
|
||||
@brief Run engine main logical interface.
|
||||
*/
|
||||
virtual int32_t run() = 0;
|
||||
/**
|
||||
@brief Pause engine main logical.
|
||||
*/
|
||||
virtual void pause() = 0;
|
||||
/**
|
||||
@brief Resume engine main logical.
|
||||
*/
|
||||
virtual void resume() = 0;
|
||||
/**
|
||||
@brief Restart engine main logical.
|
||||
*/
|
||||
virtual int restart() = 0;
|
||||
/**
|
||||
@brief Close engine main logical.
|
||||
*/
|
||||
virtual void close() = 0;
|
||||
/**
|
||||
@brief Gets the total number of frames in the main loop.
|
||||
*/
|
||||
virtual uint getTotalFrames() const = 0;
|
||||
/**
|
||||
* @brief Sets the preferred frame rate for main loop callback.
|
||||
* @param fps The preferred frame rate for main loop callback.
|
||||
*/
|
||||
virtual void setPreferredFramesPerSecond(int fps) = 0;
|
||||
|
||||
using SchedulerPtr = std::shared_ptr<Scheduler>;
|
||||
/**
|
||||
@brief Get engine scheduler.
|
||||
*/
|
||||
virtual SchedulerPtr getScheduler() const = 0;
|
||||
|
||||
virtual bool isInited() const = 0;
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
372
cocos/engine/Engine.cpp
Normal file
372
cocos/engine/Engine.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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 "engine/Engine.h"
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include "base/DeferredReleasePool.h"
|
||||
#include "base/Macros.h"
|
||||
#include "bindings/jswrapper/SeApi.h"
|
||||
#include "core/builtin/BuiltinResMgr.h"
|
||||
#include "engine/EngineEvents.h"
|
||||
#include "platform/BasePlatform.h"
|
||||
#include "platform/FileUtils.h"
|
||||
#include "renderer/GFXDeviceManager.h"
|
||||
#include "renderer/core/ProgramLib.h"
|
||||
#include "renderer/pipeline/RenderPipeline.h"
|
||||
#include "renderer/pipeline/custom/RenderingModule.h"
|
||||
|
||||
#if CC_USE_AUDIO
|
||||
#include "cocos/audio/include/AudioEngine.h"
|
||||
#endif
|
||||
|
||||
#if CC_USE_SOCKET
|
||||
#include "cocos/network/WebSocket.h"
|
||||
#endif
|
||||
|
||||
#if CC_USE_DRAGONBONES
|
||||
#include "editor-support/dragonbones-creator-support/ArmatureCacheMgr.h"
|
||||
#endif
|
||||
|
||||
#if CC_USE_SPINE
|
||||
#include "editor-support/spine-creator-support/SkeletonCacheMgr.h"
|
||||
#endif
|
||||
|
||||
#include "application/ApplicationManager.h"
|
||||
#include "application/BaseApplication.h"
|
||||
#include "base/Scheduler.h"
|
||||
#include "bindings/event/EventDispatcher.h"
|
||||
#include "core/assets/FreeTypeFont.h"
|
||||
#include "network/HttpClient.h"
|
||||
#include "platform/UniversalPlatform.h"
|
||||
#include "platform/interfaces/modules/IScreen.h"
|
||||
#include "platform/interfaces/modules/ISystemWindow.h"
|
||||
#include "platform/interfaces/modules/ISystemWindowManager.h"
|
||||
#if CC_USE_DEBUG_RENDERER
|
||||
#include "profiler/DebugRenderer.h"
|
||||
#endif
|
||||
#include "profiler/Profiler.h"
|
||||
|
||||
namespace {
|
||||
|
||||
bool setCanvasCallback(se::Object *global) {
|
||||
se::AutoHandleScope scope;
|
||||
se::ScriptEngine *se = se::ScriptEngine::getInstance();
|
||||
auto *window = CC_GET_MAIN_SYSTEM_WINDOW();
|
||||
auto handler = window->getWindowHandle();
|
||||
auto viewSize = window->getViewSize();
|
||||
auto dpr = cc::BasePlatform::getPlatform()->getInterface<cc::IScreen>()->getDevicePixelRatio();
|
||||
|
||||
se::Value jsbVal;
|
||||
bool ok = global->getProperty("jsb", &jsbVal);
|
||||
if (!jsbVal.isObject()) {
|
||||
se::HandleObject jsbObj(se::Object::createPlainObject());
|
||||
global->setProperty("jsb", se::Value(jsbObj));
|
||||
jsbVal.setObject(jsbObj, true);
|
||||
}
|
||||
|
||||
se::Value windowVal;
|
||||
jsbVal.toObject()->getProperty("window", &windowVal);
|
||||
if (!windowVal.isObject()) {
|
||||
se::HandleObject windowObj(se::Object::createPlainObject());
|
||||
jsbVal.toObject()->setProperty("window", se::Value(windowObj));
|
||||
windowVal.setObject(windowObj, true);
|
||||
}
|
||||
|
||||
int width = static_cast<int>(viewSize.width / dpr);
|
||||
int height = static_cast<int>(viewSize.height / dpr);
|
||||
windowVal.toObject()->setProperty("innerWidth", se::Value(width));
|
||||
windowVal.toObject()->setProperty("innerHeight", se::Value(height));
|
||||
|
||||
if (sizeof(handler) == 8) { // use bigint
|
||||
windowVal.toObject()->setProperty("windowHandle", se::Value(static_cast<uint64_t>(handler)));
|
||||
} else {
|
||||
windowVal.toObject()->setProperty("windowHandle", se::Value(static_cast<uint32_t>(handler)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace cc {
|
||||
|
||||
Engine::Engine() {
|
||||
_scriptEngine = ccnew se::ScriptEngine();
|
||||
|
||||
_windowEventListener.bind([this](const cc::WindowEvent &ev) { redirectWindowEvent(ev); });
|
||||
}
|
||||
|
||||
Engine::~Engine() {
|
||||
destroy();
|
||||
|
||||
delete _scriptEngine;
|
||||
_scriptEngine = nullptr;
|
||||
}
|
||||
|
||||
int32_t Engine::init() {
|
||||
_scheduler = std::make_shared<Scheduler>();
|
||||
_fs = createFileUtils();
|
||||
// May create gfx device in render subsystem in future.
|
||||
_gfxDevice = gfx::DeviceManager::create();
|
||||
_programLib = ccnew ProgramLib();
|
||||
_builtinResMgr = ccnew BuiltinResMgr;
|
||||
|
||||
#if CC_USE_DEBUG_RENDERER
|
||||
_debugRenderer = ccnew DebugRenderer();
|
||||
#endif
|
||||
|
||||
#if CC_USE_PROFILER
|
||||
_profiler = ccnew Profiler();
|
||||
#endif
|
||||
|
||||
EventDispatcher::init();
|
||||
|
||||
BasePlatform *platform = BasePlatform::getPlatform();
|
||||
|
||||
se::ScriptEngine::getInstance()->addRegisterCallback(setCanvasCallback);
|
||||
emit<EngineStatusChange>(ON_START);
|
||||
_inited = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Engine::destroy() {
|
||||
cc::DeferredReleasePool::clear();
|
||||
cc::network::HttpClient::destroyInstance();
|
||||
_scheduler->removeAllFunctionsToBePerformedInCocosThread();
|
||||
_scheduler->unscheduleAll();
|
||||
CCObject::deferredDestroy();
|
||||
|
||||
#if CC_USE_AUDIO
|
||||
AudioEngine::end();
|
||||
#endif
|
||||
|
||||
EventDispatcher::destroy();
|
||||
|
||||
// Should delete it before deleting DeviceManager as ScriptEngine will check gpu resource usage,
|
||||
// and ScriptEngine will hold gfx objects.
|
||||
// Because the user registration interface needs to be added during initialization.
|
||||
// ScriptEngine cannot be released here.
|
||||
_scriptEngine->cleanup();
|
||||
|
||||
#if CC_USE_PROFILER
|
||||
delete _profiler;
|
||||
#endif
|
||||
// Profiler depends on DebugRenderer, should delete it after deleting Profiler,
|
||||
// and delete DebugRenderer after RenderPipeline::destroy which destroy DebugRenderer.
|
||||
#if CC_USE_DEBUG_RENDERER
|
||||
delete _debugRenderer;
|
||||
#endif
|
||||
|
||||
// TODO(): Delete some global objects.
|
||||
#if CC_USE_DEBUG_RENDERER
|
||||
// FreeTypeFontFace is only used in DebugRenderer now, so use CC_USE_DEBUG_RENDERER macro temporarily
|
||||
FreeTypeFontFace::destroyFreeType();
|
||||
#endif
|
||||
|
||||
#if CC_USE_DRAGONBONES
|
||||
dragonBones::ArmatureCacheMgr::destroyInstance();
|
||||
#endif
|
||||
|
||||
#if CC_USE_SPINE
|
||||
spine::SkeletonCacheMgr::destroyInstance();
|
||||
#endif
|
||||
|
||||
#if CC_USE_MIDDLEWARE
|
||||
cc::middleware::MiddlewareManager::destroyInstance();
|
||||
#endif
|
||||
|
||||
CCObject::deferredDestroy();
|
||||
|
||||
delete _builtinResMgr;
|
||||
delete _programLib;
|
||||
|
||||
if (cc::render::getRenderingModule()) {
|
||||
cc::render::Factory::destroy(cc::render::getRenderingModule());
|
||||
}
|
||||
|
||||
CC_SAFE_DESTROY_AND_DELETE(_gfxDevice);
|
||||
delete _fs;
|
||||
_scheduler.reset();
|
||||
|
||||
_inited = false;
|
||||
}
|
||||
|
||||
int32_t Engine::run() {
|
||||
BasePlatform *platform = BasePlatform::getPlatform();
|
||||
_xr = CC_GET_XR_INTERFACE();
|
||||
platform->runInPlatformThread([&]() {
|
||||
tick();
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Engine::pause() {
|
||||
// TODO(cc) : Follow-up support
|
||||
}
|
||||
|
||||
void Engine::resume() {
|
||||
// TODO(cc) : Follow-up support
|
||||
}
|
||||
|
||||
int Engine::restart() {
|
||||
_needRestart = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Engine::close() { // NOLINT
|
||||
|
||||
#if CC_USE_AUDIO
|
||||
cc::AudioEngine::stopAll();
|
||||
#endif
|
||||
|
||||
// #if CC_USE_SOCKET
|
||||
// cc::network::WebSocket::closeAllConnections();
|
||||
// #endif
|
||||
|
||||
cc::DeferredReleasePool::clear();
|
||||
_scheduler->removeAllFunctionsToBePerformedInCocosThread();
|
||||
_scheduler->unscheduleAll();
|
||||
}
|
||||
|
||||
uint Engine::getTotalFrames() const {
|
||||
return _totalFrames;
|
||||
}
|
||||
|
||||
void Engine::setPreferredFramesPerSecond(int fps) {
|
||||
if (fps == 0) {
|
||||
return;
|
||||
}
|
||||
BasePlatform *platform = BasePlatform::getPlatform();
|
||||
platform->setFps(fps);
|
||||
_preferredNanosecondsPerFrame = static_cast<long>(1.0 / fps * NANOSECONDS_PER_SECOND); // NOLINT(google-runtime-int)
|
||||
}
|
||||
|
||||
void Engine::tick() {
|
||||
CC_PROFILER_BEGIN_FRAME;
|
||||
{
|
||||
CC_PROFILE(EngineTick);
|
||||
|
||||
_gfxDevice->frameSync();
|
||||
|
||||
if (_needRestart) {
|
||||
doRestart();
|
||||
_needRestart = false;
|
||||
}
|
||||
|
||||
static std::chrono::steady_clock::time_point prevTime;
|
||||
static std::chrono::steady_clock::time_point now;
|
||||
static float dt = 0.F;
|
||||
static double dtNS = NANOSECONDS_60FPS;
|
||||
|
||||
++_totalFrames;
|
||||
|
||||
// iOS/macOS use its own fps limitation algorithm.
|
||||
// Windows for Editor should not sleep,because Editor call tick function synchronously
|
||||
#if (CC_PLATFORM == CC_PLATFORM_ANDROID || (CC_PLATFORM == CC_PLATFORM_WINDOWS && !CC_EDITOR) || CC_PLATFORM == CC_PLATFORM_OHOS || CC_PLATFORM == CC_PLATFORM_OPENHARMONY || CC_PLATFORM == CC_PLATFORM_MACOS)
|
||||
if (dtNS < static_cast<double>(_preferredNanosecondsPerFrame)) {
|
||||
CC_PROFILE(EngineSleep);
|
||||
std::this_thread::sleep_for(
|
||||
std::chrono::nanoseconds(_preferredNanosecondsPerFrame - static_cast<int64_t>(dtNS)));
|
||||
dtNS = static_cast<double>(_preferredNanosecondsPerFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
events::BeforeTick::broadcast();
|
||||
|
||||
prevTime = std::chrono::steady_clock::now();
|
||||
if (_xr) _xr->beginRenderFrame();
|
||||
_scheduler->update(dt);
|
||||
|
||||
se::ScriptEngine::getInstance()->handlePromiseExceptions();
|
||||
events::Tick::broadcast(dt);
|
||||
se::ScriptEngine::getInstance()->mainLoopUpdate();
|
||||
|
||||
cc::DeferredReleasePool::clear();
|
||||
if (_xr) _xr->endRenderFrame();
|
||||
now = std::chrono::steady_clock::now();
|
||||
dtNS = dtNS * 0.1 + 0.9 * static_cast<double>(std::chrono::duration_cast<std::chrono::nanoseconds>(now - prevTime).count());
|
||||
dt = static_cast<float>(dtNS) / NANOSECONDS_PER_SECOND;
|
||||
|
||||
events::AfterTick::broadcast();
|
||||
}
|
||||
|
||||
CC_PROFILER_END_FRAME;
|
||||
}
|
||||
|
||||
void Engine::doRestart() {
|
||||
events::RestartVM::broadcast();
|
||||
destroy();
|
||||
CC_CURRENT_APPLICATION()->init();
|
||||
}
|
||||
|
||||
Engine::SchedulerPtr Engine::getScheduler() const {
|
||||
return _scheduler;
|
||||
}
|
||||
|
||||
bool Engine::redirectWindowEvent(const WindowEvent &ev) {
|
||||
bool isHandled = false;
|
||||
if (ev.type == WindowEvent::Type::SHOW ||
|
||||
ev.type == WindowEvent::Type::RESTORED) {
|
||||
emit<EngineStatusChange>(ON_RESUME);
|
||||
#if CC_PLATFORM == CC_PLATFORM_WINDOWS
|
||||
events::WindowRecreated::broadcast(ev.windowId);
|
||||
#endif
|
||||
events::EnterForeground::broadcast();
|
||||
isHandled = true;
|
||||
} else if (ev.type == WindowEvent::Type::SIZE_CHANGED ||
|
||||
ev.type == WindowEvent::Type::RESIZED) {
|
||||
auto *w = CC_GET_SYSTEM_WINDOW(ev.windowId);
|
||||
CC_ASSERT(w);
|
||||
w->setViewSize(ev.width, ev.height);
|
||||
// Because the ts layer calls the getviewsize interface in response to resize.
|
||||
// So we need to set the view size when sending the message.
|
||||
events::Resize::broadcast(ev.width, ev.height, ev.windowId);
|
||||
isHandled = true;
|
||||
} else if (ev.type == WindowEvent::Type::HIDDEN ||
|
||||
ev.type == WindowEvent::Type::MINIMIZED) {
|
||||
emit<EngineStatusChange>(ON_PAUSE);
|
||||
#if CC_PLATFORM == CC_PLATFORM_WINDOWS
|
||||
events::WindowDestroy::broadcast(ev.windowId);
|
||||
#endif
|
||||
events::EnterBackground::broadcast();
|
||||
|
||||
isHandled = true;
|
||||
} else if (ev.type == WindowEvent::Type::CLOSE) {
|
||||
emit<EngineStatusChange>(ON_CLOSE);
|
||||
events::Close::broadcast();
|
||||
// Increase the frame rate and get the program to exit as quickly as possible
|
||||
setPreferredFramesPerSecond(1000);
|
||||
isHandled = true;
|
||||
} else if (ev.type == WindowEvent::Type::QUIT) {
|
||||
// There is no need to process the quit message,
|
||||
// the quit message is a custom message for the application
|
||||
isHandled = true;
|
||||
}
|
||||
return isHandled;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
140
cocos/engine/Engine.h
Normal file
140
cocos/engine/Engine.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/Config.h"
|
||||
#include "base/TypeDef.h"
|
||||
#include "engine/BaseEngine.h"
|
||||
#include "engine/EngineEvents.h"
|
||||
#include "math/Vec2.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace se {
|
||||
class ScriptEngine;
|
||||
}
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace gfx {
|
||||
class Device;
|
||||
}
|
||||
|
||||
class FileUtils;
|
||||
class DebugRenderer;
|
||||
class Profiler;
|
||||
class BuiltinResMgr;
|
||||
class ProgramLib;
|
||||
class IXRInterface;
|
||||
|
||||
#define NANOSECONDS_PER_SECOND 1000000000
|
||||
#define NANOSECONDS_60FPS 16666667L
|
||||
|
||||
class CC_DLL Engine : public BaseEngine {
|
||||
public:
|
||||
/**
|
||||
@brief Constructor of Engine.
|
||||
*/
|
||||
Engine();
|
||||
/**
|
||||
@brief Constructor of Engine.
|
||||
*/
|
||||
~Engine();
|
||||
/**
|
||||
@brief Implement initialization engine.
|
||||
*/
|
||||
int32_t init() override;
|
||||
/**
|
||||
@brief Implement the main logic of the running engine.
|
||||
*/
|
||||
int32_t run() override;
|
||||
/**
|
||||
@brief Implement pause engine running.
|
||||
*/
|
||||
void pause() override;
|
||||
/**
|
||||
@brief Implement resume engine running.
|
||||
*/
|
||||
void resume() override;
|
||||
/**
|
||||
@brief Implement restart engine running.
|
||||
*/
|
||||
int restart() override;
|
||||
/**
|
||||
@brief Implement close engine running.
|
||||
*/
|
||||
void close() override;
|
||||
/**
|
||||
* @brief Sets the preferred frame rate for main loop callback.
|
||||
* @param fps The preferred frame rate for main loop callback.
|
||||
*/
|
||||
void setPreferredFramesPerSecond(int fps) override;
|
||||
/**
|
||||
@brief Gets the total number of frames in the main loop.
|
||||
*/
|
||||
uint getTotalFrames() const override;
|
||||
/**
|
||||
@brief Get engine scheduler.
|
||||
*/
|
||||
SchedulerPtr getScheduler() const override;
|
||||
|
||||
bool isInited() const override { return _inited; }
|
||||
|
||||
private:
|
||||
void destroy();
|
||||
void tick();
|
||||
bool redirectWindowEvent(const WindowEvent &ev);
|
||||
void doRestart();
|
||||
|
||||
SchedulerPtr _scheduler{nullptr};
|
||||
int64_t _preferredNanosecondsPerFrame{NANOSECONDS_60FPS};
|
||||
uint _totalFrames{0};
|
||||
cc::Vec2 _viewLogicalSize{0, 0};
|
||||
bool _needRestart{false};
|
||||
bool _inited{false};
|
||||
|
||||
// Some global objects.
|
||||
FileUtils *_fs{nullptr};
|
||||
#if CC_USE_PROFILER
|
||||
Profiler *_profiler{nullptr};
|
||||
#endif
|
||||
DebugRenderer *_debugRenderer{nullptr};
|
||||
se::ScriptEngine *_scriptEngine{nullptr};
|
||||
// Should move to renderer system in future.
|
||||
gfx::Device *_gfxDevice{nullptr};
|
||||
|
||||
// Should move them into material system in future.
|
||||
BuiltinResMgr *_builtinResMgr{nullptr};
|
||||
ProgramLib *_programLib{nullptr};
|
||||
|
||||
events::WindowEvent::Listener _windowEventListener;
|
||||
|
||||
CC_DISALLOW_COPY_MOVE_ASSIGN(Engine);
|
||||
|
||||
IXRInterface *_xr{nullptr};
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
352
cocos/engine/EngineEvents.h
Normal file
352
cocos/engine/EngineEvents.h
Normal file
@@ -0,0 +1,352 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "base/std/container/string.h"
|
||||
#include "base/std/container/unordered_map.h"
|
||||
#include "base/std/container/vector.h"
|
||||
#include "core/event/EventBus.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
class ISystemWindow;
|
||||
|
||||
enum class OSEventType {
|
||||
KEYBOARD_OSEVENT = 0,
|
||||
TOUCH_OSEVENT = 1,
|
||||
MOUSE_OSEVENT = 2,
|
||||
CUSTOM_OSEVENT = 3,
|
||||
DEVICE_OSEVENT = 4,
|
||||
WINDOW_OSEVENT = 5,
|
||||
APP_OSEVENT = 6,
|
||||
CONTROLLER_OSEVENT = 7,
|
||||
UNKNOWN_OSEVENT = 8
|
||||
};
|
||||
|
||||
class WindowEvent {
|
||||
public:
|
||||
WindowEvent() = default;
|
||||
enum class Type {
|
||||
QUIT = 0,
|
||||
SHOW,
|
||||
RESTORED,
|
||||
SIZE_CHANGED,
|
||||
RESIZED,
|
||||
HIDDEN,
|
||||
MINIMIZED,
|
||||
CLOSE,
|
||||
UNKNOWN,
|
||||
};
|
||||
Type type = Type::UNKNOWN;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
uint32_t windowId = 0;
|
||||
};
|
||||
// Touch event related
|
||||
|
||||
class TouchInfo {
|
||||
public:
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
int index = 0;
|
||||
|
||||
TouchInfo(float x, float y, int index)
|
||||
: x(x),
|
||||
y(y),
|
||||
index(index) {}
|
||||
};
|
||||
|
||||
class TouchEvent {
|
||||
public:
|
||||
TouchEvent() = default;
|
||||
enum class Type {
|
||||
BEGAN,
|
||||
MOVED,
|
||||
ENDED,
|
||||
CANCELLED,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
ccstd::vector<TouchInfo> touches;
|
||||
Type type = Type::UNKNOWN;
|
||||
uint32_t windowId = 0;
|
||||
};
|
||||
|
||||
enum class StickKeyCode {
|
||||
UNDEFINE = 0,
|
||||
A,
|
||||
B,
|
||||
X,
|
||||
Y,
|
||||
L1,
|
||||
R1,
|
||||
MINUS,
|
||||
PLUS,
|
||||
L3,
|
||||
R3,
|
||||
MENU,
|
||||
START,
|
||||
TRIGGER_LEFT,
|
||||
TRIGGER_RIGHT,
|
||||
};
|
||||
|
||||
enum class StickAxisCode {
|
||||
UNDEFINE = 0,
|
||||
X,
|
||||
Y,
|
||||
LEFT_STICK_X,
|
||||
LEFT_STICK_Y,
|
||||
RIGHT_STICK_X,
|
||||
RIGHT_STICK_Y,
|
||||
L2,
|
||||
R2,
|
||||
LEFT_GRIP,
|
||||
RIGHT_GRIP,
|
||||
};
|
||||
|
||||
enum class StickTouchCode {
|
||||
UNDEFINE = 0,
|
||||
A,
|
||||
B,
|
||||
X,
|
||||
Y,
|
||||
LEFT_TRIGGER,
|
||||
RIGHT_TRIGGER,
|
||||
LEFT_THUMBSTICK,
|
||||
RIGHT_THUMBSTICK,
|
||||
};
|
||||
|
||||
struct ControllerInfo {
|
||||
struct AxisInfo {
|
||||
StickAxisCode axis{StickAxisCode::UNDEFINE};
|
||||
float value{0.F};
|
||||
AxisInfo(StickAxisCode axis, float value) : axis(axis), value(value) {}
|
||||
};
|
||||
struct ButtonInfo {
|
||||
StickKeyCode key{StickKeyCode::UNDEFINE};
|
||||
bool isPress{false};
|
||||
ButtonInfo(StickKeyCode key, bool isPress) : key(key), isPress(isPress) {}
|
||||
};
|
||||
struct TouchInfo {
|
||||
StickTouchCode key{StickTouchCode::UNDEFINE};
|
||||
float value{0.F};
|
||||
TouchInfo(StickTouchCode key, float value) : key(key), value(value) {}
|
||||
};
|
||||
int napdId{0};
|
||||
std::vector<AxisInfo> axisInfos;
|
||||
std::vector<ButtonInfo> buttonInfos;
|
||||
std::vector<TouchInfo> touchInfos;
|
||||
};
|
||||
|
||||
struct ControllerEvent {
|
||||
ControllerEvent() = default;
|
||||
enum class Type {
|
||||
GAMEPAD,
|
||||
HANDLE,
|
||||
UNKNOWN
|
||||
};
|
||||
Type type = Type::UNKNOWN;
|
||||
ccstd::vector<std::unique_ptr<ControllerInfo>> controllerInfos;
|
||||
};
|
||||
|
||||
struct ControllerChangeEvent {
|
||||
ccstd::vector<uint32_t> controllerIds;
|
||||
};
|
||||
|
||||
class MouseEvent {
|
||||
public:
|
||||
MouseEvent() = default;
|
||||
enum class Type {
|
||||
DOWN,
|
||||
UP,
|
||||
MOVE,
|
||||
WHEEL,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
float x = 0.0F;
|
||||
float y = 0.0F;
|
||||
float xDelta = 0.0F;
|
||||
float yDelta = 0.0F;
|
||||
// The button number that was pressed when the mouse event was fired: Left button=0, middle button=1 (if present), right button=2.
|
||||
// For mice configured for left handed use in which the button actions are reversed the values are instead read from right to left.
|
||||
uint16_t button = 0;
|
||||
Type type = Type::UNKNOWN;
|
||||
uint32_t windowId = 0;
|
||||
};
|
||||
|
||||
enum class KeyCode {
|
||||
/**
|
||||
* @en The back key on mobile phone
|
||||
* @zh 移动端返回键
|
||||
*/
|
||||
MOBILE_BACK = 6,
|
||||
BACKSPACE = 8,
|
||||
TAB = 9,
|
||||
NUM_LOCK = 12,
|
||||
NUMPAD_ENTER = 20013,
|
||||
ENTER = 13,
|
||||
SHIFT_RIGHT = 20016,
|
||||
SHIFT_LEFT = 16,
|
||||
CONTROL_LEFT = 17,
|
||||
CONTROL_RIGHT = 20017,
|
||||
ALT_RIGHT = 20018,
|
||||
ALT_LEFT = 18,
|
||||
PAUSE = 19,
|
||||
CAPS_LOCK = 20,
|
||||
ESCAPE = 27,
|
||||
SPACE = 32,
|
||||
PAGE_UP = 33,
|
||||
PAGE_DOWN = 34,
|
||||
END = 35,
|
||||
HOME = 36,
|
||||
ARROW_LEFT = 37,
|
||||
ARROW_UP = 38,
|
||||
ARROW_RIGHT = 39,
|
||||
ARROW_DOWN = 40,
|
||||
INSERT = 45,
|
||||
DELETE_KEY = 46, // DELETE has conflict
|
||||
META_LEFT = 91,
|
||||
CONTEXT_MENU = 20093,
|
||||
PRINT_SCREEN = 20094,
|
||||
META_RIGHT = 93,
|
||||
NUMPAD_MULTIPLY = 106,
|
||||
NUMPAD_PLUS = 107,
|
||||
NUMPAD_MINUS = 109,
|
||||
NUMPAD_DECIMAL = 110,
|
||||
NUMPAD_DIVIDE = 111,
|
||||
SCROLLLOCK = 145,
|
||||
SEMICOLON = 186,
|
||||
EQUAL = 187,
|
||||
COMMA = 188,
|
||||
MINUS = 189,
|
||||
PERIOD = 190,
|
||||
SLASH = 191,
|
||||
BACKQUOTE = 192,
|
||||
BRACKET_LEFT = 219,
|
||||
BACKSLASH = 220,
|
||||
BRACKET_RIGHT = 221,
|
||||
QUOTE = 222,
|
||||
NUMPAD_0 = 10048,
|
||||
NUMPAD_1 = 10049,
|
||||
NUMPAD_2 = 10050,
|
||||
NUMPAD_3 = 10051,
|
||||
NUMPAD_4 = 10052,
|
||||
NUMPAD_5 = 10053,
|
||||
NUMPAD_6 = 10054,
|
||||
NUMPAD_7 = 10055,
|
||||
NUMPAD_8 = 10056,
|
||||
NUMPAD_9 = 10057,
|
||||
DPAD_UP = 1003,
|
||||
DPAD_LEFT = 1000,
|
||||
DPAD_DOWN = 1004,
|
||||
DPAD_RIGHT = 1001,
|
||||
DPAD_CENTER = 1005
|
||||
};
|
||||
|
||||
class KeyboardEvent {
|
||||
public:
|
||||
KeyboardEvent() = default;
|
||||
enum class Action {
|
||||
PRESS,
|
||||
RELEASE,
|
||||
REPEAT,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
uint32_t windowId = 0;
|
||||
int key = -1;
|
||||
Action action = Action::UNKNOWN;
|
||||
bool altKeyActive = false;
|
||||
bool ctrlKeyActive = false;
|
||||
bool metaKeyActive = false;
|
||||
bool shiftKeyActive = false;
|
||||
ccstd::string code;
|
||||
// TODO(mingo): support caps lock?
|
||||
};
|
||||
union EventParameterType {
|
||||
void *ptrVal;
|
||||
int32_t longVal;
|
||||
int intVal;
|
||||
int16_t shortVal;
|
||||
char charVal;
|
||||
bool boolVal;
|
||||
};
|
||||
|
||||
class CustomEvent {
|
||||
public:
|
||||
CustomEvent() = default;
|
||||
ccstd::string name;
|
||||
EventParameterType args[10];
|
||||
|
||||
virtual ~CustomEvent() = default; // NOLINT(modernize-use-nullptr)
|
||||
};
|
||||
|
||||
class DeviceEvent {
|
||||
public:
|
||||
DeviceEvent() = default;
|
||||
enum class Type {
|
||||
MEMORY,
|
||||
ORIENTATION,
|
||||
UNKNOWN
|
||||
};
|
||||
EventParameterType args[3];
|
||||
Type type{Type::UNKNOWN}; // NOLINT(modernize-use-nullptr)
|
||||
};
|
||||
|
||||
enum class ScriptEngineEvent {
|
||||
BEFORE_INIT,
|
||||
AFTER_INIT,
|
||||
BEFORE_CLEANUP,
|
||||
AFTER_CLEANUP,
|
||||
};
|
||||
|
||||
namespace events {
|
||||
DECLARE_EVENT_BUS(Engine)
|
||||
|
||||
DECLARE_BUS_EVENT_ARG0(EnterForeground, Engine)
|
||||
DECLARE_BUS_EVENT_ARG0(EnterBackground, Engine)
|
||||
DECLARE_BUS_EVENT_ARG1(WindowRecreated, Engine, uint32_t /* windowId*/)
|
||||
DECLARE_BUS_EVENT_ARG1(WindowDestroy, Engine, uint32_t /*windowId*/)
|
||||
DECLARE_BUS_EVENT_ARG1(WindowEvent, Engine, const cc::WindowEvent &)
|
||||
DECLARE_BUS_EVENT_ARG1(WindowChanged, Engine, cc::WindowEvent::Type)
|
||||
DECLARE_BUS_EVENT_ARG0(LowMemory, Engine)
|
||||
DECLARE_BUS_EVENT_ARG1(Touch, Engine, const cc::TouchEvent &)
|
||||
DECLARE_BUS_EVENT_ARG1(Mouse, Engine, const cc::MouseEvent &)
|
||||
DECLARE_BUS_EVENT_ARG1(Keyboard, Engine, const cc::KeyboardEvent &)
|
||||
DECLARE_BUS_EVENT_ARG1(Controller, Engine, const cc::ControllerEvent &)
|
||||
DECLARE_BUS_EVENT_ARG1(ControllerChange, Engine, const cc::ControllerChangeEvent &)
|
||||
DECLARE_BUS_EVENT_ARG1(Tick, Engine, float)
|
||||
DECLARE_BUS_EVENT_ARG0(BeforeTick, Engine)
|
||||
DECLARE_BUS_EVENT_ARG0(AfterTick, Engine)
|
||||
DECLARE_BUS_EVENT_ARG3(Resize, Engine, int, int, uint32_t /* windowId*/)
|
||||
DECLARE_BUS_EVENT_ARG1(Orientation, Engine, int)
|
||||
DECLARE_BUS_EVENT_ARG1(PointerLock, Engine, bool)
|
||||
DECLARE_BUS_EVENT_ARG0(RestartVM, Engine)
|
||||
DECLARE_BUS_EVENT_ARG0(Close, Engine)
|
||||
DECLARE_BUS_EVENT_ARG0(SceneLoad, Engine)
|
||||
DECLARE_BUS_EVENT_ARG1(ScriptEngine, Engine, ScriptEngineEvent)
|
||||
} // namespace events
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user