#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace frostbite2D { class Actor; class Scene; using ActorList = IntrusiveList>; class Actor : public RefObject, protected IntrusiveListValue> { public: using IntrusiveListValue>::GetNext; using IntrusiveListValue>::GetPrev; Actor(); virtual ~Actor(); virtual void Update(float deltaTime); virtual void Render(); virtual void OnUpdate(float deltaTime) {} virtual void OnAdded(Actor* parent) {} void AddChild(RefPtr child); void RemoveChild(RefPtr child); void RemoveAllChildren(); Actor* GetParent() const { return parent_; } Scene* GetScene() const { return scene_; } const std::string& GetName() const { return name_; } void SetName(const std::string& name) { name_ = name; } const UUID& GetUUID() const { return uuid_; } std::string GetUUIDString() const { return uuid_.toString(); } /** * @brief 获取锚点在父坐标系中的位置 */ const Vec2& GetPosition() const { return position_; } /** * @brief 设置锚点在父坐标系中的位置 */ void SetPosition(const Vec2& pos); void SetPosition(float x, float y); float GetRotation() const { return rotation_; } void SetRotation(float rotation); const Vec2& GetScale() const { return scale_; } void SetScale(const Vec2& scale); void SetScale(float scale); const Transform2D& GetLocalTransform() const; const Transform2D& GetWorldTransform() const; const Vec2& GetSize() const { return size_; } void SetSize(const Vec2& size); void SetSize(float width, float height); /** * @brief 获取归一化锚点,(0, 0) 为左上角,(0.5, 0.5) 为中心 */ const Vec2& GetAnchor() const { return anchor_; } /** * @brief 设置归一化锚点,不会自动补偿 position */ void SetAnchor(const Vec2& anchor); void SetAnchor(float x, float y); /** * @brief 获取未旋转矩形左上角在父坐标系中的位置 */ Vec2 GetTopLeftPosition() const; /** * @brief 设置未旋转矩形左上角在父坐标系中的位置 */ void SetTopLeftPosition(const Vec2& pos); void SetTopLeftPosition(float x, float y); bool IsVisible() const { return visible_; } void SetVisible(bool visible) { visible_ = visible; } int GetZOrder() const { return zOrder_; } void SetZOrder(int zOrder); float GetOpacity() const { return opacity_; } void SetOpacity(float opacity); float GetWorldOpacity() const; ActorList& GetChildren() { return children_; } const ActorList& GetChildren() const { return children_; } bool IsEventReceiveEnabled() const { return eventReceiveEnabled_; } void EnableEventReceive() { eventReceiveEnabled_ = true; } void DisableEventReceive() { eventReceiveEnabled_ = false; } int32 GetEventPriority() const { return eventPriority_; } void SetEventPriority(int32 priority) { eventPriority_ = priority; } bool IsEventInterceptEnabled() const { return eventInterceptEnabled_; } void EnableEventIntercept() { eventInterceptEnabled_ = true; } void DisableEventIntercept() { eventInterceptEnabled_ = false; } enum class UpdatePhase { BeforeChildren, AfterChildren }; using UpdateCallback = Function; using EventCallback = std::function; uint32 AddUpdateListener(UpdateCallback callback, UpdatePhase phase = UpdatePhase::BeforeChildren); bool RemoveUpdateListener(uint32 listenerId); void ClearUpdateListeners(); uint32 AddEventListener(EventType type, EventCallback callback); bool RemoveEventListener(uint32 listenerId); void ClearEventListeners(); virtual bool OnEvent(const Event& event); virtual bool OnKeyDown(const KeyEvent& event); virtual bool OnKeyUp(const KeyEvent& event); virtual bool OnMouseDown(const MouseEvent& event); virtual bool OnMouseUp(const MouseEvent& event); virtual bool OnMouseMove(const MouseEvent& event); virtual bool OnMouseWheel(const MouseEvent& event); virtual bool OnTouchDown(const TouchEvent& event); virtual bool OnTouchUp(const TouchEvent& event); virtual bool OnTouchMove(const TouchEvent& event); virtual bool OnJoystickAxis(const JoystickEvent& event); virtual bool OnJoystickButtonDown(const JoystickEvent& event); virtual bool OnJoystickButtonUp(const JoystickEvent& event); virtual bool OnWindowResize(const WindowEvent& event); bool DispatchEvent(const Event& event); bool BubbleEvent(const Event& event); protected: void SetParent(Actor* parent) { parent_ = parent; } void SetScene(Scene* scene) { scene_ = scene; } void insertChildByZOrder(RefPtr child); void UpdateChildren(float deltaTime); void RenderChildren(); virtual void OnTransformChanged() {}; private: Actor* parent_; Scene* scene_; ActorList children_; UUID uuid_; std::string name_; Vec2 position_; float rotation_; Vec2 scale_ = Vec2(1.0f, 1.0f); Vec2 size_; Vec2 anchor_; bool visible_; int zOrder_; float opacity_; mutable Transform2D localTransform_; mutable Transform2D worldTransform_; mutable bool transformDirty_ = true; bool eventReceiveEnabled_ = false; int32 eventPriority_ = 0; bool eventInterceptEnabled_ = false; struct UpdateListener { uint32 id; UpdatePhase phase; UpdateCallback callback; bool active = true; }; std::vector updateListeners_; uint32 nextUpdateListenerId_ = 1; bool iteratingUpdateListeners_ = false; bool updateListenersDirty_ = false; struct EventListener { uint32 id; EventType type; EventCallback callback; }; std::vector eventListeners_; uint32 nextListenerId_ = 1; void markTransformDirty(); void updateLocalTransform() const; void updateWorldTransform() const; void executeUpdateListeners(UpdatePhase phase, float deltaTime); void compactUpdateListeners(); friend class Scene; }; }