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#ifndef META_SRC_PROPERTY_H 16#define META_SRC_PROPERTY_H 17 18#include <atomic> 19#include <memory> 20#include <mutex> 21 22#include <meta/base/namespace.h> 23#include <meta/base/types.h> 24#include <meta/ext/event_impl.h> 25#include <meta/ext/minimal_object.h> 26#include <meta/interface/intf_any.h> 27#include <meta/interface/intf_lockable.h> 28#include <meta/interface/property/intf_modifier.h> 29#include <meta/interface/property/intf_property_internal.h> 30#include <meta/interface/property/property_events.h> 31 32META_BEGIN_NAMESPACE() 33namespace Internal { 34 35META_REGISTER_CLASS(Property, "1801d9a9-3557-4e0d-b90e-54791acd6768", ObjectCategoryBits::NO_CATEGORY) 36 37class PropertyBase : public MinimalObject<ClassId::Property, IProperty, IPropertyInternal, ILockable, IValue> { 38public: 39 using OnChangedEvent = EventImpl<IOnChanged>; 40 41 PropertyBase(BASE_NS::string name) : name_(BASE_NS::move(name)) {} 42 43 BASE_NS::string GetName() const override; 44 45 IObject::WeakPtr GetOwner() const override; 46 void SetOwner(IObject::Ptr owner) override; 47 void SetSelf(IProperty::Ptr self) override; 48 49 AnyReturnValue SetValue(const IAny& value) override; 50 const IAny& GetValue() const override; 51 bool IsCompatible(const TypeId& id) const override; 52 53 TypeId GetTypeId() const override; 54 void NotifyChange() const override; 55 56 IEvent::Ptr EventOnChanged() const override; 57 58 void Lock() const override; 59 void Unlock() const override; 60 void LockShared() const override; 61 void UnlockShared() const override; 62 63protected: 64 virtual IAny::Ptr& GetData() const = 0; 65 AnyReturnValue SetInternalValue(const IAny& value); 66 void CallOnChanged() const; 67 68protected: 69 // this has to be recursive because of the usage pattern 70 mutable std::recursive_mutex mutex_; 71 mutable size_t locked_ {}; 72 mutable bool pendingInvoke_ {}; 73 const BASE_NS::string name_; 74 IObject::WeakPtr owner_; 75 IProperty::WeakPtr self_; 76 // lazy event, constructed when needed 77 mutable BASE_NS::shared_ptr<OnChangedEvent> onChanged_; 78 mutable std::atomic<OnChangedEvent*> onChangedAtomic_ {}; 79}; 80 81class GenericProperty : public IntroduceInterfaces<PropertyBase, IPropertyInternalAny> { 82 using Super = IntroduceInterfaces<PropertyBase, IPropertyInternalAny>; 83 84public: 85 using Super::Super; 86 87 AnyReturnValue SetInternalAny(IAny::Ptr any) override; 88 IAny::Ptr GetInternalAny() const override; 89 90protected: 91 IAny::Ptr& GetData() const override 92 { 93 return data_; 94 } 95 96private: 97 mutable IAny::Ptr data_; 98}; 99 100} // namespace Internal 101META_END_NAMESPACE() 102 103#endif