-
Notifications
You must be signed in to change notification settings - Fork 32
/
ecs_internal.h
149 lines (128 loc) · 3.41 KB
/
ecs_internal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef LUA_ECS_INTERNAL_H
#define LUA_ECS_INTERNAL_H
#include <lua.h>
#include <lauxlib.h>
#include <string.h>
#include <stdint.h>
#include "ecs_group.h"
#include "ecs_entityindex.h"
#include "ecs_entityid.h"
#define MAX_COMPONENT_NAME 32
#define MAX_COMPONENT 256
#define ENTITY_REMOVED 0
#define ENTITYID_TAG -1
#define DEFAULT_SIZE 128
#define STRIDE_TAG 0
#define STRIDE_LUA -1
#define DUMMY_PTR (void *)(~(uintptr_t)0)
#define TYPE_INT 0
#define TYPE_FLOAT 1
#define TYPE_BOOL 2
#define TYPE_INT64 3
#define TYPE_DWORD 4
#define TYPE_WORD 5
#define TYPE_BYTE 6
#define TYPE_DOUBLE 7
#define TYPE_USERDATA 8
#define TYPE_COUNT 9
struct component_pool {
int cap;
int n;
int stride; // -1 means lua object
int last_lookup;
entity_index_t *id;
void *buffer;
};
struct component_lua {
lua_State *L; // for lua object table
unsigned int freelist;
unsigned int cap;
};
struct entity_world {
struct component_lua lua;
struct entity_id eid;
struct entity_group_arena group;
struct component_pool c[MAX_COMPONENT];
};
struct group_field {
char key[MAX_COMPONENT_NAME];
int offset;
int type;
};
struct group_key {
char name[MAX_COMPONENT_NAME];
int id;
int field_n;
int attrib;
};
struct group_iter {
struct entity_world *world;
struct group_field *f;
int nkey;
int readonly;
struct group_key k[1];
};
static inline struct entity_world *
getW(lua_State *L) {
return (struct entity_world *)lua_touserdata(L, 1);
}
static inline void
check_cid_valid(lua_State *L, struct entity_world *w, int cid) {
if (cid < 0 || cid >= MAX_COMPONENT || w->c[cid].cap == 0) {
luaL_error(L, "Invalid type %d", cid);
}
}
static inline int
check_cid(lua_State *L, struct entity_world *w, int index) {
int cid = luaL_checkinteger(L, index);
check_cid_valid(L, w, cid);
return cid;
}
static inline int
check_tagid(lua_State *L, struct entity_world *w, int index) {
int cid = luaL_checkinteger(L, index);
check_cid_valid(L, w, cid);
if (w->c[cid].stride != 0)
luaL_error(L, "Invalid tag %d", cid);
return cid;
}
static inline struct group_iter *
check_groupiter(lua_State *L, int index) {
struct group_iter *iter = lua_touserdata(L, index);
if (iter == NULL)
luaL_error(L, "Need Userdata Iterator");
return iter;
}
static inline void *
get_ptr(struct component_pool *c, int index) {
if (c->stride > 0)
return (void *)((char *)c->buffer + c->stride * index);
else
return DUMMY_PTR;
}
static inline int
get_integer(lua_State *L, int index, int i, const char *key) {
if (lua_rawgeti(L, index, i) != LUA_TNUMBER) {
return luaL_error(L, "Can't find %s in iterator", key);
}
int r = lua_tointeger(L, -1);
lua_pop(L, 1);
return r;
}
static inline uint64_t
ENTITY_EID(struct entity_world *w, entity_index_t e) {
return w->eid.id[index_(e)];
}
static inline uint64_t
ecs_get_eid(struct entity_world *w, int cid, int index) {
struct component_pool *c = &w->c[cid];
return w->eid.id[index_(c->id[index])];
}
int ecs_add_component_id_(struct entity_world *w, int cid, entity_index_t eindex);
void ecs_write_component_object_(lua_State *L, int n, struct group_field *f, void *buffer);
void ecs_read_object_(lua_State *L, struct group_iter *iter, void *buffer);
int ecs_lookup_component_(struct component_pool *pool, entity_index_t eindex, int guess_index);
entity_index_t ecs_new_entityid_(struct entity_world *w);
void ecs_reserve_component_(struct component_pool *pool, int cid, int cap);
void ecs_reserve_eid_(struct entity_world *w, int n);
#endif