1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16// clang-format off
17#include <meta/interface/object_macros.h>
18#include <meta/interface/intf_object_registry.h>
19// clang-format on
20
21#include <scene_plugin/api/material.h>
22#include <scene_plugin/interface/intf_ecs_scene.h>
23#include <scene_plugin/interface/intf_environment.h>
24#include <scene_plugin/interface/intf_nodes.h>
25#include <scene_plugin/interface/intf_scene.h>
26#include <scene_plugin/interface/intf_scene_presenter.h>
27
28#include <3d/implementation_uids.h>
29#include <core/intf_engine.h>
30#include <core/plugin/intf_plugin.h>
31#include <core/plugin/intf_plugin_register.h>
32#include <render/implementation_uids.h>
33
34#include <meta/base/plugin.h>
35
36#include "ecs_animation.h"
37#include "intf_node_private.h"
38
39namespace {
40static CORE_NS::IPluginRegister* gPluginRegistry { nullptr };
41} // namespace
42
43CORE_BEGIN_NAMESPACE()
44IPluginRegister& GetPluginRegister()
45{
46    return *gPluginRegistry;
47}
48CORE_END_NAMESPACE()
49
50using namespace CORE_NS;
51
52SCENE_BEGIN_NAMESPACE()
53template<typename T, const META_NS::ClassInfo& Info>
54class PendingRequestImpl : public META_NS::ObjectFwd<PendingRequestImpl<T, Info>, Info, META_NS::ClassId::Object,
55                               SCENE_NS::IPendingRequest<T>, SCENE_NS::IPendingRequestData<T>> {
56    META_IMPLEMENT_EVENT(META_NS::IOnChanged, OnReady)
57
58    void Add(const T& data) override
59    {
60        data_.push_back(data);
61    }
62
63    void MarkReady() override
64    {
65        applicationData_.clear();
66        META_NS::Invoke<META_NS::IOnChanged>(OnReady());
67    }
68
69    const BASE_NS::vector<T>& GetResults() const override
70    {
71        return data_;
72    }
73
74    BASE_NS::vector<T>& MutableData() override
75    {
76        return data_;
77    }
78
79    BASE_NS::vector<BASE_NS::string>& MetaData() override
80    {
81        return applicationData_;
82    }
83
84    BASE_NS::vector<T> data_;
85    BASE_NS::vector<BASE_NS::string> applicationData_;
86};
87
88void RegisterNodes();
89void UnregisterNodes();
90
91void RegisterSceneImpl();
92void UnregisterSceneImpl();
93
94void RegisterEcsObject();
95void UnregisterEcsObject();
96
97void RegisterNodeHierarchyController();
98void UnregisterNodeHierarchyController();
99
100void RegisterEngineAccess();
101void UnregisterEngineAccess();
102
103SCENE_END_NAMESPACE()
104
105class SceneBitmap : public META_NS::ObjectFwd<SceneBitmap, SCENE_NS::ClassId::Bitmap, META_NS::ClassId::Object,
106                        SCENE_NS::IBitmap, META_NS::INamed> {
107protected:
108    META_IMPLEMENT_INTERFACE_PROPERTY(META_NS::INamed, BASE_NS::string, Name)
109
110    META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::IBitmap, BASE_NS::string, Uri, {})
111
112    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(SCENE_NS::IBitmap, BASE_NS::Math::UVec2, Size,
113        BASE_NS::Math::UVec2(0, 0), META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
114    META_IMPLEMENT_INTERFACE_EVENT(SCENE_NS::IBitmap, META_NS::IOnChanged, ResourceChanged)
115    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(SCENE_NS::IBitmap, SCENE_NS::IBitmap::BitmapStatus, Status,
116        SCENE_NS::IBitmap::BitmapStatus::NOT_INITIALIZED, META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
117
118    bool Build(const IMetadata::Ptr& data) override
119    {
120        return true;
121    }
122    void SetRenderHandle(RENDER_NS::RenderHandleReference handle, const BASE_NS::Math::UVec2 size) override
123    {
124        auto cs = META_ACCESS_PROPERTY_VALUE(Size);
125        if (size != cs) {
126            META_ACCESS_PROPERTY(Size)->SetValue(size);
127        }
128        handle_ = handle;
129        if (RENDER_NS::RenderHandleUtil::IsValid(handle.GetHandle())) {
130            META_ACCESS_PROPERTY(Status)->SetValue(SCENE_NS::IBitmap::BitmapStatus::COMPLETED);
131        } else {
132            META_ACCESS_PROPERTY(Status)->SetValue(SCENE_NS::IBitmap::BitmapStatus::NOT_INITIALIZED);
133        }
134        META_ACCESS_EVENT(ResourceChanged)->Invoke();
135    }
136    RENDER_NS::RenderHandleReference GetRenderHandle() const override
137    {
138        return handle_;
139    }
140
141    RENDER_NS::RenderHandleReference handle_;
142};
143
144PluginToken RegisterInterfaces(IPluginRegister& pluginRegistry)
145{
146    // Initializing dynamic plugin.
147    // Pluginregistry access via the provided registry instance which is saved here.
148    gPluginRegistry = &pluginRegistry;
149    auto& objreg = META_NS::GetObjectRegistry();
150    objreg.RegisterObjectType<SceneBitmap>();
151
152    SCENE_NS::RegisterEcsObject();
153    SCENE_NS::RegisterNodes();
154    SCENE_NS::RegisterSceneImpl();
155    SCENE_NS::RegisterNodeHierarchyController();
156    SCENE_NS::RegisterEngineAccess();
157
158    SCENE_NS::RegisterEcsAnimationObjectType();
159    META_NS::GetObjectRegistry()
160        .RegisterObjectType<
161            SCENE_NS::PendingRequestImpl<SCENE_NS::NodeDistance, SCENE_NS::ClassId::PendingDistanceRequest>>();
162    META_NS::GetObjectRegistry()
163        .RegisterObjectType<
164            SCENE_NS::PendingRequestImpl<RENDER_NS::GraphicsState, SCENE_NS::ClassId::PendingGraphicsStateRequest>>();
165    META_NS::GetObjectRegistry()
166        .RegisterObjectType<SCENE_NS::PendingRequestImpl<BASE_NS::Math::Vec3, SCENE_NS::ClassId::PendingVec3Request>>();
167    return {};
168}
169void UnregisterInterfaces(PluginToken)
170{
171    /* META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IBloom>();
172     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IBlur>();
173     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::ICamera>();
174     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IColorConversion>();
175     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IColorFringe>();
176     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IDepthOfField>();
177     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IDither>();
178     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IEcsAnimation>();
179     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IEcsObject>();
180     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IEcsScene>();
181     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IEcsTrackAnimation>();
182     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IEnvironment>();
183     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IFxaa>();
184     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IGraphicsState>();
185     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::ILight>();
186     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IMaterial>();
187     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IMesh>();
188     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IMultiMeshProxy>();
189     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IModel>();
190     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IMotionBlur>();
191     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::INode>();
192     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IPostProcess>();
193     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IPrefab>();
194     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IPrefabInstance>();
195     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IScene>();
196     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IScenePresenter>();
197     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IShader>();
198     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::ISubMesh>();
199     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::ITaa>();
200     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::ITextureInfo>();
201     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::ITonemap>();
202     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IViewNode>();
203     META_NS::UnRegisterInterfacePropertyType<SCENE_NS::IVignette>();
204 */
205    SCENE_NS::UnregisterEcsObject();
206    SCENE_NS::UnregisterNodes();
207    SCENE_NS::UnregisterSceneImpl();
208    SCENE_NS::UnregisterNodeHierarchyController();
209    SCENE_NS::UnregisterEngineAccess();
210
211    SCENE_NS::UnregisterEcsAnimationObjectType();
212
213    META_NS::GetObjectRegistry()
214        .UnregisterObjectType<
215            SCENE_NS::PendingRequestImpl<SCENE_NS::NodeDistance, SCENE_NS::ClassId::PendingDistanceRequest>>();
216    META_NS::GetObjectRegistry()
217        .UnregisterObjectType<
218            SCENE_NS::PendingRequestImpl<RENDER_NS::GraphicsState, SCENE_NS::ClassId::PendingGraphicsStateRequest>>();
219    META_NS::GetObjectRegistry()
220        .UnregisterObjectType<
221            SCENE_NS::PendingRequestImpl<BASE_NS::Math::Vec3, SCENE_NS::ClassId::PendingVec3Request>>();
222}
223const char* VersionString()
224{
225    return "1.0";
226}
227
228const BASE_NS::Uid plugin_deps[] { RENDER_NS::UID_RENDER_PLUGIN, CORE3D_NS::UID_3D_PLUGIN,
229    META_NS::META_OBJECT_PLUGIN_UID };
230
231extern "C" {
232#if _MSC_VER
233_declspec(dllexport)
234#else
235__attribute__((visibility("default")))
236#endif
237    CORE_NS::IPlugin gPluginData { IPlugin::UID, "Scene",
238        /** Version information of the plugin. */
239        Version { SCENE_NS::UID_SCENE_PLUGIN, VersionString }, RegisterInterfaces, UnregisterInterfaces, plugin_deps };
240}
241