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 = default;
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 ParticleSystem::ParticleList& GetParticleList();
84 uint32_t AddModifier(const ParticleSystem::ParticleModifier& modifier);
86 void AttachTo(Actor actor);
88 [[nodiscard]] Actor GetActor() const;
92 void UpdateSource(uint32_t count);
94 void UpdateModifierMT(Dali::Toolkit::ParticleSystem::ParticleModifier& modifier);
98 void SetEmissionRate(uint32_t ratePerSecond);
100 [[nodiscard]] uint32_t GetEmissionRate() const;
102 void SetInitialParticleCount(uint32_t count);
104 [[nodiscard]] uint32_t GetInitialParticleCount() const;
110 void EnableParallelProcessing(bool enabled);
112 [[nodiscard]] bool IsParallelProcessingEnabled() const;
114 void SetActiveParticlesLimit(uint32_t count);
116 [[nodiscard]] uint32_t GetActiveParticlesLimit() const;
118 [[nodiscard]] ParticleSystem::ParticleEmitter::Status GetStatus() const;
120 [[nodiscard]] std::chrono::milliseconds GetCurrentTimeMillis() const;
122 // All these bits must be set in order to consider emitter COMPLETE
123 const uint32_t SOURCE_SET_STATUS_BIT = 1 << 0;
124 const uint32_t RENDERER_SET_STATUS_BIT = 1 << 1;
125 const uint32_t DOMAIN_SET_STATUS_BIT = 1 << 2;
127 // 1. Only one of these flags can be set at a time
128 // 2. They are invalid as long as emitter is INCOMPLETE
129 const uint32_t SIMULATION_STARTED_STATUS_BIT = 1 << 3;
130 const uint32_t SIMULATION_PAUSED_STATUS_BIT = 1 << 4;
131 const uint32_t SIMULATION_STOPPED_STATUS_BIT = 1 << 5;
133 const uint32_t STATUS_COMPLETE_BITS = SOURCE_SET_STATUS_BIT | RENDERER_SET_STATUS_BIT | DOMAIN_SET_STATUS_BIT;
135 ParticleSystem::ParticleSource mParticleSource; ///< Current particle source object
136 ParticleSystem::ParticleDomain mParticleDomain; ///< Current particle domain object
138 uint8_t mParticleStatusBits{0u}; ///< Current status of the emitter
141 ParticleSystem::ParticleList mParticleList;
143 std::vector<ParticleSystem::ParticleModifier> mModifiers;
145 ParticleSystem::ParticleRenderer mParticleRenderer;
149 uint32_t mEmissionRatePerSecond{1u};
150 std::atomic<uint32_t> mEmissionCountOnStart{0u};
151 std::atomic<uint32_t> mActiveParticlesLimit{0u}; ///< 0 - unlimited
152 std::atomic<bool> mSystemStarted{false};
153 std::chrono::milliseconds mCurrentMilliseconds{0};
154 std::chrono::milliseconds mLastUpdateMs{0};
156 bool mParallelProcessing{false};
157 std::unique_ptr<FrameCallback> mFrameCallback;
160 } // namespace Dali::Toolkit::ParticleSystem::Internal
162 namespace Dali::Toolkit::ParticleSystem
164 // Returns thread pool shared by whole particle system
165 Dali::ThreadPool& GetThreadPool();
167 inline Internal::ParticleEmitter& GetImplementation(ParticleSystem::ParticleEmitter& source)
169 DALI_ASSERT_ALWAYS(source && "ParticleEmitter handle is empty");
171 BaseObject& handle = source.GetBaseObject();
173 return static_cast<Internal::ParticleEmitter&>(handle);
176 inline const Internal::ParticleEmitter& GetImplementation(const ParticleSystem::ParticleEmitter& source)
178 DALI_ASSERT_ALWAYS(source && "ParticleEmitter handle is empty");
180 const BaseObject& handle = source.GetBaseObject();
182 return static_cast<const Internal::ParticleEmitter&>(handle);
185 } // namespace Dali::Toolkit::ParticleSystem
186 #endif // DALI_TOOLKIT_PARTICLE_SYSTEM_INTERNAL_PARTICLE_EMITTER_H