Skip to content

Instantly share code, notes, and snippets.

@filiptibell
Created September 13, 2025 21:55
Show Gist options
  • Select an option

  • Save filiptibell/efc43ea8ca34ff783452aec6f085da78 to your computer and use it in GitHub Desktop.

Select an option

Save filiptibell/efc43ea8ca34ff783452aec6f085da78 to your computer and use it in GitHub Desktop.
Even more connectors between jecs & vide (raw source, not for direct consumption)
local function createSingleSource<T>(component: ECS.Component<T>, owned: true?): EcsSourceSingle<T>
local currentId, currentVal
if owned == true then
currentId, currentVal = W:Find(component, NetworkOwned)
else
currentId, currentVal = W:Find(component)
end
local src: VIDE.Source<T?> = VIDE.Source(currentVal)
local function onChanged(id: ECS.Entity)
if currentId ~= nil and currentId == id then
-- The currently tracked entity changed
local val = W:Get(id, component)
if currentVal ~= val then
currentVal = val
pendingSingles[src] = if currentVal == nil then NONE else currentVal
end
elseif currentId ~= nil and currentId ~= id then
-- An entity different than the currently tracked changed,
-- don't override the value unless this new entity is owned
-- or ownership is simply not required for this value source
if owned ~= true or W:Has(id, NetworkOwned) then
local val = W:Get(id, component)
if currentVal ~= val then
currentVal = val
currentId = id
pendingSingles[src] = if currentVal == nil then NONE else currentVal
end
end
else
-- We don't have any currently tracked entity, and might
-- want to start tracking this entity and its value changes
local val = if owned ~= true or W:Has(id, NetworkOwned)
then W:Get(id, component)
else nil
if currentVal ~= val or (currentId == nil and val ~= nil) then
currentVal = val
if val ~= nil then
currentId = id
end
pendingSingles[src] = if currentVal == nil then NONE else currentVal
end
end
end
local function onRemoved(id: ECS.Entity)
-- If the component or NetworkOwned was removed for the currently tracked
-- entity, we should stop tracking it, and try to track another entity
-- Note that we have to manually check that the "other" entity is not the one
-- that was just removed, since OnRemove is called *before* the entity is destroyed
if currentId == id then
currentId = nil
currentVal = nil
if owned == true then
for otherId, otherVal in W:Query(component, NetworkOwned) do
if otherId ~= id then
currentId = otherId
currentVal = otherVal
end
end
else
for otherId, otherVal in W:Query(component) do
if otherId ~= id then
currentId = otherId
currentVal = otherVal
end
end
end
pendingSingles[src] = if currentVal == nil then NONE else currentVal
end
end
W:OnAdd(component, onChanged)
W:OnChange(component, onChanged)
W:OnRemove(component, onRemoved)
if owned == true then
W:OnAdd(NetworkOwned, onChanged)
W:OnChange(NetworkOwned, onChanged)
W:OnRemove(NetworkOwned, onRemoved)
end
return src
end
local function createMultiSource<T>(component: ECS.Component<T>, owned: true?): EcsSourceMulti<T>
local map: IdMap<T> = {}
if owned == true then
for id, value in W:Query(component, NetworkOwned) do
map[id] = value
end
else
for id, value in W:Query(component) do
map[id] = value
end
end
local src: VIDE.Source<IdMap<T>> = VIDE.Source(table.clone(map))
local function onChanged(id: ECS.Entity)
if owned ~= true or W:Has(id, NetworkOwned) then
-- Entity qualifies - add to, or update current value in map
local value = W:Get(id, component)
if map[id] ~= value then
map[id] = value
pendingMultis[src] = map
end
else
-- Entity doesn't meet "owned" requirements anymore - remove if tracked
if map[id] ~= nil then
map[id] = nil
pendingMultis[src] = map
end
end
end
local function onRemoved(id: ECS.Entity)
-- Remove entity from tracking regardless of which
-- component (T or NetworkOwned tag) was removed
if map[id] ~= nil then
map[id] = nil
pendingMultis[src] = map
end
end
W:OnAdd(component, onChanged)
W:OnChange(component, onChanged)
W:OnRemove(component, onRemoved)
if owned == true then
W:OnAdd(NetworkOwned, onChanged)
W:OnChange(NetworkOwned, onChanged)
W:OnRemove(NetworkOwned, onRemoved)
end
return src
end
local function createTagSource(tag: ECS.Tag, owned: true?): EcsSourceTag
local set: IdMap = {}
if owned == true then
for id in W:Query(tag, NetworkOwned) do
set[id] = true
end
else
for id in W:Query(tag) do
set[id] = true
end
end
local src: VIDE.Source<IdMap> = VIDE.Source(table.clone(set))
local function onAdded(id: ECS.Entity)
if W:Has(id, tag) and (owned ~= true or W:Has(id, NetworkOwned)) then
-- Entity qualifies - has the tag AND meets "owned" requirement
if set[id] ~= true then
set[id] = true
pendingTags[src] = set
end
end
end
local function onRemoved(id: ECS.Entity)
-- Remove entity from set regardless of which
-- component (tag or NetworkOwned) was removed
if set[id] ~= nil then
set[id] = nil
pendingTags[src] = set
end
end
W:OnAdd(tag, onAdded)
W:OnRemove(tag, onRemoved)
if owned == true then
W:OnAdd(NetworkOwned, onAdded)
W:OnRemove(NetworkOwned, onRemoved)
end
return src
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment