Nebula
Loading...
Searching...
No Matches
world.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
9//------------------------------------------------------------------------------
10#include "core/refcounted.h"
11#include "entity.h"
12#include "entitypool.h"
13#include "component.h"
15#include "util/queue.h"
16#include "category.h"
17#include "processorid.h"
18#include "processor.h"
20#include "frameevent.h"
21#include "util/fourcc.h"
22
23namespace MemDb
24{
25class Database;
26}
27namespace Util
28{
29class Blob;
30}
31
32namespace Game
33{
34
35class PackedLevel;
36
37//------------------------------------------------------------------------------
41{
43 TemplateId templateId = TemplateId::Invalid();
45 bool immediate = false;
46};
47
49World* GetWorld(WorldHash worldHash);
51World* GetWorld(WorldId worldId);
52
53//------------------------------------------------------------------------------
80class World
81{
82public:
83 // Generally, only the game server should create worlds
85 ~World();
86
88 WorldHash GetWorldHash() const;
90 WorldId GetWorldId() const;
91
93 Entity CreateEntity(bool immediate = true);
97 void DeleteEntity(Entity entity);
98
100 bool IsValid(Entity entity) const;
102 bool HasInstance(Entity entity) const;
103
106
108 template <typename TYPE>
109 TYPE* AddComponent(Entity entity);
111 void* AddComponent(Entity entity, ComponentId component);
112
114 template <typename TYPE>
115 bool HasComponent(Entity entity) const;
117 bool HasComponent(Entity entity, ComponentId component) const;
118
120 template <typename TYPE>
121 void RemoveComponent(Entity entity);
123 void RemoveComponent(Entity entity, ComponentId component);
124
126 template <typename TYPE>
127 void SetComponent(Entity entity, TYPE const& value);
129 template <typename TYPE>
130 TYPE GetComponent(Entity entity);
131
133 void MarkAsModified(Game::Entity entity);
134
136 Dataset Query(Filter filter);
140
143
147 void UnloadLevel(PackedLevel* level);
149 void ExportLevel(Util::String const& path);
150
153
156
157 // -- Internal methods -- Use with caution! --
158
160 MemDb::RowId GetInstance(Entity entity) const;
162 void SetComponentValue(Entity entity, ComponentId component, void* value, uint64_t size);
164 void ReinitializeComponent(Entity entity, ComponentId component, void* value, uint64_t size);
168 static void Override(World* src, World* dst);
172 void DeallocateEntityId(Entity entity);
174 MemDb::RowId AllocateInstance(Entity entity, MemDb::TableId table, Util::Blob const* const data = nullptr);
178 MemDb::RowId AllocateInstance(Entity entity, TemplateId templateId, bool performInitialize);
179 void FinalizeAllocate(Entity entity);
181 void DeallocateInstance(MemDb::TableId table, MemDb::RowId instance);
183 void DeallocateInstance(Entity entity);
185 void Defragment(MemDb::TableId tableId);
187 void* GetInstanceBuffer(MemDb::TableId const tableId, uint16_t partitionId, ComponentId const component);
189 void* GetColumnData(MemDb::TableId const tableId, uint16_t partitionId, MemDb::ColumnIndex const column);
194
195 void RenderDebug();
196
197private:
198 friend class GameServer;
199 friend class BlueprintManager;
200 friend class PackedLevel;
201
207
212
214 {
216 ComponentId componentId = ComponentId::Invalid();
218 void* data = nullptr;
219 };
220
226
227 // These functions are called from game server
228 void Start();
229 void BeginFrame();
230 void SimFrame();
231 void EndFrame();
232 void OnLoad();
233 void OnSave();
234 void ManageEntities();
235 void Reset();
236 void PrefilterProcessors();
238 void ClearDecayBuffers();
239
241
244
246 MemDb::RowId Migrate(Entity entity, MemDb::TableId newTable);
248 void Migrate(
249 Util::Array<Entity> const& entities,
250 MemDb::TableId fromTable,
251 MemDb::TableId newTable,
253 );
254
256 void DecayComponent(ComponentId component, MemDb::TableId tableId, MemDb::ColumnIndex column, MemDb::RowId instance);
257
260
263
268
294 bool cacheValid = false;
301};
302
303//------------------------------------------------------------------------------
306inline WorldHash
308{
309 return this->hash;
310}
311
312//------------------------------------------------------------------------------
315inline WorldId
317{
318 return this->worldId;
319}
320
321//------------------------------------------------------------------------------
324template <typename TYPE>
325inline void
326World::SetComponent(Entity entity, TYPE const& value)
327{
328#if NEBULA_DEBUG
329 n_assert2(
330 !this->pipeline.IsRunningAsync(),
331 "Settings components in arbitrary entities while executing an async processor is currently not supported!"
332 );
333#endif
334
335#if NEBULA_DEBUG
336 n_assert2(
338 "SetComponent: Provided value's type is not the correct size for the given ComponentId."
339 );
340#endif
341 EntityMapping mapping = this->GetEntityMapping(entity);
342 TYPE* ptr = (TYPE*)this->GetInstanceBuffer(mapping.table, mapping.instance.partition, GetComponentId<TYPE>());
343 *(ptr + mapping.instance.index) = value;
344}
345
346//------------------------------------------------------------------------------
349template <typename TYPE>
350inline TYPE
352{
353#if NEBULA_DEBUG
354 n_assert2(
355 !this->pipeline.IsRunningAsync(),
356 "Getting components from entities while executing an async processor is currently not supported!"
357 );
358#endif
359
360#if NEBULA_DEBUG
361 n_assert2(
363 "GetComponent: Provided value's type is not the correct size for the given ComponentId."
364 );
365#endif
366 EntityMapping mapping = this->GetEntityMapping(entity);
367 TYPE* ptr = (TYPE*)this->GetInstanceBuffer(mapping.table, mapping.instance.partition, GetComponentId<TYPE>());
368 return *(ptr + mapping.instance.index);
369}
370
371//------------------------------------------------------------------------------
374template <typename TYPE>
375inline void
377{
378#if NEBULA_DEBUG
379 n_assert2(
380 !this->pipeline.IsRunningAsync(),
381 "Removing components from entities while executing an async processor is currently not supported!"
382 );
383#endif
385 .entity = entity,
386 .componentId = Game::GetComponentId<TYPE>(),
387 };
388 this->removeComponentQueue.Append(cmd);
389}
390
391//------------------------------------------------------------------------------
394template <typename TYPE>
395inline bool
397{
398 return this->HasComponent(entity, Game::GetComponentId<TYPE>());
399}
400
401//------------------------------------------------------------------------------
404template <typename TYPE>
405inline TYPE*
407{
408 /*
409 We could possibly support this by either having thread local allocators and
410 staged queues and gathering after the processors have finished (must clear
411 allocators by issuing a separate job for this at the end of the frame), or by
412 just introducing a simple mutex.
413 */
414#if NEBULA_DEBUG
415 n_assert2(
416 !this->pipeline.IsRunningAsync(), "Adding component to entities while in an async processor is currently not supported!"
417 );
418#endif
420#if NEBULA_DEBUG
421 n_assert(MemDb::AttributeRegistry::TypeSize(id) == sizeof(TYPE));
422 //n_assert(!this->HasComponent<TYPE>(entity));
423#endif
424 TYPE* data = this->componentStageAllocator.Alloc<TYPE>();
425 const void* defaultValue = MemDb::AttributeRegistry::DefaultValue(id);
426 Memory::Copy(defaultValue, data, sizeof(TYPE));
427
429 .entity = entity,
430 .componentId = id,
431 .dataSize = sizeof(TYPE),
432 .data = data,
433 };
434 this->addStagedQueue.Append(cmd);
435
437 ComponentInterface* cInterface;
438 cInterface = static_cast<ComponentInterface*>(attr);
439
440 if (cInterface->Init != nullptr)
441 {
442 // run initialization function if it exists.
443 cInterface->Init(this, entity, data);
444 }
445
446 return data;
447}
448
449template <>
451template <>
453template <>
455
456template <>
458template <>
460template <>
462
463} // namespace Game
Loads the 'data:tables/blueprint.json' file and subsequently sets up categories based on the blueprin...
Definition blueprintmanager.h:31
These are registered to the attribute registry so that we can add more functionality to attributes.
Definition component.h:75
ComponentInitFunc Init
Definition component.h:91
Generation pool.
Definition entitypool.h:22
Definition frameevent.h:108
bool IsRunningAsync()
check if the pipeline is currently executing an async frame event batch
Definition frameevent.cc:472
The game server setups and runs the game world.
Definition gameserver.h:45
Represents a level that can be instantiated into a world.
A container of entities, their components, and processors.
PackedLevel * PreloadLevel(Util::String const &path)
preload a level that can be instantiated
Definition world.cc:88
void MoveInstance(MemDb::Table::Partition *partition, MemDb::RowId from, MemDb::RowId to)
Move a instance/row within a partition.
Definition world.cc:1359
Dataset Query(Filter filter)
Query the entity database using specified filter set. This does NOT wait for resources to be availabl...
Definition world.cc:1750
void AddStagedComponentsToEntity(Entity entity, AddStagedComponentCommand *cmds, SizeT numCmds)
Adds all components in cmds to entity.
Definition world.cc:881
Entity AllocateEntityId()
Allocate an entity id. Use this with caution!
Definition world.cc:398
bool componentInitializationEnabled
Disable if initialization of components is not required (ex. when running as editor db)
Definition world.h:193
EntityPool pool
used to allocate entity ids for this world
Definition world.h:270
Util::Array< RemoveComponentCommand > removeComponentQueue
Stores all deferred remove component commands.
Definition world.h:290
MemDb::RowId AllocateInstance(Entity entity, MemDb::TableId table, Util::Blob const *const data=nullptr)
Allocate an entity instance in a table. Use this with caution!
Definition world.cc:1103
ComponentDecayBuffer const GetDecayBuffer(ComponentId component)
Get a decay buffer for the given component.
Definition world.cc:739
Ptr< MemDb::Database > db
contains all entity instances
Definition world.h:276
Util::HashTable< BlueprintId, MemDb::TableId > blueprintToTableMap
maps from blueprint to a table that has the same signature
Definition world.h:282
void InitializeAllComponents(Entity entity, MemDb::TableId tableId, MemDb::RowId row)
Run OnInit on all components. Use with caution, since they can only be initialized once and the funct...
Definition world.cc:1145
WorldId GetWorldId() const
Returns the world ID for this world. This corresponds to Game::Entity::world.
Definition world.h:316
bool IsValid(Entity entity) const
Check if an entity ID is still valid.
Definition world.cc:764
EntityMapping GetEntityMapping(Entity entity) const
Returns the entity mapping of an entity.
Definition world.cc:783
TYPE GetComponent(Entity entity)
Get an entitys component.
Definition world.h:351
void PrefilterProcessors()
Definition world.cc:490
void ClearDecayBuffers()
Clears all decay buffers. This is called by the game server automatically.
Definition world.cc:751
bool HasComponent(Entity entity) const
Check if entity has a specific component.
Definition world.h:396
void ExecuteAddComponentCommands()
dispatches all staged components to be added to entities
Definition world.cc:814
Entity CreateEntity(bool immediate=true)
Create a new empty entity.
Definition world.cc:565
void RenderDebug()
Definition world.cc:1470
bool cacheValid
Set to true if the caches for the frame pipeline are valid.
Definition world.h:294
Util::Queue< AllocateInstanceCommand > allocQueue
Stores all deferred allocation commands.
Definition world.h:284
void SetComponentValue(Entity entity, ComponentId component, void *value, uint64_t size)
Set the value of a component by providing a pointer and type size.
Definition world.cc:1414
void Reset()
Definition world.cc:546
void SimFrame()
Definition world.cc:446
void DeleteEntity(Entity entity)
Delete entity.
Definition world.cc:620
void ReinitializeComponent(Entity entity, ComponentId component, void *value, uint64_t size)
Set the value of a component by providing a pointer and type size, then reinitialize the component.
Definition world.cc:1432
void UnloadLevel(PackedLevel *level)
unload a preloaded level
Definition world.cc:213
~World()
Definition world.cc:79
bool HasInstance(Entity entity) const
Check if an entity has an instance. It might be valid, but not have received an instance just after i...
Definition world.cc:773
FramePipeline pipeline
The frame pipeline for this world.
Definition world.h:296
World(WorldHash hash, WorldId id)
Definition world.cc:52
void FinalizeAllocate(Entity entity)
Definition world.cc:1251
SizeT GetNumInstances(MemDb::TableId tid)
Get total number of instances in an entity table.
Definition world.cc:805
void * GetColumnData(MemDb::TableId const tableId, uint16_t partitionId, MemDb::ColumnIndex const column)
Get a pointer to the first instance of a column in a partition of an entity table....
Definition world.cc:1026
Util::FixedArray< ComponentDecayBuffer > componentDecayTable
Contains all the component decay buffers. Lookup directly via ComponentId.
Definition world.h:300
MemDb::TableId CreateEntityTable(EntityTableCreateInfo const &info)
Create a table in the entity database that has a specific set of components.
Definition world.cc:1045
void DecayComponent(ComponentId component, MemDb::TableId tableId, MemDb::ColumnIndex column, MemDb::RowId instance)
Copies the component to the decay table.
Definition world.cc:642
void ExportLevel(Util::String const &path)
Export the world as a level.
Definition world.cc:222
void RemoveComponentsFromEntity(Entity entity, RemoveComponentCommand *cmds, SizeT numCmds)
Removes all components in cmds from entity.
Definition world.cc:950
void RemoveComponent(Entity entity)
Remove a component from an entity.
Definition world.h:376
void ExecuteRemoveComponentCommands()
Definition world.cc:848
void DeallocateEntityId(Entity entity)
Deallocate an entity id. Use this with caution!
Definition world.cc:414
Util::Array< EntityMapping > entityMap
maps entity index to table+row pair
Definition world.h:274
FramePipeline & GetFramePipeline()
Get the frame pipeline.
Definition world.cc:1725
void BeginFrame()
Definition world.cc:436
MemDb::RowId GetInstance(Entity entity) const
Get instance of entity.
Definition world.cc:1036
WorldId worldId
world id
Definition world.h:280
void Start()
Definition world.cc:425
void EndFrame()
Definition world.cc:456
Ptr< MemDb::Database > GetDatabase()
Get the entity database. Be careful when directly modifying the database, as some information is only...
Definition world.cc:556
WorldHash GetWorldHash() const
Returns the world hash for this world.
Definition world.h:307
void Defragment(MemDb::TableId tableId)
Defragment an entity table.
Definition world.cc:1389
void DeallocateInstance(MemDb::TableId table, MemDb::RowId instance)
Deallocate an entity instance. Use this with caution!
Definition world.cc:1261
MemDb::RowId Migrate(Entity entity, MemDb::TableId newTable)
Migrate an entity from it's current table to a different table.
Definition world.cc:1299
static void Override(World *src, World *dst)
copies and overrides dst with src. This is extremely destructive - make sure you understand the impli...
Definition world.cc:1686
void ManageEntities()
Definition world.cc:500
TYPE * AddComponent(Entity entity)
Create a component. This queues the component in a command buffer to be added later.
Definition world.h:406
Util::Queue< DeallocInstanceCommand > deallocQueue
Stores all deferred deallocation commands.
Definition world.h:286
void * GetInstanceBuffer(MemDb::TableId const tableId, uint16_t partitionId, ComponentId const component)
Get a pointer to the first instance of a component in a partition of an entity table....
Definition world.cc:1008
void OnSave()
Definition world.cc:481
Util::Array< AddStagedComponentCommand > addStagedQueue
Stores all deferred add staged component commands.
Definition world.h:288
Memory::ArenaAllocator< 4096_KB > componentStageAllocator
Allocator for staged components.
Definition world.h:292
void OnLoad()
Definition world.cc:472
SizeT numEntities
Number of entities alive.
Definition world.h:272
MemDb::TableId defaultTableId
The default table that empty entities are instantiated into.
Definition world.h:298
void MarkAsModified(Game::Entity entity)
Mark an entity as modified in its table.
Definition world.cc:1734
void SetComponent(Entity entity, TYPE const &value)
Set the value of an entitys component.
Definition world.h:326
WorldHash hash
world hash
Definition world.h:278
Definition attribute.h:29
static void const *const DefaultValue(AttributeId descriptor)
get attribute default value pointer
Definition attributeregistry.h:268
static SizeT TypeSize(AttributeId descriptor)
get type size by attribute id
Definition attributeregistry.h:246
static Attribute * GetAttribute(AttributeId descriptor)
get attribute description by id
Definition attributeregistry.h:228
Represents a partition within a Table in MemDb.
Allocates memory in chunks.
Definition arenaallocator.h:36
T * Alloc()
allocate new object, and calls constructor, but beware because this allocator does not run the destru...
Definition arenaallocator.h:186
Nebula's smart pointer class which manages the life time of RefCounted objects.
Definition ptr.h:38
Nebula's dynamic array class.
Definition array.h:60
The Util::Blob class encapsulates a chunk of raw memory into a C++ object which can be copied,...
Definition blob.h:22
Implements a fixed size one-dimensional array.
Definition fixedarray.h:20
Organizes key/value pairs by a hash code.
Definition hashtable.h:42
Nebula's queue class (a FIFO container).
Definition queue.h:28
#define n_assert2(exp, msg)
Definition debug.h:51
#define n_assert(exp)
Definition debug.h:50
Game::EditorState.
Definition graphicsmanager.h:60
uint32_t Filter
Opaque filter identifier.
Definition filter.h:26
ComponentId GetComponentId()
Returns a component id, based on template type.
Definition component.h:120
uint32_t WorldId
Definition entity.h:28
World * GetWorld(WorldHash hash)
returns a world by hash
Definition world.cc:35
Attribute.
Definition attribute.h:26
void Copy(const void *from, void *to, size_t numBytes)
Copy a chunk of memory (note the argument order is different from memcpy()!!!)
Definition osxmemory.cc:213
A pinned array is an array which manages its own virtual memory.
Definition String.cs:6
Definition category.h:17
Contains data for components flagged with COMPONENTFLAG_DECAY, that has been deleted this frame.
Definition component.h:47
A dataset that contains views into category tables.
Definition dataset.h:23
Definition world.h:41
TemplateId templateId
template to instantiate.
Definition world.h:43
bool immediate
set if the entity should be instantiated immediately or deferred until end of frame.
Definition world.h:45
An entity is essentially just an Id with some utility functions attached.
Definition entity.h:35
static constexpr Entity Invalid()
Definition entity.h:138
Maps an entity to a table and instance id.
Definition entity.h:87
MemDb::RowId instance
Definition entity.h:89
MemDb::TableId table
Definition entity.h:88
Definition category.h:21
A component that stores the orientation of an entity.
A component that stores the position of an entity in world space coordinates.
A component that stores the scale of an entity.
Definition category.h:18
ComponentId componentId
Definition world.h:216
SizeT dataSize
Definition world.h:217
void * data
Definition world.h:218
Game::Entity entity
Definition world.h:215
Game::Entity entity
Definition world.h:204
TemplateId tid
Definition world.h:205
Game::Entity entity
Definition world.h:210
ComponentId componentId
Definition world.h:224
Entity entity
Definition world.h:223
Definition entity.h:29
Definition attributeid.h:19
column id
Definition tableid.h:38
row identifier
Definition tableid.h:18
uint16_t partition
Definition tableid.h:19
uint16_t index
Definition tableid.h:20
Table identifier.
Definition tableid.h:14
Nebula's universal string class.
Definition string.h:50
int SizeT
Definition types.h:49