parent
f7cc01d294
commit
de5a51462e
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
using ActionCallback = std::function<void()>;
|
using ActionCallback = Closure<void()>;
|
||||||
|
|
||||||
class ActionManager;
|
class ActionManager;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
// 缓动函数
|
// 缓动函数
|
||||||
using EaseFunc = std::function<float(float)>;
|
using EaseFunc = Closure<float(float)>;
|
||||||
|
|
||||||
// 缓动函数枚举
|
// 缓动函数枚举
|
||||||
// See https://easings.net for more information
|
// See https://easings.net for more information
|
||||||
|
|
@ -380,8 +380,8 @@ namespace easy2d
|
||||||
public:
|
public:
|
||||||
// 创建淡出动作
|
// 创建淡出动作
|
||||||
explicit ActionFadeOut(
|
explicit ActionFadeOut(
|
||||||
Duration duration, /* 持续时长 */
|
Duration duration, /* 持续时长 */
|
||||||
EaseFunc func = Ease::Linear /* 速度变化 */
|
EaseFunc func = nullptr /* 速度变化 */
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ namespace easy2d
|
||||||
return crop_rect_.origin;
|
return crop_rect_.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect const& Image::GetCropRect() const
|
Rect Image::GetCropRect() const
|
||||||
{
|
{
|
||||||
return crop_rect_;
|
return crop_rect_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ namespace easy2d
|
||||||
Point GetCropPos() const;
|
Point GetCropPos() const;
|
||||||
|
|
||||||
// »ñÈ¡²Ã¼ô¾ØÐÎ
|
// »ñÈ¡²Ã¼ô¾ØÐÎ
|
||||||
Rect const& GetCropRect() const;
|
Rect GetCropRect() const;
|
||||||
|
|
||||||
ComPtr<ID2D1Bitmap> const& GetBitmap() const;
|
ComPtr<ID2D1Bitmap> const& GetBitmap() const;
|
||||||
|
|
||||||
|
|
@ -98,7 +98,7 @@ namespace easy2d
|
||||||
);
|
);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Rect crop_rect_;
|
Rect crop_rect_;
|
||||||
ComPtr<ID2D1Bitmap> bitmap_;
|
ComPtr<ID2D1Bitmap> bitmap_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,14 +28,14 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
SetSize(Renderer::Instance().GetOutputSize());
|
SetSize(Renderer::Instance().GetOutputSize());
|
||||||
|
|
||||||
AddListener(Event::MouseBtnDown, Closure(this, &Layer::HandleMessages));
|
AddListener(Event::MouseBtnDown, MakeClosure(this, &Layer::HandleMessages));
|
||||||
AddListener(Event::MouseBtnUp, Closure(this, &Layer::HandleMessages));
|
AddListener(Event::MouseBtnUp, MakeClosure(this, &Layer::HandleMessages));
|
||||||
AddListener(Event::MouseMove, Closure(this, &Layer::HandleMessages));
|
AddListener(Event::MouseMove, MakeClosure(this, &Layer::HandleMessages));
|
||||||
AddListener(Event::MouseWheel, Closure(this, &Layer::HandleMessages));
|
AddListener(Event::MouseWheel, MakeClosure(this, &Layer::HandleMessages));
|
||||||
|
|
||||||
AddListener(Event::KeyDown, Closure(this, &Layer::HandleMessages));
|
AddListener(Event::KeyDown, MakeClosure(this, &Layer::HandleMessages));
|
||||||
AddListener(Event::KeyUp, Closure(this, &Layer::HandleMessages));
|
AddListener(Event::KeyUp, MakeClosure(this, &Layer::HandleMessages));
|
||||||
AddListener(Event::Char, Closure(this, &Layer::HandleMessages));
|
AddListener(Event::Char, MakeClosure(this, &Layer::HandleMessages));
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer::~Layer()
|
Layer::~Layer()
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,11 @@ namespace easy2d
|
||||||
dirty_transform_ = true;
|
dirty_transform_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::SetAnchor(Point const& anchor)
|
||||||
|
{
|
||||||
|
this->SetAnchor(anchor.x, anchor.y);
|
||||||
|
}
|
||||||
|
|
||||||
void Node::SetWidth(float width)
|
void Node::SetWidth(float width)
|
||||||
{
|
{
|
||||||
this->SetSize(width, size_.y);
|
this->SetSize(width, size_.y);
|
||||||
|
|
@ -407,6 +412,11 @@ namespace easy2d
|
||||||
dirty_transform_ = true;
|
dirty_transform_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::SetScale(Point const& scale)
|
||||||
|
{
|
||||||
|
this->SetScale(scale.x, scale.y);
|
||||||
|
}
|
||||||
|
|
||||||
void Node::SetSkewX(float skew_x)
|
void Node::SetSkewX(float skew_x)
|
||||||
{
|
{
|
||||||
this->SetSkew(skew_x, transform_.skew.y);
|
this->SetSkew(skew_x, transform_.skew.y);
|
||||||
|
|
@ -427,6 +437,11 @@ namespace easy2d
|
||||||
dirty_transform_ = true;
|
dirty_transform_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::SetSkew(Point const& skew)
|
||||||
|
{
|
||||||
|
this->SetSkew(skew.x, skew.y);
|
||||||
|
}
|
||||||
|
|
||||||
void Node::SetRotation(float angle)
|
void Node::SetRotation(float angle)
|
||||||
{
|
{
|
||||||
if (transform_.rotation == angle)
|
if (transform_.rotation == angle)
|
||||||
|
|
@ -522,26 +537,24 @@ namespace easy2d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Node::RemoveChild(NodePtr const& child)
|
void Node::RemoveChild(NodePtr const& child)
|
||||||
{
|
{
|
||||||
return RemoveChild(child.Get());
|
RemoveChild(child.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Node::RemoveChild(Node * child)
|
void Node::RemoveChild(Node * child)
|
||||||
{
|
{
|
||||||
E2D_ASSERT(child && "Node::RemoveChild failed, NULL pointer exception");
|
E2D_ASSERT(child && "Node::RemoveChild failed, NULL pointer exception");
|
||||||
|
|
||||||
if (children_.IsEmpty())
|
if (children_.IsEmpty())
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
if (child)
|
if (child)
|
||||||
{
|
{
|
||||||
child->parent_ = nullptr;
|
child->parent_ = nullptr;
|
||||||
if (child->scene_) child->SetScene(nullptr);
|
if (child->scene_) child->SetScene(nullptr);
|
||||||
children_.Remove(NodePtr(child));
|
children_.Remove(NodePtr(child));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::RemoveChildren(String const& child_name)
|
void Node::RemoveChildren(String const& child_name)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace easy2d
|
||||||
friend class IntrusiveList<NodePtr>;
|
friend class IntrusiveList<NodePtr>;
|
||||||
|
|
||||||
using Children = IntrusiveList<NodePtr>;
|
using Children = IntrusiveList<NodePtr>;
|
||||||
using UpdateCallback = std::function<void(Duration)>;
|
using UpdateCallback = Closure<void(Duration)>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Node();
|
Node();
|
||||||
|
|
@ -56,6 +56,9 @@ namespace easy2d
|
||||||
// 获取显示状态
|
// 获取显示状态
|
||||||
bool IsVisible() const { return visible_; }
|
bool IsVisible() const { return visible_; }
|
||||||
|
|
||||||
|
// 获取响应状态
|
||||||
|
bool IsResponsible() const { return responsible_; }
|
||||||
|
|
||||||
// 获取名称的 Hash 值
|
// 获取名称的 Hash 值
|
||||||
size_t GetHashName() const { return hash_name_; }
|
size_t GetHashName() const { return hash_name_; }
|
||||||
|
|
||||||
|
|
@ -63,7 +66,7 @@ namespace easy2d
|
||||||
int GetZOrder() const { return z_order_; }
|
int GetZOrder() const { return z_order_; }
|
||||||
|
|
||||||
// 获取坐标
|
// 获取坐标
|
||||||
Point const& GetPosition() const { return transform_.position; }
|
Point GetPosition() const { return transform_.position; }
|
||||||
|
|
||||||
// 获取 x 坐标
|
// 获取 x 坐标
|
||||||
float GetPositionX() const { return transform_.position.x; }
|
float GetPositionX() const { return transform_.position.x; }
|
||||||
|
|
@ -71,12 +74,18 @@ namespace easy2d
|
||||||
// 获取 y 坐标
|
// 获取 y 坐标
|
||||||
float GetPositionY() const { return transform_.position.y; }
|
float GetPositionY() const { return transform_.position.y; }
|
||||||
|
|
||||||
|
// 获取横向缩放比例
|
||||||
|
Point GetScale() const { return transform_.scale; }
|
||||||
|
|
||||||
// 获取横向缩放比例
|
// 获取横向缩放比例
|
||||||
float GetScaleX() const { return transform_.scale.x; }
|
float GetScaleX() const { return transform_.scale.x; }
|
||||||
|
|
||||||
// 获取纵向缩放比例
|
// 获取纵向缩放比例
|
||||||
float GetScaleY() const { return transform_.scale.y; }
|
float GetScaleY() const { return transform_.scale.y; }
|
||||||
|
|
||||||
|
// 获取错切角度
|
||||||
|
Point GetSkew() const { return transform_.skew; }
|
||||||
|
|
||||||
// 获取横向错切角度
|
// 获取横向错切角度
|
||||||
float GetSkewX() const { return transform_.skew.x; }
|
float GetSkewX() const { return transform_.skew.x; }
|
||||||
|
|
||||||
|
|
@ -93,7 +102,7 @@ namespace easy2d
|
||||||
float GetHeight() const { return size_.y; }
|
float GetHeight() const { return size_.y; }
|
||||||
|
|
||||||
// 获取大小
|
// 获取大小
|
||||||
Size const& GetSize() const { return size_; }
|
Size GetSize() const { return size_; }
|
||||||
|
|
||||||
// 获取缩放后的宽度
|
// 获取缩放后的宽度
|
||||||
float GetScaledWidth() const { return size_.x * transform_.scale.x; }
|
float GetScaledWidth() const { return size_.x * transform_.scale.x; }
|
||||||
|
|
@ -104,6 +113,9 @@ namespace easy2d
|
||||||
// 获取缩放后的大小
|
// 获取缩放后的大小
|
||||||
Size GetScaledSize() const { return Size{ GetScaledWidth(), GetScaledHeight() }; }
|
Size GetScaledSize() const { return Size{ GetScaledWidth(), GetScaledHeight() }; }
|
||||||
|
|
||||||
|
// 获取锚点
|
||||||
|
Point GetAnchor() const { return anchor_; }
|
||||||
|
|
||||||
// 获取 x 方向锚点
|
// 获取 x 方向锚点
|
||||||
float GetAnchorX() const { return anchor_.x; }
|
float GetAnchorX() const { return anchor_.x; }
|
||||||
|
|
||||||
|
|
@ -114,7 +126,7 @@ namespace easy2d
|
||||||
float GetOpacity() const { return opacity_; }
|
float GetOpacity() const { return opacity_; }
|
||||||
|
|
||||||
// 获取变换
|
// 获取变换
|
||||||
Transform const& GetTransform() const { return transform_; }
|
Transform GetTransform() const { return transform_; }
|
||||||
|
|
||||||
// 获取边框
|
// 获取边框
|
||||||
Rect GetBounds() const;
|
Rect GetBounds() const;
|
||||||
|
|
@ -195,6 +207,12 @@ namespace easy2d
|
||||||
float scale_y
|
float scale_y
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 设置缩放比例
|
||||||
|
// 默认为 (1.0, 1.0)
|
||||||
|
void SetScale(
|
||||||
|
Point const& scale
|
||||||
|
);
|
||||||
|
|
||||||
// 设置缩放比例
|
// 设置缩放比例
|
||||||
// 默认为 1.0
|
// 默认为 1.0
|
||||||
void SetScale(
|
void SetScale(
|
||||||
|
|
@ -220,6 +238,12 @@ namespace easy2d
|
||||||
float skew_y
|
float skew_y
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 设置错切角度
|
||||||
|
// 默认为 (0, 0)
|
||||||
|
void SetSkew(
|
||||||
|
Point const& skew
|
||||||
|
);
|
||||||
|
|
||||||
// 设置旋转角度
|
// 设置旋转角度
|
||||||
// 默认为 0
|
// 默认为 0
|
||||||
void SetRotation(
|
void SetRotation(
|
||||||
|
|
@ -245,6 +269,12 @@ namespace easy2d
|
||||||
float anchor_y
|
float anchor_y
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 设置锚点位置
|
||||||
|
// 默认为 (0, 0), 范围 [0, 1]
|
||||||
|
void SetAnchor(
|
||||||
|
Point const& anchor
|
||||||
|
);
|
||||||
|
|
||||||
// 修改宽度
|
// 修改宽度
|
||||||
void SetWidth(
|
void SetWidth(
|
||||||
float width
|
float width
|
||||||
|
|
@ -317,12 +347,12 @@ namespace easy2d
|
||||||
Children const& GetChildren() const;
|
Children const& GetChildren() const;
|
||||||
|
|
||||||
// 移除子节点
|
// 移除子节点
|
||||||
bool RemoveChild(
|
void RemoveChild(
|
||||||
NodePtr const& child
|
NodePtr const& child
|
||||||
);
|
);
|
||||||
|
|
||||||
// 移除子节点
|
// 移除子节点
|
||||||
bool RemoveChild(
|
void RemoveChild(
|
||||||
Node* child
|
Node* child
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -376,22 +406,22 @@ namespace easy2d
|
||||||
void SetScene(Scene* scene);
|
void SetScene(Scene* scene);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool visible_;
|
bool visible_;
|
||||||
bool hover_;
|
bool hover_;
|
||||||
bool pressed_;
|
bool pressed_;
|
||||||
bool responsible_;
|
bool responsible_;
|
||||||
bool update_pausing_;
|
bool update_pausing_;
|
||||||
int z_order_;
|
int z_order_;
|
||||||
float opacity_;
|
float opacity_;
|
||||||
float display_opacity_;
|
float display_opacity_;
|
||||||
size_t hash_name_;
|
size_t hash_name_;
|
||||||
Transform transform_;
|
Transform transform_;
|
||||||
Point anchor_;
|
Point anchor_;
|
||||||
Size size_;
|
Size size_;
|
||||||
Node* parent_;
|
Node* parent_;
|
||||||
Scene* scene_;
|
Scene* scene_;
|
||||||
Children children_;
|
Children children_;
|
||||||
UpdateCallback cb_update_;
|
UpdateCallback cb_update_;
|
||||||
|
|
||||||
mutable bool dirty_transform_;
|
mutable bool dirty_transform_;
|
||||||
mutable bool dirty_transform_inverse_;
|
mutable bool dirty_transform_inverse_;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ namespace easy2d
|
||||||
|
|
||||||
void AsyncTask::Start()
|
void AsyncTask::Start()
|
||||||
{
|
{
|
||||||
std::thread thread(Closure(this, &AsyncTask::TaskThread));
|
std::thread thread(MakeClosure(this, &AsyncTask::TaskThread));
|
||||||
thread.detach();
|
thread.detach();
|
||||||
|
|
||||||
// retain this object until finished
|
// retain this object until finished
|
||||||
|
|
@ -77,7 +77,7 @@ namespace easy2d
|
||||||
|
|
||||||
if (thread_cb_)
|
if (thread_cb_)
|
||||||
{
|
{
|
||||||
AsyncTaskThread::Instance().PerformTaskCallback(Closure(this, &AsyncTask::Complete));
|
AsyncTaskThread::Instance().PerformTaskCallback(MakeClosure(this, &AsyncTask::Complete));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncTaskThread::PerformTaskCallback(std::function<void()> func)
|
void AsyncTaskThread::PerformTaskCallback(Closure<void()> func)
|
||||||
{
|
{
|
||||||
if (app_)
|
if (app_)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
|
#include "../common/Closure.hpp"
|
||||||
#include "../common/Singleton.hpp"
|
#include "../common/Singleton.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
@ -29,8 +30,8 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
E2D_DECLARE_SMART_PTR(AsyncTask);
|
E2D_DECLARE_SMART_PTR(AsyncTask);
|
||||||
|
|
||||||
typedef std::function<void()> AsyncTaskFunc;
|
typedef Closure<void()> AsyncTaskFunc;
|
||||||
typedef std::function<void()> AsyncTaskCallback;
|
typedef Closure<void()> AsyncTaskCallback;
|
||||||
|
|
||||||
class AsyncTask
|
class AsyncTask
|
||||||
: public Object
|
: public Object
|
||||||
|
|
@ -74,7 +75,7 @@ namespace easy2d
|
||||||
|
|
||||||
virtual void DestroyComponent();
|
virtual void DestroyComponent();
|
||||||
|
|
||||||
void PerformTaskCallback(std::function<void()> func);
|
void PerformTaskCallback(Closure<void()> func);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application* app_;
|
Application* app_;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../base/SmartPtr.hpp"
|
#include "../base/SmartPtr.hpp"
|
||||||
#include "../common/helper.h"
|
#include "../common/helper.h"
|
||||||
|
#include "../common/Closure.hpp"
|
||||||
#include "../common/IntrusiveList.hpp"
|
#include "../common/IntrusiveList.hpp"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "Event.hpp"
|
#include "Event.hpp"
|
||||||
|
|
@ -28,7 +29,7 @@
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
typedef std::function<void(Event const&)> EventCallback;
|
typedef Closure<void(Event const&)> EventCallback;
|
||||||
|
|
||||||
class EventDispatcher;
|
class EventDispatcher;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../common/helper.h"
|
#include "../common/helper.h"
|
||||||
|
#include "../common/Closure.hpp"
|
||||||
#include "../common/IntrusiveList.hpp"
|
#include "../common/IntrusiveList.hpp"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
@ -39,7 +40,7 @@ namespace easy2d
|
||||||
friend class TimerManager;
|
friend class TimerManager;
|
||||||
friend class IntrusiveList<TimerPtr>;
|
friend class IntrusiveList<TimerPtr>;
|
||||||
|
|
||||||
using Callback = std::function<void()>;
|
using Callback = Closure<void()>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Timer(
|
explicit Timer(
|
||||||
|
|
|
||||||
|
|
@ -163,9 +163,9 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
if (enabled_ && has_console_)
|
if (enabled_ && has_console_)
|
||||||
{
|
{
|
||||||
std::wstring output = MakeOutputString(prompt, format, args);
|
std::wstring output = MakeOutputStringf(prompt, format, args);
|
||||||
|
|
||||||
os << color << output;
|
os << color << output << std::flush;
|
||||||
::OutputDebugStringW(output.c_str());
|
::OutputDebugStringW(output.c_str());
|
||||||
|
|
||||||
ResetConsoleColor();
|
ResetConsoleColor();
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
std::wstring output = MakeOutputString(prompt, std::forward<_Args>(args)...);
|
std::wstring output = MakeOutputString(prompt, std::forward<_Args>(args)...);
|
||||||
|
|
||||||
os << color << output;
|
os << color << output << std::flush;
|
||||||
::OutputDebugStringW(output.c_str());
|
::OutputDebugStringW(output.c_str());
|
||||||
|
|
||||||
ResetConsoleColor();
|
ResetConsoleColor();
|
||||||
|
|
|
||||||
|
|
@ -19,79 +19,262 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <functional>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Closure is a simple function for binding member functions
|
// Closure is a light weight std::function<>-like class
|
||||||
//
|
//
|
||||||
|
|
||||||
template<typename _Ty, typename _Ret, typename... _Args>
|
namespace __closure_detail
|
||||||
std::function<_Ret(_Args...)> Closure(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...));
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Details of Closure
|
|
||||||
//
|
|
||||||
namespace __closure__detail
|
|
||||||
{
|
{
|
||||||
// sequence & generater
|
template<typename _Ret, typename... _Args>
|
||||||
|
class Callable
|
||||||
template<int... _Num>
|
|
||||||
struct Seq
|
|
||||||
{
|
{
|
||||||
using NextType = Seq<_Num..., sizeof...(_Num)>;
|
public:
|
||||||
|
virtual ~Callable() {}
|
||||||
|
|
||||||
|
virtual void AddRef() = 0;
|
||||||
|
virtual void Release() = 0;
|
||||||
|
virtual _Ret Invoke(_Args... args) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename...>
|
template<typename _Ret, typename... _Args>
|
||||||
struct Gen;
|
class RefCountCallable
|
||||||
|
: public Callable<_Ret, _Args...>
|
||||||
template<>
|
|
||||||
struct Gen<>
|
|
||||||
{
|
{
|
||||||
using SeqType = Seq<>;
|
public:
|
||||||
|
RefCountCallable() : ref_count_(0) {}
|
||||||
|
|
||||||
|
virtual void AddRef() override
|
||||||
|
{
|
||||||
|
++ref_count_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Release() override
|
||||||
|
{
|
||||||
|
--ref_count_;
|
||||||
|
if (ref_count_ <= 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int ref_count_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Ty1, typename... _Args>
|
|
||||||
struct Gen<_Ty1, _Args...>
|
|
||||||
{
|
|
||||||
using SeqType = typename Gen<_Args...>::SeqType::NextType;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// ClosureHelper
|
|
||||||
|
|
||||||
template<typename _Ty, typename _Ret, typename... _Args>
|
template<typename _Ty, typename _Ret, typename... _Args>
|
||||||
struct ClosureHelper
|
class ProxyCallable
|
||||||
|
: public RefCountCallable<_Ret, _Args...>
|
||||||
{
|
{
|
||||||
template<int... _Num>
|
public:
|
||||||
static inline std::function<_Ret(_Args...)> MakeFunc(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...), Seq<_Num...>)
|
ProxyCallable(_Ty&& val)
|
||||||
|
: callee_(std::move(val))
|
||||||
{
|
{
|
||||||
return std::bind(_Func, _Ptr, std::_Ph<_Num + 1>()...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int... _Num>
|
virtual _Ret Invoke(_Args... args) const override
|
||||||
static inline std::function<_Ret(_Args...)> MakeFunc(_Ty* _Ptr, _Ret(_Ty::* _Func)(_Args...) const, Seq<_Num...>)
|
|
||||||
{
|
{
|
||||||
return std::bind(_Func, _Ptr, std::_Ph<_Num + 1>()...);
|
return callee_(std::forward<_Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Callable<_Ret, _Args...>* Make(_Ty&& val)
|
||||||
|
{
|
||||||
|
return new (std::nothrow) ProxyCallable<_Ty, _Ret, _Args...>(std::move(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
_Ty callee_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _Ty, typename _Ret, typename... _Args>
|
||||||
|
class ProxyMemCallable
|
||||||
|
: public RefCountCallable<_Ret, _Args...>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef _Ret(_Ty::* _FuncType)(_Args...);
|
||||||
|
|
||||||
|
ProxyMemCallable(void* ptr, _FuncType func)
|
||||||
|
: ptr_(ptr)
|
||||||
|
, func_(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual _Ret Invoke(_Args... args) const override
|
||||||
|
{
|
||||||
|
return (static_cast<_Ty*>(ptr_)->*func_)(std::forward<_Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Callable<_Ret, _Args...>* Make(void* ptr, _FuncType func)
|
||||||
|
{
|
||||||
|
return new (std::nothrow) ProxyMemCallable<_Ty, _Ret, _Args...>(ptr, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* ptr_;
|
||||||
|
_FuncType func_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _Ty, typename _Ret, typename... _Args>
|
||||||
|
class ProxyConstMemCallable
|
||||||
|
: public RefCountCallable<_Ret, _Args...>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef _Ret(_Ty::* _FuncType)(_Args...) const;
|
||||||
|
|
||||||
|
ProxyConstMemCallable(void* ptr, _FuncType func)
|
||||||
|
: ptr_(ptr)
|
||||||
|
, func_(func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual _Ret Invoke(_Args... args) const override
|
||||||
|
{
|
||||||
|
return (static_cast<_Ty*>(ptr_)->*func_)(std::forward<_Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Callable<_Ret, _Args...>* Make(void* ptr, _FuncType func)
|
||||||
|
{
|
||||||
|
return new (std::nothrow) ProxyConstMemCallable<_Ty, _Ret, _Args...>(ptr, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* ptr_;
|
||||||
|
_FuncType func_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Ty, typename _Ret, typename... _Args>
|
//
|
||||||
inline std::function<_Ret(_Args...)> Closure(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...))
|
// exceptions
|
||||||
|
//
|
||||||
|
class bad_function_call : public std::exception
|
||||||
{
|
{
|
||||||
using namespace __closure__detail;
|
public:
|
||||||
return ClosureHelper<_Ty, _Ret, _Args...>::
|
bad_function_call() {}
|
||||||
MakeFunc(_Ptr, _Func, typename Gen<_Args...>::SeqType{});
|
|
||||||
|
virtual const char* what() const override
|
||||||
|
{
|
||||||
|
return "bad function call";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Closure details
|
||||||
|
//
|
||||||
|
template<typename _Ty>
|
||||||
|
class Closure;
|
||||||
|
|
||||||
|
template<typename _Ret, typename... _Args>
|
||||||
|
class Closure<_Ret(_Args...)>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Closure()
|
||||||
|
: callable_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Closure(std::nullptr_t)
|
||||||
|
: callable_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Closure(const Closure& rhs)
|
||||||
|
: callable_(rhs.callable_)
|
||||||
|
{
|
||||||
|
if (callable_) callable_->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
Closure(Closure&& rhs)
|
||||||
|
: callable_(rhs.callable_)
|
||||||
|
{
|
||||||
|
rhs.callable_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename _Ty>
|
||||||
|
Closure(_Ty val)
|
||||||
|
{
|
||||||
|
callable_ = __closure_detail::ProxyCallable<_Ty, _Ret, _Args...>::Make(std::move(val));
|
||||||
|
if (callable_) callable_->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename _Ty>
|
||||||
|
Closure(void* ptr, _Ret(_Ty::* func)(_Args...))
|
||||||
|
{
|
||||||
|
callable_ = __closure_detail::ProxyMemCallable<_Ty, _Ret, _Args...>::Make(ptr, func);
|
||||||
|
if (callable_) callable_->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename _Ty>
|
||||||
|
Closure(void* ptr, _Ret(_Ty::* func)(_Args...) const)
|
||||||
|
{
|
||||||
|
callable_ = __closure_detail::ProxyConstMemCallable<_Ty, _Ret, _Args...>::Make(ptr, func);
|
||||||
|
if (callable_) callable_->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
~Closure()
|
||||||
|
{
|
||||||
|
tidy();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void swap(const Closure& rhs)
|
||||||
|
{
|
||||||
|
std::swap(callable_, rhs.callable_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline _Ret operator()(_Args... args) const
|
||||||
|
{
|
||||||
|
if (!callable_)
|
||||||
|
throw bad_function_call();
|
||||||
|
return callable_->Invoke(std::forward<_Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator bool() const
|
||||||
|
{
|
||||||
|
return !!callable_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Closure& operator=(const Closure& rhs)
|
||||||
|
{
|
||||||
|
tidy();
|
||||||
|
callable_ = rhs.callable_;
|
||||||
|
if (callable_) callable_->AddRef();
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Closure& operator=(Closure&& rhs)
|
||||||
|
{
|
||||||
|
tidy();
|
||||||
|
callable_ = rhs.callable_;
|
||||||
|
rhs.callable_ = nullptr;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline void tidy()
|
||||||
|
{
|
||||||
|
if (callable_)
|
||||||
|
{
|
||||||
|
callable_->Release();
|
||||||
|
callable_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
__closure_detail::Callable<_Ret, _Args...>* callable_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _Ty, typename _Ret, typename... _Args>
|
||||||
|
inline Closure<_Ret(_Args...)> MakeClosure(void* ptr, _Ret(_Ty::* func)(_Args...))
|
||||||
|
{
|
||||||
|
return Closure<_Ret(_Args...)>(ptr, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Ty, typename _Ret, typename... _Args>
|
template<typename _Ty, typename _Ret, typename... _Args>
|
||||||
inline std::function<_Ret(_Args...)> Closure(_Ty* _Ptr, _Ret(_Ty::*_Func)(_Args...) const)
|
inline Closure<_Ret(_Args...)> MakeClosure(void* ptr, _Ret(_Ty::* func)(_Args...) const)
|
||||||
{
|
{
|
||||||
using namespace __closure__detail;
|
return Closure<_Ret(_Args...)>(ptr, func);
|
||||||
return ClosureHelper<_Ty, _Ret, _Args...>::
|
|
||||||
MakeFunc(_Ptr, _Func, typename Gen<_Args...>::SeqType{});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace easy2d
|
||||||
|
|
||||||
E2D_DECLARE_SMART_PTR(ImGuiLayer);
|
E2D_DECLARE_SMART_PTR(ImGuiLayer);
|
||||||
|
|
||||||
using ImGuiPipeline = std::function<void()>;
|
using ImGuiPipeline = Closure<void()>;
|
||||||
|
|
||||||
class ImGuiLayer
|
class ImGuiLayer
|
||||||
: public Layer
|
: public Layer
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ namespace easy2d
|
||||||
|
|
||||||
::curl_global_init(CURL_GLOBAL_ALL);
|
::curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
|
||||||
std::thread thread(Closure(this, &HttpClient::NetworkThread));
|
std::thread thread(MakeClosure(this, &HttpClient::NetworkThread));
|
||||||
thread.detach();
|
thread.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -301,7 +301,7 @@ namespace easy2d
|
||||||
|
|
||||||
if (app_)
|
if (app_)
|
||||||
{
|
{
|
||||||
app_->PreformFunctionInMainThread(Closure(this, &HttpClient::DispatchResponseCallback));
|
app_->PreformFunctionInMainThread(MakeClosure(this, &HttpClient::DispatchResponseCallback));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
namespace network
|
namespace network
|
||||||
{
|
{
|
||||||
typedef std::function<void(HttpRequestPtr, HttpResponsePtr)> ResponseCallback;
|
typedef Closure<void(HttpRequestPtr, HttpResponsePtr)> ResponseCallback;
|
||||||
|
|
||||||
class E2D_API HttpRequest
|
class E2D_API HttpRequest
|
||||||
: public Object
|
: public Object
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ namespace easy2d
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::PreformFunctionInMainThread(std::function<void()> function)
|
void Application::PreformFunctionInMainThread(Closure<void()> function)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(perform_mutex_);
|
std::lock_guard<std::mutex> lock(perform_mutex_);
|
||||||
functions_to_perform_.push(function);
|
functions_to_perform_.push(function);
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ namespace easy2d
|
||||||
// 在 Easy2D 主线程中执行函数
|
// 在 Easy2D 主线程中执行函数
|
||||||
// 当在其他线程调用 Easy2D 函数时使用
|
// 当在其他线程调用 Easy2D 函数时使用
|
||||||
void PreformFunctionInMainThread(
|
void PreformFunctionInMainThread(
|
||||||
std::function<void()> function
|
Closure<void()> function
|
||||||
);
|
);
|
||||||
|
|
||||||
// 显示控制台
|
// 显示控制台
|
||||||
|
|
@ -163,6 +163,6 @@ namespace easy2d
|
||||||
Array<Component*> components_;
|
Array<Component*> components_;
|
||||||
|
|
||||||
std::mutex perform_mutex_;
|
std::mutex perform_mutex_;
|
||||||
Queue<std::function<void()>> functions_to_perform_;
|
Queue<Closure<void()>> functions_to_perform_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,10 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
SetResponsible(true);
|
SetResponsible(true);
|
||||||
|
|
||||||
AddListener(Event::MouseHover, Closure(this, &Button::UpdateStatus));
|
AddListener(Event::MouseHover, MakeClosure(this, &Button::UpdateStatus));
|
||||||
AddListener(Event::MouseOut, Closure(this, &Button::UpdateStatus));
|
AddListener(Event::MouseOut, MakeClosure(this, &Button::UpdateStatus));
|
||||||
AddListener(Event::MouseBtnDown, Closure(this, &Button::UpdateStatus));
|
AddListener(Event::MouseBtnDown, MakeClosure(this, &Button::UpdateStatus));
|
||||||
AddListener(Event::MouseBtnUp, Closure(this, &Button::UpdateStatus));
|
AddListener(Event::MouseBtnUp, MakeClosure(this, &Button::UpdateStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
Button::Button(const Callback& click)
|
Button::Button(const Callback& click)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ namespace easy2d
|
||||||
class E2D_API Button
|
class E2D_API Button
|
||||||
: public Sprite
|
: public Sprite
|
||||||
{
|
{
|
||||||
using Callback = std::function<void()>;
|
using Callback = Closure<void()>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Button();
|
Button();
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public:
|
||||||
SetResponsible(true);
|
SetResponsible(true);
|
||||||
|
|
||||||
// 添加消息监听
|
// 添加消息监听
|
||||||
AddListener(Event::Click, Closure(this, &MainScene::Click));
|
AddListener(Event::Click, MakeClosure(this, &MainScene::Click));
|
||||||
|
|
||||||
// 创建物理世界
|
// 创建物理世界
|
||||||
world_ = new b2World(b2Vec2(0, 10));
|
world_ = new b2World(b2Vec2(0, 10));
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,10 @@ public:
|
||||||
}, L"DemoWindow");
|
}, L"DemoWindow");
|
||||||
|
|
||||||
// 添加一个简单窗口
|
// 添加一个简单窗口
|
||||||
layer->AddItem(Closure(this, &MainScene::SimpleWindow), L"SimpleWindow");
|
layer->AddItem(MakeClosure(this, &MainScene::SimpleWindow), L"SimpleWindow");
|
||||||
|
|
||||||
// 再添加一个窗口
|
// 再添加一个窗口
|
||||||
layer->AddItem(Closure(this, &MainScene::AnotherWindow), L"AnotherWindow");
|
layer->AddItem(MakeClosure(this, &MainScene::AnotherWindow), L"AnotherWindow");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleWindow()
|
void SimpleWindow()
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// 添加按键监听
|
// 添加按键监听
|
||||||
AddListener(Event::KeyDown, Closure(this, &Tiger::OnKeyDown));
|
AddListener(Event::KeyDown, MakeClosure(this, &Tiger::OnKeyDown));
|
||||||
AddListener(Event::KeyUp, Closure(this, &Tiger::OnKeyUp));
|
AddListener(Event::KeyUp, MakeClosure(this, &Tiger::OnKeyUp));
|
||||||
|
|
||||||
// 默认方向为 Left
|
// 默认方向为 Left
|
||||||
facing_left = true;
|
facing_left = true;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public:
|
||||||
Demo5()
|
Demo5()
|
||||||
{
|
{
|
||||||
// 添加按键监听
|
// 添加按键监听
|
||||||
AddListener(Event::KeyDown, Closure(this, &Demo5::OnKeyDown));
|
AddListener(Event::KeyDown, MakeClosure(this, &Demo5::OnKeyDown));
|
||||||
|
|
||||||
// 创建说明文字
|
// 创建说明文字
|
||||||
TextPtr text = new Text(L"按G发送GET请求\n按P发送POST请求\n按U发送PUT请求\n按D发送DELETE请求");
|
TextPtr text = new Text(L"按G发送GET请求\n按P发送POST请求\n按U发送PUT请求\n按D发送DELETE请求");
|
||||||
|
|
@ -74,7 +74,7 @@ public:
|
||||||
// 设置请求类型为 GET
|
// 设置请求类型为 GET
|
||||||
request->SetType(HttpRequest::Type::Get);
|
request->SetType(HttpRequest::Type::Get);
|
||||||
// 设置请求完成后的回调函数
|
// 设置请求完成后的回调函数
|
||||||
request->SetResponseCallback(Closure(this, &Demo5::Complete));
|
request->SetResponseCallback(MakeClosure(this, &Demo5::Complete));
|
||||||
|
|
||||||
// 发送 HTTP 请求
|
// 发送 HTTP 请求
|
||||||
HttpClient::Instance().Send(request);
|
HttpClient::Instance().Send(request);
|
||||||
|
|
@ -100,7 +100,7 @@ public:
|
||||||
request->SetType(HttpRequest::Type::Post);
|
request->SetType(HttpRequest::Type::Post);
|
||||||
// 设置 POST 请求的数据
|
// 设置 POST 请求的数据
|
||||||
request->SetJsonData(request_data);
|
request->SetJsonData(request_data);
|
||||||
request->SetResponseCallback(Closure(this, &Demo5::Complete));
|
request->SetResponseCallback(MakeClosure(this, &Demo5::Complete));
|
||||||
|
|
||||||
HttpClient::Instance().Send(request);
|
HttpClient::Instance().Send(request);
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +118,7 @@ public:
|
||||||
request->SetType(HttpRequest::Type::Put);
|
request->SetType(HttpRequest::Type::Put);
|
||||||
// 设置 PUT 请求的数据
|
// 设置 PUT 请求的数据
|
||||||
request->SetJsonData(request_data);
|
request->SetJsonData(request_data);
|
||||||
request->SetResponseCallback(Closure(this, &Demo5::Complete));
|
request->SetResponseCallback(MakeClosure(this, &Demo5::Complete));
|
||||||
|
|
||||||
HttpClient::Instance().Send(request);
|
HttpClient::Instance().Send(request);
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +131,7 @@ public:
|
||||||
HttpRequestPtr request = new HttpRequest;
|
HttpRequestPtr request = new HttpRequest;
|
||||||
request->SetUrl(L"http://httpbin.org/delete");
|
request->SetUrl(L"http://httpbin.org/delete");
|
||||||
request->SetType(HttpRequest::Type::Delete);
|
request->SetType(HttpRequest::Type::Delete);
|
||||||
request->SetResponseCallback(Closure(this, &Demo5::Complete));
|
request->SetResponseCallback(MakeClosure(this, &Demo5::Complete));
|
||||||
|
|
||||||
HttpClient::Instance().Send(request);
|
HttpClient::Instance().Send(request);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ public:
|
||||||
EnterScene(scene);
|
EnterScene(scene);
|
||||||
|
|
||||||
// 添加按键监听
|
// 添加按键监听
|
||||||
scene->AddListener(Event::KeyUp, Closure(this, &DemoApp::KeyPressed));
|
scene->AddListener(Event::KeyUp, MakeClosure(this, &DemoApp::KeyPressed));
|
||||||
|
|
||||||
// 显示提示文字
|
// 显示提示文字
|
||||||
String intro_str = format_wstring(L"按键 1~%d 可切换示例\n", s_DemoNum);
|
String intro_str = format_wstring(L"按键 1~%d 可切换示例\n", s_DemoNum);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue