[deploy] Merge pull request #55 from KiwanoEngine/dev
Merge develop branch
This commit is contained in:
commit
a8c13b49c1
|
|
@ -28,7 +28,7 @@ void ImGuiModule::SetupModule()
|
|||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
window_ = Application::GetInstance().GetMainWindow();
|
||||
window_ = Application::GetInstance().GetWindow();
|
||||
|
||||
// Setup Platform/Renderer bindings
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace kiwano
|
|||
|
||||
CanvasPtr Canvas::Create(const Size& size)
|
||||
{
|
||||
void* mem = memory::Alloc<Canvas>();
|
||||
void* mem = memory::Alloc(sizeof(Canvas));
|
||||
CanvasPtr ptr = ::new (mem) Canvas;
|
||||
if (ptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -62,14 +62,14 @@ void Button::SetStatus(Status status)
|
|||
|
||||
if (status == Status::Normal)
|
||||
{
|
||||
Application::GetInstance().GetMainWindow()->SetCursor(CursorType::Arrow);
|
||||
Application::GetInstance().GetWindow()->SetCursor(CursorType::Arrow);
|
||||
|
||||
if (mouse_out_callback_)
|
||||
mouse_out_callback_(this, GetBoundActor());
|
||||
}
|
||||
else if (status == Status::Hover)
|
||||
{
|
||||
Application::GetInstance().GetMainWindow()->SetCursor(CursorType::Hand);
|
||||
Application::GetInstance().GetWindow()->SetCursor(CursorType::Hand);
|
||||
|
||||
if (old_status != Status::Pressed)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,6 +27,26 @@ namespace memory
|
|||
|
||||
MemoryAllocator* current_allocator_ = nullptr;
|
||||
|
||||
MemoryAllocator* GetGlobalAllocator()
|
||||
{
|
||||
class KGE_API GlobalAllocator : public MemoryAllocator
|
||||
{
|
||||
public:
|
||||
virtual void* Alloc(size_t size) override
|
||||
{
|
||||
return ::operator new(size);
|
||||
}
|
||||
|
||||
virtual void Free(void* ptr, size_t size) override
|
||||
{
|
||||
::operator delete(ptr, size);
|
||||
}
|
||||
};
|
||||
|
||||
static GlobalAllocator global_allocator;
|
||||
return &global_allocator;
|
||||
}
|
||||
|
||||
MemoryAllocator* GetAllocator()
|
||||
{
|
||||
if (!current_allocator_)
|
||||
|
|
@ -42,21 +62,5 @@ void SetAllocator(MemoryAllocator* allocator)
|
|||
current_allocator_ = allocator;
|
||||
}
|
||||
|
||||
GlobalAllocator* GetGlobalAllocator()
|
||||
{
|
||||
static GlobalAllocator global_allocator;
|
||||
return &global_allocator;
|
||||
}
|
||||
|
||||
void* GlobalAllocator::Alloc(size_t size)
|
||||
{
|
||||
return ::malloc(size);
|
||||
}
|
||||
|
||||
void GlobalAllocator::Free(void* ptr)
|
||||
{
|
||||
::free(ptr);
|
||||
}
|
||||
|
||||
} // namespace memory
|
||||
} // namespace kiwano
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <utility> // std::forward
|
||||
#include <limits> // std::numeric_limits
|
||||
#include <memory> // std::addressof
|
||||
#include <kiwano/macros.h>
|
||||
|
||||
namespace kiwano
|
||||
|
|
@ -39,7 +40,7 @@ public:
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 释放内存
|
||||
virtual void Free(void* ptr) = 0;
|
||||
virtual void Free(void* ptr, size_t size) = 0;
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
|
|
@ -52,30 +53,32 @@ void SetAllocator(MemoryAllocator* allocator);
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 使用当前内存分配器分配内存
|
||||
template <typename _Ty>
|
||||
inline void* Alloc()
|
||||
inline void* Alloc(size_t size)
|
||||
{
|
||||
return memory::GetAllocator()->Alloc(sizeof(_Ty));
|
||||
return memory::GetAllocator()->Alloc(size);
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 使用当前内存分配器释放内存
|
||||
inline void Free(void* ptr)
|
||||
inline void Free(void* ptr, size_t size)
|
||||
{
|
||||
return memory::GetAllocator()->Free(ptr);
|
||||
memory::GetAllocator()->Free(ptr, size);
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 使用当前内存分配器创建对象
|
||||
template <typename _Ty>
|
||||
inline _Ty* New()
|
||||
/// @brief 构造对象
|
||||
template <typename _Ty, typename... _Args>
|
||||
inline _Ty* Construct(void* ptr, _Args&&... args)
|
||||
{
|
||||
void* ptr = memory::Alloc<_Ty>();
|
||||
if (ptr)
|
||||
{
|
||||
return ::new (ptr) _Ty;
|
||||
}
|
||||
return nullptr;
|
||||
return ::new (ptr) _Ty(std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 销毁对象
|
||||
template <typename _Ty, typename... _Args>
|
||||
inline void Destroy(_Ty* ptr)
|
||||
{
|
||||
ptr->~_Ty();
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
|
|
@ -83,10 +86,10 @@ inline _Ty* New()
|
|||
template <typename _Ty, typename... _Args>
|
||||
inline _Ty* New(_Args&&... args)
|
||||
{
|
||||
void* ptr = memory::Alloc<_Ty>();
|
||||
void* ptr = memory::Alloc(sizeof(_Ty));
|
||||
if (ptr)
|
||||
{
|
||||
return ::new (ptr) _Ty(std::forward<_Args>(args)...);
|
||||
return memory::Construct<_Ty>(ptr, std::forward<_Args>(args)...);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -98,28 +101,119 @@ inline void Delete(_Ty* ptr)
|
|||
{
|
||||
if (ptr)
|
||||
{
|
||||
ptr->~_Ty();
|
||||
memory::Free(ptr);
|
||||
memory::Destroy<_Ty>(ptr);
|
||||
memory::Free(ptr, sizeof(_Ty));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 全局内存分配器,使用malloc和free分配内存
|
||||
class KGE_API GlobalAllocator : public MemoryAllocator
|
||||
/// @brief 分配器
|
||||
template <typename _Ty>
|
||||
class Allocator
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 申请内存
|
||||
virtual void* Alloc(size_t size) override;
|
||||
typedef _Ty value_type;
|
||||
typedef _Ty* pointer;
|
||||
typedef const _Ty* const_pointer;
|
||||
typedef _Ty& reference;
|
||||
typedef const _Ty& const_reference;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 释放内存
|
||||
virtual void Free(void* ptr) override;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
template <class _Other>
|
||||
struct rebind
|
||||
{
|
||||
using other = Allocator<_Other>;
|
||||
};
|
||||
|
||||
Allocator() noexcept {}
|
||||
|
||||
Allocator(const Allocator&) noexcept = default;
|
||||
|
||||
template <class _Other>
|
||||
Allocator(const Allocator<_Other>&) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
inline _Ty* allocate(size_t count)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
return static_cast<_Ty*>(memory::Alloc(sizeof(_Ty) * count));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline void* allocate(size_t count, const void*)
|
||||
{
|
||||
return allocate(count);
|
||||
}
|
||||
|
||||
inline void deallocate(void* ptr, size_t count)
|
||||
{
|
||||
memory::Free(ptr, sizeof(_Ty) * count);
|
||||
}
|
||||
|
||||
template <typename _UTy, typename... _Args>
|
||||
inline void construct(_UTy* ptr, _Args&&... args)
|
||||
{
|
||||
memory::Construct<_UTy>(ptr, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename _UTy>
|
||||
inline void destroy(_UTy* ptr)
|
||||
{
|
||||
memory::Destroy<_UTy>(ptr);
|
||||
}
|
||||
|
||||
size_t max_size() const noexcept
|
||||
{
|
||||
return std::numeric_limits<size_t>::max() / sizeof(_Ty);
|
||||
}
|
||||
|
||||
_Ty* address(_Ty& val) const noexcept
|
||||
{
|
||||
return std::addressof(val);
|
||||
}
|
||||
|
||||
const _Ty* address(const _Ty& val) const noexcept
|
||||
{
|
||||
return std::addressof(val);
|
||||
}
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取全局内存分配器
|
||||
GlobalAllocator* GetGlobalAllocator();
|
||||
// Allocator<void>
|
||||
template <>
|
||||
class Allocator<void>
|
||||
{
|
||||
public:
|
||||
using value_type = void;
|
||||
typedef void* pointer;
|
||||
typedef const void* const_pointer;
|
||||
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
template <class _Other>
|
||||
struct rebind
|
||||
{
|
||||
using other = Allocator<_Other>;
|
||||
};
|
||||
};
|
||||
|
||||
template <class _Ty, class _Other>
|
||||
bool operator==(const Allocator<_Ty>&, const Allocator<_Other>&) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class _Ty, class _Other>
|
||||
bool operator!=(const Allocator<_Ty>&, const Allocator<_Other>&) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace memory
|
||||
} // namespace kiwano
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include <kiwano/platform/Application.h>
|
||||
#include <kiwano/platform/Input.h>
|
||||
#include <kiwano/base/Director.h>
|
||||
#include <kiwano/utils/Logger.h>
|
||||
#include <kiwano/base/Director.h>
|
||||
#include <kiwano/render/Renderer.h>
|
||||
#include <kiwano/render/TextureCache.h>
|
||||
#include <kiwano/utils/ResourceCache.h>
|
||||
|
|
@ -39,9 +38,6 @@ Application::Application()
|
|||
, is_paused_(false)
|
||||
, time_scale_(1.f)
|
||||
{
|
||||
Use(Renderer::GetInstance());
|
||||
Use(Input::GetInstance());
|
||||
Use(Director::GetInstance());
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
|
|
@ -49,25 +45,22 @@ Application::~Application()
|
|||
this->Destroy();
|
||||
}
|
||||
|
||||
void Application::Run(RunnerPtr runner, bool debug)
|
||||
void Application::Run(RunnerPtr runner)
|
||||
{
|
||||
KGE_ASSERT(runner);
|
||||
runner_ = runner;
|
||||
running_ = true;
|
||||
is_paused_ = false;
|
||||
|
||||
// Initialize runner
|
||||
runner->InitSettings();
|
||||
|
||||
// Setup all modules
|
||||
for (auto c : modules_)
|
||||
{
|
||||
c->SetupModule();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Director::GetInstance().ShowDebugInfo(true);
|
||||
Renderer::GetInstance().GetContext().SetCollectingStatus(true);
|
||||
}
|
||||
|
||||
// Everything is ready
|
||||
runner->OnReady();
|
||||
|
||||
|
|
@ -128,16 +121,19 @@ void Application::Destroy()
|
|||
runner_ = nullptr;
|
||||
}
|
||||
|
||||
// Clear all resources
|
||||
// Clear user resources
|
||||
Director::GetInstance().ClearStages();
|
||||
ResourceCache::GetInstance().Clear();
|
||||
TextureCache::GetInstance().Clear();
|
||||
|
||||
for (auto iter = modules_.rbegin(); iter != modules_.rend(); ++iter)
|
||||
{
|
||||
(*iter)->DestroyModule();
|
||||
}
|
||||
modules_.clear();
|
||||
|
||||
// Clear device resources
|
||||
TextureCache::GetInstance().Clear();
|
||||
Renderer::GetInstance().Destroy();
|
||||
}
|
||||
|
||||
void Application::Use(Module& module)
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public:
|
|||
* @param debug 是否启用调试模式
|
||||
* @note 该函数是阻塞的,应用程序结束时函数返回
|
||||
*/
|
||||
void Run(RunnerPtr runner, bool debug = false);
|
||||
void Run(RunnerPtr runner);
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
|
|
@ -99,9 +99,9 @@ public:
|
|||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief »ñÈ¡Ö÷´°¿Ú
|
||||
* @brief »ñÈ¡´°¿Ú
|
||||
*/
|
||||
WindowPtr GetMainWindow() const;
|
||||
WindowPtr GetWindow() const;
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
|
|
@ -183,10 +183,10 @@ inline RunnerPtr Application::GetRunner() const
|
|||
return runner_;
|
||||
}
|
||||
|
||||
inline WindowPtr Application::GetMainWindow() const
|
||||
inline WindowPtr Application::GetWindow() const
|
||||
{
|
||||
KGE_ASSERT(runner_);
|
||||
return runner_->GetMainWindow();
|
||||
return runner_->GetWindow();
|
||||
}
|
||||
|
||||
inline TickerPtr Application::GetFrameTicker() const
|
||||
|
|
|
|||
|
|
@ -20,24 +20,25 @@
|
|||
|
||||
#include <kiwano/utils/Logger.h>
|
||||
#include <kiwano/platform/Runner.h>
|
||||
#include <kiwano/platform/Input.h>
|
||||
#include <kiwano/platform/Application.h>
|
||||
|
||||
#define KGE_MAX_SKIP_FRAMES 10
|
||||
#include <kiwano/render/Renderer.h>
|
||||
#include <kiwano/base/Director.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
|
||||
RunnerPtr Runner::Create(WindowPtr main_window)
|
||||
RunnerPtr Runner::Create(Settings settings)
|
||||
{
|
||||
RunnerPtr ptr = memory::New<Runner>();
|
||||
if (ptr)
|
||||
{
|
||||
ptr->SetMainWindow(main_window);
|
||||
ptr->SetSettings(settings);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
RunnerPtr Runner::Create(WindowPtr main_window, Function<void()> on_ready, Function<void()> on_destroy)
|
||||
RunnerPtr Runner::Create(Settings settings, Function<void()> on_ready, Function<void()> on_destroy)
|
||||
{
|
||||
class CallbackRunner : public Runner
|
||||
{
|
||||
|
|
@ -63,7 +64,7 @@ RunnerPtr Runner::Create(WindowPtr main_window, Function<void()> on_ready, Funct
|
|||
{
|
||||
ptr->on_ready = on_ready;
|
||||
ptr->on_destroy = on_destroy;
|
||||
ptr->SetMainWindow(main_window);
|
||||
ptr->SetSettings(settings);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
|
@ -72,6 +73,36 @@ Runner::Runner() {}
|
|||
|
||||
Runner::~Runner() {}
|
||||
|
||||
void Runner::InitSettings()
|
||||
{
|
||||
if (settings_.debug_mode)
|
||||
{
|
||||
// Show console window before creating main window
|
||||
Logger::GetInstance().ShowConsole(true);
|
||||
}
|
||||
|
||||
// Create game window
|
||||
WindowPtr window =
|
||||
Window::Create(settings_.title, settings_.width, settings_.height, settings_.icon, settings_.resizable);
|
||||
SetWindow(window);
|
||||
|
||||
// Update renderer settings
|
||||
Renderer::GetInstance().MakeContextForWindow(window);
|
||||
Renderer::GetInstance().SetClearColor(settings_.bg_color);
|
||||
Renderer::GetInstance().SetVSyncEnabled(settings_.vsync_enabled);
|
||||
|
||||
// Use defaut modules
|
||||
Application::GetInstance().Use(Input::GetInstance());
|
||||
Application::GetInstance().Use(Director::GetInstance());
|
||||
|
||||
// Enable debug mode
|
||||
if (settings_.debug_mode)
|
||||
{
|
||||
Director::GetInstance().ShowDebugInfo(true);
|
||||
Renderer::GetInstance().GetContext().SetCollectingStatus(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool Runner::MainLoop(Duration dt)
|
||||
{
|
||||
if (!main_window_)
|
||||
|
|
@ -79,7 +110,7 @@ bool Runner::MainLoop(Duration dt)
|
|||
|
||||
if (main_window_->ShouldClose())
|
||||
{
|
||||
if (this->OnClosing())
|
||||
if (this->OnClose())
|
||||
return false;
|
||||
|
||||
main_window_->SetShouldClose(false);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include <kiwano/core/Common.h>
|
||||
#include <kiwano/core/Time.h>
|
||||
#include <kiwano/platform/Window.h>
|
||||
#include <kiwano/render/Color.h>
|
||||
#include <kiwano/render/Texture.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
|
|
@ -30,26 +32,52 @@ class Application;
|
|||
|
||||
KGE_DECLARE_SMART_PTR(Runner);
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 游戏设置
|
||||
*/
|
||||
struct Settings
|
||||
{
|
||||
uint32_t width; ///< 窗口宽度
|
||||
uint32_t height; ///< 窗口高度
|
||||
String title; ///< 窗口标题
|
||||
uint32_t icon; ///< 窗口图标
|
||||
bool resizable; ///< 窗口大小可调整
|
||||
Color bg_color; ///< 窗口背景色
|
||||
bool vsync_enabled; ///< 垂直同步
|
||||
bool debug_mode; ///< 调试模式
|
||||
|
||||
Settings()
|
||||
: width(800)
|
||||
, height(600)
|
||||
, title("Kiwano")
|
||||
, icon()
|
||||
, resizable(false)
|
||||
, bg_color(Color::Black)
|
||||
, vsync_enabled(true)
|
||||
, debug_mode(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 程序运行器
|
||||
*/
|
||||
class KGE_API Runner : public ObjectBase
|
||||
{
|
||||
friend class Application;
|
||||
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 创建程序运行器
|
||||
/// @param main_window 主窗口
|
||||
static RunnerPtr Create(WindowPtr main_window);
|
||||
static RunnerPtr Create(Settings settings);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 创建程序运行器
|
||||
/// @param main_window 主窗口
|
||||
/// @param on_ready 应用程序初始化完成后执行的回调函数
|
||||
/// @param on_destroy 应用程序销毁时执行的回调函数
|
||||
static RunnerPtr Create(WindowPtr main_window, Function<void()> on_ready, Function<void()> on_destroy = nullptr);
|
||||
static RunnerPtr Create(Settings settings, Function<void()> on_ready, Function<void()> on_destroy = nullptr);
|
||||
|
||||
Runner();
|
||||
|
||||
|
|
@ -69,7 +97,7 @@ public:
|
|||
/// @brief 应用程序关闭处理
|
||||
/// @details 重载该函数以处理用户关闭应用程序时的行为,如保存用户数据等
|
||||
/// @return 返回true允许用户关闭程序,否则阻止程序关闭
|
||||
virtual bool OnClosing();
|
||||
virtual bool OnClose();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 应用程序主循环
|
||||
|
|
@ -79,14 +107,29 @@ public:
|
|||
virtual bool MainLoop(Duration dt);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief »ñÈ¡Ö÷´°¿Ú
|
||||
WindowPtr GetMainWindow() const;
|
||||
/// @brief 获取窗口
|
||||
WindowPtr GetWindow() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief ÉèÖÃÖ÷´°¿Ú
|
||||
void SetMainWindow(WindowPtr window);
|
||||
/// @brief 设置窗口
|
||||
void SetWindow(WindowPtr window);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取设置
|
||||
Settings GetSettings() const;
|
||||
|
||||
protected:
|
||||
/// \~chinese
|
||||
/// @brief 修改设置
|
||||
void SetSettings(Settings settings);
|
||||
|
||||
private:
|
||||
friend class Application;
|
||||
|
||||
void InitSettings();
|
||||
|
||||
private:
|
||||
Settings settings_;
|
||||
WindowPtr main_window_;
|
||||
};
|
||||
|
||||
|
|
@ -94,19 +137,29 @@ inline void Runner::OnReady() {}
|
|||
|
||||
inline void Runner::OnDestroy() {}
|
||||
|
||||
inline bool Runner::OnClosing()
|
||||
inline bool Runner::OnClose()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline WindowPtr Runner::GetMainWindow() const
|
||||
inline WindowPtr Runner::GetWindow() const
|
||||
{
|
||||
return main_window_;
|
||||
}
|
||||
|
||||
inline void Runner::SetMainWindow(WindowPtr window)
|
||||
inline void Runner::SetWindow(WindowPtr window)
|
||||
{
|
||||
main_window_ = window;
|
||||
}
|
||||
|
||||
inline Settings Runner::GetSettings() const
|
||||
{
|
||||
return settings_;
|
||||
}
|
||||
|
||||
inline void Runner::SetSettings(Settings settings)
|
||||
{
|
||||
settings_ = settings;
|
||||
}
|
||||
|
||||
} // namespace kiwano
|
||||
|
|
|
|||
|
|
@ -269,21 +269,6 @@ void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height,
|
|||
|
||||
::ShowWindow(handle_, SW_SHOWNORMAL);
|
||||
::UpdateWindow(handle_);
|
||||
|
||||
// Initialize Direct3D resources
|
||||
auto d3d_res = graphics::directx::GetD3DDeviceResources();
|
||||
|
||||
HRESULT hr = d3d_res->Initialize(handle_);
|
||||
|
||||
// Initialize Direct2D resources
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
auto d2d_res = graphics::directx::GetD2DDeviceResources();
|
||||
|
||||
hr = d2d_res->Initialize(d3d_res->GetDXGIDevice(), d3d_res->GetDXGISwapChain());
|
||||
}
|
||||
|
||||
KGE_THROW_IF_FAILED(hr, "Create DirectX resources failed");
|
||||
}
|
||||
|
||||
void WindowWin32Impl::PumpEvents()
|
||||
|
|
|
|||
|
|
@ -58,11 +58,41 @@ void RendererImpl::MakeContextForWindow(WindowPtr window)
|
|||
HWND target_window = window->GetHandle();
|
||||
output_size_ = window->GetSize();
|
||||
|
||||
d2d_res_ = graphics::directx::GetD2DDeviceResources();
|
||||
d3d_res_ = graphics::directx::GetD3DDeviceResources();
|
||||
|
||||
HRESULT hr = target_window ? S_OK : E_FAIL;
|
||||
|
||||
// Initialize Direct3D resources
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
auto d3d_res = graphics::directx::GetD3DDeviceResources();
|
||||
|
||||
hr = d3d_res->Initialize(target_window);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
d3d_res->DiscardResources();
|
||||
}
|
||||
else
|
||||
{
|
||||
d3d_res_ = d3d_res;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize Direct2D resources
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
auto d2d_res = graphics::directx::GetD2DDeviceResources();
|
||||
|
||||
hr = d2d_res->Initialize(d3d_res_->GetDXGIDevice(), d3d_res_->GetDXGISwapChain());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
d2d_res->DiscardResources();
|
||||
}
|
||||
else
|
||||
{
|
||||
d2d_res_ = d2d_res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initialize other device resources
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
@ -114,6 +144,8 @@ void RendererImpl::Destroy()
|
|||
{
|
||||
KGE_SYS_LOG("Destroying device resources");
|
||||
|
||||
if (d2d_res_)
|
||||
{
|
||||
d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.Get());
|
||||
res_font_file_loader_.Reset();
|
||||
|
||||
|
|
@ -121,8 +153,14 @@ void RendererImpl::Destroy()
|
|||
res_font_collection_loader_.Reset();
|
||||
|
||||
render_ctx_.Reset();
|
||||
d2d_res_.Reset();
|
||||
d2d_res_->DiscardResources();
|
||||
}
|
||||
|
||||
if (d3d_res_)
|
||||
{
|
||||
d3d_res_->DiscardResources();
|
||||
d3d_res_.Reset();
|
||||
}
|
||||
|
||||
::CoUninitialize();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,13 +79,13 @@ public:
|
|||
|
||||
void Resize(uint32_t width, uint32_t height) override;
|
||||
|
||||
protected:
|
||||
RendererImpl();
|
||||
|
||||
void MakeContextForWindow(WindowPtr window) override;
|
||||
|
||||
void Destroy() override;
|
||||
|
||||
protected:
|
||||
RendererImpl();
|
||||
|
||||
private:
|
||||
using ID2DDeviceResources = kiwano::graphics::directx::ID2DDeviceResources;
|
||||
using ID3DDeviceResources = kiwano::graphics::directx::ID3DDeviceResources;
|
||||
|
|
|
|||
|
|
@ -31,22 +31,6 @@ Renderer::Renderer()
|
|||
{
|
||||
}
|
||||
|
||||
void Renderer::SetupModule()
|
||||
{
|
||||
WindowPtr window = Application::GetInstance().GetMainWindow();
|
||||
MakeContextForWindow(window);
|
||||
}
|
||||
|
||||
void Renderer::DestroyModule()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void Renderer::HandleEvent(Event* evt)
|
||||
{
|
||||
// DO NOTHING
|
||||
}
|
||||
|
||||
void Renderer::BeginDraw()
|
||||
{
|
||||
KGE_ASSERT(render_ctx_);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace kiwano
|
|||
* \~chinese
|
||||
* @brief 渲染器
|
||||
*/
|
||||
class KGE_API Renderer : public EventModule
|
||||
class KGE_API Renderer : public Noncopyable
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
|
|
@ -235,20 +235,17 @@ public:
|
|||
/// @throw kiwano::SystemError 呈现失败时抛出
|
||||
virtual void Present() = 0;
|
||||
|
||||
public:
|
||||
void SetupModule() override;
|
||||
/// \~chinese
|
||||
/// @brief 为窗口创建渲染上下文
|
||||
virtual void MakeContextForWindow(WindowPtr window) = 0;
|
||||
|
||||
void DestroyModule() override;
|
||||
|
||||
void HandleEvent(Event* evt) override;
|
||||
/// \~chinese
|
||||
/// @brief 销毁渲染器资源
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
protected:
|
||||
Renderer();
|
||||
|
||||
virtual void MakeContextForWindow(WindowPtr window) = 0;
|
||||
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
protected:
|
||||
bool vsync_;
|
||||
Color clear_color_;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ StringView Trim(StringView str)
|
|||
while (std::isspace(str[end - 1]))
|
||||
--end;
|
||||
|
||||
if (end - start)
|
||||
if (end > start)
|
||||
return StringView(str.Data() + start, end - start);
|
||||
}
|
||||
return StringView();
|
||||
|
|
@ -158,6 +158,9 @@ bool ConfigIni::Save(std::ostream& os)
|
|||
std::sort(keys.begin(), keys.end());
|
||||
|
||||
// Output to ini
|
||||
std::ostream::sentry ok(os);
|
||||
if (ok)
|
||||
{
|
||||
for (const auto& key : keys)
|
||||
{
|
||||
os << '[' << key << ']' << std::endl;
|
||||
|
|
@ -167,7 +170,8 @@ bool ConfigIni::Save(std::ostream& os)
|
|||
}
|
||||
os << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return !os.fail();
|
||||
}
|
||||
|
||||
ConfigIni::SectionMap ConfigIni::GetSectionMap() const
|
||||
|
|
@ -177,23 +181,20 @@ ConfigIni::SectionMap ConfigIni::GetSectionMap() const
|
|||
|
||||
ConfigIni::ValueMap ConfigIni::GetSection(const String& section) const
|
||||
{
|
||||
auto iter = sections_.find(section);
|
||||
if (iter != sections_.end())
|
||||
return iter->second;
|
||||
if (HasSection(section))
|
||||
{
|
||||
return sections_.at(section);
|
||||
}
|
||||
return ValueMap();
|
||||
}
|
||||
|
||||
String ConfigIni::GetString(const String& section_name, const String& key) const
|
||||
String ConfigIni::GetString(const String& section, const String& key, const String& default_value) const
|
||||
{
|
||||
if (HasSection(section_name))
|
||||
if (HasKey(section, key))
|
||||
{
|
||||
const auto& section = sections_.at(section_name);
|
||||
|
||||
auto iter_key = section.find(key);
|
||||
if (iter_key != section.end())
|
||||
return iter_key->second;
|
||||
return sections_.at(section).at(key);
|
||||
}
|
||||
return String();
|
||||
return default_value;
|
||||
}
|
||||
|
||||
float ConfigIni::GetFloat(const String& section, const String& key, float default_value) const
|
||||
|
|
@ -274,7 +275,7 @@ bool ConfigIni::HasSection(const String& section) const
|
|||
return !!sections_.count(section);
|
||||
}
|
||||
|
||||
bool ConfigIni::HasValue(const String& section, const String& key) const
|
||||
bool ConfigIni::HasKey(const String& section, const String& key) const
|
||||
{
|
||||
if (HasSection(section))
|
||||
{
|
||||
|
|
@ -324,6 +325,22 @@ void ConfigIni::SetBool(const String& section, const String& key, bool value)
|
|||
SetString(section, key, value ? "true" : "false");
|
||||
}
|
||||
|
||||
void ConfigIni::DeleteSection(const String& section)
|
||||
{
|
||||
if (HasSection(section))
|
||||
{
|
||||
sections_.erase(section);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigIni::DeleteKey(const String& section, const String& key)
|
||||
{
|
||||
if (HasKey(section, key))
|
||||
{
|
||||
sections_.at(section).erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
ConfigIni::ValueMap& ConfigIni::operator[](const String& section)
|
||||
{
|
||||
if (!HasSection(section))
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 键值字典
|
||||
typedef Map<String, String> ValueMap;
|
||||
typedef UnorderedMap<String, String> ValueMap;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief Section字典
|
||||
|
|
@ -65,6 +65,17 @@ public:
|
|||
/// @param os 输出流
|
||||
bool Save(std::ostream& os);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 是否存在section
|
||||
/// @param section section的名称
|
||||
bool HasSection(const String& section) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 是否存在值
|
||||
/// @param section section的名称
|
||||
/// @param key key的名称
|
||||
bool HasKey(const String& section, const String& key) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取所有section
|
||||
SectionMap GetSectionMap() const;
|
||||
|
|
@ -78,7 +89,7 @@ public:
|
|||
/// @brief 获取值
|
||||
/// @param section section的名称
|
||||
/// @param key key的名称
|
||||
String GetString(const String& section, const String& key) const;
|
||||
String GetString(const String& section, const String& key, const String& default_value = String()) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取值
|
||||
|
|
@ -108,17 +119,6 @@ public:
|
|||
/// @param default_value 不存在时的默认值
|
||||
bool GetBool(const String& section, const String& key, bool default_value = false) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 是否存在section
|
||||
/// @param section section的名称
|
||||
bool HasSection(const String& section) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 是否存在值
|
||||
/// @param section section的名称
|
||||
/// @param key key的名称
|
||||
bool HasValue(const String& section, const String& key) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置所有section
|
||||
/// @param sections section字典
|
||||
|
|
@ -165,6 +165,17 @@ public:
|
|||
/// @param value 值
|
||||
void SetBool(const String& section, const String& key, bool value);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 删除section
|
||||
/// @param section section的名称
|
||||
void DeleteSection(const String& section);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 删除值
|
||||
/// @param section section的名称
|
||||
/// @param key key的名称
|
||||
void DeleteKey(const String& section, const String& key);
|
||||
|
||||
ValueMap& operator[](const String& section);
|
||||
|
||||
const ValueMap& operator[](const String& section) const;
|
||||
|
|
|
|||
Loading…
Reference in New Issue