Skip to content

Commit

Permalink
Versioning
Browse files Browse the repository at this point in the history
  • Loading branch information
nidorx committed Oct 14, 2021
1 parent e628607 commit 3226ef1
Show file tree
Hide file tree
Showing 8 changed files with 530 additions and 181 deletions.
9 changes: 4 additions & 5 deletions ECS.lua

Large diffs are not rendered by default.

293 changes: 190 additions & 103 deletions ECS_concat.lua

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ local SRC_FILES = {
}

local HEADER = [[
ECS-Lua v2.0.0 [2021-10-02 17:25]
ECS Lua v2.0.0 [2021-10-14 18:00]
ECS-Lua is a tiny and easy to use ECS (Entity Component System) engine for
game development
ECS Lua is a lua ECS (Entity Component System) library used for game developments.
This is a minified version of ECS-Lua, to see the full source code visit
This is a minified version of ECS Lua, to see the full source code visit
https://github.com/nidorx/ecs-lua
------------------------------------------------------------------------------
Expand Down
126 changes: 71 additions & 55 deletions src/Component.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ local function createComponentClass(initializer, superClass)
if superClass == nil then
superClass = ComponentClass
superClass._Qualifiers = { ["Primary"] = ComponentClass }
superClass._QualifiersArr = { ComponentClass }
superClass._Initializers = {}
else
superClass.HasQualifier = true
ComponentClass.IsQualifier = true
end

local Qualifiers = superClass._Qualifiers
local QualifiersArr = superClass._QualifiersArr

setmetatable(ComponentClass, {
__call = function(t, value)
Expand Down Expand Up @@ -80,7 +83,7 @@ local function createComponentClass(initializer, superClass)
]]
function ComponentClass.Qualifier(qualifier)
if type(qualifier) ~= "string" then
for _, qualifiedClass in pairs(Qualifiers) do
for _, qualifiedClass in ipairs(QualifiersArr) do
if qualifiedClass == qualifier then
return qualifier
end
Expand All @@ -92,6 +95,7 @@ local function createComponentClass(initializer, superClass)
if qualifiedClass == nil then
qualifiedClass = createComponentClass(initializer, superClass)
Qualifiers[qualifier] = qualifiedClass
table.insert(QualifiersArr, qualifiedClass)
end
return qualifiedClass
end
Expand All @@ -103,15 +107,11 @@ local function createComponentClass(initializer, superClass)
@return ComponentClass[]
]]
function ComponentClass.Qualifiers(...)

local qualifiers = {}

local filter = {...}
if #filter == 0 then
for _, qualifiedClass in pairs(Qualifiers) do
table.insert(qualifiers, qualifiedClass)
end
return QualifiersArr
else
local qualifiers = {}
local cTypes = {}
for _,qualifier in ipairs({...}) do
local qualifiedClass = ComponentClass.Qualifier(qualifier)
Expand All @@ -120,9 +120,8 @@ local function createComponentClass(initializer, superClass)
table.insert(qualifiers, qualifiedClass)
end
end
return qualifiers
end

return qualifiers
end

--[[
Expand Down Expand Up @@ -197,63 +196,80 @@ local function createComponentClass(initializer, superClass)
end

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

if self._qualifiers == other._qualifiers then
return
end
-- remove old unlink
self._qualifiers[ComponentClass] = nil

if not other:Is(superClass) then
return
end
-- new link
self._qualifiers = { [ComponentClass] = self }
end

local selfClass = ComponentClass
local otherClass = other:GetType()

-- does anyone know the reference to the primary entity?
local primaryQualifiers
if selfClass == superClass then
primaryQualifiers = self._qualifiers
elseif otherClass == superClass then
primaryQualifiers = other._qualifiers
elseif self._qualifiers[superClass] ~= nil then
primaryQualifiers = self._qualifiers[superClass]._qualifiers
elseif other._qualifiers[superClass] ~= nil then
primaryQualifiers = other._qualifiers[superClass]._qualifiers
end
--[[
Merges data from the other component into the current component. This method should not be invoked, it is used
by the entity to ensure correct retrieval of a component's qualifiers.
if primaryQualifiers ~= nil then
if self._qualifiers ~= primaryQualifiers then
for qualifiedClass, component in pairs(self._qualifiers) do
if superClass ~= qualifiedClass then
primaryQualifiers[qualifiedClass] = component
component._qualifiers = primaryQualifiers
@param other {Component}
]]
function ComponentClass:Merge(other)
if superClass.HasQualifier then
if self == other then
return
end

if self._qualifiers == other._qualifiers then
return
end

if not other:Is(superClass) then
return
end

local selfClass = ComponentClass
local otherClass = other:GetType()

-- does anyone know the reference to the primary entity?
local primaryQualifiers
if selfClass == superClass then
primaryQualifiers = self._qualifiers
elseif otherClass == superClass then
primaryQualifiers = other._qualifiers
elseif self._qualifiers[superClass] ~= nil then
primaryQualifiers = self._qualifiers[superClass]._qualifiers
elseif other._qualifiers[superClass] ~= nil then
primaryQualifiers = other._qualifiers[superClass]._qualifiers
end

if primaryQualifiers ~= nil then
if self._qualifiers ~= primaryQualifiers then
for qualifiedClass, component in pairs(self._qualifiers) do
if superClass ~= qualifiedClass then
primaryQualifiers[qualifiedClass] = component
component._qualifiers = primaryQualifiers
end
end
end
end

if other._qualifiers ~= primaryQualifiers then
for qualifiedClass, component in pairs(other._qualifiers) do
if superClass ~= qualifiedClass then
primaryQualifiers[qualifiedClass] = component
component._qualifiers = primaryQualifiers

if other._qualifiers ~= primaryQualifiers then
for qualifiedClass, component in pairs(other._qualifiers) do
if superClass ~= qualifiedClass then
primaryQualifiers[qualifiedClass] = component
component._qualifiers = primaryQualifiers
end
end
end
end
else
-- none of the instances know the Primary, use the current object reference
for qualifiedClass, component in pairs(other._qualifiers) do
if selfClass ~= qualifiedClass then
self._qualifiers[qualifiedClass] = component
component._qualifiers = self._qualifiers
else
-- none of the instances know the Primary, use the current object reference
for qualifiedClass, component in pairs(other._qualifiers) do
if selfClass ~= qualifiedClass then
self._qualifiers[qualifiedClass] = component
component._qualifiers = self._qualifiers
end
end
end
end
Expand Down
5 changes: 2 additions & 3 deletions src/ECS.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
--[[
ECS-Lua v2.0.0 [2021-10-02 17:25]
ECS Lua v2.0.0 [2021-10-14 18:00]
Roblox-ECS is a tiny and easy to use ECS (Entity Component System) engine for
game development on the Roblox platform
ECS Lua is a lua ECS (Entity Component System) library used for game developments.
https://github.com/nidorx/ecs-lua
Expand Down
91 changes: 83 additions & 8 deletions src/Entity.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,31 @@ local function getComponent(entity, ...)
return table.unpack(components)
end

--[[
Merges the qualifiers of a new added component.
@param entity {Entity}
@param newComponent {Component}
@param newComponentClass {ComponentClass}
]]
local function mergeComponents(entity, newComponent, newComponentClass)
local data = entity._data
local otherComponent
-- get first instance
for _,oCType in ipairs(newComponentClass.Qualifiers()) do
if oCType ~= newComponentClass then
otherComponent = data[oCType]
if otherComponent then
break
end
end
end

if otherComponent then
otherComponent:Merge(newComponent)
end
end

--[[
[SET]
01) entity[CompType1] = nil
Expand All @@ -56,34 +81,76 @@ local function setComponent(entity, ...)
local archetypeOld = entity.archetype
local archetypeNew = archetypeOld

local toMerge = {}

local cType = values[1]
if (cType and cType.IsCType and not cType.isComponent) then
if (cType and cType.IsCType and not cType.isComponent) then
local value = values[2]
local component
-- 01) entity[CompType1] = nil
-- 02) entity[CompType1] = value
-- 03) entity:Set(CompType1, nil)
-- 04) entity:Set(CompType1, value)
if value == nil then
local old = data[cType]
if old then
old:Detach()
end

data[cType] = nil
archetypeNew = archetypeNew:Without(cType)

elseif value.isComponent then
cType = value:GetType()
data[cType] = value
archetypeNew = archetypeNew:With(cType)
local old = data[cType]
if (old ~= value) then
if old then
old:Detach()
end

cType = value:GetType()
data[cType] = value
archetypeNew = archetypeNew:With(cType)

-- merge components
if (cType.HasQualifier or cType.IsQualifier) then
mergeComponents(entity, value, cType)
end
end
else
data[cType] = cType(value)
local old = data[cType]
if old then
old:Detach()
end

local component = cType(value)
data[cType] = component
archetypeNew = archetypeNew:With(cType)

-- merge components
if (cType.HasQualifier or cType.IsQualifier) then
mergeComponents(entity, component, cType)
end
end
else
-- 05) entity:Set(comp1)
-- 06) entity:Set(comp1, comp2, ...)
for i,component in ipairs(values) do
if (component.isComponent) then
local ctype = component:GetType()
data[ctype] = component
archetypeNew = archetypeNew:With(ctype)
local cType = component:GetType()
local old = data[cType]
if (old ~= component) then
if old then
old:Detach()
end

data[cType] = component
archetypeNew = archetypeNew:With(cType)

-- merge components
if (cType.HasQualifier or cType.IsQualifier) then
mergeComponents(entity, component, cType)
end
end
end
end
end
Expand Down Expand Up @@ -113,13 +180,21 @@ local function unsetComponent(entity, ...)
-- 01) enity:Unset(comp1)
-- 04) enity:Unset(comp1, comp1, ...)
local cType = value:GetType()
local old = data[cType]
if old then
old:Detach()
end
data[cType] = nil
archetypeNew = archetypeNew:Without(cType)

elseif value.IsCType then
-- 02) entity[CompType1] = nil
-- 03) enity:Unset(CompType1)
-- 05) enity:Unset(CompType1, CompType2, ...)
local old = data[value]
if old then
old:Detach()
end
data[value] = nil
archetypeNew = archetypeNew:Without(value)
end
Expand Down
6 changes: 3 additions & 3 deletions test/test_Component.lua
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,13 @@ function TestComponent:test_Should_CreateQualifier()
lu.assertEquals(buffMission:Qualified("Mission"), buffMission)

-- all
lu.assertEquals(buff:QualifiedAll("Mission"), {
lu.assertEquals(buff:QualifiedAll(), {
["Primary"] = buff, ["Level"] = buffLevel, ["Mission"] = buffMission
})
lu.assertEquals(buffLevel:QualifiedAll("Mission"), {
lu.assertEquals(buffLevel:QualifiedAll(), {
["Primary"] = buff, ["Level"] = buffLevel, ["Mission"] = buffMission
})
lu.assertEquals(buffMission:QualifiedAll("Mission"), {
lu.assertEquals(buffMission:QualifiedAll(), {
["Primary"] = buff, ["Level"] = buffLevel, ["Mission"] = buffMission
})
end
Expand Down
Loading

0 comments on commit 3226ef1

Please sign in to comment.