1 #ifndef DALI_TOOLKIT_PARTICLE_SYSTEM_INTERNAL_PARTICLE_EMITTER_H
2 #define DALI_TOOLKIT_PARTICLE_SYSTEM_INTERNAL_PARTICLE_EMITTER_H
4 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dali/public-api/adaptor-framework/timer.h>
22 #include <dali/public-api/object/base-object.h>
27 // For multithreading update
28 #include <dali/devel-api/threading/thread-pool.h>
31 #include <dali-toolkit/public-api/particle-system/particle-domain.h>
32 #include <dali-toolkit/public-api/particle-system/particle-emitter.h>
33 #include <dali-toolkit/public-api/particle-system/particle-list.h>
34 #include <dali-toolkit/public-api/particle-system/particle-modifier.h>
35 #include <dali-toolkit/public-api/particle-system/particle-renderer.h>
36 #include <dali-toolkit/public-api/particle-system/particle-source.h>
38 namespace Dali::Toolkit::ParticleSystem::Internal
41 class ParticleEmitter : public Dali::BaseObject, public Dali::ConnectionTracker
52 ~ParticleEmitter() override;
55 * @brief Tests whether emitter is complete (ready for simulation)
57 * @return True if emitter is complete, false otherwise
59 [[nodiscard]] bool IsComplete() const
61 return (mParticleStatusBits & STATUS_COMPLETE_BITS) == STATUS_COMPLETE_BITS;
64 [[nodiscard]] ParticleSystem::ParticleSource GetSource() const;
66 void SetSource(const ParticleSystem::ParticleSource& source);
68 [[nodiscard]] ParticleSystem::ParticleDomain GetDomain() const;
70 void SetDomain(const ParticleSystem::ParticleDomain& domain);
72 [[nodiscard]] ParticleSystem::ParticleRenderer GetRenderer() const;
74 [[nodiscard]] ParticleSystem::ParticleModifier GetModifierAt(uint32_t index);
76 void RemoveModifierAt(uint32_t index);
78 void SetRenderer(const ParticleSystem::ParticleRenderer& renderer);
80 void SetParticleCount(uint32_t maxParticleCount);
82 uint32_t GetParticleCount();
84 ParticleSystem::ParticleList& GetParticleList();
86 uint32_t AddModifier(const ParticleSystem::ParticleModifier& modifier);
88 void AttachTo(Actor actor);
90 [[nodiscard]] Actor GetActor() const;
94 void UpdateSource(uint32_t count);
96 void UpdateModifierMT(Dali::Toolkit::ParticleSystem::ParticleModifier& modifier);
100 void SetEmissionRate(uint32_t ratePerSecond);
102 [[nodiscard]] uint32_t GetEmissionRate() const;
104 void SetInitialParticleCount(uint32_t count);
106 [[nodiscard]] uint32_t GetInitialParticleCount() const;
112 void EnableParallelProcessing(bool enabled);
114 [[nodiscard]] bool IsParallelProcessingEnabled() const;
116 void SetActiveParticlesLimit(uint32_t count);
118 [[nodiscard]] uint32_t GetActiveParticlesLimit() const;
120 [[nodiscard]] ParticleSystem::ParticleEmitter::Status GetStatus() const;
122 [[nodiscard]] std::chrono::milliseconds GetCurrentTimeMillis() const;
124 // All these bits must be set in order to consider emitter COMPLETE
125 const uint32_t SOURCE_SET_STATUS_BIT = 1 << 0;
126 const uint32_t RENDERER_SET_STATUS_BIT = 1 << 1;
127 const uint32_t DOMAIN_SET_STATUS_BIT = 1 << 2;
129 // 1. Only one of these flags can be set at a time
130 // 2. They are invalid as long as emitter is INCOMPLETE
131 const uint32_t SIMULATION_STARTED_STATUS_BIT = 1 << 3;
132 const uint32_t SIMULATION_PAUSED_STATUS_BIT = 1 << 4;
133 const uint32_t SIMULATION_STOPPED_STATUS_BIT = 1 << 5;
135 const uint32_t STATUS_COMPLETE_BITS = SOURCE_SET_STATUS_BIT | RENDERER_SET_STATUS_BIT | DOMAIN_SET_STATUS_BIT;
137 ParticleSystem::ParticleSource mParticleSource; ///< Current particle source object
138 ParticleSystem::ParticleDomain mParticleDomain; ///< Current particle domain object
140 uint8_t mParticleStatusBits{0u}; ///< Current status of the emitter
143 ParticleSystem::ParticleList mParticleList;
145 std::vector<ParticleSystem::ParticleModifier> mModifiers;
147 ParticleSystem::ParticleRenderer mParticleRenderer;
151 uint32_t mEmissionRatePerSecond{1u};
152 std::atomic<uint32_t> mEmissionCountOnStart{0u};
153 std::atomic<uint32_t> mActiveParticlesLimit{0u}; ///< 0 - unlimited
154 std::atomic<bool> mSystemStarted{false};
155 std::chrono::milliseconds mCurrentMilliseconds{0};
156 std::chrono::milliseconds mLastUpdateMs{0};
158 bool mParallelProcessing{false};
159 std::unique_ptr<FrameCallback> mFrameCallback;
162 } // namespace Dali::Toolkit::ParticleSystem::Internal
164 namespace Dali::Toolkit::ParticleSystem
166 // Returns thread pool shared by whole particle system
167 Dali::ThreadPool& GetThreadPool();
169 inline Internal::ParticleEmitter& GetImplementation(ParticleSystem::ParticleEmitter& source)
171 DALI_ASSERT_ALWAYS(source && "ParticleEmitter handle is empty");
173 BaseObject& handle = source.GetBaseObject();
175 return static_cast<Internal::ParticleEmitter&>(handle);
178 inline const Internal::ParticleEmitter& GetImplementation(const ParticleSystem::ParticleEmitter& source)
180 DALI_ASSERT_ALWAYS(source && "ParticleEmitter handle is empty");
182 const BaseObject& handle = source.GetBaseObject();
184 return static_cast<const Internal::ParticleEmitter&>(handle);
187 } // namespace Dali::Toolkit::ParticleSystem
188 #endif // DALI_TOOLKIT_PARTICLE_SYSTEM_INTERNAL_PARTICLE_EMITTER_H