Discarded entityactions and updated target
Discarded entityactions: was not used and bloat. Need a new system that handled networked entities static vs dynamic (non-moving non networked vs moving networked) updated target to improve performance on canInteract. It seems that the target systems spam this function. Using a state and checking every second instead of allowing spamming Added ClientEntity.ChangeModel
This commit is contained in:
1 parent
cbd340326d
commit
b06d2fb49e
8 files changed
+73
-190
No files matched your search
@@ -1,7 +1,6 @@
|
||||
Utility = Utility or Require("lib/utility/client/utility.lua")
|
||||
Ids = Ids or Require("lib/utility/shared/ids.lua")
|
||||
Point = Point or Require("lib/points/client/points.lua")
|
||||
ClientEntityActions = ClientEntityActions or Require("lib/entities/client/client_entity_actions_ext.lua") -- Added
|
||||
|
||||
local Entities = {} -- Stores entity data received from server
|
||||
ClientEntity = {} -- Renamed from BaseEntity
|
||||
@@ -86,8 +85,6 @@ end
|
||||
-- Depricated use ClientEntity.CreateBulk instead
|
||||
ClientEntity.RegisterBulk = ClientEntity.CreateBulk
|
||||
|
||||
|
||||
|
||||
--- Unregisters an entity and removes it from the world if spawned.
|
||||
-- @param id string|number The ID of the entity to unregister.
|
||||
function ClientEntity.Destroy(id)
|
||||
@@ -100,7 +97,6 @@ function ClientEntity.Destroy(id)
|
||||
end
|
||||
ClientEntity.Unregister = ClientEntity.Destroy
|
||||
|
||||
|
||||
--- Updates the data for a registered entity.
|
||||
-- @param id string|number The ID of the entity to update.
|
||||
-- @param data table The data fields to update.
|
||||
@@ -165,10 +161,6 @@ function ClientEntity.GetAll()
|
||||
return Entities
|
||||
end
|
||||
|
||||
function ClientEntity.RegisterAction(name, func)
|
||||
ClientEntityActions.RegisterAction(name, func)
|
||||
end
|
||||
|
||||
function ClientEntity.OnCreate(_type, func)
|
||||
ClientEntity.OnCreates = ClientEntity.OnCreates or {}
|
||||
if not ClientEntity.OnCreates[_type] then
|
||||
@@ -203,11 +195,22 @@ function ClientEntity.UpdateCoords(id, coords)
|
||||
end
|
||||
entityData.coords = coords
|
||||
Point.UpdateCoords(id, coords)
|
||||
if entityData.spawned and DoesEntityExist(entityData.spawned) then
|
||||
SetEntityCoords(entityData.spawned, coords.x, coords.y, coords.z, false, false, false, true)
|
||||
end
|
||||
if not entityData.spawned or not DoesEntityExist(entityData.spawned) then return end
|
||||
SetEntityCoords(entityData.spawned, coords.x, coords.y, coords.z, false, false, false, true)
|
||||
end
|
||||
|
||||
function ClientEntity.ChangeModel(id, model)
|
||||
local entityData = Entities[id]
|
||||
if not entityData then return print(string.format("[ClientEntity] ChangeModel: Entity %s does not exist", id)) end
|
||||
|
||||
entityData.model = model
|
||||
if not entityData.spawned or not DoesEntityExist(entityData.spawned) then return end
|
||||
|
||||
RemoveEntity(entityData)
|
||||
SpawnEntity(entityData)
|
||||
end
|
||||
|
||||
|
||||
-- Network Event Handlers
|
||||
RegisterNetEvent("community_bridge:client:CreateEntity", function(entityData)
|
||||
ClientEntity.Create(entityData)
|
||||
@@ -225,46 +228,6 @@ RegisterNetEvent("community_bridge:client:UpdateEntity", function(id, data)
|
||||
ClientEntity.Update(id, data)
|
||||
end)
|
||||
|
||||
-- New handler for entity actions
|
||||
RegisterNetEvent("community_bridge:client:TriggerEntityAction", function(entityId, actionName, ...)
|
||||
local entityData = Entities[entityId]
|
||||
-- Check if entity exists locally (it doesn't need to be spawned to queue actions)
|
||||
if entityData then
|
||||
if actionName == "Stop" then
|
||||
ClientEntityActions.StopAction(entityId)
|
||||
elseif actionName == "Skip" then
|
||||
ClientEntityActions.SkipAction(entityId)
|
||||
else
|
||||
print(string.format("[ClientEntity] Triggering action '%s' for entity %s", actionName, entityId))
|
||||
local currentAction = ClientEntityActions.ActionQueue[entityId] and ClientEntityActions.ActionQueue[entityId][1]
|
||||
ClientEntityActions.QueueAction(entityData, actionName, ...)
|
||||
end
|
||||
-- else
|
||||
-- Optional: Log if action received but entity doesn't exist locally at all
|
||||
-- print(string.format("[ClientEntity] Received action '%s' for non-existent entity %s.", actionName, entityId))
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("community_bridge:client:TriggerEntityActions", function(entityId, actions, endPosition)
|
||||
local entityData = Entities[entityId]
|
||||
if entityData then
|
||||
for _, actionData in pairs(actions) do
|
||||
local actionName = actionData.name
|
||||
local actionParams = actionData.params
|
||||
if actionName == "Stop" then
|
||||
ClientEntityActions.StopAction(entityId)
|
||||
elseif actionName == "Skip" then
|
||||
ClientEntityActions.SkipAction(entityId)
|
||||
else
|
||||
local currentAction = ClientEntityActions.ActionQueue[entityId] and ClientEntityActions.ActionQueue[entityId][1]
|
||||
ClientEntityActions.QueueAction(entityData, actionName, table.unpack(actionParams))
|
||||
end
|
||||
end
|
||||
else
|
||||
print(string.format("[ClientEntity] Received actions for non-existent entity %s.", entityId))
|
||||
end
|
||||
end)
|
||||
|
||||
-- Resource Stop Cleanup
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if resourceName == GetCurrentResourceName() then
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
|
||||
|
||||
ClientEntityActions = {}
|
||||
ClientEntityActions.ActionThreads = {} -- Store running action threads { [entityId] = thread }
|
||||
ClientEntityActions.ActionQueue = {} -- Stores pending actions { [entityId] = {{name="ActionName", args={...}}, ...} }
|
||||
ClientEntityActions.IsActionRunning = {} -- Tracks if an action is currently running { [entityId] = boolean }
|
||||
ClientEntityActions.RegisteredActions = {} -- New: Registry for action implementations { [actionName] = function(entityData, ...) }
|
||||
-- Forward declaration
|
||||
|
||||
|
||||
--- Processes the next action in the queue for a given entity.
|
||||
-- @param entityId string|number The ID of the entity.
|
||||
function ClientEntityActions.ProcessNextAction(entityId)
|
||||
if ClientEntityActions.IsActionRunning [entityId] then return end -- Already running something
|
||||
local queue = ClientEntityActions.ActionQueue[entityId]
|
||||
if not queue or #queue == 0 then return end -- Queue is empty
|
||||
|
||||
local nextAction = table.remove(queue, 1) -- Dequeue (FIFO)
|
||||
local entityData = ClientEntity.Get(entityId) -- Assumes ClientEntity is accessible
|
||||
-- Check if entity is still valid and spawned before starting next action
|
||||
if not entityData or not entityData.spawned or not DoesEntityExist(entityData.spawned) then
|
||||
-- Entity despawned while idle, clear queue and do nothing
|
||||
ClientEntityActions.ActionQueue[entityId] = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- Look up the action in the registry
|
||||
local actionFunc = ClientEntityActions.RegisteredActions [nextAction.name]
|
||||
if actionFunc then
|
||||
-- print(string.format("[ClientEntityActions] Starting action '%s' for entity %s", nextAction.name, entityId))
|
||||
ClientEntityActions.IsActionRunning [entityId] = true
|
||||
-- Call the registered function
|
||||
ClientEntityActions.ActionQueue[entityId] = actionFunc(entityData, table.unpack(nextAction.args))
|
||||
if not ClientEntityActions.ActionQueue[entityId] then
|
||||
-- If the action function doesn't return a queue, set it to nil
|
||||
ClientEntityActions.IsActionRunning[entityId] = false
|
||||
ClientEntityActions.ProcessNextAction(entityId) -- Try next action if this one failed immediately
|
||||
end
|
||||
else
|
||||
print(string.format("[ClientEntityActions] Unknown action '%s' dequeued for entity %s", nextAction.name, entityId))
|
||||
-- Skip unknown action and try the next one immediately
|
||||
ClientEntityActions.ActionQueue[entityId] = ClientEntityActions.ProcessNextAction(entityId)
|
||||
end
|
||||
end
|
||||
--- Registers a custom action implementation.
|
||||
-- The action function should handle its own logic, including threading if needed,
|
||||
-- and MUST call ClientEntityActions.ProcessNextAction(entityData.id) when it completes or fails,
|
||||
-- after setting ClientEntityActions.IsActionRunning [entityData.id] = false.
|
||||
-- @param actionName string The name used to trigger this action.
|
||||
-- @param actionFunc function The function to execute. Signature: function(entityData, ...)
|
||||
function ClientEntityActions.RegisterAction(actionName, actionFunc)
|
||||
if ClientEntityActions.RegisteredActions [actionName] then
|
||||
print(string.format("[ClientEntityActions] WARNING: Overwriting registered action '%s'", actionName))
|
||||
end
|
||||
assert(type(actionName) == "string", "actionName must be a string")
|
||||
ClientEntityActions.RegisteredActions[actionName] = actionFunc
|
||||
-- print(string.format("[ClientEntityActions] Registered action: %s", actionName))
|
||||
end
|
||||
|
||||
--- Queues an action for an entity. Starts processing if idle.
|
||||
-- @param entityData table The entity data.
|
||||
-- @param actionName string The name of the action.
|
||||
-- @param ... any Arguments for the action.
|
||||
function ClientEntityActions.QueueAction(entityData, actionName, ...)
|
||||
local entityId = entityData.id
|
||||
if not ClientEntityActions.ActionQueue[entityId] then
|
||||
ClientEntityActions.ActionQueue[entityId] = {}
|
||||
end
|
||||
|
||||
local actionArgs = {...}
|
||||
table.insert(ClientEntityActions.ActionQueue[entityId], { name = actionName, args = actionArgs })
|
||||
-- print(string.format("[ClientEntityActions] Queued action '%s' for entity %s. Queue size: %d", actionName, entityId, #ClientEntityActions.ActionQueue[entityId]))
|
||||
|
||||
-- If the entity isn't currently doing anything, start processing immediately
|
||||
if not ClientEntityActions.IsActionRunning [entityId] then
|
||||
ClientEntityActions.ProcessNextAction(entityId)
|
||||
end
|
||||
end
|
||||
--- Stops the current action and clears the queue for a specific entity.
|
||||
-- @param entityId string|number The ID of the entity.
|
||||
function ClientEntityActions.StopAction(entityId)
|
||||
-- print(string.format("[ClientEntityActions] Stopping all actions for entity %s", entityId))
|
||||
ClientEntityActions.ActionQueue[entityId] = nil -- Clear the queue
|
||||
ClientEntityActions.IsActionRunning [entityId] = false -- Mark as not running (this will stop loops in threads)
|
||||
|
||||
-- Stop current task/thread if applicable
|
||||
if ClientEntityActions.ActionThreads[entityId] then
|
||||
-- Lua threads stop themselves based on ClientEntityActions.IsActionRunning flag
|
||||
ClientEntityActions.ActionThreads[entityId] = nil
|
||||
end
|
||||
|
||||
-- Specific task clearing for peds
|
||||
local entityData = ClientEntity.Get(entityId)
|
||||
if entityData and entityData.spawned and DoesEntityExist(entityData.spawned) then
|
||||
if IsEntityAPed(entityData.spawned) then
|
||||
ClearPedTasksImmediately(entityData.spawned) -- Use Immediately for forceful stop
|
||||
end
|
||||
-- Other entity types might need different stop logic
|
||||
end
|
||||
end
|
||||
--- Skips the current action and starts the next one in the queue, if any.
|
||||
-- @param entityId string|number The ID of the entity.
|
||||
function ClientEntityActions.SkipAction(entityId)
|
||||
if not ClientEntityActions.IsActionRunning [entityId] then
|
||||
-- print(string.format("[ClientEntityActions] SkipAction called for %s, but no action running.", entityId))
|
||||
return -- Nothing to skip
|
||||
end
|
||||
-- print(string.format("[ClientEntityActions] Skipping current action for entity %s", entityId))
|
||||
|
||||
ClientEntityActions.IsActionRunning [entityId] = false -- Mark as not running (this will stop loops in threads)
|
||||
|
||||
-- Stop current task/thread if applicable
|
||||
if ClientEntityActions.ActionThreads[entityId] then
|
||||
ClientEntityActions.ActionThreads[entityId] = nil
|
||||
end
|
||||
|
||||
local entityData = ClientEntity.Get(entityId)
|
||||
if entityData and entityData.spawned and DoesEntityExist(entityData.spawned) then
|
||||
if IsEntityAPed(entityData.spawned) then
|
||||
ClearPedTasksImmediately(entityData.spawned)
|
||||
end
|
||||
end
|
||||
|
||||
-- Immediately try to process the next action
|
||||
ClientEntityActions.ProcessNextAction(entityId)
|
||||
end
|
||||
-- Add server-callable functions for Stop and Skip
|
||||
function ClientEntityActions.Stop(entityData)
|
||||
ClientEntityActions.StopAction(entityData.id)
|
||||
end
|
||||
|
||||
function ClientEntityActions.Skip(entityData)
|
||||
ClientEntityActions.SkipAction(entityData.id)
|
||||
end
|
||||
|
||||
return ClientEntityActions
|
||||
@@ -29,7 +29,6 @@ end
|
||||
function ServerEntity.Create(id, entityType, model, coords, rotation, meta)
|
||||
local self = ServerEntity.New(id, entityType, model, coords, rotation, meta)
|
||||
if not self then
|
||||
-- print("Failed to create entity with ID: " .. tostring(id))
|
||||
return nil
|
||||
end
|
||||
TriggerClientEvent("community_bridge:client:CreateEntity", -1, self)
|
||||
|
||||
@@ -76,7 +76,6 @@ cLib.Point = Point or Require("lib/points/client/pointsv2.lua")
|
||||
cLib.Particle = Particle or Require("lib/particles/client/particles.lua")
|
||||
cLib.Cache = Cache or Require("lib/cache/client/cache.lua")
|
||||
cLib.ClientEntity = ClientEntity or Require("lib/entities/client/client_entity.lua")
|
||||
cLib.ClientEntityActions = ClientEntityActions or Require("lib/entities/client/client_entity_actions.lua")
|
||||
cLib.ClientStateBag = ClientStateBag or Require("lib/statebags/client/client.lua")
|
||||
cLib.Marker = Marker or Require("lib/markers/client/markers.lua")
|
||||
cLib.Anim = Anim or Require("lib/anim/client/client.lua")
|
||||
|
||||
@@ -1,9 +1,40 @@
|
||||
---@diagnostic disable: duplicate-set-field
|
||||
Target = Target or {}
|
||||
Ids = Ids or Require("lib/utility/shared/ids.lua")
|
||||
|
||||
local function warnUser()
|
||||
print("Currently Only Targeting Is Supported By Community Bridge, You Are Using A Resource That Requires The Target Module To Be Used.")
|
||||
end
|
||||
local InteractIds = {}
|
||||
|
||||
Target.GetCanInteract = function(id)
|
||||
return InteractIds[id]
|
||||
end
|
||||
|
||||
Target.CreateCanInteract = function(cb)
|
||||
if not cb then return end
|
||||
local id = Ids.CreateUniqueId(InteractIds)
|
||||
InteractIds[id] = {
|
||||
id = id,
|
||||
ableToInteract = -1,
|
||||
onInteract = cb
|
||||
}
|
||||
return id
|
||||
end
|
||||
|
||||
Target.CanInteract = function(id, ...)
|
||||
local interactData = InteractIds[id]
|
||||
if not interactData then return true end
|
||||
if interactData.ableToInteract == -1 then
|
||||
local cb = interactData.onInteract
|
||||
local canInteractStatus = cb(...)
|
||||
interactData.ableToInteract = canInteractStatus and 1 or 0
|
||||
SetTimeout(1000, function()
|
||||
interactData.ableToInteract = -1
|
||||
end)
|
||||
end
|
||||
return interactData.ableToInteract > 0
|
||||
end
|
||||
|
||||
Target.FixOptions = function(options)
|
||||
for k, v in pairs(options) do
|
||||
@@ -15,6 +46,13 @@ Target.FixOptions = function(options)
|
||||
return action(entityOrData)
|
||||
end
|
||||
options[k].onSelect = select
|
||||
local optionsCanInteract = v.canInteract
|
||||
if optionsCanInteract then
|
||||
local id = Target.CreateCanInteract(optionsCanInteract)
|
||||
v.canInteract = function(...)
|
||||
return Target.CanInteract(id, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
return options
|
||||
end
|
||||
@@ -78,7 +116,6 @@ Target.AddLocalEntity = function(entities, _options)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Target.AddModel = function(models, options)
|
||||
warnUser()
|
||||
end
|
||||
|
||||
@@ -40,6 +40,13 @@ Target.FixOptions = function(options)
|
||||
|
||||
end
|
||||
v.groups = v.job or v.groups
|
||||
local optionsCanInteract = v.canInteract
|
||||
if optionsCanInteract then
|
||||
local id = Target.CreateCanInteract(optionsCanInteract)
|
||||
v.canInteract = function(...)
|
||||
return Target.CanInteract(id, ...)
|
||||
end
|
||||
end
|
||||
-- print(json.encode(v))
|
||||
end
|
||||
return options
|
||||
|
||||
@@ -40,6 +40,13 @@ Target.FixOptions = function(options)
|
||||
options[k].action = select
|
||||
options[k].job = v.job or v.groups
|
||||
options[k].jobType = v.jobType
|
||||
local optionsCanInteract = v.canInteract
|
||||
if optionsCanInteract then
|
||||
local id = Target.CreateCanInteract(optionsCanInteract)
|
||||
v.canInteract = function(...)
|
||||
return Target.CanInteract(id, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
return options
|
||||
end
|
||||
|
||||
@@ -29,6 +29,13 @@ Target.FixOptions = function(options)
|
||||
end
|
||||
options[k].onSelect = select
|
||||
options[k].groups = v.job or v.groups
|
||||
local optionsCanInteract = v.canInteract
|
||||
if optionsCanInteract then
|
||||
local id = Target.CreateCanInteract(optionsCanInteract)
|
||||
v.canInteract = function(...)
|
||||
return Target.CanInteract(id, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
return options
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user