Nebula
Loading...
Searching...
No Matches
processor.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
9//------------------------------------------------------------------------------
10#include "timing/timer.h"
11#include "util/stringatom.h"
12#include "filter.h"
13#include "processorid.h"
14
15namespace Game
16{
17
18class World;
19
21
23enum ProcessorPhase : uint8_t
24{
25 EditorPhase = 1 << 0, // runs when the world is not simulating
26 PlayPhase = 1 << 1, // runs when the world is simulating
28};
29
31{
32public:
36 int order = 100;
38 bool async = false;
42 std::function<void(World*, Dataset::View const&)> callback;
46 bool cacheValid = false;
48 bool active = true;
49#ifdef NEBULA_ENABLE_PROFILING
51 Timing::Timer timer;
52#endif
55
56private:
58
59 template <typename... TYPES, std::size_t... Is>
60 static void
61 UpdateExpander(World* world, std::function<void(World*, TYPES...)> const& func, Game::Dataset::View const& view, const IndexT instance, uint8_t const bufferStartOffset, std::index_sequence<Is...>)
62 {
63 func(
64 world,
65 *((typename std::remove_const<typename std::remove_reference<TYPES>::type>::type*)view.buffers[Is] + instance)...
66 );
67 }
68
69 template <typename... COMPONENTS>
70 static std::function<void(World*, Dataset::View const&)>
71 ForEach(std::function<void(World*, COMPONENTS...)> func, uint8_t bufferStartOffset)
72 {
73 return [func, bufferStartOffset](World* world, Game::Dataset::View const& view)
74 {
75 uint16_t i = 0;
76 while (i < view.numInstances)
77 {
78 // check validity of instances in sections of 64 instances
79 if (!view.validInstances.SectionIsNull(i / 64))
80 {
81 uint16_t const end = Math::min<uint16_t>(i + uint16_t(64), view.numInstances);
82 for (uint32_t instance = i; instance < end; ++instance)
83 {
84 // make sure the instance we're processing is valid
85 if (view.validInstances.IsSet(instance))
86 {
87 UpdateExpander<COMPONENTS...>(
88 world,
89 func,
90 view,
91 instance,
92 bufferStartOffset,
93 std::make_index_sequence<sizeof...(COMPONENTS)>()
94 );
95 }
96 }
97 }
98 // progress 64 instances, which corresponds to 1 section
99 i += 64;
100 }
101 };
102 }
103
104 template <typename... COMPONENTS>
105 static std::function<void(World*, Dataset::View const&)>
106 ForEachModified(std::function<void(World*, COMPONENTS...)> func, uint8_t bufferStartOffset)
107 {
108 return [func, bufferStartOffset](World* world, Game::Dataset::View const& view)
109 {
110 uint16_t i = 0;
111 while (i < view.numInstances)
112 {
113
114 // check validity of instances in sections of 64 instances
115 uint64_t section = i / 64;
116 if (!view.validInstances.SectionIsNull(section) && !view.modifiedInstances.SectionIsNull(section))
117 {
118 uint16_t const end = Math::min<uint16_t>(i + uint16_t(64), view.numInstances);
119 for (uint32_t instance = i; instance < end; ++instance)
120 {
121 // make sure the instance we're processing is valid
122 if (view.validInstances.IsSet(instance) && view.modifiedInstances.IsSet(instance))
123 {
124 UpdateExpander<COMPONENTS...>(
125 world,
126 func,
127 view,
128 instance,
129 bufferStartOffset,
130 std::make_index_sequence<sizeof...(COMPONENTS)>()
131 );
132 }
133 }
134 }
135 // progress 64 instances, which corresponds to 1 section
136 i += 64;
137 }
138 };
139 }
140};
141
143{
144public:
147
149 template<typename LAMBDA>
150 ProcessorBuilder& Func(LAMBDA);
151
153 template<typename ...COMPONENTS>
154 ProcessorBuilder& Func(std::function<void(World*, COMPONENTS...)> func);
155
157 template<typename ... COMPONENTS>
159
161 template<typename ... COMPONENTS>
163
165 ProcessorBuilder& Excluding(std::initializer_list<ComponentId>);
166
169
172
175
178
181
184
187
189 Processor* Build();
190
191private:
195 std::function<void(World*, Dataset::View const&)> func = nullptr;
196 std::function<void(World*, Dataset::View const&)> funcModified = nullptr;
198 bool async = false;
199 bool onlyModified = false;
200 int order = 100;
202};
203
204//------------------------------------------------------------------------------
207template<typename LAMBDA>
209{
210 static_assert(std::is_invocable<LAMBDA()>());
211 return this->Func(std::function(lambda));
212}
213
214//------------------------------------------------------------------------------
217template<typename ...COMPONENTS>
218inline ProcessorBuilder&
219ProcessorBuilder::Func(std::function<void(World*, COMPONENTS...)> func)
220{
221 uint8_t const bufferStartOffset = this->filterBuilder.GetNumInclusive();
222 this->filterBuilder.Including<COMPONENTS...>();
223 this->func = Processor::ForEach(func, bufferStartOffset);
224 this->funcModified = Processor::ForEachModified(func, bufferStartOffset);
225 return *this;
226}
227
228//------------------------------------------------------------------------------
231template<typename ...COMPONENTS>
233{
234 this->filterBuilder.Including<COMPONENTS...>();
235 return *this;
236}
237
238//------------------------------------------------------------------------------
241template<typename ...COMPONENTS>
243{
244 this->filterBuilder.Excluding<COMPONENTS...>();
245 return *this;
246}
247
248} // namespace Game
Definition filter.h:45
uint8_t GetNumInclusive()
Definition filter.h:149
FilterBuilder & Excluding()
Definition filter.h:139
FilterBuilder & Including()
Definition filter.h:128
Definition processor.h:143
bool async
Definition processor.h:198
ProcessorBuilder & Order(int order)
Set the sorting order for the processor.
Definition processor.cc:74
Processor * Build()
Build the processor and attach it to the world.
Definition processor.cc:114
ProcessorBuilder & OnlyModified()
entities must be marked as modified for them to actually be processed
Definition processor.cc:64
FilterBuilder filterBuilder
Definition processor.h:197
ProcessorBuilder & EditorOnly()
Processor only runs when the world is not simulating.
Definition processor.cc:84
std::function< void(World *, Dataset::View const &)> funcModified
Definition processor.h:196
std::function< void(World *, Dataset::View const &)> func
Definition processor.h:195
int order
Definition processor.h:200
ProcessorPhase phase
Definition processor.h:201
Util::StringAtom name
Definition processor.h:193
ProcessorBuilder & Func(LAMBDA)
which function to run with the processor
Definition processor.h:208
ProcessorBuilder & PlayOnly()
Processor only runs when the world is simulating.
Definition processor.cc:94
ProcessorBuilder & Excluding()
entities must not have any of these components
Definition processor.h:242
ProcessorBuilder & Async()
processor should run async
Definition processor.cc:54
ProcessorBuilder & Including()
entities must have these components
Definition processor.h:232
bool onlyModified
Definition processor.h:199
ProcessorBuilder & RunInEditor()
Processor should always run, even in editor; when the game is paused.
Definition processor.cc:104
ProcessorBuilder & On(Util::StringAtom eventName)
select on which event the processor is executed
Definition processor.cc:38
World * world
Definition processor.h:192
Util::StringAtom onEvent
Definition processor.h:194
Definition processor.h:31
Util::String name
name of the processor
Definition processor.h:34
friend ProcessorBuilder
Definition processor.h:57
int order
sorting order within frame event (same as batch order).
Definition processor.h:36
Filter filter
filter used for creating the dataset
Definition processor.h:40
bool active
set to false if the processor shouldn't execute in the frame.
Definition processor.h:48
static void UpdateExpander(World *world, std::function< void(World *, TYPES...)> const &func, Game::Dataset::View const &view, const IndexT instance, uint8_t const bufferStartOffset, std::index_sequence< Is... >)
Definition processor.h:61
bool cacheValid
set to false if the cache is invalid
Definition processor.h:46
ProcessorPhase phase
which world modes this processor is allowed to run in
Definition processor.h:54
bool async
set if this processor should run as a job.
Definition processor.h:38
static std::function< void(World *, Dataset::View const &)> ForEachModified(std::function< void(World *, COMPONENTS...)> func, uint8_t bufferStartOffset)
Definition processor.h:106
std::function< void(World *, Dataset::View const &)> callback
function that this processor runs
Definition processor.h:42
static std::function< void(World *, Dataset::View const &)> ForEach(std::function< void(World *, COMPONENTS...)> func, uint8_t bufferStartOffset)
Definition processor.h:71
Util::Array< MemDb::TableId > cache
cached tables that fulfill the requirements of the filter
Definition processor.h:44
A container of entities, their components, and processors.
Definition world.h:85
Nebula's dynamic array class.
Definition array.h:61
A StringAtom.
Definition stringatom.h:22
Nebula's universal string class.
Definition string.h:50
Resolves local hierarchical transforms into the mandatory world transform components.
Definition graphicsmanager.h:66
uint32_t Filter
Opaque filter identifier.
Definition filter.h:26
ProcessorPhase
which world mode a processor is allowed to run in
Definition processor.h:24
@ BothPhases
Definition processor.h:27
@ PlayPhase
Definition processor.h:26
@ EditorPhase
Definition processor.h:25
__forceinline TYPE min(TYPE a, TYPE b)
Definition scalar.h:399
This represents a "view" into an entity table.
Definition dataset.h:35
void * buffers[MAX_COMPONENT_BUFFERS]
component buffers.
Definition dataset.h:43
int IndexT
Definition types.h:41