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 #ifndef META_ENGINE_INTERFACE_ENGINE_VALUE_H 17 #define META_ENGINE_INTERFACE_ENGINE_VALUE_H 18 19 #include <core/ecs/entity.h> 20 #include <core/ecs/intf_component_manager.h> 21 #include <core/property/intf_property_handle.h> 22 23 #include <meta/interface/intf_value.h> 24 25 META_BEGIN_NAMESPACE() 26 27 /** 28 * @brief Direction to which synchronise engine values 29 */ 30 enum class EngineSyncDirection { 31 AUTO, /// Synchronise cached value to engine if changed, otherwise sync engine to cached value 32 TO_ENGINE, /// Synchronise cached value to engine 33 FROM_ENGINE /// Synchronise from engine to cached value 34 }; 35 36 META_REGISTER_INTERFACE(IEngineValue, "2edaea8a-936d-4bc5-a5eb-ecfdbb50574d") 37 38 /** 39 * @brief Value which can be synchronise with core engine property 40 */ 41 class IEngineValue : public IValue { 42 META_INTERFACE(IValue, IEngineValue) 43 public: 44 /// Name of this value 45 virtual BASE_NS::string GetName() const = 0; 46 /** 47 * @brief Synchronise value with engine core property 48 * @note Careful where this is called (usually same thread as other core engine calls) 49 * @return Result of the synchronisation 50 */ 51 virtual AnyReturnValue Sync(EngineSyncDirection) = 0; 52 }; 53 54 /** 55 * @brief Internal handle for core engine property 56 */ 57 struct EnginePropertyHandle { 58 CORE_NS::IComponentManager* manager {}; 59 CORE_NS::Entity entity; 60 // in case the property path contains IPropertyHandle*, we need to keep pointer to the most 61 // recent value having such handle, so that we are able to update the handle properly 62 IValue::Ptr parentValue; 63 HandleEnginePropertyHandle64 CORE_NS::IPropertyHandle* Handle() const 65 { 66 if (parentValue) { 67 return GetValue<CORE_NS::IPropertyHandle*>(parentValue->GetValue()); 68 } 69 return manager ? manager->GetData(entity) : nullptr; 70 } 71 72 explicit operator bool() const 73 { 74 return (manager && CORE_NS::EntityUtil::IsValid(entity)) || parentValue; 75 } 76 }; 77 78 /** 79 * @brief Internal property parameters 80 */ 81 struct EnginePropertyParams { 82 EnginePropertyHandle handle; 83 CORE_NS::Property property {}; 84 // offset to the parent property data, this is needed for member properties 85 // calculate baseOffset + property.offset to access the data, 86 // baseOffset is zero if not a member property 87 uintptr_t baseOffset {}; 88 OffsetEnginePropertyParams89 uintptr_t Offset() const 90 { 91 return baseOffset + property.offset; 92 } 93 94 uint32_t index {}; 95 const CORE_NS::ContainerApi* containerMethods {}; 96 uintptr_t arraySubsOffset {}; 97 98 // to support some old code, we allow to push the value directly to the engine property 99 // if this is set, the values can only be set in the engine task queue thread 100 bool pushValueToEngineDirectly {}; 101 102 EnginePropertyParams() = default; 103 EnginePropertyParamsEnginePropertyParams104 EnginePropertyParams(const EnginePropertyHandle& h, const CORE_NS::Property& p, uintptr_t bOffset) 105 : handle(h), property(p), baseOffset(bOffset) 106 {} 107 EnginePropertyParamsEnginePropertyParams108 EnginePropertyParams(const EnginePropertyParams& base, const CORE_NS::Property& p) : EnginePropertyParams(base) 109 { 110 property = p; 111 baseOffset = base.Offset(); 112 } 113 EnginePropertyParamsEnginePropertyParams114 EnginePropertyParams(const EnginePropertyParams& base, const CORE_NS::ContainerApi* capi, uint32_t i) 115 : EnginePropertyParams(base) 116 { 117 arraySubsOffset = base.Offset(); 118 property = capi->property; 119 index = i; 120 containerMethods = capi; 121 baseOffset = 0; 122 } 123 }; 124 125 META_REGISTER_INTERFACE(IEngineInternalValueAccess, "f11f1272-e936-4804-9202-3b93606c25ea") 126 127 /** 128 * @brief Internal access implementation for specific core engine type 129 */ 130 class IEngineInternalValueAccess : public CORE_NS::IInterface { 131 META_INTERFACE(CORE_NS::IInterface, IEngineInternalValueAccess) 132 public: 133 /// Create any of mapped property type for the core engine type 134 virtual IAny::Ptr CreateAny(const CORE_NS::Property&) const = 0; 135 /// Create any of compatible type which can be serialised 136 virtual IAny::Ptr CreateSerializableAny() const = 0; 137 /// Check if given core type is compatible with the type this access implements 138 virtual bool IsCompatible(const CORE_NS::PropertyTypeDecl& type) const = 0; 139 /// Synchronise value to given engine property 140 virtual AnyReturnValue SyncToEngine(const IAny& value, const EnginePropertyParams& params) const = 0; 141 /// Synchronise value from given engine property 142 virtual AnyReturnValue SyncFromEngine(const EnginePropertyParams& params, IAny& out) const = 0; 143 }; 144 145 /** 146 * @brief Internal engine value functions to get parameters et al 147 */ 148 class IEngineValueInternal : public CORE_NS::IInterface { 149 META_INTERFACE(CORE_NS::IInterface, IEngineValueInternal, "86afd68c-7924-46b8-8bb8-aeace0029945") 150 public: 151 /// Create any of the property type 152 virtual IAny::Ptr CreateAny() const = 0; 153 /// Get synchronisation access type for this engine value 154 virtual IEngineInternalValueAccess::ConstPtr GetInternalAccess() const = 0; 155 /// Get property parameters for this engine value 156 virtual EnginePropertyParams GetPropertyParams() const = 0; 157 /// Set property parameters for this engine value 158 virtual bool SetPropertyParams(const EnginePropertyParams& p) = 0; 159 /// Reset pending notifications, returns true if there were any. 160 virtual bool ResetPendingNotify() = 0; 161 }; 162 163 META_INTERFACE_TYPE(META_NS::IEngineValue) 164 META_END_NAMESPACE() 165 166 #endif 167