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,
|
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/wrapper.lua',
|
||||||
'client/modules/callback.lua',
|
'client/modules/callback.lua',
|
||||||
'client/modules/adjustments.lua',
|
'client/modules/adjustments.lua',
|
||||||
'client/modules/points.lua',
|
|
||||||
|
|
||||||
'client/modules/events.lua',
|
'client/modules/events.lua',
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ if not IsDuplicityVersion() then -- Only register this event for the client
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
local external = { { "Class", "class.lua" }, { "Point", "point.lua" } }
|
local external = { { "Class", "class.lua" } }
|
||||||
for i = 1, #external do
|
for i = 1, #external do
|
||||||
local module = external[i]
|
local module = external[i]
|
||||||
local path = string.format("client/imports/%s", module[2])
|
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