[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / particle-system / particle-list-impl.h
1 #ifndef DALI_TOOLKIT_PARTICLE_SYSTEM_INTERNAL_PARTICLE_LIST_H
2 #define DALI_TOOLKIT_PARTICLE_SYSTEM_INTERNAL_PARTICLE_LIST_H
3 /*
4  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 // INTERNAL INCLUDES
21 #include <dali-toolkit/public-api/particle-system/particle-list.h>
22 #include <dali-toolkit/public-api/particle-system/particle.h>
23
24 // EXTERNAL INCLUDES
25 #include <dali/public-api/object/base-object.h>
26 #include <dali/public-api/common/vector-wrapper.h>
27 #include <dali/public-api/common/list-wrapper.h>
28 #include <dali/devel-api/common/map-wrapper.h>
29 #include <algorithm>
30 #include <memory>
31
32
33 namespace Dali::Toolkit::ParticleSystem::Internal
34 {
35 template<class T>
36 struct StreamDataTypeWrapper
37 {
38   static ParticleStream::StreamDataType GetType()
39   {
40     return {};
41   }
42 };
43
44 struct ParticleDataStream
45 {
46   ~ParticleDataStream() = default;
47   template<class T>
48   ParticleDataStream(uint32_t capacity, const T& defaultValue, ParticleStream::StreamDataType dataType)
49   : ParticleDataStream(capacity, sizeof(T), &defaultValue, dataType)
50   {
51   }
52
53   /**
54    * Creates new stream of requested capacity and (optionally) fills with default data
55    */
56   ParticleDataStream(uint32_t capacity, uint32_t dataSize, const void* defaultValue, ParticleStream::StreamDataType dataType)
57   {
58     this->capacity = capacity;
59     data.resize(capacity * dataSize);
60     if(defaultValue)
61     {
62       for(auto i = 0u; i < capacity; ++i)
63       {
64         auto dstPtr = data.data() + (i * dataSize);
65         std::copy(reinterpret_cast<const uint8_t*>(defaultValue), reinterpret_cast<const uint8_t*>(defaultValue) + dataSize, dstPtr);
66       }
67     }
68     type           = dataType;
69     alive          = 0u;
70     this->dataSize = dataSize;
71   }
72
73   void SetStreamName(const char* name)
74   {
75     streamName = name;
76   }
77
78   void SetStreamLocal(bool local)
79   {
80     localStream = local;
81   }
82
83   /**
84    * Converts raw data into requested type (does not guarantee compatibility)
85    */
86   template<class T>
87   T* GetAs()
88   {
89     return reinterpret_cast<T*>(data.data());
90   }
91
92   ParticleStream::StreamDataType type;
93   std::vector<uint8_t>           data;
94   std::string                    streamName;
95   uint32_t                       alive{0u};
96   uint32_t                       capacity;
97   uint32_t                       dataSize;
98   bool                           localStream{true};
99 };
100
101 /**
102  * Particle list stores particle-specific data and manages the particles memory
103  * It can return a sub-list.
104  *
105  * ParticleList manages the storage memory.
106  *
107  *
108  */
109 class ParticleList : public Dali::BaseObject
110 {
111 public:
112
113   ParticleList(uint32_t capacity, ParticleSystem::ParticleList::ParticleStreamTypeFlags streamFlags);
114
115   ~ParticleList();
116
117   /**
118    * Returns raw pointer to the stream data
119    */
120   void* GetRawStream(uint32_t index);
121
122   /**
123    * Returns number of available data streams
124    * @return
125    */
126   uint32_t GetStreamCount() const;
127
128   /**
129    * Returns number of particles per list
130    * @return
131    */
132   uint32_t GetParticleCount() const;
133
134   /**
135    * Returns number of currently active particles
136    * @return
137    */
138   uint32_t GetActiveParticleCount() const;
139
140   /**
141    * Returns stream data-type
142    * @param streamIndex
143    * @return
144    */
145   ParticleStream::StreamDataType GetStreamDataType(uint32_t streamIndex);
146
147   /**
148    * Returns stream data type size
149    * @param streamIndex
150    * @return
151    */
152   [[nodiscard]] uint32_t GetStreamDataTypeSize(uint32_t streamIndex) const;
153
154   [[nodiscard]] const std::string& GetStreamName(uint32_t streamIndex) const;
155
156   [[nodiscard]] bool IsStreamLocal(uint32_t streamIndex) const;
157
158   /**
159    * Allocates new particle in the streams
160    * @param lifetime
161    * @return
162    */
163   ParticleSystem::Particle NewParticle(float lifetime);
164
165   void* GetDefaultStream(ParticleStreamTypeFlagBit streamBit);
166
167   uint32_t GetDefaultStreamIndex(ParticleStreamTypeFlagBit streamBit);
168
169   std::list<ParticleSystem::Particle>& GetParticles();
170
171   void ReleaseParticle(uint32_t particleIndex);
172
173   uint32_t GetStreamElementSize(bool includeLocalStream);
174
175 private:
176   template<class T>
177   uint32_t AddStream(const T& defaultValue, const char* streamName, bool localStream)
178   {
179     return AddStream(sizeof(T), &defaultValue, StreamDataTypeWrapper<T>::GetType(), streamName, localStream);
180   }
181
182 public:
183   /**
184    * Adds new stream and returns index
185    */
186   uint32_t AddStream(uint32_t sizeOfDataType, const void* defaultValue, ParticleStream::StreamDataType dataType, const char* streamName, bool localStream);
187
188 private:
189   std::vector<char> mBuffer[2];
190
191   uint32_t mAliveParticleCount{0u};
192   uint32_t mMaxParticleCount;
193
194   // Data storage
195   std::vector<std::unique_ptr<ParticleDataStream>> mDataStreams;
196
197   std::vector<uint32_t> mFreeChain;
198   int32_t               mFreeIndex{0u};
199
200   std::map<uint32_t, uint32_t> mBuiltInStreamMap;
201
202   std::list<ParticleSystem::Particle> mParticles;
203
204   uint32_t mParticleStreamElementSizeWithLocal{0u};
205   uint32_t mParticleStreamElementSize{0u};
206 };
207
208 } // namespace Dali::Toolkit::ParticleSystem::Internal
209 namespace Dali::Toolkit::ParticleSystem
210 {
211 inline Internal::ParticleList& GetImplementation(ParticleSystem::ParticleList& source)
212 {
213   DALI_ASSERT_ALWAYS(source && "ParticleList handle is empty");
214
215   BaseObject& handle = source.GetBaseObject();
216
217   return static_cast<Internal::ParticleList&>(handle);
218 }
219
220 inline const Internal::ParticleList& GetImplementation(const ParticleSystem::ParticleList& source)
221 {
222   DALI_ASSERT_ALWAYS(source && "ParticleList handle is empty");
223
224   const BaseObject& handle = source.GetBaseObject();
225
226   return static_cast<const Internal::ParticleList&>(handle);
227 }
228
229 } // namespace Dali::Toolkit::ParticleSystem
230
231 #endif // DALI_TOOLKIT_PARTICLE_SYSTEM_INTERNAL_PARTICLE_LIST_H