* Copyright (c) 2024 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.
*/
#ifndef SCENE_SRC_ENTITY_CONVERTING_VALUE_H
#define SCENE_SRC_ENTITY_CONVERTING_VALUE_H
#include <scene/ext/intf_ecs_context.h>
#include <scene/ext/intf_ecs_object_access.h>
#include <scene/ext/intf_render_resource.h>
#include <3d/ecs/components/render_handle_component.h>
#include "converting_value.h"
#include "util.h"
SCENE_BEGIN_NAMESPACE()
template <typename Interface>
CORE_NS::Entity ConvertPtrToTarget(const typename Interface::Ptr& v)
{
return GetEcsObjectEntity(interface_cast<IEcsObjectAccess>(v));
}
template <typename Interface>
typename Interface::Ptr ConvertPtrToSource(
META_NS::IAny& any, const CORE_NS::Entity& v, const IInternalScene::Ptr& scene, META_NS::ObjectId id)
{
auto p = META_NS::GetPointer<Interface>(any);
if (scene) {
if (CORE_NS::EntityUtil::IsValid(v)) {
if (p && (GetEcsObjectEntity(interface_cast<IEcsObjectAccess>(p)) != v)) {
p = nullptr;
}
if (!p) {
scene->RunDirectlyOrInTask([&] { p = interface_pointer_cast<Interface>(scene->CreateObject(id, v)); });
}
} else {
p = nullptr;
}
}
return p;
}
template <typename Interface>
struct InterfacePtrEntityConverter {
using SourceType = typename Interface::Ptr;
using TargetType = CORE_NS::Entity;
InterfacePtrEntityConverter(IInternalScene::Ptr scene, META_NS::ObjectId id) : scene_(scene), id_(id)
{}
SourceType ConvertToSource(META_NS::IAny& any, const TargetType& v) const
{
return ConvertPtrToSource<Interface>(any, v, scene_.lock(), id_);
}
TargetType ConvertToTarget(const SourceType& v) const
{
return ConvertPtrToTarget<Interface>(v);
}
protected:
IInternalScene::WeakPtr scene_;
META_NS::ObjectId id_;
};
template <typename Interface>
struct DynamicInterfacePtrEntityConverter {
using SourceType = typename Interface::Ptr;
using TargetType = CORE_NS::Entity;
explicit DynamicInterfacePtrEntityConverter(IInternalScene::Ptr scene) : scene_(scene)
{}
SourceType ConvertToSource(META_NS::IAny& any, const TargetType& v) const
{
const auto scene = scene_.lock();
META_NS::ObjectId id{};
if (scene) {
id = GetObjectId(*(scene->GetEcsContext().GetNativeEcs()), v);
}
return ConvertPtrToSource<Interface>(any, v, scene, id);
}
TargetType ConvertToTarget(const SourceType& v) const
{
return ConvertPtrToTarget<Interface>(v);
}
protected:
* @brief To be overridden by implementations to provide dynamic entity<->ObjectId mapping.
*/
virtual META_NS::ObjectId GetObjectId(const CORE_NS::IEcs& ecs, const CORE_NS::Entity& e) const = 0;
IInternalScene::WeakPtr scene_;
};
template <typename Interface>
using InterfacePtrEntityValue = ConvertingValue<InterfacePtrEntityConverter<Interface>>;
template <typename Interface>
struct RenderResourceConverter {
using SourceType = typename Interface::Ptr;
using TargetType = CORE_NS::EntityReference;
RenderResourceConverter(IInternalScene::Ptr scene, META_NS::ObjectId id) : scene_(scene), id_(id)
{}
SourceType ConvertToSource(META_NS::IAny& any, const TargetType& v) const
{
auto p = META_NS::GetPointer<Interface>(any);
if (auto scene = scene_.lock()) {
if (v) {
p = scene->RunDirectlyOrInTask([&] { return ObjectWithRenderHandle<Interface>(scene, v, p, id_); });
} else {
p = nullptr;
}
}
return p;
}
TargetType ConvertToTarget(const SourceType& v) const
{
CORE_NS::EntityReference ent;
if (auto scene = scene_.lock()) {
ent = scene->RunDirectlyOrInTask([&] { return HandleFromRenderResource<Interface>(scene, v); });
}
return ent;
}
protected:
IInternalScene::WeakPtr scene_;
META_NS::ObjectId id_;
};
template <typename Interface>
using RenderResourceValue = ConvertingValue<RenderResourceConverter<Interface>>;
SCENE_END_NAMESPACE()
#endif