Skip to content
38 changes: 35 additions & 3 deletions lua/entities/gmod_wire_expression2/core/custom/prop.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1460,10 +1460,10 @@ e2function number trackCollision( entity ent )
if self.data.E2TrackedCollisions[entIndex] then
return self:throw("Attempting to track collisions for an already tracked entity",0) -- Already being tracked.
end
local chip = self.entity
local ctx = self
local callbackID = ent:AddCallback("PhysicsCollide",
function( us, cd )
chip:ExecuteEvent("entityCollision",{us,cd.HitEntity,cd})
table.insert(ctx.data.E2QueuedCollisions,{us=us,xcd=cd})
end)
self.data.E2TrackedCollisions[entIndex] = callbackID -- This ID is needed to remove the physcollide callback
ent:CallOnRemove("E2Chip_CCB" .. callbackID, function()
Expand Down Expand Up @@ -1503,8 +1503,11 @@ e2function void stopTrackingCollision( entity ent )
end
end

local registered_chips = {}

registerCallback("construct", function( self )
self.data.E2TrackedCollisions = {}
self.data.E2QueuedCollisions = {}
end)

registerCallback("destruct", function( self )
Expand All @@ -1517,8 +1520,37 @@ registerCallback("destruct", function( self )
end
end)



E2Lib.registerEvent("entityCollision", {
{"Entity", "e"},
{"HitEntity", "e"},
{"CollisionData", "xcd"},
})
},
function(ctx) -- Event constructor
registered_chips[ctx.entity] = ctx
end,
function(ctx) -- Event destructor
registered_chips[ctx.entity] = nil
end
)

local function E2CollisionEventHandler()
for chip,ctx in pairs(registered_chips) do
if IsValid(chip) then
if not chip.error then
for _,i in ipairs(ctx.data.E2QueuedCollisions) do
chip:ExecuteEvent("entityCollision",{i.us,i.xcd.HitEntity,i.xcd})
if chip.error then break end
end
end
-- Wipe queued collisions regardless of error
ctx.data.E2QueuedCollisions = {}
end
end
end

hook.Add("Think", "Expression2CollisionClock", E2CollisionEventHandler)
timer.Create("Expression2CollisionClock", 5, 0, function()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this timer exist. You should add the think hook when a collision is queued and remove it after it runs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So like, the function I have right now is fine, just have it added on a collision and have it hook.remove itself after run?
Or do you want a unique hook generated for each chip / collision to run the event once for that single event?

Is there a big cost to hook.add overwriting a pre-existing hook that might make it worth storing a bool for the hooks existence locally to check against?

On the matter of the timer, I figured it was a failsafe for the e2 tick hook getting cleared during load but if we shift away from the check being every think to just the think after a collision the timer can definitely go.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even better is

if not var then
    var = true
    timer.Simple(0,function()
        processCollisions()
        var = false
    end)
end

hook.Add("Think", "Expression2CollisionClock", E2CollisionEventHandler)
end)