Line data Source code
1 : /* Copyright (C) 2017 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_ENTITY
19 : #define INCLUDED_ENTITY
20 :
21 : #include "lib/types.h"
22 :
23 : class IComponent;
24 :
25 : /**
26 : * Entity ID type.
27 : * ID numbers are never reused within a simulation run.
28 : */
29 : typedef u32 entity_id_t;
30 :
31 : /**
32 : * Invalid entity ID. Used as an error return value by some functions.
33 : * No valid entity will have this ID.
34 : */
35 : const entity_id_t INVALID_ENTITY = 0;
36 :
37 : /**
38 : * Entity ID for singleton 'system' components.
39 : * Use with QueryInterface to get the component instance.
40 : * (This allows those systems to make convenient use of the common infrastructure
41 : * for message-passing, scripting, serialisation, etc.)
42 : */
43 : const entity_id_t SYSTEM_ENTITY = 1;
44 :
45 : // Entities are split into two kinds:
46 : // "Normal" (for most entities)
47 : // "Local" (for entities that only exist on the local machine, aren't synchronised across the network,
48 : // aren't retained in saved games, etc)
49 : // The distinction is encoded in the entity ID, so that they're easily distinguished.
50 : //
51 : // We want all entity_id_ts to fit in an integer JS::Value, i.e. 1-2^30 .. 2^30-1 (inclusive)
52 : // We want them to be unsigned ints (actually it shouldn't matter but unsigned seems simpler)
53 : // We want 1 tag bit
54 : // So we have 1 JS-reserved bit, 1 unused sign bit, 1 local tag bit, 29 counter bits
55 : // (0.5B entities should be plenty)
56 :
57 : #define ENTITY_TAGMASK (1 << 29)
58 : #define ENTITY_IS_NORMAL(id) (((id) & ENTITY_TAGMASK) == 0)
59 : #define ENTITY_IS_LOCAL(id) (((id) & ENTITY_TAGMASK) == ENTITY_TAGMASK)
60 : const entity_id_t FIRST_LOCAL_ENTITY = ENTITY_TAGMASK;
61 :
62 : struct SEntityComponentCache
63 : {
64 : size_t numInterfaces;
65 : IComponent* interfaces[1]; /* variable length array */
66 : };
67 :
68 : /**
69 : * Object wrapping an entity_id_t, with a SEntityComponentCache to support fast
70 : * QueryInterface() / CmpPtr<>() calls.
71 : *
72 : * Components can use IComponent::GetSystemEntity() and IComponent::GetEntityHandle()
73 : * to get handles to SYSTEM_ENTITY and themselves, and then pass those handles around.
74 : *
75 : * Be careful not to store a CEntityHandle for longer than the lifetime of the entity
76 : * (listen to MT_Destroy messages to know when to release it) - otherwise the handle will
77 : * contain a dangling pointer and will probably crash.
78 : */
79 : class CEntityHandle
80 : {
81 : public:
82 742 : CEntityHandle() : m_Id(INVALID_ENTITY), m_ComponentCache(NULL) { }
83 129 : CEntityHandle(entity_id_t id, SEntityComponentCache* componentCache)
84 129 : : m_Id(id), m_ComponentCache(componentCache)
85 : {
86 129 : }
87 :
88 802 : entity_id_t GetId() const { return m_Id; }
89 256 : SEntityComponentCache* GetComponentCache() const { return m_ComponentCache; }
90 :
91 : private:
92 : entity_id_t m_Id;
93 : SEntityComponentCache* m_ComponentCache;
94 : };
95 :
96 : #endif // INCLUDED_ENTITY
|