18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci#ifndef META_SRC_PROPERTY_H
168bf80f4bSopenharmony_ci#define META_SRC_PROPERTY_H
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <atomic>
198bf80f4bSopenharmony_ci#include <memory>
208bf80f4bSopenharmony_ci#include <mutex>
218bf80f4bSopenharmony_ci
228bf80f4bSopenharmony_ci#include <meta/base/namespace.h>
238bf80f4bSopenharmony_ci#include <meta/base/types.h>
248bf80f4bSopenharmony_ci#include <meta/ext/event_impl.h>
258bf80f4bSopenharmony_ci#include <meta/ext/minimal_object.h>
268bf80f4bSopenharmony_ci#include <meta/interface/intf_any.h>
278bf80f4bSopenharmony_ci#include <meta/interface/intf_lockable.h>
288bf80f4bSopenharmony_ci#include <meta/interface/property/intf_modifier.h>
298bf80f4bSopenharmony_ci#include <meta/interface/property/intf_property_internal.h>
308bf80f4bSopenharmony_ci#include <meta/interface/property/property_events.h>
318bf80f4bSopenharmony_ci
328bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
338bf80f4bSopenharmony_cinamespace Internal {
348bf80f4bSopenharmony_ci
358bf80f4bSopenharmony_ciMETA_REGISTER_CLASS(Property, "1801d9a9-3557-4e0d-b90e-54791acd6768", ObjectCategoryBits::NO_CATEGORY)
368bf80f4bSopenharmony_ci
378bf80f4bSopenharmony_ciclass PropertyBase : public MinimalObject<ClassId::Property, IProperty, IPropertyInternal, ILockable, IValue> {
388bf80f4bSopenharmony_cipublic:
398bf80f4bSopenharmony_ci    using OnChangedEvent = EventImpl<IOnChanged>;
408bf80f4bSopenharmony_ci
418bf80f4bSopenharmony_ci    PropertyBase(BASE_NS::string name) : name_(BASE_NS::move(name)) {}
428bf80f4bSopenharmony_ci
438bf80f4bSopenharmony_ci    BASE_NS::string GetName() const override;
448bf80f4bSopenharmony_ci
458bf80f4bSopenharmony_ci    IObject::WeakPtr GetOwner() const override;
468bf80f4bSopenharmony_ci    void SetOwner(IObject::Ptr owner) override;
478bf80f4bSopenharmony_ci    void SetSelf(IProperty::Ptr self) override;
488bf80f4bSopenharmony_ci
498bf80f4bSopenharmony_ci    AnyReturnValue SetValue(const IAny& value) override;
508bf80f4bSopenharmony_ci    const IAny& GetValue() const override;
518bf80f4bSopenharmony_ci    bool IsCompatible(const TypeId& id) const override;
528bf80f4bSopenharmony_ci
538bf80f4bSopenharmony_ci    TypeId GetTypeId() const override;
548bf80f4bSopenharmony_ci    void NotifyChange() const override;
558bf80f4bSopenharmony_ci
568bf80f4bSopenharmony_ci    IEvent::Ptr EventOnChanged() const override;
578bf80f4bSopenharmony_ci
588bf80f4bSopenharmony_ci    void Lock() const override;
598bf80f4bSopenharmony_ci    void Unlock() const override;
608bf80f4bSopenharmony_ci    void LockShared() const override;
618bf80f4bSopenharmony_ci    void UnlockShared() const override;
628bf80f4bSopenharmony_ci
638bf80f4bSopenharmony_ciprotected:
648bf80f4bSopenharmony_ci    virtual IAny::Ptr& GetData() const = 0;
658bf80f4bSopenharmony_ci    AnyReturnValue SetInternalValue(const IAny& value);
668bf80f4bSopenharmony_ci    void CallOnChanged() const;
678bf80f4bSopenharmony_ci
688bf80f4bSopenharmony_ciprotected:
698bf80f4bSopenharmony_ci    // this has to be recursive because of the usage pattern
708bf80f4bSopenharmony_ci    mutable std::recursive_mutex mutex_;
718bf80f4bSopenharmony_ci    mutable size_t locked_ {};
728bf80f4bSopenharmony_ci    mutable bool pendingInvoke_ {};
738bf80f4bSopenharmony_ci    const BASE_NS::string name_;
748bf80f4bSopenharmony_ci    IObject::WeakPtr owner_;
758bf80f4bSopenharmony_ci    IProperty::WeakPtr self_;
768bf80f4bSopenharmony_ci    // lazy event, constructed when needed
778bf80f4bSopenharmony_ci    mutable BASE_NS::shared_ptr<OnChangedEvent> onChanged_;
788bf80f4bSopenharmony_ci    mutable std::atomic<OnChangedEvent*> onChangedAtomic_ {};
798bf80f4bSopenharmony_ci};
808bf80f4bSopenharmony_ci
818bf80f4bSopenharmony_ciclass GenericProperty : public IntroduceInterfaces<PropertyBase, IPropertyInternalAny> {
828bf80f4bSopenharmony_ci    using Super = IntroduceInterfaces<PropertyBase, IPropertyInternalAny>;
838bf80f4bSopenharmony_ci
848bf80f4bSopenharmony_cipublic:
858bf80f4bSopenharmony_ci    using Super::Super;
868bf80f4bSopenharmony_ci
878bf80f4bSopenharmony_ci    AnyReturnValue SetInternalAny(IAny::Ptr any) override;
888bf80f4bSopenharmony_ci    IAny::Ptr GetInternalAny() const override;
898bf80f4bSopenharmony_ci
908bf80f4bSopenharmony_ciprotected:
918bf80f4bSopenharmony_ci    IAny::Ptr& GetData() const override
928bf80f4bSopenharmony_ci    {
938bf80f4bSopenharmony_ci        return data_;
948bf80f4bSopenharmony_ci    }
958bf80f4bSopenharmony_ci
968bf80f4bSopenharmony_ciprivate:
978bf80f4bSopenharmony_ci    mutable IAny::Ptr data_;
988bf80f4bSopenharmony_ci};
998bf80f4bSopenharmony_ci
1008bf80f4bSopenharmony_ci} // namespace Internal
1018bf80f4bSopenharmony_ciMETA_END_NAMESPACE()
1028bf80f4bSopenharmony_ci
1038bf80f4bSopenharmony_ci#endif