refactoring

This commit is contained in:
Nomango 2019-01-24 12:21:01 +08:00 committed by Nomango
parent 3b5704ee22
commit de4751c2d3
63 changed files with 1107 additions and 1172 deletions

View File

@ -36,21 +36,19 @@
<ClInclude Include="..\..\src\core\Factory.h" />
<ClInclude Include="..\..\src\core\Font.hpp" />
<ClInclude Include="..\..\src\core\Frames.h" />
<ClInclude Include="..\..\src\core\Game.h" />
<ClInclude Include="..\..\src\core\Application.h" />
<ClInclude Include="..\..\src\core\Geometry.h" />
<ClInclude Include="..\..\src\core\GeometryNode.h" />
<ClInclude Include="..\..\src\core\helper.hpp" />
<ClInclude Include="..\..\src\core\Image.h" />
<ClInclude Include="..\..\src\core\include-forwards.h" />
<ClInclude Include="..\..\src\core\Input.h" />
<ClInclude Include="..\..\src\core\intrusive\List.hpp" />
<ClInclude Include="..\..\src\core\intrusive\SmartPtr.hpp" />
<ClInclude Include="..\..\src\core\KeyEvent.hpp" />
<ClInclude Include="..\..\src\core\IntrusiveList.hpp" />
<ClInclude Include="..\..\src\core\IntrusivePtr.hpp" />
<ClInclude Include="..\..\src\core\keys.hpp" />
<ClInclude Include="..\..\src\core\logs.h" />
<ClInclude Include="..\..\src\core\macros.h" />
<ClInclude Include="..\..\src\core\modules.h" />
<ClInclude Include="..\..\src\core\MouseEvent.hpp" />
<ClInclude Include="..\..\src\core\Music.h" />
<ClInclude Include="..\..\src\core\Node.h" />
<ClInclude Include="..\..\src\core\noncopyable.hpp" />
@ -102,7 +100,7 @@
<ClCompile Include="..\..\src\core\EventListener.cpp" />
<ClCompile Include="..\..\src\core\Factory.cpp" />
<ClCompile Include="..\..\src\core\Frames.cpp" />
<ClCompile Include="..\..\src\core\Game.cpp" />
<ClCompile Include="..\..\src\core\Application.cpp" />
<ClCompile Include="..\..\src\core\Geometry.cpp" />
<ClCompile Include="..\..\src\core\GeometryNode.cpp" />
<ClCompile Include="..\..\src\core\Image.cpp" />

View File

@ -17,9 +17,6 @@
<ClInclude Include="..\..\src\core\Color.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Game.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Image.h">
<Filter>core</Filter>
</ClInclude>
@ -125,12 +122,6 @@
<ClInclude Include="..\..\src\core\Font.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\intrusive\List.hpp">
<Filter>core\intrusive</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\intrusive\SmartPtr.hpp">
<Filter>core\intrusive</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Transform.hpp">
<Filter>core</Filter>
</ClInclude>
@ -167,15 +158,6 @@
<ClInclude Include="..\..\src\core\EventDispatcher.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Event.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\KeyEvent.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\MouseEvent.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\EventListener.h">
<Filter>core</Filter>
</ClInclude>
@ -203,6 +185,18 @@
<ClInclude Include="..\..\src\utils\ResLoader.h">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Application.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Event.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\IntrusiveList.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\IntrusivePtr.hpp">
<Filter>core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="core">
@ -217,9 +211,6 @@
<Filter Include="ui">
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
</Filter>
<Filter Include="core\intrusive">
<UniqueIdentifier>{0f508149-735a-43da-ab16-36cc1e9ab63a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\core\ActionCombined.cpp">
@ -237,9 +228,6 @@
<ClCompile Include="..\..\src\core\Color.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Game.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Image.cpp">
<Filter>core</Filter>
</ClCompile>
@ -354,5 +342,8 @@
<ClCompile Include="..\..\src\utils\ResLoader.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Application.cpp">
<Filter>core</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -36,21 +36,19 @@
<ClInclude Include="..\..\src\core\Factory.h" />
<ClInclude Include="..\..\src\core\Font.hpp" />
<ClInclude Include="..\..\src\core\Frames.h" />
<ClInclude Include="..\..\src\core\Game.h" />
<ClInclude Include="..\..\src\core\Application.h" />
<ClInclude Include="..\..\src\core\Geometry.h" />
<ClInclude Include="..\..\src\core\GeometryNode.h" />
<ClInclude Include="..\..\src\core\helper.hpp" />
<ClInclude Include="..\..\src\core\Image.h" />
<ClInclude Include="..\..\src\core\include-forwards.h" />
<ClInclude Include="..\..\src\core\Input.h" />
<ClInclude Include="..\..\src\core\intrusive\List.hpp" />
<ClInclude Include="..\..\src\core\intrusive\SmartPtr.hpp" />
<ClInclude Include="..\..\src\core\KeyEvent.hpp" />
<ClInclude Include="..\..\src\core\IntrusiveList.hpp" />
<ClInclude Include="..\..\src\core\IntrusivePtr.hpp" />
<ClInclude Include="..\..\src\core\keys.hpp" />
<ClInclude Include="..\..\src\core\logs.h" />
<ClInclude Include="..\..\src\core\macros.h" />
<ClInclude Include="..\..\src\core\modules.h" />
<ClInclude Include="..\..\src\core\MouseEvent.hpp" />
<ClInclude Include="..\..\src\core\Music.h" />
<ClInclude Include="..\..\src\core\Node.h" />
<ClInclude Include="..\..\src\core\noncopyable.hpp" />
@ -102,7 +100,7 @@
<ClCompile Include="..\..\src\core\EventListener.cpp" />
<ClCompile Include="..\..\src\core\Factory.cpp" />
<ClCompile Include="..\..\src\core\Frames.cpp" />
<ClCompile Include="..\..\src\core\Game.cpp" />
<ClCompile Include="..\..\src\core\Application.cpp" />
<ClCompile Include="..\..\src\core\Geometry.cpp" />
<ClCompile Include="..\..\src\core\GeometryNode.cpp" />
<ClCompile Include="..\..\src\core\Image.cpp" />

View File

@ -17,9 +17,6 @@
<ClInclude Include="..\..\src\core\Color.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Game.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Image.h">
<Filter>core</Filter>
</ClInclude>
@ -125,12 +122,6 @@
<ClInclude Include="..\..\src\core\Font.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\intrusive\List.hpp">
<Filter>core\intrusive</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\intrusive\SmartPtr.hpp">
<Filter>core\intrusive</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Transform.hpp">
<Filter>core</Filter>
</ClInclude>
@ -167,15 +158,6 @@
<ClInclude Include="..\..\src\core\EventDispatcher.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Event.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\KeyEvent.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\MouseEvent.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\EventListener.h">
<Filter>core</Filter>
</ClInclude>
@ -203,6 +185,18 @@
<ClInclude Include="..\..\src\utils\ResLoader.h">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Application.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Event.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\IntrusiveList.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\IntrusivePtr.hpp">
<Filter>core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="core">
@ -217,9 +211,6 @@
<Filter Include="ui">
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
</Filter>
<Filter Include="core\intrusive">
<UniqueIdentifier>{0f508149-735a-43da-ab16-36cc1e9ab63a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\core\ActionCombined.cpp">
@ -237,9 +228,6 @@
<ClCompile Include="..\..\src\core\Color.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Game.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Image.cpp">
<Filter>core</Filter>
</ClCompile>
@ -354,5 +342,8 @@
<ClCompile Include="..\..\src\utils\ResLoader.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Application.cpp">
<Filter>core</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -36,21 +36,19 @@
<ClInclude Include="..\..\src\core\Factory.h" />
<ClInclude Include="..\..\src\core\Font.hpp" />
<ClInclude Include="..\..\src\core\Frames.h" />
<ClInclude Include="..\..\src\core\Game.h" />
<ClInclude Include="..\..\src\core\Application.h" />
<ClInclude Include="..\..\src\core\Geometry.h" />
<ClInclude Include="..\..\src\core\GeometryNode.h" />
<ClInclude Include="..\..\src\core\helper.hpp" />
<ClInclude Include="..\..\src\core\Image.h" />
<ClInclude Include="..\..\src\core\include-forwards.h" />
<ClInclude Include="..\..\src\core\Input.h" />
<ClInclude Include="..\..\src\core\intrusive\List.hpp" />
<ClInclude Include="..\..\src\core\intrusive\SmartPtr.hpp" />
<ClInclude Include="..\..\src\core\KeyEvent.hpp" />
<ClInclude Include="..\..\src\core\IntrusiveList.hpp" />
<ClInclude Include="..\..\src\core\IntrusivePtr.hpp" />
<ClInclude Include="..\..\src\core\keys.hpp" />
<ClInclude Include="..\..\src\core\logs.h" />
<ClInclude Include="..\..\src\core\macros.h" />
<ClInclude Include="..\..\src\core\modules.h" />
<ClInclude Include="..\..\src\core\MouseEvent.hpp" />
<ClInclude Include="..\..\src\core\Music.h" />
<ClInclude Include="..\..\src\core\Node.h" />
<ClInclude Include="..\..\src\core\noncopyable.hpp" />
@ -102,7 +100,7 @@
<ClCompile Include="..\..\src\core\EventListener.cpp" />
<ClCompile Include="..\..\src\core\Factory.cpp" />
<ClCompile Include="..\..\src\core\Frames.cpp" />
<ClCompile Include="..\..\src\core\Game.cpp" />
<ClCompile Include="..\..\src\core\Application.cpp" />
<ClCompile Include="..\..\src\core\Geometry.cpp" />
<ClCompile Include="..\..\src\core\GeometryNode.cpp" />
<ClCompile Include="..\..\src\core\Image.cpp" />

View File

@ -17,9 +17,6 @@
<ClInclude Include="..\..\src\core\Color.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Game.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Image.h">
<Filter>core</Filter>
</ClInclude>
@ -125,12 +122,6 @@
<ClInclude Include="..\..\src\core\Font.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\intrusive\List.hpp">
<Filter>core\intrusive</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\intrusive\SmartPtr.hpp">
<Filter>core\intrusive</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Transform.hpp">
<Filter>core</Filter>
</ClInclude>
@ -167,15 +158,6 @@
<ClInclude Include="..\..\src\core\EventDispatcher.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Event.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\KeyEvent.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\MouseEvent.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\EventListener.h">
<Filter>core</Filter>
</ClInclude>
@ -203,6 +185,18 @@
<ClInclude Include="..\..\src\utils\ResLoader.h">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Application.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\Event.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\IntrusiveList.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\IntrusivePtr.hpp">
<Filter>core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="core">
@ -217,9 +211,6 @@
<Filter Include="ui">
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
</Filter>
<Filter Include="core\intrusive">
<UniqueIdentifier>{0f508149-735a-43da-ab16-36cc1e9ab63a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\core\ActionCombined.cpp">
@ -237,9 +228,6 @@
<ClCompile Include="..\..\src\core\Color.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Game.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Image.cpp">
<Filter>core</Filter>
</ClCompile>
@ -354,5 +342,8 @@
<ClCompile Include="..\..\src\utils\ResLoader.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\Application.cpp">
<Filter>core</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -22,21 +22,21 @@
#include "include-forwards.h"
#include "time.h"
#include "noncopyable.hpp"
#include "intrusive/List.hpp"
#include "IntrusiveList.hpp"
namespace easy2d
{
class ActionManager;
class Action
: public Object
, protected intrusive::ListItem<ActionPtr>
: public virtual Object
, protected IntrusiveListItem<ActionPtr>
{
friend class ActionManager;
friend class Loop;
friend class Sequence;
friend class Spawn;
friend class intrusive::List<ActionPtr>;
friend class IntrusiveList<ActionPtr>;
public:
Action() : running_(false), done_(false), initialized_(false) {}

View File

@ -25,7 +25,7 @@ namespace easy2d
{
class ActionManager
{
using Actions = intrusive::List<ActionPtr>;
using Actions = IntrusiveList<ActionPtr>;
public:
// 执行动作

View File

@ -18,15 +18,14 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "Game.h"
#include "Application.h"
#include "logs.h"
#include "modules.h"
#include "Factory.h"
#include "Event.hpp"
#include "Scene.h"
#include "DebugNode.h"
#include "Transition.h"
#include "KeyEvent.hpp"
#include "MouseEvent.hpp"
#include <windowsx.h>
#include <imm.h>
@ -34,29 +33,24 @@
namespace easy2d
{
Game::Game()
Application::Application(String const& app_name)
: active_(false)
, debug_(false)
, curr_scene_(nullptr)
, next_scene_(nullptr)
, transition_(nullptr)
, time_scale_(1.f)
, app_name_(app_name)
{
::CoInitialize(nullptr);
}
Game::Game(Options const & options)
: Game()
{
Init(options);
}
Game::~Game()
Application::~Application()
{
::CoUninitialize();
}
void Game::Init(const Options& options)
void Application::Init(const Options& options)
{
debug_ = options.debug;
@ -70,7 +64,7 @@ namespace easy2d
options.width,
options.height,
options.icon,
Game::WndProc,
Application::WndProc,
debug_
)
);
@ -78,7 +72,7 @@ namespace easy2d
HWND hwnd = Window::Instance()->GetHandle();
ThrowIfFailed(
Graphics::Instance()->Init(
RenderSystem::Instance()->Init(
hwnd,
options.vsync,
debug_
@ -126,11 +120,13 @@ namespace easy2d
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
}
// use Game instance in message loop
// use Application instance in message loop
::SetWindowLongW(hwnd, GWLP_USERDATA, PtrToUlong(this));
Setup();
}
void Game::Run()
void Application::Run()
{
HWND hwnd = Window::Instance()->GetHandle();
@ -148,14 +144,14 @@ namespace easy2d
}
}
void Game::Quit()
void Application::Quit()
{
Window::Instance()->Destroy();
}
void Game::EnterScene(ScenePtr const & scene)
void Application::EnterScene(ScenePtr const & scene)
{
E2D_ASSERT(scene && "Game::EnterScene failed, NULL pointer exception");
E2D_ASSERT(scene && "Application::EnterScene failed, NULL pointer exception");
if (curr_scene_ == scene || next_scene_ == scene)
return;
@ -163,7 +159,7 @@ namespace easy2d
next_scene_ = scene;
}
void Game::EnterScene(ScenePtr const& scene, TransitionPtr const& transition)
void Application::EnterScene(ScenePtr const& scene, TransitionPtr const& transition)
{
EnterScene(scene);
@ -178,17 +174,17 @@ namespace easy2d
}
}
ScenePtr const& Game::GetCurrentScene()
ScenePtr const& Application::GetCurrentScene()
{
return curr_scene_;
}
void Game::SetTimeScale(float scale)
void Application::SetTimeScale(float scale)
{
time_scale_ = scale;
}
void Game::Update()
void Application::Update()
{
static auto last = time::Now();
@ -229,12 +225,12 @@ namespace easy2d
DebugNode::Instance()->Update(dt);
}
void Game::Render(HWND hwnd)
void Application::Render(HWND hwnd)
{
auto graphics = Graphics::Instance();
auto rt = RenderSystem::Instance();
ThrowIfFailed(
graphics->BeginDraw(hwnd)
rt->BeginDraw(hwnd)
);
if (transition_)
@ -250,27 +246,18 @@ namespace easy2d
DebugNode::Instance()->Render();
ThrowIfFailed(
graphics->EndDraw()
rt->EndDraw()
);
if (active_)
::InvalidateRect(hwnd, NULL, FALSE);
}
void Game::Dispatch(Event * event)
LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (transition_)
return;
Application * app = reinterpret_cast<Application*>(::GetWindowLongW(hwnd, GWLP_USERDATA));
if (curr_scene_)
curr_scene_->DispatchEvent(event);
}
LRESULT CALLBACK Game::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
Game * game = reinterpret_cast<Game*>(::GetWindowLongW(hwnd, GWLP_USERDATA));
if (!game)
if (!app)
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
switch (msg)
@ -280,8 +267,8 @@ namespace easy2d
PAINTSTRUCT ps;
::BeginPaint(hwnd, &ps);
game->Update();
game->Render(hwnd);
app->Update();
app->Render(hwnd);
::EndPaint(hwnd, &ps);
@ -289,11 +276,25 @@ namespace easy2d
}
break;
case WM_KEYDOWN:
case WM_KEYUP:
{
if (!app->transition_ && app->curr_scene_)
{
Event evt((msg == WM_KEYDOWN) ? KeyboardEvent::Down : KeyboardEvent::Up);
evt.key.code = KeyCode(wparam);
evt.key.count = static_cast<int>(lparam & 0xFF);
app->curr_scene_->Dispatch(evt);
}
}
break;
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
//case WM_LBUTTONDBLCLK:
//case WM_MBUTTONUP:
//case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MBUTTONDOWN:
//case WM_MBUTTONDBLCLK:
case WM_RBUTTONUP:
case WM_RBUTTONDOWN:
@ -301,70 +302,36 @@ namespace easy2d
case WM_MOUSEMOVE:
case WM_MOUSEWHEEL:
{
float x = GET_X_LPARAM(lparam) * Window::Instance()->GetContentScaleX();
float y = GET_Y_LPARAM(lparam) * Window::Instance()->GetContentScaleY();
float wheel_delta = 0.f;
MouseEvent::Type type;
if (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN)
type = MouseEvent::Down;
else if (msg == WM_LBUTTONUP || msg == WM_RBUTTONUP)
type = MouseEvent::Up;
else if (msg == WM_MOUSEMOVE)
type = MouseEvent::Move;
else
if (!app->transition_ && app->curr_scene_)
{
type = MouseEvent::Wheel;
wheel_delta = GET_WHEEL_DELTA_WPARAM(wparam) / 120.f;
Event evt;
evt.mouse.x = GET_X_LPARAM(lparam) * Window::Instance()->GetContentScaleX();
evt.mouse.y = GET_Y_LPARAM(lparam) * Window::Instance()->GetContentScaleY();
evt.mouse.left_btn_down = !!(wparam & MK_LBUTTON);
evt.mouse.left_btn_down = !!(wparam & MK_RBUTTON);
if (msg == WM_MOUSEMOVE)
evt.type = MouseEvent::Move;
else if (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN)
evt.type = MouseEvent::Down;
else if (msg == WM_LBUTTONUP || msg == WM_RBUTTONUP || msg == WM_MBUTTONUP)
evt.type = MouseEvent::Up;
else
{
evt.type = MouseEvent::Wheel;
evt.mouse.wheel_delta = GET_WHEEL_DELTA_WPARAM(wparam) / 120.f;
}
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP)
evt.mouse.button = MouseButton::Left;
else if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONUP)
evt.mouse.button = MouseButton::Right;
else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONUP)
evt.mouse.button = MouseButton::Middle;
app->curr_scene_->Dispatch(evt);
}
MouseEvent event(type, x, y, wheel_delta);
if (wparam & MK_LBUTTON || wparam & MK_RBUTTON)
event.button_down = true;
game->Dispatch(&event);
}
break;
case WM_KEYDOWN:
case WM_KEYUP:
{
KeyEvent event(msg, KeyCode(wparam));
game->Dispatch(&event);
}
break;
case WM_DISPLAYCHANGE:
{
E2D_LOG(L"The display resolution has changed");
::InvalidateRect(hwnd, nullptr, FALSE);
}
break;
case WM_CLOSE:
{
E2D_LOG(L"Received a message to close the window");
SysEvent event(SysEvent::WindowClose);
game->Dispatch(&event);
if (game->OnClose())
{
::DestroyWindow(hwnd);
}
return 0;
}
break;
case WM_DESTROY:
{
E2D_LOG(L"Window was destroyed");
game->OnExit();
::PostQuitMessage(0);
return 0;
}
break;
@ -372,13 +339,13 @@ namespace easy2d
{
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
{
game->active_ = false;
app->active_ = false;
E2D_LOG(L"Window minimized");
}
else if (SIZE_RESTORED == wparam)
{
game->active_ = true;
app->active_ = true;
::InvalidateRect(hwnd, nullptr, FALSE);
E2D_LOG(L"Window restored");
@ -390,7 +357,7 @@ namespace easy2d
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
Graphics::Instance()->Resize(width, height);
RenderSystem::Instance()->Resize(width, height);
}
break;
@ -401,15 +368,21 @@ namespace easy2d
{
E2D_LOG(L"Window activated");
SysEvent event(SysEvent::WindowActivate);
game->Dispatch(&event);
if (app->curr_scene_)
{
Event evt(WindowEvent::Activate);
app->curr_scene_->Dispatch(evt);
}
}
else
{
E2D_LOG(L"Window deactivated");
SysEvent event(SysEvent::WindowDeavtivate);
game->Dispatch(&event);
if (app->curr_scene_)
{
Event evt(WindowEvent::Deavtivate);
app->curr_scene_->Dispatch(evt);
}
}
}
break;
@ -425,6 +398,37 @@ namespace easy2d
E2D_LOG(L"Window icon changed");
}
break;
case WM_DISPLAYCHANGE:
{
E2D_LOG(L"The display resolution has changed");
::InvalidateRect(hwnd, nullptr, FALSE);
}
break;
case WM_CLOSE:
{
E2D_LOG(L"Received a message to close the window");
if (app->curr_scene_)
{
Event evt(WindowEvent::Closing);
app->curr_scene_->Dispatch(evt);
}
::DestroyWindow(hwnd);
return 0;
}
break;
case WM_DESTROY:
{
E2D_LOG(L"Window was destroyed");
::PostQuitMessage(0);
return 0;
}
break;
}
return ::DefWindowProcW(hwnd, msg, wparam, lparam);

View File

@ -25,7 +25,6 @@
#include "render.h"
#include "input.h"
#include "audio.h"
#include "Event.hpp"
namespace easy2d
{
@ -49,23 +48,18 @@ namespace easy2d
};
class Game
class Application
: protected Noncopyable
{
public:
Game();
Game(
Options const& options
Application(
String const& app_name = L"Easy2dGame"
);
virtual ~Game();
virtual ~Application();
// 退出游戏
virtual void OnExit() {}
// 窗口关闭
virtual bool OnClose() { return true; }
// Æô¶¯
virtual void Setup() {}
// ³õʼ»¯
void Init(
@ -100,18 +94,15 @@ namespace easy2d
void Update();
void Dispatch(
Event* event
);
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
private:
bool debug_;
bool active_;
float time_scale_;
ScenePtr curr_scene_;
ScenePtr next_scene_;
String app_name_;
ScenePtr curr_scene_;
ScenePtr next_scene_;
TransitionPtr transition_;
};
}

View File

@ -32,7 +32,7 @@ namespace easy2d
, stroke_width_(1.0f)
{
ThrowIfFailed(
Graphics::Instance()->CreateBitmapRenderTarget(render_target_)
RenderSystem::Instance()->CreateBitmapRenderTarget(render_target_)
);
auto properties = D2D1::BrushProperties();
@ -105,7 +105,7 @@ namespace easy2d
if (bitmap_cached_)
{
Graphics::Instance()->DrawBitmap(bitmap_cached_);
RenderSystem::Instance()->DrawBitmap(bitmap_cached_);
}
}

View File

@ -224,11 +224,9 @@ namespace easy2d
D2DBitmapPtr const& GetBitmap() const;
protected:
mutable bool cache_expired_;
mutable D2DBitmapPtr bitmap_cached_;
float stroke_width_;
Font text_font_;
TextStyle text_style_;
float stroke_width_;
Font text_font_;
TextStyle text_style_;
D2DPathGeometryPtr current_geometry_;
D2DGeometrySinkPtr current_sink_;
D2DStrokeStylePtr outline_join_style_;
@ -237,5 +235,8 @@ namespace easy2d
D2DSolidColorBrushPtr text_brush_;
D2DTextRendererPtr text_renderer_;
D2DBitmapRenderTargetPtr render_target_;
mutable bool cache_expired_;
mutable D2DBitmapPtr bitmap_cached_;
};
}

View File

@ -28,8 +28,7 @@
namespace easy2d
{
DebugNodeImpl::DebugNodeImpl()
DebugNode::DebugNode()
{
debug_text_ = new Text();
debug_text_->SetPosition(15, 15);
@ -46,11 +45,11 @@ namespace easy2d
debug_text_->SetStyle(style);
}
DebugNodeImpl::~DebugNodeImpl()
DebugNode::~DebugNode()
{
}
void DebugNodeImpl::AddDebugText(String const & text)
void DebugNode::AddDebugText(String const & text)
{
try
{
@ -61,29 +60,29 @@ namespace easy2d
}
}
void DebugNodeImpl::ClearDebugText()
void DebugNode::ClearDebugText()
{
texts_.clear();
}
void DebugNodeImpl::OnRender()
void DebugNode::OnRender()
{
auto graphics = Graphics::Instance();
auto rt = RenderSystem::Instance();
graphics->SetTransform(Matrix{});
rt->SetTransform(Matrix{});
graphics->GetSolidBrush()->SetColor(Color(0.0f, 0.0f, 0.0f, 0.5f));
rt->GetSolidBrush()->SetColor(Color(0.0f, 0.0f, 0.0f, 0.5f));
graphics->GetRenderTarget()->FillRoundedRectangle(
rt->GetRenderTarget()->FillRoundedRectangle(
D2D1::RoundedRect(
D2D1_RECT_F{ 10, 10, 200, 120 },
6.f,
6.f),
graphics->GetSolidBrush().Get()
rt->GetSolidBrush().Get()
);
}
void DebugNodeImpl::OnUpdate(Duration const & dt)
void DebugNode::OnUpdate(Duration const & dt)
{
try
{
@ -106,9 +105,9 @@ namespace easy2d
ss << "Objects: " << Object::__GetTracingObjects().size() << std::endl;
#endif
ss << "Render: " << Graphics::Instance()->GetStatus().duration.Milliseconds() << "ms" << std::endl;
ss << "Render: " << RenderSystem::Instance()->GetStatus().duration.Milliseconds() << "ms" << std::endl;
ss << "Primitives / sec: " << Graphics::Instance()->GetStatus().primitives * frame_time_.size() << std::endl;
ss << "Primitives / sec: " << RenderSystem::Instance()->GetStatus().primitives * frame_time_.size() << std::endl;
PROCESS_MEMORY_COUNTERS_EX pmc;
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));

View File

@ -25,15 +25,16 @@
namespace easy2d
{
class DebugNodeImpl
class DebugNode
: public Node
, public ISingleton<DebugNode>
{
E2D_DECLARE_SINGLETON(DebugNodeImpl);
E2D_DECLARE_SINGLETON(DebugNode);
public:
DebugNodeImpl();
DebugNode();
virtual ~DebugNodeImpl();
virtual ~DebugNode();
void AddDebugText(String const& text);
@ -48,6 +49,4 @@ namespace easy2d
Array<TimePoint> frame_time_;
Array<String> texts_;
};
E2D_DECLARE_SINGLETON_TYPE(DebugNodeImpl, DebugNode);
}

View File

@ -20,39 +20,116 @@
#pragma once
#include "macros.h"
#include "keys.hpp"
namespace easy2d
{
typedef UINT EventType;
class Event
// 鼠标事件
struct MouseEvent
{
public:
Event(EventType type) : type(type), has_target(false) {}
enum Type : EventType
{
First = WM_MOUSEFIRST,
virtual ~Event() {}
Move, // 移动
Down, // 按下
Up, // 抬起
Wheel, // 滚轮滚动
EventType type;
bool has_target;
Hover, // 鼠标移入
Out, // 鼠标移出
Click, // 鼠标点击
Last // 结束标志
};
float x;
float y;
bool left_btn_down; // 左键是否按下
bool right_btn_down; // 右键是否按下
struct
{
MouseButton button; // 仅当消息类型为 Down | Up | Click 时有效
};
struct
{
float wheel_delta; // 仅当消息类型为 Wheel 时有效
};
static inline bool Check(EventType type)
{
return type > Type::First && type < Type::Last;
}
};
class SysEvent
: public Event
// 键盘事件
struct KeyboardEvent
{
public:
enum Type
enum Type : UINT
{
First = WM_NULL,
First = WM_KEYFIRST,
WindowActivate, // 窗口获得焦点
WindowDeavtivate, // 窗口失去焦点
WindowClose, // 关闭窗口
Down, // 键按下
Up, // 键抬起
Last
};
SysEvent(EventType type) : Event(type) {}
KeyCode code;
int count;
static bool Check(Event* e) { return e->type > Type::First && e->type < Type::Last; }
static inline bool Check(UINT type)
{
return type > Type::First && type < Type::Last;
}
};
// 窗口事件
struct WindowEvent
{
public:
enum Type : EventType
{
First = WM_NULL,
Activate, // 窗口获得焦点
Deavtivate, // 窗口失去焦点
Closing, // 关闭窗口
Last
};
static inline bool Check(EventType type)
{
return type > Type::First && type < Type::Last;
}
};
// 事件
struct Event
{
EventType type;
bool has_target;
union
{
MouseEvent mouse;
KeyboardEvent key;
WindowEvent win;
};
Event()
: type(0)
, has_target(false)
{}
Event(EventType type)
: type(type)
, has_target(false)
{}
};
}

View File

@ -23,7 +23,7 @@
namespace easy2d
{
void EventDispatcher::DispatchEvent(Event* e)
void EventDispatcher::Dispatch(Event& evt)
{
if (listeners_.IsEmpty())
return;
@ -33,9 +33,9 @@ namespace easy2d
{
next = listener->NextItem();
if (listener->type_ == e->type)
if (listener->type_ == evt.type)
{
listener->callback_(e);
listener->callback_(evt);
}
}
}

View File

@ -25,7 +25,7 @@ namespace easy2d
{
class EventDispatcher
{
using Listeners = intrusive::List<EventListenerPtr>;
using Listeners = IntrusiveList<EventListenerPtr>;
public:
// 添加监听器
@ -70,7 +70,7 @@ namespace easy2d
EventType type
);
virtual void DispatchEvent(Event* e);
virtual void Dispatch(Event& evt);
protected:
Listeners listeners_;

View File

@ -20,22 +20,21 @@
#pragma once
#include "include-forwards.h"
#include "intrusive/List.hpp"
#include "IntrusiveList.hpp"
#include "Event.hpp"
namespace easy2d
{
typedef std::function<void(Event*)> EventCallback;
using EventCallback = std::function<void(Event const&)>;
class EventDispatcher;
class EventListener
: public Object
, protected intrusive::ListItem<EventListenerPtr>
: public virtual Object
, protected IntrusiveListItem<EventListenerPtr>
{
friend class EventDispatcher;
friend class intrusive::List<EventListenerPtr>;
friend class IntrusiveList<EventListenerPtr>;
public:
EventListener(

View File

@ -25,18 +25,18 @@
namespace easy2d
{
FactoryImpl::FactoryImpl()
Factory::Factory()
{
}
FactoryImpl::~FactoryImpl()
Factory::~Factory()
{
E2D_LOG(L"Destroying device independent resources");
E2D_LOG(L"Destroying device-independent resources");
}
HRESULT FactoryImpl::Init(bool debug)
HRESULT Factory::Init(bool debug)
{
E2D_LOG(L"Creating device independent resources");
E2D_LOG(L"Creating device-independent resources");
D2D1_FACTORY_OPTIONS fact_options;
fact_options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE;
@ -111,7 +111,7 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateHwndRenderTarget(D2DHwndRenderTargetPtr & hwnd_render_target, D2D1_RENDER_TARGET_PROPERTIES const & properties, D2D1_HWND_RENDER_TARGET_PROPERTIES const & hwnd_rt_properties) const
HRESULT Factory::CreateHwndRenderTarget(D2DHwndRenderTargetPtr & hwnd_render_target, D2D1_RENDER_TARGET_PROPERTIES const & properties, D2D1_HWND_RENDER_TARGET_PROPERTIES const & hwnd_rt_properties) const
{
if (!factory_)
return E_UNEXPECTED;
@ -128,7 +128,7 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateTextRenderer(
HRESULT Factory::CreateTextRenderer(
D2DTextRendererPtr& text_renderer,
D2DRenderTargetPtr const& render_target,
D2DSolidColorBrushPtr const& brush
@ -150,20 +150,18 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateBitmapFromFile(D2DBitmapPtr & bitmap, D2DRenderTargetPtr const & rt, String const & file_path)
HRESULT Factory::CreateBitmapFromFile(D2DBitmapPtr & bitmap, D2DRenderTargetPtr const & rt, String const & file_path)
{
if (imaging_factory_ == nullptr)
{
return E_UNEXPECTED;
}
using namespace intrusive;
SmartPtr<IWICBitmapDecoder> decoder;
SmartPtr<IWICBitmapFrameDecode> source;
SmartPtr<IWICStream> stream;
SmartPtr<IWICFormatConverter> converter;
SmartPtr<ID2D1Bitmap> bitmap_tmp;
IntrusivePtr<IWICBitmapDecoder> decoder;
IntrusivePtr<IWICBitmapFrameDecode> source;
IntrusivePtr<IWICStream> stream;
IntrusivePtr<IWICFormatConverter> converter;
IntrusivePtr<ID2D1Bitmap> bitmap_tmp;
HRESULT hr = imaging_factory_->CreateDecoderFromFilename(
file_path.c_str(),
@ -211,20 +209,18 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateBitmapFromResource(D2DBitmapPtr & bitmap, D2DRenderTargetPtr const & rt, Resource const & res)
HRESULT Factory::CreateBitmapFromResource(D2DBitmapPtr & bitmap, D2DRenderTargetPtr const & rt, Resource const & res)
{
if (imaging_factory_ == nullptr)
{
return E_UNEXPECTED;
}
using namespace intrusive;
SmartPtr<IWICBitmapDecoder> decoder;
SmartPtr<IWICBitmapFrameDecode> source;
SmartPtr<IWICStream> stream;
SmartPtr<IWICFormatConverter> converter;
SmartPtr<ID2D1Bitmap> bitmap_tmp;
IntrusivePtr<IWICBitmapDecoder> decoder;
IntrusivePtr<IWICBitmapFrameDecode> source;
IntrusivePtr<IWICStream> stream;
IntrusivePtr<IWICFormatConverter> converter;
IntrusivePtr<ID2D1Bitmap> bitmap_tmp;
// ¼ÓÔØ×ÊÔ´
LPVOID buffer;
@ -294,7 +290,7 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateRectangleGeometry(D2DRectangleGeometryPtr & geo, Rect const& rect) const
HRESULT Factory::CreateRectangleGeometry(D2DRectangleGeometryPtr & geo, Rect const& rect) const
{
if (!factory_)
return E_UNEXPECTED;
@ -310,7 +306,7 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateRoundedRectangleGeometry(D2DRoundedRectangleGeometryPtr & geo, Rect const & rect, float radius_x, float radius_y) const
HRESULT Factory::CreateRoundedRectangleGeometry(D2DRoundedRectangleGeometryPtr & geo, Rect const & rect, float radius_x, float radius_y) const
{
if (!factory_)
return E_UNEXPECTED;
@ -330,7 +326,7 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateEllipseGeometry(D2DEllipseGeometryPtr & geo, Point const & center, float radius_x, float radius_y) const
HRESULT Factory::CreateEllipseGeometry(D2DEllipseGeometryPtr & geo, Point const & center, float radius_x, float radius_y) const
{
if (!factory_)
return E_UNEXPECTED;
@ -350,7 +346,7 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateTransformedGeometry(
HRESULT Factory::CreateTransformedGeometry(
D2DTransformedGeometryPtr& transformed,
Matrix const& matrix,
D2DGeometryPtr const& geo
@ -373,7 +369,7 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreatePathGeometry(D2DPathGeometryPtr & geometry) const
HRESULT Factory::CreatePathGeometry(D2DPathGeometryPtr & geometry) const
{
if (!factory_)
return E_UNEXPECTED;
@ -381,7 +377,7 @@ namespace easy2d
return factory_->CreatePathGeometry(&geometry);
}
HRESULT FactoryImpl::CreateTextFormat(D2DTextFormatPtr & text_format, Font const & font, TextStyle const & text_style) const
HRESULT Factory::CreateTextFormat(D2DTextFormatPtr & text_format, Font const & font, TextStyle const & text_style) const
{
if (!write_factory_)
return E_UNEXPECTED;
@ -419,7 +415,7 @@ namespace easy2d
return hr;
}
HRESULT FactoryImpl::CreateTextLayout(D2DTextLayoutPtr & text_layout, Size& layout_size, String const & text, D2DTextFormatPtr const& text_format, TextStyle const & text_style) const
HRESULT Factory::CreateTextLayout(D2DTextLayoutPtr & text_layout, Size& layout_size, String const & text, D2DTextFormatPtr const& text_format, TextStyle const & text_style) const
{
if (!write_factory_)
return E_UNEXPECTED;
@ -497,7 +493,7 @@ namespace easy2d
return hr;
}
D2DStrokeStylePtr const& FactoryImpl::GetStrokeStyle(StrokeStyle stroke) const
D2DStrokeStylePtr const& Factory::GetStrokeStyle(StrokeStyle stroke) const
{
switch (stroke)
{

View File

@ -25,14 +25,13 @@
#include "Resource.h"
#include "TextRenderer.h"
#include "TextStyle.hpp"
#include "../math/Matrix.hpp"
namespace easy2d
{
class FactoryImpl
: protected Noncopyable
class Factory
: public ISingleton<Factory>
{
E2D_DECLARE_SINGLETON(FactoryImpl);
E2D_DECLARE_SINGLETON(Factory);
public:
HRESULT Init(bool debug);
@ -109,9 +108,9 @@ namespace easy2d
) const;
protected:
FactoryImpl();
Factory();
~FactoryImpl();
~Factory();
protected:
D2DFactoryPtr factory_;
@ -121,6 +120,4 @@ namespace easy2d
D2DStrokeStylePtr bevel_stroke_style_;
D2DStrokeStylePtr round_stroke_style_;
};
E2D_DECLARE_SINGLETON_TYPE(FactoryImpl, Factory);
}

View File

@ -26,7 +26,7 @@ namespace easy2d
{
// Ö¡¼¯ºÏ
class Frames
: public Object
: public virtual Object
{
public:
Frames();

View File

@ -25,7 +25,7 @@ namespace easy2d
{
// 섯부녜蹶
class Geometry
: public RefCounter
: public virtual Object
{
friend class Canvas;
friend class GeometryNode;

View File

@ -70,14 +70,14 @@ namespace easy2d
{
if (geometry_ && geometry_->geo_)
{
auto graphics = Graphics::Instance();
auto rt = RenderSystem::Instance();
graphics->FillGeometry(
rt->FillGeometry(
geometry_->geo_,
fill_color_
);
graphics->DrawGeometry(
rt->DrawGeometry(
geometry_->geo_,
stroke_color_,
stroke_width_,

View File

@ -67,11 +67,11 @@ namespace easy2d
logs::Warningln(L"Image file '%s' not found!", res.GetFileName());
return false;
}
hr = Graphics::Instance()->CreateBitmapFromFile(bitmap, res.GetFileName());
hr = RenderSystem::Instance()->CreateBitmapFromFile(bitmap, res.GetFileName());
}
else
{
hr = Graphics::Instance()->CreateBitmapFromResource(bitmap, res);
hr = RenderSystem::Instance()->CreateBitmapFromResource(bitmap, res);
}
if (FAILED(hr))

View File

@ -26,7 +26,7 @@ namespace easy2d
{
// ͼƬ
class Image
: public Object
: public virtual Object
{
public:
Image();

View File

@ -24,7 +24,7 @@
namespace easy2d
{
InputDevice::InputDevice()
Input::Input()
: hwnd_(nullptr)
, scale_x_(1.f)
, scale_y_(1.f)
@ -33,12 +33,12 @@ namespace easy2d
ZeroMemory(keys_cache_, sizeof(keys_cache_));
}
InputDevice::~InputDevice()
Input::~Input()
{
E2D_LOG(L"Destroying input device");
}
HRESULT InputDevice::Init(HWND hwnd, float scale_x, float scale_y, bool debug)
HRESULT Input::Init(HWND hwnd, float scale_x, float scale_y, bool debug)
{
E2D_LOG(L"Initing input device");
@ -49,47 +49,47 @@ namespace easy2d
return S_OK;
}
void InputDevice::Update()
void Input::Update()
{
memcpy(keys_cache_, keys_, sizeof(keys_cache_));
GetKeyboardState(keys_);
}
bool InputDevice::IsDown(KeyCode code)
bool Input::IsDown(KeyCode code)
{
return !!(keys_[static_cast<int>(code)] & 0x80);
}
bool InputDevice::IsDown(MouseButton btn)
bool Input::IsDown(MouseButton btn)
{
return !!(keys_[static_cast<int>(btn)] & 0x80);
}
bool InputDevice::WasPressed(KeyCode code)
bool Input::WasPressed(KeyCode code)
{
return !(keys_cache_[static_cast<int>(code)] & 0x80)
&& (keys_[static_cast<int>(code)] & 0x80);
}
bool InputDevice::WasPressed(MouseButton btn)
bool Input::WasPressed(MouseButton btn)
{
return !(keys_cache_[static_cast<int>(btn)] & 0x80)
&& (keys_[static_cast<int>(btn)] & 0x80);
}
bool InputDevice::WasReleased(KeyCode code)
bool Input::WasReleased(KeyCode code)
{
return (keys_cache_[static_cast<int>(code)] & 0x80)
&& !(keys_[static_cast<int>(code)] & 0x80);
}
bool InputDevice::WasReleased(MouseButton btn)
bool Input::WasReleased(MouseButton btn)
{
return (keys_cache_[static_cast<int>(btn)] & 0x80)
&& !(keys_[static_cast<int>(btn)] & 0x80);
}
float InputDevice::GetMouseX()
float Input::GetMouseX()
{
POINT pos;
::GetCursorPos(&pos);
@ -97,7 +97,7 @@ namespace easy2d
return pos.x * scale_x_;
}
float InputDevice::GetMouseY()
float Input::GetMouseY()
{
POINT pos;
::GetCursorPos(&pos);
@ -105,7 +105,7 @@ namespace easy2d
return pos.y * scale_y_;
}
Point InputDevice::GetMousePos()
Point Input::GetMousePos()
{
POINT pos;
::GetCursorPos(&pos);

View File

@ -25,19 +25,10 @@
namespace easy2d
{
// 報炎囚峙
enum class MouseButton : int
class Input
: public ISingleton<Input>
{
Left = VK_LBUTTON, // 報炎恣囚
Right = VK_RBUTTON, // 報炎嘔囚
Middle = VK_MBUTTON // 報炎嶄囚
};
class InputDevice
: protected Noncopyable
{
E2D_DECLARE_SINGLETON(InputDevice);
E2D_DECLARE_SINGLETON(Input);
public:
HRESULT Init(HWND hwnd, float scale_x, float scale_y, bool debug);
@ -84,9 +75,9 @@ namespace easy2d
void Update();
protected:
InputDevice();
Input();
~InputDevice();
~Input();
protected:
HWND hwnd_;
@ -95,6 +86,4 @@ namespace easy2d
BYTE keys_[256];
BYTE keys_cache_[256];
};
E2D_DECLARE_SINGLETON_TYPE(InputDevice, Input);
}

254
src/core/IntrusiveList.hpp Normal file
View File

@ -0,0 +1,254 @@
// Copyright (c) 2016-2018 Easy2D - Nomango
//
// 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 "macros.h"
#include <functional>
#undef DEBUG_CHECK_LIST
#ifdef E2D_DEBUG
# define DEBUG_CHECK_LIST(list_ptr) list_ptr->Check()
#else
# define DEBUG_CHECK_LIST __noop
#endif
namespace easy2d
{
template <typename T> class IntrusiveList;
template <typename T>
class IntrusiveListItem
{
T prev_;
T next_;
template <typename U>
friend class IntrusiveList;
public:
using ItemType = T;
IntrusiveListItem() : prev_(), next_() {}
T const& PrevItem() const { return prev_; }
T& PrevItem() { return prev_; }
T const& NextItem() const { return next_; }
T& NextItem() { return next_; }
};
template <typename T>
class IntrusiveList
{
T first_;
T last_;
public:
using ItemType = T;
IntrusiveList() : first_(), last_() {}
~IntrusiveList() { Clear(); }
T const& First() const { return first_; }
T& First() { return first_; }
T const& Last() const { return last_; }
T& Last() { return last_; }
bool IsEmpty() const { return !first_; }
void PushBack(T const& child)
{
if (child->prev_)
child->prev_->next_ = child->next_;
if (child->next_)
child->next_->prev_ = child->prev_;
child->prev_ = last_;
child->next_ = nullptr;
if (first_)
{
last_->next_ = child;
}
else
{
first_ = child;
}
last_ = child;
DEBUG_CHECK_LIST(this);
}
void PushFront(T const& child)
{
if (child->prev_)
child->prev_->next_ = child->next_;
if (child->next_)
child->next_->prev_ = child->prev_;
child->prev_ = nullptr;
child->next_ = first_;
if (first_)
{
first_->prev_ = child;
}
else
{
last_ = child;
}
first_ = child;
DEBUG_CHECK_LIST(this);
}
void InsertBefore(T const& child, T const& before)
{
if (child->prev_)
child->prev_->next_ = child->next_;
if (child->next_)
child->next_->prev_ = child->prev_;
if (before->prev_)
before->prev_->next_ = child;
else
first_ = child;
child->prev_ = before->prev_;
child->next_ = before;
before->prev_ = child;
DEBUG_CHECK_LIST(this);
}
void InsertAfter(T const& child, T const& after)
{
if (child->prev_)
child->prev_->next_ = child->next_;
if (child->next_)
child->next_->prev_ = child->prev_;
if (after->next_)
after->next_->prev_ = child;
else
last_ = child;
child->next_ = after->next_;
child->prev_ = after;
after->next_ = child;
DEBUG_CHECK_LIST(this);
}
void Remove(T const& child)
{
#ifdef E2D_DEBUG
T tmp = first_;
while (tmp != child)
{
if (tmp == last_)
E2D_ASSERT(false && "The node to be removed is not in this list");
tmp = tmp->next_;
}
#endif
if (child->next_)
{
child->next_->prev_ = child->prev_;
}
else
{
last_ = child->prev_;
}
if (child->prev_)
{
child->prev_->next_ = child->next_;
}
else
{
first_ = child->next_;
}
child->prev_ = nullptr;
child->next_ = nullptr;
DEBUG_CHECK_LIST(this);
}
void Clear()
{
T p = first_;
while (p)
{
T tmp = p;
p = p->next_;
if (tmp)
{
tmp->next_ = nullptr;
tmp->prev_ = nullptr;
}
}
first_ = nullptr;
last_ = nullptr;
}
#ifdef E2D_DEBUG
private:
void Check()
{
if (!first_)
return;
int pos = 0;
T p = first_;
T tmp = p;
do
{
tmp = p;
p = p->next_;
++pos;
if (p)
{
E2D_ASSERT(p->prev_ == tmp && "Check list failed");
}
else
{
E2D_ASSERT(tmp == last_ && "Check list failed");
}
} while (p);
}
#endif
};
}
#undef DEBUG_CHECK_LIST

201
src/core/IntrusivePtr.hpp Normal file
View File

@ -0,0 +1,201 @@
// Copyright (c) 2016-2018 Easy2D - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining lhs 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 "macros.h"
#include <utility>
namespace easy2d
{
template <typename T>
class IntrusivePtr
{
T* ptr_{ nullptr };
public:
using Type = T;
IntrusivePtr() E2D_NOEXCEPT {}
IntrusivePtr(nullptr_t) E2D_NOEXCEPT {}
IntrusivePtr(Type* p) E2D_NOEXCEPT : ptr_(p)
{
IntrusivePtrAddRef(ptr_);
}
IntrusivePtr(const IntrusivePtr& other) E2D_NOEXCEPT
: ptr_(other.ptr_)
{
IntrusivePtrAddRef(ptr_);
}
template <typename U>
IntrusivePtr(const IntrusivePtr<U>& other) E2D_NOEXCEPT
: ptr_(other.Get())
{
IntrusivePtrAddRef(ptr_);
}
IntrusivePtr(IntrusivePtr&& other) E2D_NOEXCEPT
{
ptr_ = other.ptr_;
other.ptr_ = nullptr;
}
~IntrusivePtr() E2D_NOEXCEPT
{
IntrusivePtrRelease(ptr_);
}
inline Type* Get() const E2D_NOEXCEPT { return ptr_; }
inline void Swap(IntrusivePtr& other) E2D_NOEXCEPT
{
std::swap(ptr_, other.ptr_);
}
inline Type* operator ->() const
{
E2D_ASSERT(ptr_ != nullptr && "Invalid pointer");
return ptr_;
}
inline Type& operator *() const
{
E2D_ASSERT(ptr_ != nullptr && "Invalid pointer");
return *ptr_;
}
inline Type** operator &()
{
E2D_ASSERT(ptr_ == nullptr && "Memory leak");
return &ptr_;
}
inline operator bool() const E2D_NOEXCEPT { return ptr_ != nullptr; }
inline bool operator !() const E2D_NOEXCEPT { return ptr_ == 0; }
inline IntrusivePtr& operator =(const IntrusivePtr& other) E2D_NOEXCEPT
{
if (other.ptr_ != ptr_)
IntrusivePtr(other).Swap(*this);
return *this;
}
inline IntrusivePtr& operator =(IntrusivePtr&& other) E2D_NOEXCEPT
{
IntrusivePtrRelease(ptr_);
ptr_ = other.ptr_;
other.ptr_ = nullptr;
return *this;
}
inline IntrusivePtr& operator =(Type* p) E2D_NOEXCEPT
{
if (p != ptr_)
IntrusivePtr(p).Swap(*this);
return *this;
}
inline IntrusivePtr& operator =(nullptr_t) E2D_NOEXCEPT
{
if (nullptr != ptr_)
IntrusivePtr{}.Swap(*this);
return *this;
}
};
template<class T, class U>
inline bool operator==(IntrusivePtr<T> const& lhs, IntrusivePtr<U> const& rhs) E2D_NOEXCEPT
{
return lhs.Get() == rhs.Get();
}
template<class T, class U>
inline bool operator!=(IntrusivePtr<T> const& lhs, IntrusivePtr<U> const& rhs) E2D_NOEXCEPT
{
return lhs.Get() != rhs.Get();
}
template<class T, class U>
inline bool operator<(IntrusivePtr<T> const& lhs, IntrusivePtr<U> const& rhs) E2D_NOEXCEPT
{
return lhs.Get() < rhs.Get();
}
template<class T>
inline bool operator==(IntrusivePtr<T> const& lhs, T* rhs) E2D_NOEXCEPT
{
return lhs.Get() == rhs;
}
template<class T>
inline bool operator!=(IntrusivePtr<T> const& lhs, T* rhs) E2D_NOEXCEPT
{
return lhs.Get() != rhs;
}
template<class T>
inline bool operator==(T* lhs, IntrusivePtr<T> const& rhs) E2D_NOEXCEPT
{
return lhs == rhs.Get();
}
template<class T>
inline bool operator!=(T* lhs, IntrusivePtr<T> const& rhs) E2D_NOEXCEPT
{
return lhs != rhs.Get();
}
template<class T>
inline bool operator==(IntrusivePtr<T> const& lhs, nullptr_t) E2D_NOEXCEPT
{
return !static_cast<bool>(lhs);
}
template<class T>
inline bool operator!=(IntrusivePtr<T> const& lhs, nullptr_t) E2D_NOEXCEPT
{
return static_cast<bool>(lhs);
}
template<class T>
inline bool operator==(nullptr_t, IntrusivePtr<T> const& rhs) E2D_NOEXCEPT
{
return !static_cast<bool>(rhs);
}
template<class T>
inline bool operator!=(nullptr_t, IntrusivePtr<T> const& rhs) E2D_NOEXCEPT
{
return static_cast<bool>(rhs);
}
// template class cannot specialize std::swap,
// so implement a swap function in easy2d namespace
template<class T>
inline void swap(IntrusivePtr<T>& lhs, IntrusivePtr<T>& rhs) E2D_NOEXCEPT
{
lhs.Swap(rhs);
}
}

View File

@ -1,47 +0,0 @@
// Copyright (c) 2016-2018 Easy2D - Nomango
//
// 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 "Event.hpp"
#include "keys.hpp"
namespace easy2d
{
class KeyEvent
: public Event
{
public:
enum Type
{
First = WM_KEYFIRST,
Down, // ¼ü°´ÏÂ
Up, // ¼ü̧Æð
Last // ½áÊø±êÖ¾
};
KeyEvent(EventType type, KeyCode key) : Event(type), key(key) {}
static bool Check(Event* e) { return e->type > Type::First && e->type < Type::Last; }
KeyCode key;
};
}

View File

@ -1,55 +0,0 @@
// Copyright (c) 2016-2018 Easy2D - Nomango
//
// 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 "Event.hpp"
#include "helper.hpp"
namespace easy2d
{
class MouseEvent
: public Event
{
public:
enum Type
{
First = WM_MOUSEFIRST,
Move, // 移动
Down, // 按下
Up, // 抬起
Wheel, // 滚轮滚动
Hover, // 鼠标移入
Out, // 鼠标移出
Click, // 鼠标点击
Last // 结束标志
};
MouseEvent(EventType type, float x, float y, float wheel_delta) : Event(type), position(x, y), wheel_delta(wheel_delta), button_down(false) {}
static bool Check(Event* e) { return e->type > Type::First && e->type < Type::Last; }
Point position;
float wheel_delta;
bool button_down;
};
}

View File

@ -27,7 +27,7 @@ namespace easy2d
{
// 稜있
class Music
: public Object
: public virtual Object
{
public:
Music();

View File

@ -23,7 +23,6 @@
#include "Factory.h"
#include "Scene.h"
#include "Task.h"
#include "MouseEvent.hpp"
#include "render.h"
#include "logs.h"
@ -31,18 +30,19 @@ namespace easy2d
{
namespace
{
float default_pivot_x = 0.f;
float default_pivot_y = 0.f;
float default_anchor_x = 0.f;
float default_anchor_y = 0.f;
}
void Node::SetDefaultPivot(float pivot_x, float pivot_y)
void Node::SetDefaultAnchor(float anchor_x, float anchor_y)
{
default_pivot_x = pivot_x;
default_pivot_y = pivot_y;
default_anchor_x = anchor_x;
default_anchor_y = anchor_y;
}
Node::Node()
: visible_(true)
, pause_(false)
, dirty_transform_(false)
, dirty_transform_inverse_(false)
, parent_(nullptr)
@ -50,12 +50,15 @@ namespace easy2d
, z_order_(0)
, opacity_(1.f)
, display_opacity_(1.f)
, pivot_(default_pivot_x, default_pivot_y)
, anchor_(default_anchor_x, default_anchor_y)
{
}
void Node::Update(Duration const & dt)
{
if (pause_)
return;
OnUpdate(dt);
UpdateActions(this, dt);
UpdateTasks(dt);
@ -78,12 +81,12 @@ namespace easy2d
UpdateTransform();
auto graphics = Graphics::Instance();
auto rt = RenderSystem::Instance();
if (children_.IsEmpty())
{
graphics->SetTransform(transform_matrix_);
graphics->SetOpacity(display_opacity_);
rt->SetTransform(transform_matrix_);
rt->SetOpacity(display_opacity_);
OnRender();
}
@ -100,8 +103,8 @@ namespace easy2d
child = child->NextItem().Get();
}
graphics->SetTransform(transform_matrix_);
graphics->SetOpacity(display_opacity_);
rt->SetTransform(transform_matrix_);
rt->SetOpacity(display_opacity_);
OnRender();
@ -113,7 +116,7 @@ namespace easy2d
}
}
void Node::DispatchEvent(Event * e)
void Node::Dispatch(Event& evt)
{
if (!visible_)
return;
@ -122,26 +125,24 @@ namespace easy2d
for (auto child = children_.Last(); child; child = prev)
{
prev = child->PrevItem();
child->DispatchEvent(e);
child->Dispatch(evt);
}
if (MouseEvent::Check(e))
if (MouseEvent::Check(evt.type))
{
MouseEvent* me = static_cast<MouseEvent*>(e);
if (me->type == MouseEvent::Move)
if (evt.type == MouseEvent::Move)
{
if (!me->has_target && ContainsPoint(me->position))
if (!evt.has_target && ContainsPoint(Point{ evt.mouse.x, evt.mouse.y }))
{
me->has_target = true;
evt.has_target = true;
if (!hover_)
{
hover_ = true;
MouseEvent hover = *me;
Event hover = evt;
hover.type = MouseEvent::Hover;
DispatchEvent(&hover);
Dispatch(hover);
}
}
else if (hover_)
@ -149,28 +150,38 @@ namespace easy2d
hover_ = false;
pressed_ = false;
MouseEvent hover = *me;
hover.type = MouseEvent::Out;
DispatchEvent(&hover);
Event out = evt;
out.type = MouseEvent::Out;
Dispatch(out);
}
}
if (me->type == MouseEvent::Down && hover_)
if (evt.type == MouseEvent::Down && hover_)
{
pressed_ = true;
}
if (me->type == MouseEvent::Up && pressed_)
if (evt.type == MouseEvent::Up && pressed_)
{
pressed_ = false;
MouseEvent click = *me;
Event click = evt;
click.type = MouseEvent::Click;
DispatchEvent(&click);
Dispatch(click);
}
}
EventDispatcher::DispatchEvent(e);
EventDispatcher::Dispatch(evt);
}
void Node::PauseUpdating()
{
pause_ = true;
}
void Node::ResumeUpdating()
{
pause_ = false;
}
Matrix const & Node::GetTransformMatrix() const
@ -214,7 +225,7 @@ namespace easy2d
* Matrix::Rotation(transform_.rotation)
* Matrix::Translation(transform_.position);
Point offset{ -size_.x * pivot_.x, -size_.y * pivot_.y };
Point offset{ -size_.x * anchor_.x, -size_.y * anchor_.y };
transform_matrix_.Translate(offset);
if (parent_)
@ -290,23 +301,23 @@ namespace easy2d
UpdateOpacity();
}
void Node::SetPivotX(float pivot_x)
void Node::SetAnchorX(float anchor_x)
{
this->SetPivot(pivot_x, pivot_.y);
this->SetAnchor(anchor_x, anchor_.y);
}
void Node::SetPivotY(float pivot_y)
void Node::SetAnchorY(float anchor_y)
{
this->SetPivot(pivot_.x, pivot_y);
this->SetAnchor(anchor_.x, anchor_y);
}
void Node::SetPivot(float pivot_x, float pivot_y)
void Node::SetAnchor(float anchor_x, float anchor_y)
{
if (pivot_.x == pivot_x && pivot_.y == pivot_y)
if (anchor_.x == anchor_x && anchor_.y == anchor_y)
return;
pivot_.x = pivot_x;
pivot_.y = pivot_y;
anchor_.x = anchor_x;
anchor_.y = anchor_y;
dirty_transform_ = true;
}

View File

@ -25,26 +25,26 @@
#include "TaskManager.h"
#include "ActionManager.h"
#include "EventDispatcher.h"
#include "intrusive/List.hpp"
#include "IntrusiveList.hpp"
namespace easy2d
{
class Game;
class Application;
// 节点
class Node
: public Object
: public virtual Object
, public TaskManager
, public ActionManager
, public EventDispatcher
, protected intrusive::ListItem<NodePtr>
, protected IntrusiveListItem<NodePtr>
{
friend class Game;
friend class Application;
friend class Scene;
friend class Transition;
friend class intrusive::List<NodePtr>;
friend class IntrusiveList<NodePtr>;
using Children = intrusive::List<NodePtr>;
using Children = IntrusiveList<NodePtr>;
public:
Node();
@ -55,11 +55,14 @@ namespace easy2d
// 渲染节点
virtual void OnRender() {}
// 事件分发
virtual void Dispatch(Event& evt) override;
// 获取显示状态
bool IsVisible() const { return visible_; }
// 获取名称
String const& GetName() const { return name_; }
String const& GetName() const { return name_; }
// 获取名称的 Hash 值
size_t GetHashName() const { return hash_name_; }
@ -109,11 +112,11 @@ namespace easy2d
// 获取缩放后的大小
Size GetScaledSize() const { return Size{ GetScaledWidth(), GetScaledHeight() }; }
// 获取 x 方向
float GetPivotX() const { return pivot_.x; }
// 获取 x 方向
float GetAnchorX() const { return anchor_.x; }
// 获取 y 方向
float GetPivotY() const { return pivot_.y; }
// 获取 y 方向
float GetAnchorY() const { return anchor_.y; }
// 获取透明度
float GetOpacity() const { return opacity_; }
@ -228,23 +231,23 @@ namespace easy2d
float rotation
);
// 设置点的横向位置
// 设置点的横向位置
// 默认为 0, 范围 [0, 1]
void SetPivotX(
float pivot_x
void SetAnchorX(
float anchor_x
);
// 设置点的纵向位置
// 设置点的纵向位置
// 默认为 0, 范围 [0, 1]
void SetPivotY(
float pivot_y
void SetAnchorY(
float anchor_y
);
// 设置点位置
// 设置点位置
// 默认为 (0, 0), 范围 [0, 1]
void SetPivot(
float pivot_x,
float pivot_y
void SetAnchor(
float anchor_x,
float anchor_y
);
// 修改宽度
@ -333,12 +336,16 @@ namespace easy2d
// 从父节点移除
void RemoveFromParent();
virtual void DispatchEvent(Event* e) override;
// 暂停节点更新
void PauseUpdating();
// 设置默认支点
static void SetDefaultPivot(
float pivot_x,
float pivot_y
// 继续节点更新
void ResumeUpdating();
// 设置默认锚点
static void SetDefaultAnchor(
float anchor_x,
float anchor_y
);
protected:
@ -356,13 +363,14 @@ namespace easy2d
bool visible_;
bool hover_;
bool pressed_;
bool pause_;
int z_order_;
float opacity_;
float display_opacity_;
String name_;
size_t hash_name_;
Transform transform_;
Point pivot_;
Point anchor_;
Size size_;
Node* parent_;
Scene* scene_;

View File

@ -26,8 +26,8 @@ namespace easy2d
{
Scene::Scene()
{
AddListener(SysEvent::WindowActivate, std::bind(&Scene::OnActivate, this));
AddListener(SysEvent::WindowDeavtivate, std::bind(&Scene::OnDeactivate, this));
AddListener(WindowEvent::Activate, std::bind(&Scene::OnActivate, this));
AddListener(WindowEvent::Deavtivate, std::bind(&Scene::OnDeactivate, this));
scene_ = this;
}

View File

@ -37,7 +37,7 @@ namespace easy2d
return instance_.get();
}
private:
protected:
ISingleton() = default;
~ISingleton() {}
@ -53,8 +53,3 @@ namespace easy2d
friend struct ::std::default_delete< type >;\
friend class ::easy2d::ISingleton< type >
#endif
#ifndef E2D_DECLARE_SINGLETON_TYPE
#define E2D_DECLARE_SINGLETON_TYPE( type, singleton_type ) \
using singleton_type = ::easy2d::ISingleton< type >
#endif

View File

@ -99,7 +99,7 @@ namespace easy2d
{
if (image_)
{
Graphics::Instance()->DrawImage(image_);
RenderSystem::Instance()->DrawImage(image_);
}
}
}

View File

@ -21,7 +21,7 @@
#pragma once
#include "include-forwards.h"
#include "time.h"
#include "intrusive/List.hpp"
#include "IntrusiveList.hpp"
#include <functional>
namespace easy2d
@ -30,11 +30,11 @@ namespace easy2d
// 定时任务
class Task
: public Object
, protected intrusive::ListItem<TaskPtr>
: public virtual Object
, protected IntrusiveListItem<TaskPtr>
{
friend class TaskManager;
friend class intrusive::List<TaskPtr>;
friend class IntrusiveList<TaskPtr>;
using Callback = std::function<void()>;

View File

@ -25,7 +25,7 @@ namespace easy2d
{
class TaskManager
{
using Tasks = intrusive::List<TaskPtr>;
using Tasks = IntrusiveList<TaskPtr>;
public:
// Ìí¼ÓÈÎÎñ

View File

@ -295,15 +295,15 @@ namespace easy2d
{
if (text_layout_)
{
auto graphics = Graphics::Instance();
graphics->SetTextStyle(
auto rt = RenderSystem::Instance();
rt->SetTextStyle(
style_.color,
style_.outline,
style_.outline_color,
style_.outline_width,
style_.outline_stroke
);
graphics->DrawTextLayout(text_layout_);
rt->DrawTextLayout(text_layout_);
}
}

View File

@ -66,14 +66,14 @@ namespace easy2d
if (in_scene_)
{
ThrowIfFailed(
Graphics::Instance()->CreateLayer(in_layer_)
RenderSystem::Instance()->CreateLayer(in_layer_)
);
}
if (out_scene_)
{
ThrowIfFailed(
Graphics::Instance()->CreateLayer(out_layer_)
RenderSystem::Instance()->CreateLayer(out_layer_)
);
}
@ -101,34 +101,34 @@ namespace easy2d
void Transition::Render()
{
auto graphics = Graphics::Instance();
auto rt = RenderSystem::Instance();
if (out_scene_)
{
graphics->PushClip(
rt->PushClip(
out_scene_->GetTransformMatrix(),
window_size_
);
graphics->PushLayer(out_layer_, out_layer_prop_);
rt->PushLayer(out_layer_, out_layer_prop_);
out_scene_->Render();
graphics->PopLayer();
graphics->PopClip();
rt->PopLayer();
rt->PopClip();
}
if (in_scene_)
{
graphics->PushClip(
rt->PushClip(
in_scene_->GetTransformMatrix(),
window_size_
);
graphics->PushLayer(in_layer_, in_layer_prop_);
rt->PushLayer(in_layer_, in_layer_prop_);
in_scene_->Render();
graphics->PopLayer();
graphics->PopClip();
rt->PopLayer();
rt->PopClip();
}
}
@ -337,13 +337,13 @@ namespace easy2d
if (out_scene_)
{
out_scene_->SetTransform(transform);
out_scene_->SetPivot(0.5f, 0.5f);
out_scene_->SetAnchor(0.5f, 0.5f);
}
if (in_scene_)
{
in_scene_->SetTransform(transform);
in_scene_->SetPivot(0.5f, 0.5f);
in_scene_->SetAnchor(0.5f, 0.5f);
}
in_layer_prop_.opacity = 0;
@ -384,13 +384,13 @@ namespace easy2d
if (out_scene_)
{
out_scene_->SetTransform(Transform{});
out_scene_->SetPivot(0.f, 0.f);
out_scene_->SetAnchor(0.f, 0.f);
}
if (in_scene_)
{
in_scene_->SetTransform(Transform{});
in_scene_->SetPivot(0.f, 0.f);
in_scene_->SetAnchor(0.f, 0.f);
}
}
}

View File

@ -28,9 +28,9 @@ namespace easy2d
// 场景过渡
class Transition
: public Object
: public virtual Object
{
friend class Game;
friend class Application;
public:
explicit Transition(

View File

@ -156,16 +156,16 @@ namespace easy2d
//-------------------------------------------------------
// AudioDevice
// Audio
//-------------------------------------------------------
AudioDevice::AudioDevice()
Audio::Audio()
: x_audio2_(nullptr)
, mastering_voice_(nullptr)
{
}
AudioDevice::~AudioDevice()
Audio::~Audio()
{
E2D_LOG(L"Destroying audio device");
@ -182,7 +182,7 @@ namespace easy2d
modules::MediaFoundation::Get().MFShutdown();
}
HRESULT AudioDevice::Init(bool debug)
HRESULT Audio::Init(bool debug)
{
E2D_LOG(L"Initing audio device");
@ -201,7 +201,7 @@ namespace easy2d
return hr;
}
HRESULT AudioDevice::CreateVoice(Voice& voice, const WAVEFORMATEX* wfx)
HRESULT Audio::CreateVoice(Voice& voice, const WAVEFORMATEX* wfx)
{
HRESULT hr;
IXAudio2SourceVoice* source_voice;
@ -215,12 +215,12 @@ namespace easy2d
return hr;
}
void AudioDevice::DeleteVoice(Voice* voice)
void Audio::DeleteVoice(Voice* voice)
{
voice_cache_.erase(voice);
}
void AudioDevice::ClearVoiceCache()
void Audio::ClearVoiceCache()
{
for (auto voice : voice_cache_)
{
@ -229,12 +229,12 @@ namespace easy2d
voice_cache_.clear();
}
void AudioDevice::Open()
void Audio::Open()
{
x_audio2_->StartEngine();
}
void AudioDevice::Close()
void Audio::Close()
{
x_audio2_->StopEngine();
}

View File

@ -74,10 +74,10 @@ namespace easy2d
};
class AudioDevice
: protected Noncopyable
class Audio
: public ISingleton<Audio>
{
E2D_DECLARE_SINGLETON(AudioDevice);
E2D_DECLARE_SINGLETON(Audio);
using VoiceMap = UnorderedSet<Voice*>;
@ -102,15 +102,13 @@ namespace easy2d
void ClearVoiceCache();
protected:
AudioDevice();
Audio();
~AudioDevice();
~Audio();
protected:
VoiceMap voice_cache_;
IXAudio2* x_audio2_;
IXAudio2MasteringVoice* mastering_voice_;
};
E2D_DECLARE_SINGLETON_TYPE(AudioDevice, Audio);
}

View File

@ -19,13 +19,13 @@
// THE SOFTWARE.
#pragma once
#include "intrusive/SmartPtr.hpp"
#include "IntrusivePtr.hpp"
#include <d2d1.h>
#include <dwrite.h>
#ifndef E2D_DECLARE_D2D_SMART_PTR
#define E2D_DECLARE_D2D_SMART_PTR(class_name, sp_name)\
using sp_name = ::easy2d::intrusive::SmartPtr< class_name >
using sp_name = ::easy2d::IntrusivePtr< class_name >
#endif

View File

@ -20,7 +20,7 @@
#pragma once
#include "RefCounter.hpp"
#include "intrusive/SmartPtr.hpp"
#include "IntrusivePtr.hpp"
#include "../math/vector.hpp"
#include "../math/Rect.hpp"
#include "../math/Matrix.hpp"
@ -34,13 +34,13 @@
#ifndef E2D_DECLARE_SMART_PTR
#define E2D_DECLARE_SMART_PTR(class_name)\
class class_name;\
using class_name##Ptr = ::easy2d::intrusive::SmartPtr< class_name >
using class_name##Ptr = ::easy2d::IntrusivePtr< class_name >
#define E2D_DECLARE_NS_SMART_PTR(ns_name, class_name)\
namespace ns_name\
{\
class class_name; \
using class_name##Ptr = ::easy2d::intrusive::SmartPtr< class_name >;\
using class_name##Ptr = ::easy2d::IntrusivePtr< class_name >;\
}
#endif
@ -76,9 +76,10 @@ namespace easy2d
E2D_DECLARE_SMART_PTR(Image);
E2D_DECLARE_SMART_PTR(Music);
E2D_DECLARE_SMART_PTR(Task);
E2D_DECLARE_SMART_PTR(EventListener);
E2D_DECLARE_SMART_PTR(Frames);
E2D_DECLARE_SMART_PTR(EventListener);
E2D_DECLARE_SMART_PTR(Geometry);
E2D_DECLARE_SMART_PTR(LineGeometry);
E2D_DECLARE_SMART_PTR(RectangleGeometry);
@ -141,9 +142,9 @@ namespace easy2d
}
template<typename T>
inline intrusive::SmartPtr<T> operator- (T* ptr) const
inline IntrusivePtr<T> operator- (T* ptr) const
{
return intrusive::SmartPtr<T>(ptr);
return IntrusivePtr<T>(ptr);
}
};
}

View File

@ -1,257 +0,0 @@
// Copyright (c) 2016-2018 Easy2D - Nomango
//
// 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 "../macros.h"
#include <functional>
#undef DEBUG_CHECK_LIST
#ifdef E2D_DEBUG
# define DEBUG_CHECK_LIST(list_ptr) list_ptr->Check()
#else
# define DEBUG_CHECK_LIST __noop
#endif
namespace easy2d
{
namespace intrusive
{
template <typename T> class List;
template <typename T>
class ListItem
{
T prev_;
T next_;
template <typename U>
friend class List;
public:
using ItemType = T;
ListItem() : prev_(), next_() {}
T const& PrevItem() const { return prev_; }
T& PrevItem() { return prev_; }
T const& NextItem() const { return next_; }
T& NextItem() { return next_; }
};
template <typename T>
class List
{
T first_;
T last_;
public:
using ItemType = T;
List() : first_(), last_() {}
~List() { Clear(); }
T const& First() const { return first_; }
T& First() { return first_; }
T const& Last() const { return last_; }
T& Last() { return last_; }
bool IsEmpty() const { return !first_; }
void PushBack(T const& child)
{
if (child->prev_)
child->prev_->next_ = child->next_;
if (child->next_)
child->next_->prev_ = child->prev_;
child->prev_ = last_;
child->next_ = nullptr;
if (first_)
{
last_->next_ = child;
}
else
{
first_ = child;
}
last_ = child;
DEBUG_CHECK_LIST(this);
}
void PushFront(T const& child)
{
if (child->prev_)
child->prev_->next_ = child->next_;
if (child->next_)
child->next_->prev_ = child->prev_;
child->prev_ = nullptr;
child->next_ = first_;
if (first_)
{
first_->prev_ = child;
}
else
{
last_ = child;
}
first_ = child;
DEBUG_CHECK_LIST(this);
}
void InsertBefore(T const& child, T const& before)
{
if (child->prev_)
child->prev_->next_ = child->next_;
if (child->next_)
child->next_->prev_ = child->prev_;
if (before->prev_)
before->prev_->next_ = child;
else
first_ = child;
child->prev_ = before->prev_;
child->next_ = before;
before->prev_ = child;
DEBUG_CHECK_LIST(this);
}
void InsertAfter(T const& child, T const& after)
{
if (child->prev_)
child->prev_->next_ = child->next_;
if (child->next_)
child->next_->prev_ = child->prev_;
if (after->next_)
after->next_->prev_ = child;
else
last_ = child;
child->next_ = after->next_;
child->prev_ = after;
after->next_ = child;
DEBUG_CHECK_LIST(this);
}
void Remove(T const& child)
{
#ifdef E2D_DEBUG
T tmp = first_;
while (tmp != child)
{
if (tmp == last_)
E2D_ASSERT(false && "The node to be removed is not in this list");
tmp = tmp->next_;
}
#endif
if (child->next_)
{
child->next_->prev_ = child->prev_;
}
else
{
last_ = child->prev_;
}
if (child->prev_)
{
child->prev_->next_ = child->next_;
}
else
{
first_ = child->next_;
}
child->prev_ = nullptr;
child->next_ = nullptr;
DEBUG_CHECK_LIST(this);
}
void Clear()
{
T p = first_;
while (p)
{
T tmp = p;
p = p->next_;
if (tmp)
{
tmp->next_ = nullptr;
tmp->prev_ = nullptr;
}
}
first_ = nullptr;
last_ = nullptr;
}
#ifdef E2D_DEBUG
private:
void Check()
{
if (!first_)
return;
int pos = 0;
T p = first_;
T tmp = p;
do
{
tmp = p;
p = p->next_;
++pos;
if (p)
{
E2D_ASSERT(p->prev_ == tmp && "Check list failed");
}
else
{
E2D_ASSERT(tmp == last_ && "Check list failed");
}
} while (p);
}
#endif
};
}
}
#undef DEBUG_CHECK_LIST

View File

@ -1,204 +0,0 @@
// Copyright (c) 2016-2018 Easy2D - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining lhs 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 "../macros.h"
#include <utility>
namespace easy2d
{
namespace intrusive
{
template <typename T>
class SmartPtr
{
T* ptr_{ nullptr };
public:
using Type = T;
SmartPtr() E2D_NOEXCEPT {}
SmartPtr(nullptr_t) E2D_NOEXCEPT {}
SmartPtr(Type* p) E2D_NOEXCEPT : ptr_(p)
{
IntrusivePtrAddRef(ptr_);
}
SmartPtr(const SmartPtr& other) E2D_NOEXCEPT
: ptr_(other.ptr_)
{
IntrusivePtrAddRef(ptr_);
}
template <typename U>
SmartPtr(const SmartPtr<U>& other) E2D_NOEXCEPT
: ptr_(other.Get())
{
IntrusivePtrAddRef(ptr_);
}
SmartPtr(SmartPtr&& other) E2D_NOEXCEPT
{
ptr_ = other.ptr_;
other.ptr_ = nullptr;
}
~SmartPtr() E2D_NOEXCEPT
{
IntrusivePtrRelease(ptr_);
}
inline Type* Get() const E2D_NOEXCEPT { return ptr_; }
inline void Swap(SmartPtr& other) E2D_NOEXCEPT
{
std::swap(ptr_, other.ptr_);
}
inline Type* operator ->() const
{
E2D_ASSERT(ptr_ != nullptr && "Invalid pointer");
return ptr_;
}
inline Type& operator *() const
{
E2D_ASSERT(ptr_ != nullptr && "Invalid pointer");
return *ptr_;
}
inline Type** operator &()
{
E2D_ASSERT(ptr_ == nullptr && "Memory leak");
return &ptr_;
}
inline operator bool() const E2D_NOEXCEPT { return ptr_ != nullptr; }
inline bool operator !() const E2D_NOEXCEPT { return ptr_ == 0; }
inline SmartPtr& operator =(const SmartPtr& other) E2D_NOEXCEPT
{
if (other.ptr_ != ptr_)
SmartPtr(other).Swap(*this);
return *this;
}
inline SmartPtr& operator =(SmartPtr&& other) E2D_NOEXCEPT
{
IntrusivePtrRelease(ptr_);
ptr_ = other.ptr_;
other.ptr_ = nullptr;
return *this;
}
inline SmartPtr& operator =(Type* p) E2D_NOEXCEPT
{
if (p != ptr_)
SmartPtr(p).Swap(*this);
return *this;
}
inline SmartPtr& operator =(nullptr_t) E2D_NOEXCEPT
{
if (nullptr != ptr_)
SmartPtr{}.Swap(*this);
return *this;
}
};
template<class T, class U>
inline bool operator==(SmartPtr<T> const& lhs, SmartPtr<U> const& rhs) E2D_NOEXCEPT
{
return lhs.Get() == rhs.Get();
}
template<class T, class U>
inline bool operator!=(SmartPtr<T> const& lhs, SmartPtr<U> const& rhs) E2D_NOEXCEPT
{
return lhs.Get() != rhs.Get();
}
template<class T, class U>
inline bool operator<(SmartPtr<T> const& lhs, SmartPtr<U> const& rhs) E2D_NOEXCEPT
{
return lhs.Get() < rhs.Get();
}
template<class T>
inline bool operator==(SmartPtr<T> const& lhs, T* rhs) E2D_NOEXCEPT
{
return lhs.Get() == rhs;
}
template<class T>
inline bool operator!=(SmartPtr<T> const& lhs, T* rhs) E2D_NOEXCEPT
{
return lhs.Get() != rhs;
}
template<class T>
inline bool operator==(T* lhs, SmartPtr<T> const& rhs) E2D_NOEXCEPT
{
return lhs == rhs.Get();
}
template<class T>
inline bool operator!=(T* lhs, SmartPtr<T> const& rhs) E2D_NOEXCEPT
{
return lhs != rhs.Get();
}
template<class T>
inline bool operator==(SmartPtr<T> const& lhs, nullptr_t) E2D_NOEXCEPT
{
return !static_cast<bool>(lhs);
}
template<class T>
inline bool operator!=(SmartPtr<T> const& lhs, nullptr_t) E2D_NOEXCEPT
{
return static_cast<bool>(lhs);
}
template<class T>
inline bool operator==(nullptr_t, SmartPtr<T> const& rhs) E2D_NOEXCEPT
{
return !static_cast<bool>(rhs);
}
template<class T>
inline bool operator!=(nullptr_t, SmartPtr<T> const& rhs) E2D_NOEXCEPT
{
return static_cast<bool>(rhs);
}
}
// template class cannot specialize std::swap,
// so implement a swap function in easy2d namespace
template<class T>
inline void swap(intrusive::SmartPtr<T>& lhs, intrusive::SmartPtr<T>& rhs) E2D_NOEXCEPT
{
lhs.Swap(rhs);
}
}

View File

@ -23,19 +23,28 @@
namespace easy2d
{
// 報炎梓囚
enum class MouseButton : int
{
Left = VK_LBUTTON, // 報炎恣囚
Right = VK_RBUTTON, // 報炎嘔囚
Middle = VK_MBUTTON // 報炎嶄囚
};
// °´¼ü¼üÖµ
enum class KeyCode : int
{
Unknown = 0,
Up = VK_UP,
Left = VK_LEFT,
Right = VK_RIGHT,
Down = VK_DOWN,
Enter = VK_RETURN,
acePtr = VK_SPACE,
Esc = VK_ESCAPE,
Ctrl = VK_CONTROL,
Shift = VK_SHIFT,
Up = VK_UP,
Left = VK_LEFT,
Right = VK_RIGHT,
Down = VK_DOWN,
Enter = VK_RETURN,
Space = VK_SPACE,
Esc = VK_ESCAPE,
Ctrl = VK_CONTROL,
Shift = VK_SHIFT,
A = 0x41,
B,

View File

@ -33,7 +33,7 @@ namespace easy2d
{
bool enabled = true;
void Out(std::ostream& stream, const wchar_t* output)
void Out(std::wostream& stream, const wchar_t* output)
{
stream << output;
::OutputDebugStringW(output);
@ -47,7 +47,7 @@ namespace easy2d
ss << std::put_time(&tmbuf, L"[easy2d] %H:%M:%S ");
}
void Output(std::ostream& stream, const wchar_t* prompt, const wchar_t* format, va_list args)
void Output(std::wostream& stream, const wchar_t* prompt, const wchar_t* format, va_list args)
{
if (!enabled)
return;
@ -64,7 +64,7 @@ namespace easy2d
delete[] buffer;
}
void OutputLine(std::ostream& stream, const wchar_t* prompt, const wchar_t* format, va_list args)
void OutputLine(std::wostream& stream, const wchar_t* prompt, const wchar_t* format, va_list args)
{
if (!enabled)
return;
@ -89,7 +89,7 @@ namespace easy2d
va_list args = nullptr;
va_start(args, format);
Output(std::cout, L"", format, args);
Output(std::wcout, L"", format, args);
va_end(args);
}
@ -99,7 +99,7 @@ namespace easy2d
va_list args = nullptr;
va_start(args, format);
OutputLine(std::cout, L"", format, args);
OutputLine(std::wcout, L"", format, args);
va_end(args);
}
@ -109,7 +109,7 @@ namespace easy2d
va_list args = nullptr;
va_start(args, format);
Output(std::cerr, L"Warning: ", format, args);
Output(std::wcerr, L"Warning: ", format, args);
va_end(args);
}
@ -119,7 +119,7 @@ namespace easy2d
va_list args = nullptr;
va_start(args, format);
OutputLine(std::cerr, L"Warning: ", format, args);
OutputLine(std::wcerr, L"Warning: ", format, args);
va_end(args);
}
@ -129,7 +129,7 @@ namespace easy2d
va_list args = nullptr;
va_start(args, format);
Output(std::cerr, L"Error: ", format, args);
Output(std::wcerr, L"Error: ", format, args);
va_end(args);
}
@ -139,7 +139,7 @@ namespace easy2d
va_list args = nullptr;
va_start(args, format);
OutputLine(std::cerr, L"Error: ", format, args);
OutputLine(std::wcerr, L"Error: ", format, args);
va_end(args);
}

View File

@ -26,7 +26,7 @@
namespace easy2d
{
GraphicsDevice::GraphicsDevice()
RenderSystem::RenderSystem()
: fps_text_format_(nullptr)
, fps_text_layout_(nullptr)
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
@ -39,14 +39,14 @@ namespace easy2d
{
}
GraphicsDevice::~GraphicsDevice()
RenderSystem::~RenderSystem()
{
E2D_LOG(L"Destroying graphics device");
ClearImageCache();
}
HRESULT GraphicsDevice::Init(HWND hwnd, bool vsync, bool debug)
HRESULT RenderSystem::Init(HWND hwnd, bool vsync, bool debug)
{
E2D_LOG(L"Initing graphics device");
@ -56,7 +56,7 @@ namespace easy2d
return CreateResources(hwnd);
}
HRESULT GraphicsDevice::BeginDraw(HWND hwnd)
HRESULT RenderSystem::BeginDraw(HWND hwnd)
{
HRESULT hr = CreateResources(hwnd);
@ -79,7 +79,7 @@ namespace easy2d
return hr;
}
HRESULT GraphicsDevice::EndDraw()
HRESULT RenderSystem::EndDraw()
{
HRESULT hr = S_OK;
@ -103,22 +103,22 @@ namespace easy2d
return hr;
}
void GraphicsDevice::ClearImageCache()
void RenderSystem::ClearImageCache()
{
bitmap_cache_.clear();
}
D2DHwndRenderTargetPtr const & GraphicsDevice::GetRenderTarget() const
D2DHwndRenderTargetPtr const & RenderSystem::GetRenderTarget() const
{
return render_target_;
}
D2DSolidColorBrushPtr const & GraphicsDevice::GetSolidBrush() const
D2DSolidColorBrushPtr const & RenderSystem::GetSolidBrush() const
{
return solid_brush_;
}
HRESULT GraphicsDevice::CreateLayer(D2DLayerPtr& layer)
HRESULT RenderSystem::CreateLayer(D2DLayerPtr& layer)
{
if (!render_target_)
return E_UNEXPECTED;
@ -127,7 +127,7 @@ namespace easy2d
return render_target_->CreateLayer(&layer);
}
HRESULT GraphicsDevice::CreateSolidColorBrush(D2DSolidColorBrushPtr & brush) const
HRESULT RenderSystem::CreateSolidColorBrush(D2DSolidColorBrushPtr & brush) const
{
if (!render_target_)
return E_UNEXPECTED;
@ -139,7 +139,7 @@ namespace easy2d
);
}
HRESULT GraphicsDevice::DrawGeometry(
HRESULT RenderSystem::DrawGeometry(
D2DGeometryPtr const& geometry,
Color const& stroke_color,
float stroke_width,
@ -167,7 +167,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::FillGeometry(D2DGeometryPtr const & geometry, const Color & fill_color)
HRESULT RenderSystem::FillGeometry(D2DGeometryPtr const & geometry, const Color & fill_color)
{
if (!solid_brush_ ||
!render_target_)
@ -187,7 +187,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::DrawImage(ImagePtr const & image)
HRESULT RenderSystem::DrawImage(ImagePtr const & image)
{
if (!render_target_)
return E_UNEXPECTED;
@ -211,7 +211,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::DrawBitmap(
HRESULT RenderSystem::DrawBitmap(
D2DBitmapPtr const& bitmap
)
{
@ -236,7 +236,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::DrawTextLayout(D2DTextLayoutPtr const& text_layout)
HRESULT RenderSystem::DrawTextLayout(D2DTextLayoutPtr const& text_layout)
{
if (!text_renderer_)
return E_UNEXPECTED;
@ -249,7 +249,7 @@ namespace easy2d
return text_layout->Draw(nullptr, text_renderer_.Get(), 0, 0);
}
HRESULT GraphicsDevice::PushClip(const Matrix & clip_matrix, const Size & clip_size)
HRESULT RenderSystem::PushClip(const Matrix & clip_matrix, const Size & clip_size)
{
if (!render_target_)
return E_UNEXPECTED;
@ -265,7 +265,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::PopClip()
HRESULT RenderSystem::PopClip()
{
if (!render_target_)
return E_UNEXPECTED;
@ -277,7 +277,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::PushLayer(D2DLayerPtr const& layer, LayerProperties const& properties)
HRESULT RenderSystem::PushLayer(D2DLayerPtr const& layer, LayerProperties const& properties)
{
if (!render_target_ ||
!solid_brush_)
@ -301,7 +301,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::PopLayer()
HRESULT RenderSystem::PopLayer()
{
if (!render_target_)
return E_UNEXPECTED;
@ -313,7 +313,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::GetSize(Size & size)
HRESULT RenderSystem::GetSize(Size & size)
{
if (!render_target_)
return E_UNEXPECTED;
@ -324,7 +324,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::CreateBitmapFromFile(D2DBitmapPtr& bitmap, String const& file_path)
HRESULT RenderSystem::CreateBitmapFromFile(D2DBitmapPtr& bitmap, String const& file_path)
{
if (render_target_ == nullptr)
{
@ -353,7 +353,7 @@ namespace easy2d
return hr;
}
HRESULT GraphicsDevice::CreateBitmapFromResource(D2DBitmapPtr& bitmap, Resource const& res)
HRESULT RenderSystem::CreateBitmapFromResource(D2DBitmapPtr& bitmap, Resource const& res)
{
if (render_target_ == nullptr)
{
@ -381,7 +381,7 @@ namespace easy2d
return hr;
}
HRESULT GraphicsDevice::CreateBitmapRenderTarget(D2DBitmapRenderTargetPtr & brt)
HRESULT RenderSystem::CreateBitmapRenderTarget(D2DBitmapRenderTargetPtr & brt)
{
if (!render_target_)
return E_UNEXPECTED;
@ -390,7 +390,7 @@ namespace easy2d
return render_target_->CreateCompatibleRenderTarget(&brt);
}
HRESULT GraphicsDevice::Resize(UINT32 width, UINT32 height)
HRESULT RenderSystem::Resize(UINT32 width, UINT32 height)
{
if (!render_target_)
return E_UNEXPECTED;
@ -399,7 +399,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::SetTransform(const Matrix & matrix)
HRESULT RenderSystem::SetTransform(const Matrix & matrix)
{
if (!render_target_)
return E_UNEXPECTED;
@ -408,7 +408,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::SetOpacity(float opacity)
HRESULT RenderSystem::SetOpacity(float opacity)
{
if (!render_target_)
return E_UNEXPECTED;
@ -418,7 +418,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::SetTextStyle(
HRESULT RenderSystem::SetTextStyle(
Color const& color,
bool has_outline,
Color const& outline_color,
@ -440,12 +440,12 @@ namespace easy2d
return S_OK;
}
void GraphicsDevice::SetClearColor(const Color& color)
void RenderSystem::SetClearColor(const Color& color)
{
clear_color_ = color;
}
HRESULT GraphicsDevice::SetAntialiasMode(bool enabled)
HRESULT RenderSystem::SetAntialiasMode(bool enabled)
{
if (!render_target_)
return E_UNEXPECTED;
@ -457,7 +457,7 @@ namespace easy2d
return S_OK;
}
HRESULT GraphicsDevice::SetTextAntialiasMode(TextAntialias mode)
HRESULT RenderSystem::SetTextAntialiasMode(TextAntialias mode)
{
if (!render_target_)
return E_UNEXPECTED;
@ -485,12 +485,12 @@ namespace easy2d
return S_OK;
}
GraphicsDevice::Status const & GraphicsDevice::GetStatus() const
RenderSystem::Status const & RenderSystem::GetStatus() const
{
return status_;
}
HRESULT GraphicsDevice::CreateResources(HWND hwnd)
HRESULT RenderSystem::CreateResources(HWND hwnd)
{
HRESULT hr = S_OK;
@ -540,9 +540,9 @@ namespace easy2d
return hr;
}
void GraphicsDevice::DiscardResources()
void RenderSystem::DiscardResources()
{
// FIXME! 应通知 Game 类销毁所有节点的 device resources
// FIXME! 应通知 Application 类销毁所有节点的 device resources
fps_text_format_ = nullptr;
fps_text_layout_ = nullptr;
text_renderer_ = nullptr;

View File

@ -31,10 +31,10 @@
namespace easy2d
{
class GraphicsDevice
: protected Noncopyable
class RenderSystem
: public ISingleton<RenderSystem>
{
E2D_DECLARE_SINGLETON(GraphicsDevice);
E2D_DECLARE_SINGLETON(RenderSystem);
struct Status
{
@ -169,26 +169,24 @@ namespace easy2d
D2DSolidColorBrushPtr const& GetSolidBrush() const;
protected:
GraphicsDevice();
RenderSystem();
~GraphicsDevice();
~RenderSystem();
protected:
bool debug_;
bool window_occluded_;
bool vsync_enabled_;
bool antialias_;
float opacity_;
D2D1_COLOR_F clear_color_;
TextAntialias text_antialias_;
Status status_;
bool debug_;
bool window_occluded_;
bool vsync_enabled_;
bool antialias_;
float opacity_;
D2D1_COLOR_F clear_color_;
TextAntialias text_antialias_;
Status status_;
D2DTextRendererPtr text_renderer_;
D2DSolidColorBrushPtr solid_brush_;
D2DHwndRenderTargetPtr render_target_;
D2DTextFormatPtr fps_text_format_;
D2DTextLayoutPtr fps_text_layout_;
BitmapMap bitmap_cache_;
BitmapMap bitmap_cache_;
};
E2D_DECLARE_SINGLETON_TYPE(GraphicsDevice, Graphics);
}

View File

@ -35,19 +35,19 @@ namespace easy2d
Rect LocateWindow(int width, int height, float scale_x, float scale_y);
}
WindowImpl::WindowImpl()
Window::Window()
: handle(nullptr)
, scale_x(1.f)
, scale_y(1.f)
{
}
WindowImpl::~WindowImpl()
Window::~Window()
{
E2D_LOG(L"Destroying window");
}
HRESULT WindowImpl::Init(String title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug)
HRESULT Window::Init(String title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug)
{
E2D_LOG(L"Creating window");
@ -76,6 +76,10 @@ namespace easy2d
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE
);
}
else
{
wcex.hIcon = ::LoadIcon(nullptr, IDI_APPLICATION);
}
::RegisterClassEx(&wcex);
@ -105,7 +109,7 @@ namespace easy2d
return S_OK;
}
String WindowImpl::GetTitle() const
String Window::GetTitle() const
{
if (handle)
{
@ -116,13 +120,13 @@ namespace easy2d
return String();
}
void WindowImpl::SetTitle(String const& title)
void Window::SetTitle(String const& title)
{
if (handle)
::SetWindowText(handle, title.c_str());
}
Size WindowImpl::GetSize() const
Size Window::GetSize() const
{
if (handle)
{
@ -136,17 +140,17 @@ namespace easy2d
return Size{};
}
float WindowImpl::GetWidth() const
float Window::GetWidth() const
{
return GetSize().x;
}
float WindowImpl::GetHeight() const
float Window::GetHeight() const
{
return GetSize().y;
}
void WindowImpl::SetSize(int width, int height)
void Window::SetSize(int width, int height)
{
if (handle)
{
@ -162,7 +166,7 @@ namespace easy2d
}
}
void WindowImpl::SetIcon(LPCWSTR icon_resource)
void Window::SetIcon(LPCWSTR icon_resource)
{
if (handle)
{
@ -181,22 +185,22 @@ namespace easy2d
}
}
HWND WindowImpl::GetHandle() const
HWND Window::GetHandle() const
{
return handle;
}
float WindowImpl::GetContentScaleX() const
float Window::GetContentScaleX() const
{
return scale_x;
}
float WindowImpl::GetContentScaleY() const
float Window::GetContentScaleY() const
{
return scale_y;
}
void WindowImpl::Destroy()
void Window::Destroy()
{
if (handle)
::DestroyWindow(handle);

View File

@ -24,10 +24,10 @@
namespace easy2d
{
class WindowImpl
: protected Noncopyable
class Window
: public ISingleton<Window>
{
E2D_DECLARE_SINGLETON(WindowImpl);
E2D_DECLARE_SINGLETON(Window);
public:
HRESULT Init(
@ -69,15 +69,13 @@ namespace easy2d
void Destroy();
protected:
WindowImpl();
Window();
~WindowImpl();
~Window();
private:
HWND handle;
float scale_x;
float scale_y;
};
E2D_DECLARE_SINGLETON_TYPE(WindowImpl, Window);
}

View File

@ -47,8 +47,8 @@
#include "core/noncopyable.hpp"
#include "core/RefCounter.hpp"
#include "core/intrusive/SmartPtr.hpp"
#include "core/intrusive/List.hpp"
#include "core/IntrusivePtr.hpp"
#include "core/IntrusiveList.hpp"
#include "core/Object.h"
#include "core/Image.h"
@ -66,8 +66,6 @@
#include "core/Transition.h"
#include "core/Event.hpp"
#include "core/MouseEvent.hpp"
#include "core/KeyEvent.hpp"
#include "core/EventListener.h"
#include "core/EventDispatcher.h"
@ -80,7 +78,7 @@
#include "core/DebugNode.h"
#include "core/Factory.h"
#include "core/Game.h"
#include "core/Application.h"
//

View File

@ -26,7 +26,7 @@ namespace easy2d
{
namespace math
{
class Matrix;
struct Matrix;
template <typename L, typename R>
struct MatrixMultiply;
@ -39,7 +39,7 @@ namespace easy2d
operator *(MatrixMultiply<L, R> const& lhs, Matrix const& rhs);
class Matrix
struct Matrix
{
union
{

View File

@ -26,16 +26,12 @@ namespace easy2d
{
namespace math
{
//
// 矩形
//
class Rect
struct Rect
{
public:
Vector2 origin; // 左上角坐标
Vector2 size; // 宽度和高度
public:
Rect() {}
Rect(

View File

@ -26,13 +26,11 @@ namespace easy2d
{
namespace math
{
class Vector2
struct Vector2
{
public:
float x;
float y;
public:
Vector2() : x(0.f), y(0.f) {}
Vector2(float x, float y) : x(x), y(y) {}

View File

@ -19,7 +19,6 @@
// THE SOFTWARE.
#include "Button.h"
#include "../core/MouseEvent.hpp"
namespace easy2d
{
@ -97,35 +96,34 @@ namespace easy2d
}
}
void Button::UpdateStatus(Event * e)
void Button::UpdateStatus(Event const& evt)
{
E2D_ASSERT(MouseEvent::Check(e));
E2D_ASSERT(MouseEvent::Check(evt.type));
MouseEvent* me = static_cast<MouseEvent*>(e);
if (enabled_)
{
if (me->type == MouseEvent::Hover)
if (evt.type == MouseEvent::Hover)
{
SetStatus(Status::Hover);
if (mouse_over_callback_)
mouse_over_callback_();
}
else if (me->type == MouseEvent::Out)
else if (evt.type == MouseEvent::Out)
{
SetStatus(Status::Normal);
if (mouse_out_callback_)
mouse_out_callback_();
}
else if (me->type == MouseEvent::Down && status_ == Status::Hover)
else if (evt.type == MouseEvent::Down && status_ == Status::Hover)
{
SetStatus(Status::Pressed);
if (pressed_callback_)
pressed_callback_();
}
else if (me->type == MouseEvent::Up && status_ == Status::Pressed)
else if (evt.type == MouseEvent::Up && status_ == Status::Pressed)
{
SetStatus(Status::Hover);

View File

@ -82,7 +82,7 @@ namespace easy2d
Status status
);
void UpdateStatus(Event* e);
void UpdateStatus(Event const& evt);
private:
bool enabled_;

View File

@ -19,9 +19,10 @@
// THE SOFTWARE.
#include "ResLoader.h"
#include "../core/modules.h"
#include "../core/Image.h"
#include "../core/Frames.h"
#include "../core/modules.h"
#include "../core/Music.h"
namespace easy2d
{
@ -46,11 +47,9 @@ namespace easy2d
res_.insert(std::make_pair(id, ImagePtr(new Image(path.c_str()))));
}
void ResLoader::AddFrames(String const& id, Array<Resource> const& images, Duration const& interval)
void ResLoader::AddFrames(String const& id, Array<Resource> const& images)
{
auto frames = FramesPtr(new Frames);
frames->SetInterval(interval);
for (const auto& image : images)
{
auto path = Search(image.GetFileName(), search_paths_);
@ -59,6 +58,12 @@ namespace easy2d
res_.insert(std::make_pair(id, frames));
}
void ResLoader::AddMusic(String const & id, Resource const & music)
{
auto path = Search(music.GetFileName(), search_paths_);
res_.insert(std::make_pair(id, MusicPtr(new Music(path.c_str()))));
}
void ResLoader::AddObj(String const& id, ObjectPtr const& obj)
{
res_.insert(std::make_pair(id, obj));
@ -74,6 +79,11 @@ namespace easy2d
return Get<Frames*>(id);
}
MusicPtr ResLoader::GetMusic(String const & id) const
{
return Get<Music*>(id);
}
ObjectPtr ResLoader::GetObj(String const & id) const
{
return Get<Object*>(id);

View File

@ -29,7 +29,9 @@ namespace easy2d
public:
void AddImage(String const& id, Resource const& image);
void AddFrames(String const& id, Array<Resource> const& images, Duration const& interval = 200);
void AddFrames(String const& id, Array<Resource> const& images);
void AddMusic(String const& id, Resource const& music);
void AddObj(String const& id, ObjectPtr const& obj);
@ -37,6 +39,8 @@ namespace easy2d
FramesPtr GetFrames(String const& id) const;
MusicPtr GetMusic(String const& id) const;
ObjectPtr GetObj(String const& id) const;
void Delete(String const& id);

View File

@ -26,8 +26,6 @@
namespace easy2d
{
using namespace intrusive;
Transcoder::Transcoder()
: wave_format_(nullptr)
{
@ -51,7 +49,7 @@ namespace easy2d
{
HRESULT hr = S_OK;
SmartPtr<IMFSourceReader> reader;
IntrusivePtr<IMFSourceReader> reader;
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromURL(
file_path,
@ -72,9 +70,9 @@ namespace easy2d
HRESULT hr = S_OK;
HINSTANCE hinstance = GetModuleHandle(nullptr);
SmartPtr<IStream> stream;
SmartPtr<IMFByteStream> byte_stream;
SmartPtr<IMFSourceReader> reader;
IntrusivePtr<IStream> stream;
IntrusivePtr<IMFByteStream> byte_stream;
IntrusivePtr<IMFSourceReader> reader;
LPVOID buffer;
DWORD buffer_size;
@ -118,8 +116,8 @@ namespace easy2d
HRESULT hr = S_OK;
DWORD max_stream_size = 0;
SmartPtr<IMFMediaType> partial_type;
SmartPtr<IMFMediaType> uncompressed_type;
IntrusivePtr<IMFMediaType> partial_type;
IntrusivePtr<IMFMediaType> uncompressed_type;
hr = modules::MediaFoundation::Get().MFCreateMediaType(&partial_type);
@ -199,8 +197,8 @@ namespace easy2d
DWORD position = 0;
BYTE* data = new (std::nothrow) BYTE[max_stream_size];
SmartPtr<IMFSample> sample;
SmartPtr<IMFMediaBuffer> buffer;
IntrusivePtr<IMFSample> sample;
IntrusivePtr<IMFMediaBuffer> buffer;
if (data == nullptr)
{