--[[ ECS SystemFilter class @author : Eiyeron Fulmincendii A SystemFilter is just an internal class to avoid multiplying the same requirement list for every System. Instead of blindly storing the given requirement lists on World's side, this class intends to store all Systems that share the same component requirement list. ]]-- local class = require("class") local object = require("object") local utils = require("utils") local SystemFilter = class(object) function SystemFilter:init(required_components) self.required_components = required_components self.systems = {} self.registered_entries = {} end --[[ Called by World to register an entity for the systems to process it. ]]-- function SystemFilter:registerEntry(entity) local index = #self.registered_entries+1 for i,reg in ipairs(self.registered_entries) do if not reg then index = i break end end self.registered_entries[index] = entity end --[[ Called by World to unregister an entity. ]]-- function SystemFilter:unregisterEntry(entity) for i,entity in ipairs(self.registered_entries) do if entity.__eid == entity.__eid then self.registered_entries[i] = nil return end end end function SystemFilter:hasEntity(entity) for _,current_entity in ipairs(self.registered_entries) do if current_entity.__eid == entity.__eid then return true end end return false end --[[ Called by World to register a compatible system. ]]-- function SystemFilter:registerSystem(system) if not self.systems[system.__sid] then self.systems[system.__sid] = system return true end return false end --[[ Checks if the givent component list matches the current filter's list. Warning : it requires the list to be sorted for now. ]] function SystemFilter:compareComponentList(component_list) if #component_list ~= #self.required_components then return false end -- Compare every registered system for j=0,#self.required_components do if component_list[j] ~= self.required_components[j] then return false end end return true end --[[ Returns true if the entity has all the components for the current filter. ]] function SystemFilter:checkEntityCompatibility(entity) local num_valid_components = 0 for i,component in ipairs(self.required_components) do if entity:hasComponent(component) then num_valid_components = num_valid_components + 1 end end return num_valid_components == #self.required_components end --[[ Called by world to dispatch the update event to the systems. ]] function SystemFilter:update(dt) for j,system in ipairs(self.systems) do system.update(dt, self.registered_entries) end end return SystemFilter