mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-28 17:01:14 +00:00
feat(esx_lib/points): move points and Point class to xLib
Integrated fixes during the move: - monotonic handle counter (handleCount) instead of count+1; no handle collision after a point is removed - unified single proximity loop: per-frame inside() plus a 500ms enter/leave scan, adaptive Wait(next(insidePoints) and 0 or 500), replacing the previous two separate loops - emptiness detected via next() instead of # on a sparse-keyed table Non-portable substitutions documented: - ESX.PlayerData.ped -> PlayerPedId() (ESX.PlayerData is not available in the lib VM) - GetGameTimer() used to gate the 500ms scan within the single loop
This commit is contained in:
@@ -57,3 +57,9 @@ ESX.Scaleform = {
|
||||
RunMethod = xLib.scaleform.utils.runMethod,
|
||||
},
|
||||
}
|
||||
|
||||
ESX.CreatePointInternal = xLib.points.create
|
||||
ESX.RemovePointInternal = xLib.points.remove
|
||||
ESX.HidePointInternal = xLib.points.hide
|
||||
StartPointsLoop = xLib.points.startLoop
|
||||
ESX.Point = xLib.point
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
local Point = ESX.Class()
|
||||
|
||||
local nearby, loop = {}, nil
|
||||
|
||||
function Point:constructor(properties)
|
||||
self.coords = properties.coords
|
||||
self.hidden = properties.hidden
|
||||
self.enter = properties.enter
|
||||
self.leave = properties.leave
|
||||
self.inside = properties.inside
|
||||
self.handle = ESX.CreatePointInternal(properties.coords, properties.distance, properties.hidden, function()
|
||||
nearby[self.handle] = self
|
||||
if self.enter then
|
||||
self:enter()
|
||||
end
|
||||
if not loop then
|
||||
loop = true
|
||||
CreateThread(function()
|
||||
while loop do
|
||||
local coords = GetEntityCoords(ESX.PlayerData.ped)
|
||||
for _, point in pairs(nearby) do
|
||||
if point.inside then
|
||||
point:inside(#(coords - point.coords))
|
||||
end
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end, function()
|
||||
nearby[self.handle] = nil
|
||||
if self.leave then
|
||||
self:leave()
|
||||
end
|
||||
if #nearby == 0 then
|
||||
loop = false
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function Point:delete()
|
||||
ESX.RemovePointInternal(self.handle)
|
||||
end
|
||||
|
||||
function Point:toggle(hidden)
|
||||
if hidden == nil then
|
||||
hidden = not self.hidden
|
||||
end
|
||||
self.hidden = hidden
|
||||
ESX.HidePointInternal(self.handle, hidden)
|
||||
end
|
||||
|
||||
return Point
|
||||
@@ -1,54 +0,0 @@
|
||||
local points = {}
|
||||
|
||||
function ESX.CreatePointInternal(coords, distance, hidden, enter, leave)
|
||||
local point = {
|
||||
coords = coords,
|
||||
distance = distance,
|
||||
hidden = hidden,
|
||||
enter = enter,
|
||||
leave = leave,
|
||||
resource = GetInvokingResource()
|
||||
}
|
||||
local handle = ESX.Table.SizeOf(points) + 1
|
||||
points[handle] = point
|
||||
return handle
|
||||
end
|
||||
|
||||
function ESX.RemovePointInternal(handle)
|
||||
points[handle] = nil
|
||||
end
|
||||
|
||||
function ESX.HidePointInternal(handle, hidden)
|
||||
if points[handle] then
|
||||
points[handle].hidden = hidden
|
||||
end
|
||||
end
|
||||
|
||||
function StartPointsLoop()
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local coords = GetEntityCoords(ESX.PlayerData.ped)
|
||||
for handle, point in pairs(points) do
|
||||
if not point.hidden and #(coords - point.coords) <= point.distance then
|
||||
if not point.nearby then
|
||||
points[handle].nearby = true
|
||||
points[handle].enter()
|
||||
end
|
||||
elseif point.nearby then
|
||||
points[handle].nearby = false
|
||||
points[handle].leave()
|
||||
end
|
||||
end
|
||||
Wait(500)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
AddEventHandler('onResourceStop', function(resource)
|
||||
for handle, point in pairs(points) do
|
||||
if point.resource == resource then
|
||||
points[handle] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -49,7 +49,6 @@ client_scripts {
|
||||
'client/modules/wrapper.lua',
|
||||
'client/modules/callback.lua',
|
||||
'client/modules/adjustments.lua',
|
||||
'client/modules/points.lua',
|
||||
|
||||
'client/modules/events.lua',
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ if not IsDuplicityVersion() then -- Only register this event for the client
|
||||
end)
|
||||
end
|
||||
|
||||
local external = { { "Class", "class.lua" }, { "Point", "point.lua" } }
|
||||
local external = { { "Class", "class.lua" } }
|
||||
for i = 1, #external do
|
||||
local module = external[i]
|
||||
local path = string.format("client/imports/%s", module[2])
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
---@class xPoint
|
||||
---@field coords vector3
|
||||
---@field hidden? boolean
|
||||
---@field enter? function
|
||||
---@field leave? function
|
||||
---@field inside? function
|
||||
---@field handle integer
|
||||
xLib.point = xLib.class()
|
||||
|
||||
---@param properties table coords, distance, hidden, enter, leave, inside
|
||||
function xLib.point:constructor(properties)
|
||||
self.coords = properties.coords
|
||||
self.hidden = properties.hidden
|
||||
self.enter = properties.enter
|
||||
self.leave = properties.leave
|
||||
self.inside = properties.inside
|
||||
|
||||
self.handle = xLib.points.create(
|
||||
properties.coords,
|
||||
properties.distance,
|
||||
properties.hidden,
|
||||
function()
|
||||
if self.enter then
|
||||
self:enter()
|
||||
end
|
||||
end,
|
||||
function()
|
||||
if self.leave then
|
||||
self:leave()
|
||||
end
|
||||
end,
|
||||
properties.inside and function(dist)
|
||||
self:inside(dist)
|
||||
end or nil
|
||||
)
|
||||
end
|
||||
|
||||
function xLib.point:delete()
|
||||
xLib.points.remove(self.handle)
|
||||
end
|
||||
|
||||
---@param hidden? boolean
|
||||
function xLib.point:toggle(hidden)
|
||||
if hidden == nil then
|
||||
hidden = not self.hidden
|
||||
end
|
||||
|
||||
self.hidden = hidden
|
||||
xLib.points.hide(self.handle, hidden)
|
||||
end
|
||||
|
||||
return xLib.point
|
||||
@@ -0,0 +1,100 @@
|
||||
---@class pointslib
|
||||
xLib.points = {}
|
||||
|
||||
local points = {}
|
||||
local insidePoints = {}
|
||||
local handleCount = 0
|
||||
|
||||
---@param coords vector3
|
||||
---@param distance number
|
||||
---@param hidden? boolean
|
||||
---@param enter function
|
||||
---@param leave function
|
||||
---@param inside? function
|
||||
---@return integer handle
|
||||
function xLib.points.create(coords, distance, hidden, enter, leave, inside)
|
||||
handleCount = handleCount + 1
|
||||
local handle = handleCount
|
||||
|
||||
points[handle] = {
|
||||
coords = coords,
|
||||
distance = distance,
|
||||
hidden = hidden,
|
||||
enter = enter,
|
||||
leave = leave,
|
||||
inside = inside,
|
||||
resource = GetInvokingResource()
|
||||
}
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
---@param handle integer
|
||||
function xLib.points.remove(handle)
|
||||
points[handle] = nil
|
||||
insidePoints[handle] = nil
|
||||
end
|
||||
|
||||
---@param handle integer
|
||||
---@param hidden boolean
|
||||
function xLib.points.hide(handle, hidden)
|
||||
if points[handle] then
|
||||
points[handle].hidden = hidden
|
||||
end
|
||||
end
|
||||
|
||||
function xLib.points.startLoop()
|
||||
CreateThread(function()
|
||||
local lastScan = 0
|
||||
|
||||
while true do
|
||||
local coords = GetEntityCoords(PlayerPedId())
|
||||
|
||||
for _, point in pairs(insidePoints) do
|
||||
point.inside(#(coords - point.coords))
|
||||
end
|
||||
|
||||
local now = GetGameTimer()
|
||||
if now - lastScan >= 500 then
|
||||
lastScan = now
|
||||
|
||||
for handle, point in pairs(points) do
|
||||
if not point.hidden and #(coords - point.coords) <= point.distance then
|
||||
if not point.nearby then
|
||||
point.nearby = true
|
||||
|
||||
if point.enter then
|
||||
point.enter()
|
||||
end
|
||||
|
||||
if point.inside then
|
||||
insidePoints[handle] = point
|
||||
end
|
||||
end
|
||||
elseif point.nearby then
|
||||
point.nearby = false
|
||||
|
||||
if point.leave then
|
||||
point.leave()
|
||||
end
|
||||
|
||||
insidePoints[handle] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Wait(next(insidePoints) and 0 or 500)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
AddEventHandler("onResourceStop", function(resource)
|
||||
for handle, point in pairs(points) do
|
||||
if point.resource == resource then
|
||||
points[handle] = nil
|
||||
insidePoints[handle] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return xLib.points
|
||||
Reference in New Issue
Block a user