Skip to content

Commit 3226ef1

Browse files
committed
Versioning
1 parent e628607 commit 3226ef1

File tree

8 files changed

+530
-181
lines changed

8 files changed

+530
-181
lines changed

ECS.lua

Lines changed: 4 additions & 5 deletions
Large diffs are not rendered by default.

ECS_concat.lua

Lines changed: 190 additions & 103 deletions
Large diffs are not rendered by default.

build.lua

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@ local SRC_FILES = {
2323
}
2424

2525
local HEADER = [[
26-
ECS-Lua v2.0.0 [2021-10-02 17:25]
26+
ECS Lua v2.0.0 [2021-10-14 18:00]
2727
28-
ECS-Lua is a tiny and easy to use ECS (Entity Component System) engine for
29-
game development
28+
ECS Lua is a lua ECS (Entity Component System) library used for game developments.
3029
31-
This is a minified version of ECS-Lua, to see the full source code visit
30+
This is a minified version of ECS Lua, to see the full source code visit
3231
https://github.com/nidorx/ecs-lua
3332
3433
------------------------------------------------------------------------------

src/Component.lua

Lines changed: 71 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ local function createComponentClass(initializer, superClass)
2525
if superClass == nil then
2626
superClass = ComponentClass
2727
superClass._Qualifiers = { ["Primary"] = ComponentClass }
28+
superClass._QualifiersArr = { ComponentClass }
2829
superClass._Initializers = {}
2930
else
31+
superClass.HasQualifier = true
3032
ComponentClass.IsQualifier = true
3133
end
3234

3335
local Qualifiers = superClass._Qualifiers
36+
local QualifiersArr = superClass._QualifiersArr
3437

3538
setmetatable(ComponentClass, {
3639
__call = function(t, value)
@@ -80,7 +83,7 @@ local function createComponentClass(initializer, superClass)
8083
]]
8184
function ComponentClass.Qualifier(qualifier)
8285
if type(qualifier) ~= "string" then
83-
for _, qualifiedClass in pairs(Qualifiers) do
86+
for _, qualifiedClass in ipairs(QualifiersArr) do
8487
if qualifiedClass == qualifier then
8588
return qualifier
8689
end
@@ -92,6 +95,7 @@ local function createComponentClass(initializer, superClass)
9295
if qualifiedClass == nil then
9396
qualifiedClass = createComponentClass(initializer, superClass)
9497
Qualifiers[qualifier] = qualifiedClass
98+
table.insert(QualifiersArr, qualifiedClass)
9599
end
96100
return qualifiedClass
97101
end
@@ -103,15 +107,11 @@ local function createComponentClass(initializer, superClass)
103107
@return ComponentClass[]
104108
]]
105109
function ComponentClass.Qualifiers(...)
106-
107-
local qualifiers = {}
108-
109110
local filter = {...}
110111
if #filter == 0 then
111-
for _, qualifiedClass in pairs(Qualifiers) do
112-
table.insert(qualifiers, qualifiedClass)
113-
end
112+
return QualifiersArr
114113
else
114+
local qualifiers = {}
115115
local cTypes = {}
116116
for _,qualifier in ipairs({...}) do
117117
local qualifiedClass = ComponentClass.Qualifier(qualifier)
@@ -120,9 +120,8 @@ local function createComponentClass(initializer, superClass)
120120
table.insert(qualifiers, qualifiedClass)
121121
end
122122
end
123+
return qualifiers
123124
end
124-
125-
return qualifiers
126125
end
127126

128127
--[[
@@ -197,63 +196,80 @@ local function createComponentClass(initializer, superClass)
197196
end
198197

199198
--[[
200-
Merges data from the other component into the current component. This method should not be invoked, it is used
201-
by the entity to ensure correct retrieval of a component's qualifiers.
202-
203-
@param other {Component}
199+
Unlink this component with the other qualifiers
204200
]]
205-
function ComponentClass:Merge(other)
206-
if self == other then
201+
function ComponentClass:Detach()
202+
if not superClass.HasQualifier then
207203
return
208204
end
209205

210-
if self._qualifiers == other._qualifiers then
211-
return
212-
end
206+
-- remove old unlink
207+
self._qualifiers[ComponentClass] = nil
213208

214-
if not other:Is(superClass) then
215-
return
216-
end
209+
-- new link
210+
self._qualifiers = { [ComponentClass] = self }
211+
end
217212

218-
local selfClass = ComponentClass
219-
local otherClass = other:GetType()
220-
221-
-- does anyone know the reference to the primary entity?
222-
local primaryQualifiers
223-
if selfClass == superClass then
224-
primaryQualifiers = self._qualifiers
225-
elseif otherClass == superClass then
226-
primaryQualifiers = other._qualifiers
227-
elseif self._qualifiers[superClass] ~= nil then
228-
primaryQualifiers = self._qualifiers[superClass]._qualifiers
229-
elseif other._qualifiers[superClass] ~= nil then
230-
primaryQualifiers = other._qualifiers[superClass]._qualifiers
231-
end
213+
--[[
214+
Merges data from the other component into the current component. This method should not be invoked, it is used
215+
by the entity to ensure correct retrieval of a component's qualifiers.
232216
233-
if primaryQualifiers ~= nil then
234-
if self._qualifiers ~= primaryQualifiers then
235-
for qualifiedClass, component in pairs(self._qualifiers) do
236-
if superClass ~= qualifiedClass then
237-
primaryQualifiers[qualifiedClass] = component
238-
component._qualifiers = primaryQualifiers
217+
@param other {Component}
218+
]]
219+
function ComponentClass:Merge(other)
220+
if superClass.HasQualifier then
221+
if self == other then
222+
return
223+
end
224+
225+
if self._qualifiers == other._qualifiers then
226+
return
227+
end
228+
229+
if not other:Is(superClass) then
230+
return
231+
end
232+
233+
local selfClass = ComponentClass
234+
local otherClass = other:GetType()
235+
236+
-- does anyone know the reference to the primary entity?
237+
local primaryQualifiers
238+
if selfClass == superClass then
239+
primaryQualifiers = self._qualifiers
240+
elseif otherClass == superClass then
241+
primaryQualifiers = other._qualifiers
242+
elseif self._qualifiers[superClass] ~= nil then
243+
primaryQualifiers = self._qualifiers[superClass]._qualifiers
244+
elseif other._qualifiers[superClass] ~= nil then
245+
primaryQualifiers = other._qualifiers[superClass]._qualifiers
246+
end
247+
248+
if primaryQualifiers ~= nil then
249+
if self._qualifiers ~= primaryQualifiers then
250+
for qualifiedClass, component in pairs(self._qualifiers) do
251+
if superClass ~= qualifiedClass then
252+
primaryQualifiers[qualifiedClass] = component
253+
component._qualifiers = primaryQualifiers
254+
end
239255
end
240256
end
241-
end
242-
243-
if other._qualifiers ~= primaryQualifiers then
244-
for qualifiedClass, component in pairs(other._qualifiers) do
245-
if superClass ~= qualifiedClass then
246-
primaryQualifiers[qualifiedClass] = component
247-
component._qualifiers = primaryQualifiers
257+
258+
if other._qualifiers ~= primaryQualifiers then
259+
for qualifiedClass, component in pairs(other._qualifiers) do
260+
if superClass ~= qualifiedClass then
261+
primaryQualifiers[qualifiedClass] = component
262+
component._qualifiers = primaryQualifiers
263+
end
248264
end
249265
end
250-
end
251-
else
252-
-- none of the instances know the Primary, use the current object reference
253-
for qualifiedClass, component in pairs(other._qualifiers) do
254-
if selfClass ~= qualifiedClass then
255-
self._qualifiers[qualifiedClass] = component
256-
component._qualifiers = self._qualifiers
266+
else
267+
-- none of the instances know the Primary, use the current object reference
268+
for qualifiedClass, component in pairs(other._qualifiers) do
269+
if selfClass ~= qualifiedClass then
270+
self._qualifiers[qualifiedClass] = component
271+
component._qualifiers = self._qualifiers
272+
end
257273
end
258274
end
259275
end

src/ECS.lua

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
--[[
2-
ECS-Lua v2.0.0 [2021-10-02 17:25]
2+
ECS Lua v2.0.0 [2021-10-14 18:00]
33
4-
Roblox-ECS is a tiny and easy to use ECS (Entity Component System) engine for
5-
game development on the Roblox platform
4+
ECS Lua is a lua ECS (Entity Component System) library used for game developments.
65
76
https://github.com/nidorx/ecs-lua
87

src/Entity.lua

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,31 @@ local function getComponent(entity, ...)
4040
return table.unpack(components)
4141
end
4242

43+
--[[
44+
Merges the qualifiers of a new added component.
45+
46+
@param entity {Entity}
47+
@param newComponent {Component}
48+
@param newComponentClass {ComponentClass}
49+
]]
50+
local function mergeComponents(entity, newComponent, newComponentClass)
51+
local data = entity._data
52+
local otherComponent
53+
-- get first instance
54+
for _,oCType in ipairs(newComponentClass.Qualifiers()) do
55+
if oCType ~= newComponentClass then
56+
otherComponent = data[oCType]
57+
if otherComponent then
58+
break
59+
end
60+
end
61+
end
62+
63+
if otherComponent then
64+
otherComponent:Merge(newComponent)
65+
end
66+
end
67+
4368
--[[
4469
[SET]
4570
01) entity[CompType1] = nil
@@ -56,34 +81,76 @@ local function setComponent(entity, ...)
5681
local archetypeOld = entity.archetype
5782
local archetypeNew = archetypeOld
5883

84+
local toMerge = {}
85+
5986
local cType = values[1]
60-
if (cType and cType.IsCType and not cType.isComponent) then
87+
if (cType and cType.IsCType and not cType.isComponent) then
6188
local value = values[2]
89+
local component
6290
-- 01) entity[CompType1] = nil
6391
-- 02) entity[CompType1] = value
6492
-- 03) entity:Set(CompType1, nil)
6593
-- 04) entity:Set(CompType1, value)
6694
if value == nil then
95+
local old = data[cType]
96+
if old then
97+
old:Detach()
98+
end
99+
67100
data[cType] = nil
68101
archetypeNew = archetypeNew:Without(cType)
69102

70103
elseif value.isComponent then
71-
cType = value:GetType()
72-
data[cType] = value
73-
archetypeNew = archetypeNew:With(cType)
104+
local old = data[cType]
105+
if (old ~= value) then
106+
if old then
107+
old:Detach()
108+
end
109+
110+
cType = value:GetType()
111+
data[cType] = value
112+
archetypeNew = archetypeNew:With(cType)
74113

114+
-- merge components
115+
if (cType.HasQualifier or cType.IsQualifier) then
116+
mergeComponents(entity, value, cType)
117+
end
118+
end
75119
else
76-
data[cType] = cType(value)
120+
local old = data[cType]
121+
if old then
122+
old:Detach()
123+
end
124+
125+
local component = cType(value)
126+
data[cType] = component
77127
archetypeNew = archetypeNew:With(cType)
128+
129+
-- merge components
130+
if (cType.HasQualifier or cType.IsQualifier) then
131+
mergeComponents(entity, component, cType)
132+
end
78133
end
79134
else
80135
-- 05) entity:Set(comp1)
81136
-- 06) entity:Set(comp1, comp2, ...)
82137
for i,component in ipairs(values) do
83138
if (component.isComponent) then
84-
local ctype = component:GetType()
85-
data[ctype] = component
86-
archetypeNew = archetypeNew:With(ctype)
139+
local cType = component:GetType()
140+
local old = data[cType]
141+
if (old ~= component) then
142+
if old then
143+
old:Detach()
144+
end
145+
146+
data[cType] = component
147+
archetypeNew = archetypeNew:With(cType)
148+
149+
-- merge components
150+
if (cType.HasQualifier or cType.IsQualifier) then
151+
mergeComponents(entity, component, cType)
152+
end
153+
end
87154
end
88155
end
89156
end
@@ -113,13 +180,21 @@ local function unsetComponent(entity, ...)
113180
-- 01) enity:Unset(comp1)
114181
-- 04) enity:Unset(comp1, comp1, ...)
115182
local cType = value:GetType()
183+
local old = data[cType]
184+
if old then
185+
old:Detach()
186+
end
116187
data[cType] = nil
117188
archetypeNew = archetypeNew:Without(cType)
118189

119190
elseif value.IsCType then
120191
-- 02) entity[CompType1] = nil
121192
-- 03) enity:Unset(CompType1)
122193
-- 05) enity:Unset(CompType1, CompType2, ...)
194+
local old = data[value]
195+
if old then
196+
old:Detach()
197+
end
123198
data[value] = nil
124199
archetypeNew = archetypeNew:Without(value)
125200
end

test/test_Component.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,13 @@ function TestComponent:test_Should_CreateQualifier()
163163
lu.assertEquals(buffMission:Qualified("Mission"), buffMission)
164164

165165
-- all
166-
lu.assertEquals(buff:QualifiedAll("Mission"), {
166+
lu.assertEquals(buff:QualifiedAll(), {
167167
["Primary"] = buff, ["Level"] = buffLevel, ["Mission"] = buffMission
168168
})
169-
lu.assertEquals(buffLevel:QualifiedAll("Mission"), {
169+
lu.assertEquals(buffLevel:QualifiedAll(), {
170170
["Primary"] = buff, ["Level"] = buffLevel, ["Mission"] = buffMission
171171
})
172-
lu.assertEquals(buffMission:QualifiedAll("Mission"), {
172+
lu.assertEquals(buffMission:QualifiedAll(), {
173173
["Primary"] = buff, ["Level"] = buffLevel, ["Mission"] = buffMission
174174
})
175175
end

0 commit comments

Comments
 (0)