* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SceneComponentETS.h"
#include <meta/api/make_callback.h>
#include <meta/interface/intf_metadata.h>
#include <meta/interface/intf_task_queue.h>
#include <meta/interface/intf_task_queue_registry.h>
#include <meta/interface/property/property_events.h>
#include <render/intf_render_context.h>
#include <scene/ext/intf_component.h>
#include <scene/ext/intf_ecs_object_access.h>
#include <scene/ext/util.h>
#include <scene/interface/intf_node.h>
#include <scene/interface/intf_scene.h>
#ifdef __SCENE_ADAPTER__
#include "3d_widget_adapter_log.h"
#endif
#include "ImageETS.h"
#include "SceneResourceETS.h"
#include "Vec2Proxy.h"
#include "Vec3Proxy.h"
#include "Vec4Proxy.h"
namespace OHOS::Render3D {
SceneComponentETS::SceneComponentETS(SCENE_NS::IComponent::Ptr comp, const std::string& name) : comp_(comp), name_(name)
{
AddProperties();
}
SceneComponentETS::~SceneComponentETS()
{
keys_.clear();
proxies_.clear();
propertyPaths_.clear();
comp_.reset();
}
std::string SceneComponentETS::GetName()
{
return name_;
}
void SceneComponentETS::SetName(const std::string& name)
{
name_ = name;
}
void SceneComponentETS::AddProperties()
{
auto component = comp_.lock();
if (!component) {
return;
}
keys_.clear();
proxies_.clear();
propertyPaths_.clear();
auto props = component->EnumerateProperties();
for (auto&& prop : props) {
auto sv = SCENE_NS::PropertyName(prop.name);
std::string name(sv.data(), sv.size());
propertyPaths_[name] = BASE_NS::move(prop.name);
keys_.push_back(std::move(name));
}
}
std::shared_ptr<IPropertyProxy> SceneComponentETS::GetOrCreateProxy(const std::string& key)
{
auto proxyIt = proxies_.find(key);
if (proxyIt != proxies_.end()) {
return proxyIt->second;
}
auto pathIt = propertyPaths_.find(key);
if (pathIt == propertyPaths_.end()) {
return {};
}
auto component = comp_.lock();
if (!component) {
return {};
}
auto native = interface_cast<SCENE_NS::IEcsObjectAccess>(component);
if (!native) {
return {};
}
auto ecsObj = native->GetEcsObject();
if (!ecsObj) {
return {};
}
auto prop = ecsObj->CreateProperty(pathIt->second).GetResult();
if (!prop) {
return {};
}
if (auto meta = interface_cast<META_NS::IMetadata>(component)) {
meta->AddProperty(prop);
}
auto proxy = PropertyToProxy(prop);
proxies_[key] = proxy;
return proxy;
}
std::shared_ptr<IPropertyProxy> SceneComponentETS::GetProperty(const std::string& key)
{
return GetOrCreateProxy(key);
}
void SceneComponentETS::ClearArrayProperty(const std::string& key)
{
std::shared_ptr<IPropertyProxy> proxy = GetProperty(key);
if (!proxy) {
CORE_LOG_E("property [%s] proxy not found", key.c_str());
return;
}
META_NS::IProperty::Ptr prop = proxy->GetPropertyPtr();
if (!prop) {
CORE_LOG_E("property [%s] prop is invalid", key.c_str());
return;
}
if (META_NS::IsCompatibleWith<BASE_NS::vector<SCENE_NS::IImage::Ptr>>(prop)) {
SetArrayProperty(key, BASE_NS::vector<SCENE_NS::IImage::Ptr>());
return;
}
auto any = META_NS::GetInternalAny(prop);
CORE_LOG_E("property [%s] type [%s] is not supported yet",
key.c_str(),
any ? any->GetTypeIdString().c_str() : "<Unknown>");
}
}