18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci#ifndef SCENE_PLUGIN_ECS_ANIMATION_H
168bf80f4bSopenharmony_ci#define SCENE_PLUGIN_ECS_ANIMATION_H
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#undef InterlockedIncrement
198bf80f4bSopenharmony_ci#undef InterlockedDecrement
208bf80f4bSopenharmony_ci
218bf80f4bSopenharmony_ci#include <optional>
228bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_ecs_animation.h>
238bf80f4bSopenharmony_ci
248bf80f4bSopenharmony_ci#include <3d/ecs/components/animation_component.h>
258bf80f4bSopenharmony_ci#include <3d/ecs/components/animation_input_component.h>
268bf80f4bSopenharmony_ci#include <3d/ecs/components/animation_output_component.h>
278bf80f4bSopenharmony_ci#include <3d/ecs/components/animation_track_component.h>
288bf80f4bSopenharmony_ci#include <3d/ecs/components/name_component.h>
298bf80f4bSopenharmony_ci#include <core/ecs/intf_component_manager.h>
308bf80f4bSopenharmony_ci#include <core/ecs/intf_ecs.h>
318bf80f4bSopenharmony_ci
328bf80f4bSopenharmony_ci#include <meta/base/shared_ptr.h>
338bf80f4bSopenharmony_ci#include <meta/ext/animation/interpolator.h>
348bf80f4bSopenharmony_ci#include <meta/ext/attachment/attachment.h>
358bf80f4bSopenharmony_ci#include <meta/ext/object_container.h>
368bf80f4bSopenharmony_ci#include <meta/ext/event_impl.h>
378bf80f4bSopenharmony_ci#include <meta/interface/animation/builtin_animations.h>
388bf80f4bSopenharmony_ci#include <meta/interface/intf_container.h>
398bf80f4bSopenharmony_ci
408bf80f4bSopenharmony_ci#include "scene_holder.h"
418bf80f4bSopenharmony_ci
428bf80f4bSopenharmony_ciSCENE_BEGIN_NAMESPACE()
438bf80f4bSopenharmony_ci
448bf80f4bSopenharmony_ciclass EcsTrackAnimation final : public META_NS::ObjectFwd<EcsTrackAnimation, ClassId::EcsTrackAnimation, META_NS::ClassId::Object,
458bf80f4bSopenharmony_ci          IEcsTrackAnimation, META_NS::IStartableAnimation, META_NS::ITrackAnimation, META_NS::IPropertyAnimation,
468bf80f4bSopenharmony_ci          META_NS::IContainable, META_NS::IMutableContainable, SCENE_NS::IEcsProxyObject, META_NS::ITimedAnimation> {
478bf80f4bSopenharmony_cipublic:
488bf80f4bSopenharmony_ci    // From INamed
498bf80f4bSopenharmony_ci    META_IMPLEMENT_PROPERTY(BASE_NS::string, Name)
508bf80f4bSopenharmony_ci
518bf80f4bSopenharmony_ci    // From ITrackAnimation
528bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_ARRAY_PROPERTY(ITrackAnimation, float, Timestamps, {})
538bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_ARRAY_PROPERTY(ITrackAnimation, META_NS::IFunction::Ptr, KeyframeHandlers)
548bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(ITrackAnimation, uint32_t, CurrentKeyframeIndex, -1)
558bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IPropertyAnimation, META_NS::IProperty::WeakPtr, Property, {})
568bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_ARRAY_PROPERTY(ITrackAnimation, META_NS::ICurve1D::Ptr, KeyframeCurves, {})
578bf80f4bSopenharmony_ci    META_NS::IProperty::Ptr Keyframes() const override;
588bf80f4bSopenharmony_ci    size_t AddKeyframe(float timestamp, const META_NS::IAny::ConstPtr& value) override;
598bf80f4bSopenharmony_ci    bool RemoveKeyframe(size_t index) override;
608bf80f4bSopenharmony_ci    void RemoveAllKeyframes() override;
618bf80f4bSopenharmony_ci
628bf80f4bSopenharmony_ci    // From IAnimation
638bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, bool, Enabled, true)
648bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Valid, false, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
658bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, META_NS::TimeSpan, TotalDuration,
668bf80f4bSopenharmony_ci        META_NS::TimeSpan::Milliseconds(500), META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
678bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Running, false, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
688bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, float, Progress, 0, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
698bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, META_NS::ICurve1D::Ptr, Curve)
708bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(
718bf80f4bSopenharmony_ci        IAnimation, META_NS::IAnimationController::WeakPtr, Controller, {}, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
728bf80f4bSopenharmony_ci
738bf80f4bSopenharmony_ci    // From IAnimationWithModifiableDuration
748bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, META_NS::TimeSpan, Duration, META_NS::TimeSpan::Milliseconds(500))
758bf80f4bSopenharmony_ci
768bf80f4bSopenharmony_ci    bool Build(const META_NS::IMetadata::Ptr& data) override;
778bf80f4bSopenharmony_ci
788bf80f4bSopenharmony_ci    void Seek(float position) override;
798bf80f4bSopenharmony_ci    void Step(const META_NS::IClock::ConstPtr& clock) override;
808bf80f4bSopenharmony_ci    void Start() override;
818bf80f4bSopenharmony_ci    void Stop() override;
828bf80f4bSopenharmony_ci    void Pause() override;
838bf80f4bSopenharmony_ci    void Restart() override;
848bf80f4bSopenharmony_ci    void Finish() override;
858bf80f4bSopenharmony_ci
868bf80f4bSopenharmony_ci    META_IMPLEMENT_EVENT(META_NS::IOnChanged, OnFinished)
878bf80f4bSopenharmony_ci    META_IMPLEMENT_EVENT(META_NS::IOnChanged, OnStarted)
888bf80f4bSopenharmony_ci
898bf80f4bSopenharmony_ci    void SetEntity(CORE_NS::Entity entity) override
908bf80f4bSopenharmony_ci    {
918bf80f4bSopenharmony_ci        entity_ = entity;
928bf80f4bSopenharmony_ci        if (auto ecsListener = ecsListener_.lock()) {
938bf80f4bSopenharmony_ci            if (auto animationTrackManager =
948bf80f4bSopenharmony_ci                    CORE_NS::GetManager<CORE3D_NS::IAnimationTrackComponentManager>(*ecsListener->ecs_)) {
958bf80f4bSopenharmony_ci                ecsListener->AddEntity(entity, GetSelf<SCENE_NS::IEcsProxyObject>(), *animationTrackManager);
968bf80f4bSopenharmony_ci            }
978bf80f4bSopenharmony_ci            if (auto animationInputManager =
988bf80f4bSopenharmony_ci                    CORE_NS::GetManager<CORE3D_NS::IAnimationInputComponentManager>(*ecsListener->ecs_)) {
998bf80f4bSopenharmony_ci                ecsListener->AddEntity(entity, GetSelf<SCENE_NS::IEcsProxyObject>(), *animationInputManager);
1008bf80f4bSopenharmony_ci            }
1018bf80f4bSopenharmony_ci        }
1028bf80f4bSopenharmony_ci    }
1038bf80f4bSopenharmony_ci
1048bf80f4bSopenharmony_cipublic: // from IEcsProxyObject
1058bf80f4bSopenharmony_ci    void SetCommonListener(BASE_NS::shared_ptr<SCENE_NS::EcsListener> ecsListener) override
1068bf80f4bSopenharmony_ci    {
1078bf80f4bSopenharmony_ci        ecsListener_ = ecsListener;
1088bf80f4bSopenharmony_ci    }
1098bf80f4bSopenharmony_ci
1108bf80f4bSopenharmony_ci    void DoEntityEvent(CORE_NS::IEcs::EntityListener::EventType type, const CORE_NS::Entity& entity) override
1118bf80f4bSopenharmony_ci    {
1128bf80f4bSopenharmony_ci        if (auto parent = interface_pointer_cast<SCENE_NS::IEcsProxyObject>(GetParent())) {
1138bf80f4bSopenharmony_ci            parent->DoEntityEvent(type, entity);
1148bf80f4bSopenharmony_ci        }
1158bf80f4bSopenharmony_ci    }
1168bf80f4bSopenharmony_ci
1178bf80f4bSopenharmony_ci    void DoComponentEvent(CORE_NS::IEcs::ComponentListener::EventType type,
1188bf80f4bSopenharmony_ci        const CORE_NS::IComponentManager& componentManager, const CORE_NS::Entity& entity) override
1198bf80f4bSopenharmony_ci    {
1208bf80f4bSopenharmony_ci        if (auto parent = interface_pointer_cast<SCENE_NS::IEcsProxyObject>(GetParent())) {
1218bf80f4bSopenharmony_ci            parent->DoComponentEvent(type, componentManager, entity);
1228bf80f4bSopenharmony_ci        }
1238bf80f4bSopenharmony_ci    }
1248bf80f4bSopenharmony_ci
1258bf80f4bSopenharmony_ci    CORE_NS::Entity GetEntity() const override
1268bf80f4bSopenharmony_ci    {
1278bf80f4bSopenharmony_ci        return entity_;
1288bf80f4bSopenharmony_ci    }
1298bf80f4bSopenharmony_ci
1308bf80f4bSopenharmony_ci    void SetSuperInstance(const IObject::Ptr& aggr, const IObject::Ptr& super) override
1318bf80f4bSopenharmony_ci    {
1328bf80f4bSopenharmony_ci        ObjectFwd::SetSuperInstance(aggr, super);
1338bf80f4bSopenharmony_ci        containable_ = interface_cast<IContainable>(super);
1348bf80f4bSopenharmony_ci        mutableContainable_ = interface_cast<IMutableContainable>(super);
1358bf80f4bSopenharmony_ci    }
1368bf80f4bSopenharmony_ci
1378bf80f4bSopenharmony_ci    void SetParent(const IObject::Ptr& parent) override
1388bf80f4bSopenharmony_ci    {
1398bf80f4bSopenharmony_ci        if (mutableContainable_) {
1408bf80f4bSopenharmony_ci            mutableContainable_->SetParent(parent);
1418bf80f4bSopenharmony_ci        } else {
1428bf80f4bSopenharmony_ci            parent_ = parent;
1438bf80f4bSopenharmony_ci        }
1448bf80f4bSopenharmony_ci    }
1458bf80f4bSopenharmony_ci
1468bf80f4bSopenharmony_ci    IObject::Ptr GetParent() const override
1478bf80f4bSopenharmony_ci    {
1488bf80f4bSopenharmony_ci        if (containable_) {
1498bf80f4bSopenharmony_ci            return containable_->GetParent();
1508bf80f4bSopenharmony_ci        }
1518bf80f4bSopenharmony_ci        return parent_.lock();
1528bf80f4bSopenharmony_ci    }
1538bf80f4bSopenharmony_ci
1548bf80f4bSopenharmony_ci    void Destroy() override
1558bf80f4bSopenharmony_ci    {
1568bf80f4bSopenharmony_ci        if (auto ecsListener = ecsListener_.lock()) {
1578bf80f4bSopenharmony_ci            if (!ecsListener->ecs_) {
1588bf80f4bSopenharmony_ci                return;
1598bf80f4bSopenharmony_ci            }
1608bf80f4bSopenharmony_ci            if (auto animationTrackManager =
1618bf80f4bSopenharmony_ci                    CORE_NS::GetManager<CORE3D_NS::IAnimationTrackComponentManager>(*ecsListener->ecs_)) {
1628bf80f4bSopenharmony_ci                ecsListener->RemoveEntity(entity_, GetSelf<SCENE_NS::IEcsProxyObject>(), *animationTrackManager);
1638bf80f4bSopenharmony_ci            }
1648bf80f4bSopenharmony_ci            if (auto animationInputManager =
1658bf80f4bSopenharmony_ci                    CORE_NS::GetManager<CORE3D_NS::IAnimationInputComponentManager>(*ecsListener->ecs_)) {
1668bf80f4bSopenharmony_ci                ecsListener->RemoveEntity(entity_, GetSelf<SCENE_NS::IEcsProxyObject>(), *animationInputManager);
1678bf80f4bSopenharmony_ci            }
1688bf80f4bSopenharmony_ci        }
1698bf80f4bSopenharmony_ci    }
1708bf80f4bSopenharmony_ci
1718bf80f4bSopenharmony_ciprivate:
1728bf80f4bSopenharmony_ci    CORE_NS::Entity entity_;
1738bf80f4bSopenharmony_ci    BASE_NS::string name_;
1748bf80f4bSopenharmony_ci    META_NS::IProperty::Ptr keyframes_;
1758bf80f4bSopenharmony_ci
1768bf80f4bSopenharmony_ci    mutable META_NS::EventImpl<META_NS::IOnChanged> onFinished_;
1778bf80f4bSopenharmony_ci    mutable META_NS::EventImpl<META_NS::IOnChanged> onStarted_;
1788bf80f4bSopenharmony_ci
1798bf80f4bSopenharmony_ci    BASE_NS::weak_ptr<SCENE_NS::EcsListener> ecsListener_;
1808bf80f4bSopenharmony_ci    META_NS::IContainable* containable_ {};
1818bf80f4bSopenharmony_ci    META_NS::IMutableContainable* mutableContainable_ {};
1828bf80f4bSopenharmony_ci    META_NS::IObject::WeakPtr parent_;
1838bf80f4bSopenharmony_ci};
1848bf80f4bSopenharmony_ci
1858bf80f4bSopenharmony_ciclass EcsAnimation final : public META_NS::ObjectContainerFwd<EcsAnimation, ClassId::EcsAnimation, IEcsAnimation,
1868bf80f4bSopenharmony_ci                                META_NS::IParallelAnimation, META_NS::ITimedAnimation, META_NS::IStartableAnimation,
1878bf80f4bSopenharmony_ci                               SCENE_NS::IEcsProxyObject, META_NS::IAttachment> {
1888bf80f4bSopenharmony_cipublic:
1898bf80f4bSopenharmony_ci    // From IEcsAnimation
1908bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(
1918bf80f4bSopenharmony_ci        IEcsAnimation, bool, ReadOnly, false, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
1928bf80f4bSopenharmony_ci
1938bf80f4bSopenharmony_ci    // From INamed
1948bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(INamed, BASE_NS::string, Name, {})
1958bf80f4bSopenharmony_ci
1968bf80f4bSopenharmony_ci    // From IAnimation
1978bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, bool, Enabled, true)
1988bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Valid, false, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
1998bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, META_NS::TimeSpan, TotalDuration,
2008bf80f4bSopenharmony_ci        META_NS::TimeSpan::Milliseconds(500), META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
2018bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Running, false, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
2028bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, float, Progress, 0, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
2038bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, META_NS::ICurve1D::Ptr, Curve)
2048bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(
2058bf80f4bSopenharmony_ci        IAnimation, META_NS::IAnimationController::WeakPtr, Controller, {}, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
2068bf80f4bSopenharmony_ci    META_IMPLEMENT_READONLY_PROPERTY(META_NS::IObject::WeakPtr, DataContext)
2078bf80f4bSopenharmony_ci    META_IMPLEMENT_READONLY_PROPERTY(META_NS::IAttach::WeakPtr, AttachedTo)
2088bf80f4bSopenharmony_ci
2098bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(
2108bf80f4bSopenharmony_ci        ITimedAnimation, META_NS::TimeSpan, Duration, META_NS::TimeSpan::Milliseconds(500))
2118bf80f4bSopenharmony_ci
2128bf80f4bSopenharmony_ci    void AddAnimation(const IAnimation::Ptr&) override;
2138bf80f4bSopenharmony_ci    void RemoveAnimation(const IAnimation::Ptr&) override;
2148bf80f4bSopenharmony_ci
2158bf80f4bSopenharmony_ci    BASE_NS::vector<IAnimation::Ptr> GetAnimations() const override;
2168bf80f4bSopenharmony_ci
2178bf80f4bSopenharmony_cipublic:
2188bf80f4bSopenharmony_ci    void SetSceneHolder(SceneHolder::Ptr& sceneHolder)
2198bf80f4bSopenharmony_ci    {
2208bf80f4bSopenharmony_ci        sceneHolder_ = sceneHolder;
2218bf80f4bSopenharmony_ci        SetCommonListener(sceneHolder->GetCommonEcsListener());
2228bf80f4bSopenharmony_ci    }
2238bf80f4bSopenharmony_ci
2248bf80f4bSopenharmony_ci    SceneHolder::Ptr GetSceneHolder()
2258bf80f4bSopenharmony_ci    {
2268bf80f4bSopenharmony_ci        return sceneHolder_.lock();
2278bf80f4bSopenharmony_ci    }
2288bf80f4bSopenharmony_ci
2298bf80f4bSopenharmony_ci    // from IEcsProxyObject
2308bf80f4bSopenharmony_ci    void SetCommonListener(BASE_NS::shared_ptr<SCENE_NS::EcsListener> ecsListener) override
2318bf80f4bSopenharmony_ci    {
2328bf80f4bSopenharmony_ci        ecsListener_ = ecsListener;
2338bf80f4bSopenharmony_ci    }
2348bf80f4bSopenharmony_ci    void DoEntityEvent(CORE_NS::IEcs::EntityListener::EventType, const CORE_NS::Entity& entity) override {}
2358bf80f4bSopenharmony_ci    void DoComponentEvent(CORE_NS::IEcs::ComponentListener::EventType type,
2368bf80f4bSopenharmony_ci        const CORE_NS::IComponentManager& componentManager, const CORE_NS::Entity& entity) override;
2378bf80f4bSopenharmony_ci
2388bf80f4bSopenharmony_ci    // From Object
2398bf80f4bSopenharmony_ci    BASE_NS::string GetName() const override;
2408bf80f4bSopenharmony_ci
2418bf80f4bSopenharmony_ci    bool SetRootEntity(CORE_NS::Entity entity) override;
2428bf80f4bSopenharmony_ci    CORE_NS::Entity GetRootEntity() const override;
2438bf80f4bSopenharmony_ci
2448bf80f4bSopenharmony_ci    void SetEntity(CORE_NS::IEcs& ecs, CORE_NS::Entity entity) override;
2458bf80f4bSopenharmony_ci    CORE_NS::Entity GetEntity() const override;
2468bf80f4bSopenharmony_ci
2478bf80f4bSopenharmony_ci    void SetDuration(uint32_t ms) override;
2488bf80f4bSopenharmony_ci
2498bf80f4bSopenharmony_ci    bool Retarget(CORE_NS::Entity entity) override;
2508bf80f4bSopenharmony_ci
2518bf80f4bSopenharmony_ci    void Seek(float position) override;
2528bf80f4bSopenharmony_ci    void Step(const META_NS::IClock::ConstPtr& clock) override;
2538bf80f4bSopenharmony_ci    void Start() override;
2548bf80f4bSopenharmony_ci    void Stop() override;
2558bf80f4bSopenharmony_ci    void Pause() override;
2568bf80f4bSopenharmony_ci    void Restart() override;
2578bf80f4bSopenharmony_ci    void Finish() override;
2588bf80f4bSopenharmony_ci
2598bf80f4bSopenharmony_ci    META_IMPLEMENT_EVENT(META_NS::IOnChanged, OnFinished)
2608bf80f4bSopenharmony_ci    META_IMPLEMENT_EVENT(META_NS::IOnChanged, OnStarted)
2618bf80f4bSopenharmony_ci
2628bf80f4bSopenharmony_ci    void AddKey(IEcsTrackAnimation::Ptr track, float time) override;
2638bf80f4bSopenharmony_ci    void RemoveKey(IEcsTrackAnimation::Ptr track, uint32_t index) override;
2648bf80f4bSopenharmony_ci    void UpdateKey(IEcsTrackAnimation::Ptr track, uint32_t oldKeyIndex, uint32_t newKeyIndex, float time) override;
2658bf80f4bSopenharmony_ci
2668bf80f4bSopenharmony_ci    IEcsTrackAnimation::Ptr CreateAnimationTrack(
2678bf80f4bSopenharmony_ci        CORE_NS::Entity rootEntity, CORE_NS::Entity target, BASE_NS::string_view property) override;
2688bf80f4bSopenharmony_ci    IEcsTrackAnimation::Ptr GetAnimationTrack(CORE_NS::Entity target, BASE_NS::string_view property) override;
2698bf80f4bSopenharmony_ci    void DestroyAnimationTrack(IEcsTrackAnimation::Ptr track) override;
2708bf80f4bSopenharmony_ci    void DestroyAllAnimationTracks() override;
2718bf80f4bSopenharmony_ci    void Destroy() override;
2728bf80f4bSopenharmony_ci
2738bf80f4bSopenharmony_ci    BASE_NS::vector<CORE_NS::EntityReference> GetAllRelatedEntities() const override;
2748bf80f4bSopenharmony_ci
2758bf80f4bSopenharmony_cipublic: // ISerialization
2768bf80f4bSopenharmony_ci    //todo
2778bf80f4bSopenharmony_ci    //bool Export(
2788bf80f4bSopenharmony_ci    //    META_NS::Serialization::IExportContext& context, META_NS::Serialization::ClassPrimitive& value) const override;
2798bf80f4bSopenharmony_ci
2808bf80f4bSopenharmony_ci    //bool Import(
2818bf80f4bSopenharmony_ci    //    META_NS::Serialization::IImportContext& context, const META_NS::Serialization::ClassPrimitive& value) override;
2828bf80f4bSopenharmony_ci
2838bf80f4bSopenharmony_ci    /**
2848bf80f4bSopenharmony_ci     * @brief Called by the framework when an the attachment is being attached to an IObject. If this
2858bf80f4bSopenharmony_ci     *        function succeeds, the object is attached to the target.
2868bf80f4bSopenharmony_ci     * @param object The IObject instance the attachment is attached to.
2878bf80f4bSopenharmony_ci     * @param dataContext The data context for this attachment.
2888bf80f4bSopenharmony_ci     * @note The data context can be the same object as the object being attached to, or
2898bf80f4bSopenharmony_ci     *       something else. It is up to the attachment to decide how to handle them.
2908bf80f4bSopenharmony_ci     * @return The implementation should return true if the attachment can be attached to target object.
2918bf80f4bSopenharmony_ci     *         If the attachment cannot be added, the implementation should return false.
2928bf80f4bSopenharmony_ci     */
2938bf80f4bSopenharmony_ci    bool Attaching(const IAttach::Ptr& target, const IObject::Ptr& dataContext) override
2948bf80f4bSopenharmony_ci    {
2958bf80f4bSopenharmony_ci        META_ACCESS_PROPERTY(AttachedTo)->SetValue(target);
2968bf80f4bSopenharmony_ci        META_ACCESS_PROPERTY(DataContext)->SetValue(dataContext);
2978bf80f4bSopenharmony_ci        return true;
2988bf80f4bSopenharmony_ci    }
2998bf80f4bSopenharmony_ci    /**
3008bf80f4bSopenharmony_ci     * @brief Detach the attachment from an object.
3018bf80f4bSopenharmony_ci     * @param object The object to attach to.
3028bf80f4bSopenharmony_ci     * @return If the attachment can be detached from the target, the implementation should return true.
3038bf80f4bSopenharmony_ci     *         If detaching is not possible, the implementation should return false. In such a case the
3048bf80f4bSopenharmony_ci     *         target may choose to not remove the attachment. During for example object destruction,
3058bf80f4bSopenharmony_ci     *         the target will ignore the return value.
3068bf80f4bSopenharmony_ci     */
3078bf80f4bSopenharmony_ci    bool Detaching(const IAttach::Ptr& target) override
3088bf80f4bSopenharmony_ci    {
3098bf80f4bSopenharmony_ci        META_ACCESS_PROPERTY(AttachedTo)->SetValue({});
3108bf80f4bSopenharmony_ci        META_ACCESS_PROPERTY(DataContext)->SetValue({});
3118bf80f4bSopenharmony_ci        return true;
3128bf80f4bSopenharmony_ci    }
3138bf80f4bSopenharmony_ci
3148bf80f4bSopenharmony_ciprotected:
3158bf80f4bSopenharmony_ci    bool Build(const META_NS::IMetadata::Ptr& data) override;
3168bf80f4bSopenharmony_ci
3178bf80f4bSopenharmony_ciprivate:
3188bf80f4bSopenharmony_ci    struct Data {
3198bf80f4bSopenharmony_ci        inline explicit operator bool()
3208bf80f4bSopenharmony_ci        {
3218bf80f4bSopenharmony_ci            return (property != nullptr) && !data.empty();
3228bf80f4bSopenharmony_ci        };
3238bf80f4bSopenharmony_ci
3248bf80f4bSopenharmony_ci        const CORE_NS::PropertyTypeDecl* property { nullptr };
3258bf80f4bSopenharmony_ci        BASE_NS::vector<uint8_t> data;
3268bf80f4bSopenharmony_ci    };
3278bf80f4bSopenharmony_ci
3288bf80f4bSopenharmony_ci    CORE_NS::Entity TryResolveAnimationRoot();
3298bf80f4bSopenharmony_ci
3308bf80f4bSopenharmony_ci    Data GetProperty(BASE_NS::Uid componentUid, CORE_NS::Entity entity, BASE_NS::string property) const;
3318bf80f4bSopenharmony_ci    void SetKeyFrameData(CORE_NS::Entity animationTrack, float timeStamp, BASE_NS::vector<uint8_t> valueData);
3328bf80f4bSopenharmony_ci    void UpdateTimestamps(IEcsTrackAnimation& track, CORE_NS::Entity timestampEntity);
3338bf80f4bSopenharmony_ci
3348bf80f4bSopenharmony_ci    // Return the highest timestamp from the keyframes of the animation track.
3358bf80f4bSopenharmony_ci    float GetTrackDuration(CORE_NS::Entity animationTrack);
3368bf80f4bSopenharmony_ci    void UpdateAnimationTrackDuration(CORE_NS::Entity animationTrack);
3378bf80f4bSopenharmony_ci
3388bf80f4bSopenharmony_ci    void SetProgress(float progress);
3398bf80f4bSopenharmony_ci    void SetTime(uint32_t value);
3408bf80f4bSopenharmony_ci
3418bf80f4bSopenharmony_ci    void OnDestroyAnimationTrack(IEcsTrackAnimation::Ptr track);
3428bf80f4bSopenharmony_ci
3438bf80f4bSopenharmony_ci    void OnAnimationStateChanged(CORE_NS::IEcs::ComponentListener::EventType event);
3448bf80f4bSopenharmony_ci    void OnAnimationNameChanged(CORE_NS::IEcs::ComponentListener::EventType event);
3458bf80f4bSopenharmony_ci    void OnAnimationChanged(CORE_NS::IEcs::ComponentListener::EventType event);
3468bf80f4bSopenharmony_ci    void OnAnimationTracksChanged(CORE_NS::IEcs::ComponentListener::EventType event, CORE_NS::Entity entity);
3478bf80f4bSopenharmony_ci    void OnAnimationInputsChanged(CORE_NS::IEcs::ComponentListener::EventType event, CORE_NS::Entity entity);
3488bf80f4bSopenharmony_ci
3498bf80f4bSopenharmony_ci    void OnNamePropertyChanged();
3508bf80f4bSopenharmony_ci    void OnDurationPropertyChanged();
3518bf80f4bSopenharmony_ci    void OnProgressPropertyChanged();
3528bf80f4bSopenharmony_ci
3538bf80f4bSopenharmony_ci    void OnAnimationTrackChanged(IEcsTrackAnimation& track, CORE_NS::Entity trackEntity);
3548bf80f4bSopenharmony_ci    void OnAnimationTimestampsChanged(IEcsTrackAnimation& track, CORE_NS::Entity timestampEntity);
3558bf80f4bSopenharmony_ci
3568bf80f4bSopenharmony_ci    bool IsAnimationTrackArrayModified();
3578bf80f4bSopenharmony_ci    void GatherAnimationTracks();
3588bf80f4bSopenharmony_ci
3598bf80f4bSopenharmony_ci    CORE_NS::IEcs* ecs_ { nullptr };
3608bf80f4bSopenharmony_ci    CORE_NS::EntityReference entity_ {};
3618bf80f4bSopenharmony_ci    CORE_NS::Entity root_ {};
3628bf80f4bSopenharmony_ci
3638bf80f4bSopenharmony_ci    CORE3D_NS::IAnimationComponentManager* animationManager_ { nullptr };
3648bf80f4bSopenharmony_ci    CORE3D_NS::IAnimationTrackComponentManager* animationTrackManager_ { nullptr };
3658bf80f4bSopenharmony_ci    CORE3D_NS::IAnimationInputComponentManager* animationInputManager_ { nullptr };
3668bf80f4bSopenharmony_ci    CORE3D_NS::IAnimationOutputComponentManager* animationOutputManager_ { nullptr };
3678bf80f4bSopenharmony_ci    CORE_NS::IComponentManager* animationStateManager_ { nullptr };
3688bf80f4bSopenharmony_ci    CORE3D_NS::INameComponentManager* nameManager_ { nullptr };
3698bf80f4bSopenharmony_ci
3708bf80f4bSopenharmony_ci    bool updateGuard_ { false };
3718bf80f4bSopenharmony_ci
3728bf80f4bSopenharmony_ci    int32_t repeatCount_ { 1 };
3738bf80f4bSopenharmony_ci    std::optional<META_NS::TimeSpan> lastFrameTime_ {};
3748bf80f4bSopenharmony_ci
3758bf80f4bSopenharmony_ci    mutable META_NS::EventImpl<META_NS::IOnChanged> onFinished_;
3768bf80f4bSopenharmony_ci    mutable META_NS::EventImpl<META_NS::IOnChanged> onStarted_;
3778bf80f4bSopenharmony_ci
3788bf80f4bSopenharmony_ci    SceneHolder::WeakPtr sceneHolder_;
3798bf80f4bSopenharmony_ci    BASE_NS::weak_ptr<SCENE_NS::EcsListener> ecsListener_;
3808bf80f4bSopenharmony_ci};
3818bf80f4bSopenharmony_ci
3828bf80f4bSopenharmony_civoid RegisterEcsAnimationObjectType();
3838bf80f4bSopenharmony_civoid UnregisterEcsAnimationObjectType();
3848bf80f4bSopenharmony_ci
3858bf80f4bSopenharmony_ciSCENE_END_NAMESPACE()
3868bf80f4bSopenharmony_ci
3878bf80f4bSopenharmony_ci#endif // SCENE_PLUGIN_ECS_ANIMATION_H
388