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 #include <cstddef>
16 
17 #include <base/containers/string_view.h>
18 #include <base/util/uid.h>
19 #include <core/ecs/entity.h>
20 #include <core/ecs/intf_component_manager.h>
21 #include <core/property/scoped_handle.h>
22 
23 // clang-format off
24 // Component struct defines
25 #define DECLARE_GENERIC_INTERFACE1(NAME, TYPE, TYPE_UID)                                      \
26     /** @ingroup group_ecs_componentmanagers_##NAME */                                        \
27     class NAME : public CORE_NS::IComponentManager {                                          \
28     public:                                                                                   \
29         using ComponentId = CORE_NS::IComponentManager::ComponentId;                          \
30         /** UID of TYPE */                                                                    \
31         static constexpr BASE_NS::Uid UID{ TYPE_UID };                                        \
32         /** Sets TYPE */                                                                      \
33         virtual void Set(ComponentId index, const TYPE& data) = 0;                            \
34         /** Sets TYPE */                                                                      \
35         virtual void Set(CORE_NS::Entity entity, const TYPE& data) = 0;                       \
36         /** Gets TYPE */                                                                      \
37         virtual TYPE Get(ComponentId index) const = 0;                                        \
38         /** Gets TYPE */                                                                      \
39         virtual TYPE Get(CORE_NS::Entity entity) const = 0;                                   \
40         /** Scoped read access to component data. */                                          \
41         virtual CORE_NS::ScopedHandle<const TYPE> Read(ComponentId index) const = 0;          \
42         /** Scoped read access to component data. */                                          \
43         virtual CORE_NS::ScopedHandle<const TYPE> Read(CORE_NS::Entity entity) const = 0;     \
44         /** Scoped write access to component data. */                                         \
45         virtual CORE_NS::ScopedHandle<TYPE> Write(ComponentId index) = 0;                     \
46         /** Scoped write access to component data. */                                         \
47         virtual CORE_NS::ScopedHandle<TYPE> Write(CORE_NS::Entity entity) = 0;
48 
49 #define DECLARE_GENERIC_INTERFACE2(NAME, TYPE)                                                \
50     protected:                                                                                \
51         NAME() = default;                                                                     \
52         virtual ~NAME() = default;                                                            \
53         NAME(const NAME&) = delete;                                                           \
54         NAME(NAME&&) = delete;                                                                \
55         NAME& operator=(const NAME&) = delete;                                                \
56         NAME& operator=(NAME&& data) = delete;                                                \
57     };                                                                                        \
58     inline constexpr BASE_NS::string_view GetName(const NAME*)                                \
59     {                                                                                         \
60         return #TYPE;                                                                         \
61     }                                                                                         \
62     inline constexpr BASE_NS::string_view GetName(const TYPE*)                                \
63     {                                                                                         \
64         return #TYPE;                                                                         \
65     }                                                                                         \
66     inline constexpr BASE_NS::Uid GetUid(const NAME*)                                         \
67     {                                                                                         \
68         return NAME::UID;                                                                     \
69     }                                                                                         \
70     inline constexpr BASE_NS::Uid GetUid(const TYPE*)                                         \
71     {                                                                                         \
72         return NAME::UID;                                                                     \
73     }
74 
75 #define DECLARE_GENERIC_INTERFACE(NAME, TYPE, TYPE_UID)                                       \
76     DECLARE_GENERIC_INTERFACE1(NAME, TYPE, TYPE_UID)                                          \
77     DECLARE_GENERIC_INTERFACE2(NAME, TYPE)
78 
79 #if !defined(IMPLEMENT_MANAGER)
80 #undef BEGIN_COMPONENT
81 #undef VALUE
82 #undef ARRAY_VALUE
83 #undef DEFINE_PROPERTY
84 #undef DEFINE_BITFIELD_PROPERTY
85 #undef DEFINE_ARRAY_PROPERTY
86 #undef BEGIN_COMPONENT_MANAGER
87 #undef END_COMPONENT_MANAGER
88 #undef END_COMPONENT
89 #undef END_COMPONENT_EXT
90 #define BEGIN_COMPONENT(NAME, COMPONENT_NAME) /** @ingroup group_ecs_components_##COMPONENT_NAME */ \
91     struct COMPONENT_NAME {
92 #define VALUE(val) val
93 #define ARRAY_VALUE(...) __VA_ARGS__
94 #define DEFINE_PROPERTY(type, name, displayname, flags, value) type name{ value };
95 #define DEFINE_BITFIELD_PROPERTY(type, name, displayname, flags, value, enumeration) type name{ value };
96 #define DEFINE_ARRAY_PROPERTY(type, count, name, displayname, flags, value) type name[count]{ value };
97 
98 #define BEGIN_COMPONENT_MANAGER(NAME, COMPONENT_NAME, TYPE_UID) \
99     DECLARE_GENERIC_INTERFACE1(NAME, COMPONENT_NAME, TYPE_UID)
100 #define END_COMPONENT_MANAGER(NAME, COMPONENT_NAME) \
101     DECLARE_GENERIC_INTERFACE2(NAME, COMPONENT_NAME)
102 
103 #define END_COMPONENT(NAME, COMPONENT_NAME, TYPE_UID) };      \
104     BEGIN_COMPONENT_MANAGER(NAME, COMPONENT_NAME, TYPE_UID) \
105     END_COMPONENT_MANAGER(NAME, COMPONENT_NAME)
106 
107 #define END_COMPONENT_EXT(NAME, COMPONENT_NAME, TYPE_UID, METHODS) }; \
108     BEGIN_COMPONENT_MANAGER(NAME, COMPONENT_NAME, TYPE_UID) \
109     METHODS \
110     END_COMPONENT_MANAGER(NAME, COMPONENT_NAME)
111 #endif
112 // clang-format on
113