This commit is contained in:
Lorraxs 2023-12-05 15:00:07 +07:00
parent 1531de93bf
commit 7f16dedc09
5 changed files with 107 additions and 8 deletions

View File

@ -6,4 +6,5 @@ end
function Impl:OnReady() function Impl:OnReady()
main:LogInfo("%s ready", self:GetName()) main:LogInfo("%s ready", self:GetName())
end end

View File

@ -5,8 +5,14 @@ function Impl:Init()
self.data = { self.data = {
test = "test" test = "test"
} }
self.testVar = 0
end end
function Impl:GetData() function Impl:GetData()
return self.data return self.data
end
function Impl:Add(amount, amount2)
self.testVar = self.testVar + amount + amount2
return self.testVar
end end

View File

@ -0,0 +1,39 @@
local Impl = NewImpl("Test2")
function Impl:OnReady()
self:MainThread()
self:TestHook()
self:TestReplaceMethod()
end
function Impl:MainThread()
local testImpl = main:GetImpl("Test")
Citizen.CreateThread(function()
while true do
Wait(1000)
local result = testImpl:Add(1, 2)
main:LogInfo("TestImpl result %s", result)
end
end)
end
function Impl:TestHook()
local testImpl = main:GetImpl("Test")
testImpl:HookMethod("Add", function(self, amount, amount2)
return amount+1, amount2
end)
end
function Impl:TestReplaceMethod()
Citizen.CreateThread(function()
Wait(5000)
local testImpl = main:GetImpl("Test")
local oldMethod = testImpl:GetMethod("Add")
testImpl:ReplaceMethod("Add", function(self, amount, amount2)
self.testVar = self.testVar * amount * amount2
return self.testVar
end)
Wait(5000)
testImpl:ReplaceMethod("Add", oldMethod)
end)
end

View File

@ -90,7 +90,10 @@ end
-- create an instance of an object with constructor parameters -- create an instance of an object with constructor parameters
function Class:new(...) function Class:new(...)
local obj = self:extend({}) local obj = self:extend({
destroyed = false,
originalMethods = {}
})
if obj.Init then obj:Init(...) end if obj.Init then obj:Init(...) end
return obj return obj
end end
@ -115,6 +118,53 @@ end
function Impl:OnReady(...) function Impl:OnReady(...)
end end
function Impl:HookMethod(method, hookFn)
local oldMethod = self[method]
if not oldMethod then
main:LogError("Impl %s missing method %s", self.name, method)
return
end
self.originalMethods[method] = oldMethod
self[method] = function(...)
if self.destroyed then
return
end
local result = {pcall(hookFn, ...)}
print(json.encode(result))
local success = table.remove(result, 1)
if not success then
main:LogError("Impl %s hook %s error: %s", self.name, method, result[2])
self[method] = oldMethod
return oldMethod(...)
end
return oldMethod(self, table.unpack(result))
end
end
function Impl:GetMethod(method)
return self[method]
end
function Impl:ReplaceMethod(method, newMethod)
if not self[method] then
main:LogError("Impl %s missing method %s", self.name, method)
return
end
if not self.originalMethods[method] then
self.originalMethods[method] = self[method]
end
self[method] = newMethod
end
function Impl:RefreshMethod(method)
if not self.originalMethods[method] then
main:LogError("Impl %s missing method %s", self.name, method)
return
end
self[method] = self.originalMethods[method]
end
function NewImpl(name) function NewImpl(name)
local impl = Impl:extend({ local impl = Impl:extend({
name = name name = name

View File

@ -8,6 +8,7 @@ function Main:Init()
local o = {} local o = {}
setmetatable(o, {__index = Main}) setmetatable(o, {__index = Main})
o.impls = {} o.impls = {}
o.initializedImpls = {}
o.lastTimeImplRegistered = 0 o.lastTimeImplRegistered = 0
o.ready = false o.ready = false
if not IsDuplicityVersion() then if not IsDuplicityVersion() then
@ -78,28 +79,28 @@ function Main:RegisterImpl(name, impl)
self.lastTimeImplRegistered = GetGameTimer() self.lastTimeImplRegistered = GetGameTimer()
self:LogSuccess("Impl %s registered", name) self:LogSuccess("Impl %s registered", name)
if self.ready then if self.ready then
self.impls[name] = impl(self) self.initializedImpls[name] = impl(self)
self.impls[name]:OnReady() self.initializedImpls[name]:OnReady()
end end
end end
function Main:InitImpl() function Main:InitImpl()
for name, impl in pairs(self.impls) do for name, impl in pairs(self.impls) do
self.impls[name] = impl(self) self.initializedImpls[name] = impl(self)
end end
self:LogInfo("All impls initialized") self:LogInfo("All impls initialized")
self.ready = true self.ready = true
for name, impl in pairs(self.impls) do for name, impl in pairs(self.initializedImpls) do
impl:OnReady() impl:OnReady()
end end
end end
function Main:GetImpl(name) function Main:GetImpl(name)
if not self.impls[name] then if not self.initializedImpls[name] then
self:LogError("Impl %s not found", name) self:LogError("Impl %s not found", name)
return return
end end
return self.impls[name] return self.initializedImpls[name]
end end
function Main:ImplCall(name, func, ...) function Main:ImplCall(name, func, ...)
@ -114,6 +115,8 @@ function Main:ImplCall(name, func, ...)
return impl[func](impl, ...) return impl[func](impl, ...)
end end
function Main:ImplInfo() function Main:ImplInfo()
for name, impl in pairs(self.impls) do for name, impl in pairs(self.impls) do
local debug = debug.getinfo(impl.Init, "S") local debug = debug.getinfo(impl.Init, "S")