From 6c25363a858a93955ef4c3822323cf8c3a8034cf Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Wed, 25 Sep 2024 23:27:57 +0100 Subject: [PATCH 01/10] feat(modules): Scaleform class Introduces a scaleform class, based upon ox lib classes, to make scaleforms both easier to read and use --- modules/lib.lua | 11 +++ modules/scaleform.lua | 172 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 modules/scaleform.lua diff --git a/modules/lib.lua b/modules/lib.lua index 52a5685be..02efda5e7 100644 --- a/modules/lib.lua +++ b/modules/lib.lua @@ -1,5 +1,8 @@ local isServer = IsDuplicityVersion() +---@class Scaleform +local scaleform = require 'modules.scaleform' + local qbx = {} qbx.string = {} qbx.math = {} @@ -560,6 +563,14 @@ else ReleaseSoundId(soundId) end + + -- Create a new scaleform instance + -- Uses ox lib class system to create an easy to use scaleform handler + ---@param scaleformName string + ---@return Scaleform + function qbx.newScaleform(scaleformName) + return scaleform:new(scaleformName) + end end _ENV.qbx = qbx diff --git a/modules/scaleform.lua b/modules/scaleform.lua new file mode 100644 index 000000000..68f19aab2 --- /dev/null +++ b/modules/scaleform.lua @@ -0,0 +1,172 @@ +---@class Scaleform : OxClass +---@field name string +---@field scaleform number +---@field draw boolean +---@field renderTarget number +---@field targetName string +---@field handle number +local Scaleform = lib.class('Scaleform') + +---@param name string +---@return nil +---@description Create a new scaleform class +function Scaleform:constructor(name) + self.name = name -- Set the name + + local scaleform = lib.requestScaleformMovie(name) -- Request the scaleform movie + + if not scaleform then -- If the scaleform is nil + return error(('Failed to request scaleform movie - [%s]'):format(name)) -- Error the failed scaleform request + end + + self.handle = scaleform -- Set the scaleform handle + self.draw = false -- Set the draw to false +end + +---@param name string +---@param args table +---@return nil +---@description Request a scaleform method with parameters +function Scaleform:MethodArgs(name, args) + if not self.handle then -- If the scaleform handle is nil + return error('Scaleform handle is nil') -- Error the scaleform handle is nil + end + if type(args) ~= 'table' then -- If the type of args is not a table + return error('Args must be a table') -- Error args must be a table + end + + BeginScaleformMovieMethod(self.handle, name) -- Begin the scaleform movie method + for k, v in pairs(args) do -- For each key and value in args + if type(v) == 'string' then -- If the type of v is a string + ScaleformMovieMethodAddParamPlayerNameString(v) -- Add the player name string + elseif type(v) == 'number' then -- If the type of v is a number + if math.type(v) == 'integer' then -- If the math type of v is an integer + ScaleformMovieMethodAddParamInt(v) -- Add the integer + else -- If the math type of v is not an integer + ScaleformMovieMethodAddParamFloat(v) -- Add the float + end + elseif type(v) == 'boolean' then -- If the type of v is a boolean + ScaleformMovieMethodAddParamBool(v) -- Add the boolean + else + error(('Unsupported Parameter type [%s]'):format(type(v))) -- Error unsupported type + end + end + EndScaleformMovieMethod() -- End the scaleform movie method +end + +---@param name string +---@return nil +---@description Request a scaleform method with no return value or parameters +function Scaleform:Method(name) + if not self.handle then -- If the scaleform handle is nil + return error('Scaleform handle is nil') -- Error the scaleform handle is nil + end + + BeginScaleformMovieMethod(self.handle, name) -- Begin the scaleform movie method + EndScaleformMovieMethod() -- End the scaleform movie method +end + +---@param name string +---@param type string +---@return number|string | boolean +---@description Request a scaleform method with a return value +function Scaleform:MethodReturn(name, type) + if not self.handle then -- If the scaleform handle is nil + return error('Scaleform handle is nil') -- Error the scaleform handle is nil + end + + BeginScaleformMovieMethod(self.handle, name) -- Begin the scaleform movie method + local result = EndScaleformMovieMethodReturnValue() -- End the scaleform movie method with a return value + + local timeout = 0 + while not IsScaleformMovieMethodReturnValueReady(result) do -- While the return value is not ready + Wait(0) -- Wait 0 + timeout = timeout + 1 -- Increment the timeout + if timeout > 1000 then -- If the timeout is greater than 1000 + error(('Return value failed - [%s]'):format(name)) -- Error the timeout waiting for scaleform method return value + return false + end + end -- End the while loop + + if type == "int" then -- If the type is an integer + return GetScaleformMovieMethodReturnValueInt(result) -- Get the return value as an integer + elseif type == "bool" then + return GetScaleformMovieMethodReturnValueBool(result) -- Get the return value as a boolean + else -- If the type is not an integer + return GetScaleformMovieMethodReturnValueString(result) -- Get the return value as a string + end +end + +---@param name string +---@param model string|number +---@return nil +---@description Create a render target for the scaleform - optional , only if you want to render the scaleform in 3D +function Scaleform:RenderTarget(name, model) + if type(model) == 'string' then -- If the type of model is a string + model = joaat(model) -- Convert the model to a hash + end + + if not IsNamedRendertargetRegistered(name) then -- If the named render target is not registered + RegisterNamedRendertarget(name, false) -- Register the named render target + + if not IsNamedRendertargetLinked(model) then -- If the named render target is not linked + LinkNamedRendertarget(model) -- Link the named render target + end + + self.renderTarget = GetNamedRendertargetRenderId(name) -- Get the named render target render id + self.targetName = name -- Set the target name + end +end + +---@param shouldDraw boolean +---@return nil +---@description Draw the scaleform +function Scaleform:Draw(shouldDraw) + if self.draw == shouldDraw then -- If the draw is equal to should draw + return -- Return + end + + self.draw = shouldDraw -- Set the draw to should draw + if shouldDraw then -- If should draw is true + + CreateThread(function() -- Create a thread + while self.draw do -- While the draw is true + + if self.renderTarget then -- If the render target is true + SetTextRenderId(self.renderTarget) -- Set the text render id + SetScriptGfxDrawOrder(4) -- Set the script gfx draw order + SetScriptGfxDrawBehindPausemenu(true) -- allow it to draw behind pause menu + end + + DrawScaleformMovieFullscreen(self.handle, 255, 255, 255, 255, 0) + + if self.renderTarget then -- If the render target is true + SetTextRenderId(1) -- Reset the text render id + end + + Wait(0) + end + end) + + end +end + +---@return nil +---@description Dispose of the scaleform +function Scaleform:Dispose() + if self.handle then -- If the handle exists + SetScaleformMovieAsNoLongerNeeded(self.handle) -- Set the scaleform movie as no longer needed + end + + if self.renderTarget then -- If the render target exists + ReleaseNamedRendertarget(self.targetName) -- Release the named render target + end + + -- Reset the values + self.handle = nil -- Set the handle to nil + self.renderTarget = nil -- Set the render target to nil + self.draw = false -- Set the draw to false +end + +---@return Scaleform +return Scaleform \ No newline at end of file From c4fa99ddc60903826da2234f5ff491dd341a2a3d Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Wed, 25 Sep 2024 23:45:41 +0100 Subject: [PATCH 02/10] tweak(modules/scaleform): lint issue --- modules/scaleform.lua | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/scaleform.lua b/modules/scaleform.lua index 68f19aab2..cf09414f1 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -14,7 +14,7 @@ function Scaleform:constructor(name) self.name = name -- Set the name local scaleform = lib.requestScaleformMovie(name) -- Request the scaleform movie - + if not scaleform then -- If the scaleform is nil return error(('Failed to request scaleform movie - [%s]'):format(name)) -- Error the failed scaleform request end @@ -36,19 +36,20 @@ function Scaleform:MethodArgs(name, args) end BeginScaleformMovieMethod(self.handle, name) -- Begin the scaleform movie method - for k, v in pairs(args) do -- For each key and value in args - if type(v) == 'string' then -- If the type of v is a string - ScaleformMovieMethodAddParamPlayerNameString(v) -- Add the player name string - elseif type(v) == 'number' then -- If the type of v is a number - if math.type(v) == 'integer' then -- If the math type of v is an integer - ScaleformMovieMethodAddParamInt(v) -- Add the integer + for i=1, #args do -- loop through the args + local arg = args[i] -- Set the value to the current arg + if type(arg) == 'string' then -- If the type of v is a string + ScaleformMovieMethodAddParamPlayerNameString(arg) -- Add the player name string + elseif type(arg) == 'number' then -- If the type of v is a number + if math.type(arg) == 'integer' then -- If the math type of v is an integer + ScaleformMovieMethodAddParamInt(arg) -- Add the integer else -- If the math type of v is not an integer - ScaleformMovieMethodAddParamFloat(v) -- Add the float + ScaleformMovieMethodAddParamFloat(arg) -- Add the float end - elseif type(v) == 'boolean' then -- If the type of v is a boolean - ScaleformMovieMethodAddParamBool(v) -- Add the boolean + elseif type(arg) == 'boolean' then -- If the type of v is a boolean + ScaleformMovieMethodAddParamBool(arg) -- Add the boolean else - error(('Unsupported Parameter type [%s]'):format(type(v))) -- Error unsupported type + error(('Unsupported Parameter type [%s]'):format(type(arg))) -- Error unsupported type end end EndScaleformMovieMethod() -- End the scaleform movie method From 6df4a4d37e5941d133d247fa59f1df7719dcea9a Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Thu, 26 Sep 2024 01:57:43 +0100 Subject: [PATCH 03/10] tweak(modules/scaleform): make the scaleform fit the target --- modules/scaleform.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/scaleform.lua b/modules/scaleform.lua index cf09414f1..a3eb3643f 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -137,6 +137,7 @@ function Scaleform:Draw(shouldDraw) SetTextRenderId(self.renderTarget) -- Set the text render id SetScriptGfxDrawOrder(4) -- Set the script gfx draw order SetScriptGfxDrawBehindPausemenu(true) -- allow it to draw behind pause menu + SetScaleformFitRendertarget(self.handle, true) -- Set the scaleform fit render target end DrawScaleformMovieFullscreen(self.handle, 255, 255, 255, 255, 0) From 823d2bf14dc29ec60140b9114f8047b6be9a1c32 Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Thu, 26 Sep 2024 02:16:52 +0100 Subject: [PATCH 04/10] feat(modules/scaleform): add option for non-fullscreen --- modules/scaleform.lua | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/modules/scaleform.lua b/modules/scaleform.lua index a3eb3643f..b6702655f 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -14,13 +14,14 @@ function Scaleform:constructor(name) self.name = name -- Set the name local scaleform = lib.requestScaleformMovie(name) -- Request the scaleform movie - + if not scaleform then -- If the scaleform is nil return error(('Failed to request scaleform movie - [%s]'):format(name)) -- Error the failed scaleform request end self.handle = scaleform -- Set the scaleform handle self.draw = false -- Set the draw to false + self.fullScreen = true -- Set the full screen to false end ---@param name string @@ -98,6 +99,30 @@ function Scaleform:MethodReturn(name, type) end end +---@param isFullscreen boolean +---@return nil +---@description Set the scaleform to render in full screen +function Scaleform:SetFullScreen(isFullscreen) + self.fullScreen = isFullscreen +end + +---@param x number +---@param y number +---@param width number +---@param height number +---@return nil +---@description Set the properties of the scaleform (Requires SetFullScreen to be false) +function Scaleform:SetProperties(x, y, width, height) + if self.fullScreen then -- If the full screen is true + return error('Cannot set properties when full screen is enabled') -- Error cannot set properties when full screen is enabled + end + self.x = x + self.y = y + self.width = width + self.height = height +end + + ---@param name string ---@param model string|number ---@return nil @@ -137,10 +162,19 @@ function Scaleform:Draw(shouldDraw) SetTextRenderId(self.renderTarget) -- Set the text render id SetScriptGfxDrawOrder(4) -- Set the script gfx draw order SetScriptGfxDrawBehindPausemenu(true) -- allow it to draw behind pause menu - SetScaleformFitRendertarget(self.handle, true) -- Set the scaleform fit render target + SetScaleformFitRendertarget(self.handle, true) end - DrawScaleformMovieFullscreen(self.handle, 255, 255, 255, 255, 0) + if self.fullScreen then + DrawScaleformMovieFullscreen(self.handle, 255, 255, 255, 255, 0) + else + if not self.x or not self.y or not self.width or not self.height then + error('Properties not set for scaleform') -- Error properties not set for scaleform + DrawScaleformMovieFullscreen(self.handle, 255, 255, 255, 255, 0) + else + DrawScaleformMovie(self.handle, self.x, self.y, self.width, self.height, 255, 255, 255, 255, 0) + end + end if self.renderTarget then -- If the render target is true SetTextRenderId(1) -- Reset the text render id From 302aac39aed80797fbc40e3c82319b78e657e19b Mon Sep 17 00:00:00 2001 From: Kasey Fitton Date: Thu, 26 Sep 2024 14:25:07 +0100 Subject: [PATCH 05/10] refactor(modules/scaleform): better methods --- modules/scaleform.lua | 182 +++++++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 83 deletions(-) diff --git a/modules/scaleform.lua b/modules/scaleform.lua index b6702655f..2b4f9c727 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -7,11 +7,12 @@ ---@field handle number local Scaleform = lib.class('Scaleform') ----@param name string +---@param details table | string ---@return nil ---@description Create a new scaleform class -function Scaleform:constructor(name) - self.name = name -- Set the name +function Scaleform:constructor(details) + local detailProvided = type(details) == "table" + self.name = detailProvided and details.name or details -- Set the name local scaleform = lib.requestScaleformMovie(name) -- Request the scaleform movie @@ -21,24 +22,22 @@ function Scaleform:constructor(name) self.handle = scaleform -- Set the scaleform handle self.draw = false -- Set the draw to false - self.fullScreen = true -- Set the full screen to false -end - ----@param name string ----@param args table ----@return nil ----@description Request a scaleform method with parameters -function Scaleform:MethodArgs(name, args) - if not self.handle then -- If the scaleform handle is nil - return error('Scaleform handle is nil') -- Error the scaleform handle is nil - end - if type(args) ~= 'table' then -- If the type of args is not a table - return error('Args must be a table') -- Error args must be a table + self.fullScreen = detailProvided and details.fullScreen or true -- Set the full screen to false + if detailProvided then + self.x = details.x + self.y = details.y + self.width = details.width + self.height = details.height + + if details.renderTarget then + self:RenderTarget(details.renderTarget.name, details.renderTarget.model) + end end +end - BeginScaleformMovieMethod(self.handle, name) -- Begin the scaleform movie method - for i=1, #args do -- loop through the args - local arg = args[i] -- Set the value to the current arg +local function convertArgs(argsTable) + for i=1, #argsTable do -- loop through the args + local arg = argsTable[i] -- Set the value to the current arg if type(arg) == 'string' then -- If the type of v is a string ScaleformMovieMethodAddParamPlayerNameString(arg) -- Add the player name string elseif type(arg) == 'number' then -- If the type of v is a number @@ -53,42 +52,20 @@ function Scaleform:MethodArgs(name, args) error(('Unsupported Parameter type [%s]'):format(type(arg))) -- Error unsupported type end end - EndScaleformMovieMethod() -- End the scaleform movie method -end - ----@param name string ----@return nil ----@description Request a scaleform method with no return value or parameters -function Scaleform:Method(name) - if not self.handle then -- If the scaleform handle is nil - return error('Scaleform handle is nil') -- Error the scaleform handle is nil - end - - BeginScaleformMovieMethod(self.handle, name) -- Begin the scaleform movie method - EndScaleformMovieMethod() -- End the scaleform movie method end ----@param name string ----@param type string ----@return number|string | boolean ----@description Request a scaleform method with a return value -function Scaleform:MethodReturn(name, type) - if not self.handle then -- If the scaleform handle is nil - return error('Scaleform handle is nil') -- Error the scaleform handle is nil - end - - BeginScaleformMovieMethod(self.handle, name) -- Begin the scaleform movie method +---@param type string +---@return boolean | int | string +---@description Awaits the return value, and converts it to a usable data type +local function retrieveReturnValue(type) local result = EndScaleformMovieMethodReturnValue() -- End the scaleform movie method with a return value local timeout = 0 - while not IsScaleformMovieMethodReturnValueReady(result) do -- While the return value is not ready - Wait(0) -- Wait 0 - timeout = timeout + 1 -- Increment the timeout - if timeout > 1000 then -- If the timeout is greater than 1000 - error(('Return value failed - [%s]'):format(name)) -- Error the timeout waiting for scaleform method return value - return false + lib.waitFor(function() + if IsScaleformMovieMethodReturnValueReady(result) then + return true end - end -- End the while loop + end, "Failed to retrieve return value", 1000) if type == "int" then -- If the type is an integer return GetScaleformMovieMethodReturnValueInt(result) -- Get the return value as an integer @@ -99,10 +76,39 @@ function Scaleform:MethodReturn(name, type) end end +---@param name string +---@param args? table +---@param returnValue? string +---@return any +---@description Call a scaleform function, with optional args or return value. +function Scaleform:method(name, args, returnValue) + if not self.handle then -- If the scaleform handle is nil + return error('Scaleform handle is nil') -- Error the scaleform handle is nil + end + + if args and type(args) ~= 'table' then -- If the type of args is not a table + return error('Args must be a table') -- Error args must be a table + end + + BeginScaleformMovieMethod(self.handle, name) -- Begin the scaleform movie method + + -- Converts the arguments into data types usable by scaleform + if args then + convertArgs(args) + end + + -- When wanting a return value, the scaleform has to be ended with a different native + if returnValue then + retrieveReturnValue(returnValue) + else + EndScaleformMovieMethod() -- End the scaleform movie method + end +end + ---@param isFullscreen boolean ---@return nil ---@description Set the scaleform to render in full screen -function Scaleform:SetFullScreen(isFullscreen) +function Scaleform:setFullScreen(isFullscreen) self.fullScreen = isFullscreen end @@ -112,7 +118,7 @@ end ---@param height number ---@return nil ---@description Set the properties of the scaleform (Requires SetFullScreen to be false) -function Scaleform:SetProperties(x, y, width, height) +function Scaleform:setProperties(x, y, width, height) if self.fullScreen then -- If the full screen is true return error('Cannot set properties when full screen is enabled') -- Error cannot set properties when full screen is enabled end @@ -122,12 +128,18 @@ function Scaleform:SetProperties(x, y, width, height) self.height = height end - ---@param name string ---@param model string|number ---@return nil ---@description Create a render target for the scaleform - optional , only if you want to render the scaleform in 3D -function Scaleform:RenderTarget(name, model) +function Scaleform:renderTarget(name, model) + + -- ensures theres no Targets still active, since this could cause a memory leak + -- if the render targets are not released. + if self.renderTarget then + ReleaseNamedRendertarget(self.targetName) + end + if type(model) == 'string' then -- If the type of model is a string model = joaat(model) -- Convert the model to a hash end @@ -144,52 +156,56 @@ function Scaleform:RenderTarget(name, model) end end ----@param shouldDraw boolean ---@return nil ----@description Draw the scaleform -function Scaleform:Draw(shouldDraw) - if self.draw == shouldDraw then -- If the draw is equal to should draw - return -- Return +---@description Set The Scaleform to draw +function Scaleform:startDrawing() + if self.draw then -- If the draw is equal to should draw + return error("Scaleform Already Drawing") end - self.draw = shouldDraw -- Set the draw to should draw - if shouldDraw then -- If should draw is true + self.draw = true + CreateThread(function() -- Create a thread + while self.draw do -- While the draw is true - CreateThread(function() -- Create a thread - while self.draw do -- While the draw is true - - if self.renderTarget then -- If the render target is true - SetTextRenderId(self.renderTarget) -- Set the text render id - SetScriptGfxDrawOrder(4) -- Set the script gfx draw order - SetScriptGfxDrawBehindPausemenu(true) -- allow it to draw behind pause menu - SetScaleformFitRendertarget(self.handle, true) - end + if self.renderTarget then -- If the render target is true + SetTextRenderId(self.renderTarget) -- Set the text render id + SetScriptGfxDrawOrder(4) -- Set the script gfx draw order + SetScriptGfxDrawBehindPausemenu(true) -- allow it to draw behind pause menu + SetScaleformFitRendertarget(self.handle, true) + end - if self.fullScreen then + if self.fullScreen then + DrawScaleformMovieFullscreen(self.handle, 255, 255, 255, 255, 0) + else + if not self.x or not self.y or not self.width or not self.height then + error('Properties not set for scaleform') -- Error properties not set for scaleform DrawScaleformMovieFullscreen(self.handle, 255, 255, 255, 255, 0) else - if not self.x or not self.y or not self.width or not self.height then - error('Properties not set for scaleform') -- Error properties not set for scaleform - DrawScaleformMovieFullscreen(self.handle, 255, 255, 255, 255, 0) - else - DrawScaleformMovie(self.handle, self.x, self.y, self.width, self.height, 255, 255, 255, 255, 0) - end - end - - if self.renderTarget then -- If the render target is true - SetTextRenderId(1) -- Reset the text render id + DrawScaleformMovie(self.handle, self.x, self.y, self.width, self.height, 255, 255, 255, 255, 0) end + end - Wait(0) + if self.renderTarget then -- If the render target is true + SetTextRenderId(1) -- Reset the text render id end - end) + Wait(0) + end + end) +end + +---@return nil +---@description stop the scaleform from drawing, use this to only temporarily disable it, use Dispose otherwise. +function Scaleform:stopDrawing() + if not self.draw then + return end + self.draw = false end ---@return nil ---@description Dispose of the scaleform -function Scaleform:Dispose() +function Scaleform:dispose() if self.handle then -- If the handle exists SetScaleformMovieAsNoLongerNeeded(self.handle) -- Set the scaleform movie as no longer needed end From a4a70f5e38a20439b7a737500c12a1b90886c5bd Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Thu, 26 Sep 2024 18:50:27 +0100 Subject: [PATCH 06/10] fix(modules): overlapping variables --- modules/lib.lua | 6 +++--- modules/scaleform.lua | 33 +++++++++++++++++---------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/modules/lib.lua b/modules/lib.lua index 02efda5e7..28257c6dc 100644 --- a/modules/lib.lua +++ b/modules/lib.lua @@ -566,10 +566,10 @@ else -- Create a new scaleform instance -- Uses ox lib class system to create an easy to use scaleform handler - ---@param scaleformName string + ---@param scaleformDetails string | table ---@return Scaleform - function qbx.newScaleform(scaleformName) - return scaleform:new(scaleformName) + function qbx.newScaleform(scaleformDetails) + return scaleform:new(scaleformDetails) end end diff --git a/modules/scaleform.lua b/modules/scaleform.lua index 2b4f9c727..6b8f1dc5c 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -2,7 +2,7 @@ ---@field name string ---@field scaleform number ---@field draw boolean ----@field renderTarget number +---@field target number ---@field targetName string ---@field handle number local Scaleform = lib.class('Scaleform') @@ -14,15 +14,16 @@ function Scaleform:constructor(details) local detailProvided = type(details) == "table" self.name = detailProvided and details.name or details -- Set the name - local scaleform = lib.requestScaleformMovie(name) -- Request the scaleform movie - + local scaleform = lib.requestScaleformMovie(self.name) -- Request the scaleform movie + if not scaleform then -- If the scaleform is nil - return error(('Failed to request scaleform movie - [%s]'):format(name)) -- Error the failed scaleform request + return error(('Failed to request scaleform movie - [%s]'):format(self.name)) -- Error the failed scaleform request end self.handle = scaleform -- Set the scaleform handle self.draw = false -- Set the draw to false - self.fullScreen = detailProvided and details.fullScreen or true -- Set the full screen to false + self.fullScreen = detailProvided and details.fullScreen or true -- Set default for full screen + if detailProvided then self.x = details.x self.y = details.y @@ -30,7 +31,7 @@ function Scaleform:constructor(details) self.height = details.height if details.renderTarget then - self:RenderTarget(details.renderTarget.name, details.renderTarget.model) + self:renderTarget(details.renderTarget.name, details.renderTarget.model) end end end @@ -54,7 +55,7 @@ local function convertArgs(argsTable) end end ----@param type string +---@param type string ---@return boolean | int | string ---@description Awaits the return value, and converts it to a usable data type local function retrieveReturnValue(type) @@ -62,7 +63,7 @@ local function retrieveReturnValue(type) local timeout = 0 lib.waitFor(function() - if IsScaleformMovieMethodReturnValueReady(result) then + if IsScaleformMovieMethodReturnValueReady(result) then return true end end, "Failed to retrieve return value", 1000) @@ -136,7 +137,7 @@ function Scaleform:renderTarget(name, model) -- ensures theres no Targets still active, since this could cause a memory leak -- if the render targets are not released. - if self.renderTarget then + if self.target then ReleaseNamedRendertarget(self.targetName) end @@ -151,7 +152,7 @@ function Scaleform:renderTarget(name, model) LinkNamedRendertarget(model) -- Link the named render target end - self.renderTarget = GetNamedRendertargetRenderId(name) -- Get the named render target render id + self.target = GetNamedRendertargetRenderId(name) -- Get the named render target render id self.targetName = name -- Set the target name end end @@ -167,8 +168,8 @@ function Scaleform:startDrawing() CreateThread(function() -- Create a thread while self.draw do -- While the draw is true - if self.renderTarget then -- If the render target is true - SetTextRenderId(self.renderTarget) -- Set the text render id + if self.target then -- If the render target is true + SetTextRenderId(self.target) -- Set the text render id SetScriptGfxDrawOrder(4) -- Set the script gfx draw order SetScriptGfxDrawBehindPausemenu(true) -- allow it to draw behind pause menu SetScaleformFitRendertarget(self.handle, true) @@ -185,7 +186,7 @@ function Scaleform:startDrawing() end end - if self.renderTarget then -- If the render target is true + if self.target then -- If the render target is true SetTextRenderId(1) -- Reset the text render id end @@ -195,7 +196,7 @@ function Scaleform:startDrawing() end ---@return nil ----@description stop the scaleform from drawing, use this to only temporarily disable it, use Dispose otherwise. +---@description stop the scaleform from drawing, use this to only temporarily disable it, use Dispose otherwise. function Scaleform:stopDrawing() if not self.draw then return @@ -210,13 +211,13 @@ function Scaleform:dispose() SetScaleformMovieAsNoLongerNeeded(self.handle) -- Set the scaleform movie as no longer needed end - if self.renderTarget then -- If the render target exists + if self.target then -- If the render target exists ReleaseNamedRendertarget(self.targetName) -- Release the named render target end -- Reset the values self.handle = nil -- Set the handle to nil - self.renderTarget = nil -- Set the render target to nil + self.target = nil -- Set the render target to nil self.draw = false -- Set the draw to false end From ea4187d7d0350ccdae37c1e317ccd9bcc5060960 Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Thu, 26 Sep 2024 18:59:23 +0100 Subject: [PATCH 07/10] fix(modules/scaleform): unused variable --- modules/scaleform.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/scaleform.lua b/modules/scaleform.lua index 6b8f1dc5c..f0eeb6e08 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -61,7 +61,6 @@ end local function retrieveReturnValue(type) local result = EndScaleformMovieMethodReturnValue() -- End the scaleform movie method with a return value - local timeout = 0 lib.waitFor(function() if IsScaleformMovieMethodReturnValueReady(result) then return true From 01553169578a14c8d637b3467fb5e4c66eaa1236 Mon Sep 17 00:00:00 2001 From: Kasey Fitton Date: Fri, 27 Sep 2024 13:39:34 +0100 Subject: [PATCH 08/10] Update modules/scaleform.lua Co-authored-by: David Malchin --- modules/scaleform.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/scaleform.lua b/modules/scaleform.lua index f0eeb6e08..c5e214255 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -55,8 +55,8 @@ local function convertArgs(argsTable) end end ----@param type string ----@return boolean | int | string +---@param type 'bool' | 'int' | 'string' +---@return boolean | integer | string ---@description Awaits the return value, and converts it to a usable data type local function retrieveReturnValue(type) local result = EndScaleformMovieMethodReturnValue() -- End the scaleform movie method with a return value From 571c6e5cdde110d7552fc746618de81c0e0c3965 Mon Sep 17 00:00:00 2001 From: Kasey Fitton Date: Fri, 27 Sep 2024 13:40:29 +0100 Subject: [PATCH 09/10] fix(modules/scaleform): return the return value Co-authored-by: David Malchin --- modules/scaleform.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/scaleform.lua b/modules/scaleform.lua index c5e214255..54f75184d 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -99,10 +99,10 @@ function Scaleform:method(name, args, returnValue) -- When wanting a return value, the scaleform has to be ended with a different native if returnValue then - retrieveReturnValue(returnValue) - else - EndScaleformMovieMethod() -- End the scaleform movie method + return retrieveReturnValue(returnValue) end + + EndScaleformMovieMethod() -- End the scaleform movie method end ---@param isFullscreen boolean From 35c977bebb8af9716bf15e996a094059d20c03a9 Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Sat, 5 Oct 2024 17:14:39 +0100 Subject: [PATCH 10/10] tweak(modules/scaleform): adjust function names and improve typings --- modules/lib.lua | 2 +- modules/scaleform.lua | 51 ++++++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/modules/lib.lua b/modules/lib.lua index 28257c6dc..7bad25f49 100644 --- a/modules/lib.lua +++ b/modules/lib.lua @@ -566,7 +566,7 @@ else -- Create a new scaleform instance -- Uses ox lib class system to create an easy to use scaleform handler - ---@param scaleformDetails string | table + ---@param scaleformDetails string | detailsTable ---@return Scaleform function qbx.newScaleform(scaleformDetails) return scaleform:new(scaleformDetails) diff --git a/modules/scaleform.lua b/modules/scaleform.lua index 54f75184d..fc83b935a 100644 --- a/modules/scaleform.lua +++ b/modules/scaleform.lua @@ -1,38 +1,49 @@ ----@class Scaleform : OxClass +---@class renderTargetTable +---@field name string +---@field model string|number + +---@class detailsTable ---@field name string +---@field fullScreen? boolean +---@field x? number +---@field y? number +---@field width? number +---@field height? number +---@field renderTarget? renderTargetTable + +---@class Scaleform : OxClass ---@field scaleform number ---@field draw boolean ---@field target number ---@field targetName string ---@field handle number +---@field fullScreen boolean local Scaleform = lib.class('Scaleform') ----@param details table | string +---@param details detailsTable | string ---@return nil ---@description Create a new scaleform class function Scaleform:constructor(details) - local detailProvided = type(details) == "table" - self.name = detailProvided and details.name or details -- Set the name + details = type(details) == "table" and details or {name = details} -- Set the details to a table if it is not already - local scaleform = lib.requestScaleformMovie(self.name) -- Request the scaleform movie + local scaleform = lib.requestScaleformMovie(details.name) -- Request the scaleform movie if not scaleform then -- If the scaleform is nil - return error(('Failed to request scaleform movie - [%s]'):format(self.name)) -- Error the failed scaleform request + return error(('Failed to request scaleform movie - [%s]'):format(details.name)) -- Error the failed scaleform request end self.handle = scaleform -- Set the scaleform handle self.draw = false -- Set the draw to false - self.fullScreen = detailProvided and details.fullScreen or true -- Set default for full screen - if detailProvided then - self.x = details.x - self.y = details.y - self.width = details.width - self.height = details.height + -- Set Default Values if not provided + self.fullScreen = details.fullScreen ~= nil and details.fullScreen or true + self.x = details.x or 0 + self.y = details.y or 0 + self.width = details.width or 0 + self.height = details.height or 0 - if details.renderTarget then - self:renderTarget(details.renderTarget.name, details.renderTarget.model) - end + if details.renderTarget then + self:setRenderTarget(details.renderTarget.name, details.renderTarget.model) end end @@ -55,7 +66,7 @@ local function convertArgs(argsTable) end end ----@param type 'bool' | 'int' | 'string' +---@param type 'boolean' | 'integer' | 'string' ---@return boolean | integer | string ---@description Awaits the return value, and converts it to a usable data type local function retrieveReturnValue(type) @@ -67,9 +78,9 @@ local function retrieveReturnValue(type) end end, "Failed to retrieve return value", 1000) - if type == "int" then -- If the type is an integer + if type == "integer" then -- If the type is an integer return GetScaleformMovieMethodReturnValueInt(result) -- Get the return value as an integer - elseif type == "bool" then + elseif type == "boolean" then return GetScaleformMovieMethodReturnValueBool(result) -- Get the return value as a boolean else -- If the type is not an integer return GetScaleformMovieMethodReturnValueString(result) -- Get the return value as a string @@ -81,7 +92,7 @@ end ---@param returnValue? string ---@return any ---@description Call a scaleform function, with optional args or return value. -function Scaleform:method(name, args, returnValue) +function Scaleform:callMethod(name, args, returnValue) if not self.handle then -- If the scaleform handle is nil return error('Scaleform handle is nil') -- Error the scaleform handle is nil end @@ -132,7 +143,7 @@ end ---@param model string|number ---@return nil ---@description Create a render target for the scaleform - optional , only if you want to render the scaleform in 3D -function Scaleform:renderTarget(name, model) +function Scaleform:setRenderTarget(name, model) -- ensures theres no Targets still active, since this could cause a memory leak -- if the render targets are not released.