Mercurial > wow > icu
comparison Libs/AceHook-3.0/AceHook-3.0.lua @ 0:98c6f55e6619
First commit
| author | Xiiph |
|---|---|
| date | Sat, 05 Feb 2011 16:45:02 +0100 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:98c6f55e6619 |
|---|---|
| 1 --- **AceHook-3.0** offers safe Hooking/Unhooking of functions, methods and frame scripts. | |
| 2 -- Using AceHook-3.0 is recommended when you need to unhook your hooks again, so the hook chain isn't broken | |
| 3 -- when you manually restore the original function. | |
| 4 -- | |
| 5 -- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by | |
| 6 -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object | |
| 7 -- and can be accessed directly, without having to explicitly call AceHook itself.\\ | |
| 8 -- It is recommended to embed AceHook, otherwise you'll have to specify a custom `self` on all calls you | |
| 9 -- make into AceHook. | |
| 10 -- @class file | |
| 11 -- @name AceHook-3.0 | |
| 12 -- @release $Id: AceHook-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $ | |
| 13 local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 5 | |
| 14 local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR) | |
| 15 | |
| 16 if not AceHook then return end -- No upgrade needed | |
| 17 | |
| 18 AceHook.embeded = AceHook.embeded or {} | |
| 19 AceHook.registry = AceHook.registry or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) | |
| 20 AceHook.handlers = AceHook.handlers or {} | |
| 21 AceHook.actives = AceHook.actives or {} | |
| 22 AceHook.scripts = AceHook.scripts or {} | |
| 23 AceHook.onceSecure = AceHook.onceSecure or {} | |
| 24 AceHook.hooks = AceHook.hooks or {} | |
| 25 | |
| 26 -- local upvalues | |
| 27 local registry = AceHook.registry | |
| 28 local handlers = AceHook.handlers | |
| 29 local actives = AceHook.actives | |
| 30 local scripts = AceHook.scripts | |
| 31 local onceSecure = AceHook.onceSecure | |
| 32 | |
| 33 -- Lua APIs | |
| 34 local pairs, next, type = pairs, next, type | |
| 35 local format = string.format | |
| 36 local assert, error = assert, error | |
| 37 | |
| 38 -- WoW APIs | |
| 39 local issecurevariable, hooksecurefunc = issecurevariable, hooksecurefunc | |
| 40 local _G = _G | |
| 41 | |
| 42 -- functions for later definition | |
| 43 local donothing, createHook, hook | |
| 44 | |
| 45 local protectedScripts = { | |
| 46 OnClick = true, | |
| 47 } | |
| 48 | |
| 49 -- upgrading of embeded is done at the bottom of the file | |
| 50 | |
| 51 local mixins = { | |
| 52 "Hook", "SecureHook", | |
| 53 "HookScript", "SecureHookScript", | |
| 54 "Unhook", "UnhookAll", | |
| 55 "IsHooked", | |
| 56 "RawHook", "RawHookScript" | |
| 57 } | |
| 58 | |
| 59 -- AceHook:Embed( target ) | |
| 60 -- target (object) - target object to embed AceHook in | |
| 61 -- | |
| 62 -- Embeds AceEevent into the target object making the functions from the mixins list available on target:.. | |
| 63 function AceHook:Embed( target ) | |
| 64 for k, v in pairs( mixins ) do | |
| 65 target[v] = self[v] | |
| 66 end | |
| 67 self.embeded[target] = true | |
| 68 -- inject the hooks table safely | |
| 69 target.hooks = target.hooks or {} | |
| 70 return target | |
| 71 end | |
| 72 | |
| 73 -- AceHook:OnEmbedDisable( target ) | |
| 74 -- target (object) - target object that is being disabled | |
| 75 -- | |
| 76 -- Unhooks all hooks when the target disables. | |
| 77 -- this method should be called by the target manually or by an addon framework | |
| 78 function AceHook:OnEmbedDisable( target ) | |
| 79 target:UnhookAll() | |
| 80 end | |
| 81 | |
| 82 function createHook(self, handler, orig, secure, failsafe) | |
| 83 local uid | |
| 84 local method = type(handler) == "string" | |
| 85 if failsafe and not secure then | |
| 86 -- failsafe hook creation | |
| 87 uid = function(...) | |
| 88 if actives[uid] then | |
| 89 if method then | |
| 90 self[handler](self, ...) | |
| 91 else | |
| 92 handler(...) | |
| 93 end | |
| 94 end | |
| 95 return orig(...) | |
| 96 end | |
| 97 -- /failsafe hook | |
| 98 else | |
| 99 -- all other hooks | |
| 100 uid = function(...) | |
| 101 if actives[uid] then | |
| 102 if method then | |
| 103 return self[handler](self, ...) | |
| 104 else | |
| 105 return handler(...) | |
| 106 end | |
| 107 elseif not secure then -- backup on non secure | |
| 108 return orig(...) | |
| 109 end | |
| 110 end | |
| 111 -- /hook | |
| 112 end | |
| 113 return uid | |
| 114 end | |
| 115 | |
| 116 function donothing() end | |
| 117 | |
| 118 function hook(self, obj, method, handler, script, secure, raw, forceSecure, usage) | |
| 119 if not handler then handler = method end | |
| 120 | |
| 121 -- These asserts make sure AceHooks's devs play by the rules. | |
| 122 assert(not script or type(script) == "boolean") | |
| 123 assert(not secure or type(secure) == "boolean") | |
| 124 assert(not raw or type(raw) == "boolean") | |
| 125 assert(not forceSecure or type(forceSecure) == "boolean") | |
| 126 assert(usage) | |
| 127 | |
| 128 -- Error checking Battery! | |
| 129 if obj and type(obj) ~= "table" then | |
| 130 error(format("%s: 'object' - nil or table expected got %s", usage, type(obj)), 3) | |
| 131 end | |
| 132 if type(method) ~= "string" then | |
| 133 error(format("%s: 'method' - string expected got %s", usage, type(method)), 3) | |
| 134 end | |
| 135 if type(handler) ~= "string" and type(handler) ~= "function" then | |
| 136 error(format("%s: 'handler' - nil, string, or function expected got %s", usage, type(handler)), 3) | |
| 137 end | |
| 138 if type(handler) == "string" and type(self[handler]) ~= "function" then | |
| 139 error(format("%s: 'handler' - Handler specified does not exist at self[handler]", usage), 3) | |
| 140 end | |
| 141 if script then | |
| 142 if not secure and obj:IsProtected() and protectedScripts[method] then | |
| 143 error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3) | |
| 144 end | |
| 145 if not obj or not obj.GetScript or not obj:HasScript(method) then | |
| 146 error(format("%s: You can only hook a script on a frame object", usage), 3) | |
| 147 end | |
| 148 else | |
| 149 local issecure | |
| 150 if obj then | |
| 151 issecure = onceSecure[obj] and onceSecure[obj][method] or issecurevariable(obj, method) | |
| 152 else | |
| 153 issecure = onceSecure[method] or issecurevariable(method) | |
| 154 end | |
| 155 if issecure then | |
| 156 if forceSecure then | |
| 157 if obj then | |
| 158 onceSecure[obj] = onceSecure[obj] or {} | |
| 159 onceSecure[obj][method] = true | |
| 160 else | |
| 161 onceSecure[method] = true | |
| 162 end | |
| 163 elseif not secure then | |
| 164 error(format("%s: Attempt to hook secure function %s. Use `SecureHook' or add `true' to the argument list to override.", usage, method), 3) | |
| 165 end | |
| 166 end | |
| 167 end | |
| 168 | |
| 169 local uid | |
| 170 if obj then | |
| 171 uid = registry[self][obj] and registry[self][obj][method] | |
| 172 else | |
| 173 uid = registry[self][method] | |
| 174 end | |
| 175 | |
| 176 if uid then | |
| 177 if actives[uid] then | |
| 178 -- Only two sane choices exist here. We either a) error 100% of the time or b) always unhook and then hook | |
| 179 -- choice b would likely lead to odd debuging conditions or other mysteries so we're going with a. | |
| 180 error(format("Attempting to rehook already active hook %s.", method)) | |
| 181 end | |
| 182 | |
| 183 if handlers[uid] == handler then -- turn on a decative hook, note enclosures break this ability, small memory leak | |
| 184 actives[uid] = true | |
| 185 return | |
| 186 elseif obj then -- is there any reason not to call unhook instead of doing the following several lines? | |
| 187 if self.hooks and self.hooks[obj] then | |
| 188 self.hooks[obj][method] = nil | |
| 189 end | |
| 190 registry[self][obj][method] = nil | |
| 191 else | |
| 192 if self.hooks then | |
| 193 self.hooks[method] = nil | |
| 194 end | |
| 195 registry[self][method] = nil | |
| 196 end | |
| 197 handlers[uid], actives[uid], scripts[uid] = nil, nil, nil | |
| 198 uid = nil | |
| 199 end | |
| 200 | |
| 201 local orig | |
| 202 if script then | |
| 203 orig = obj:GetScript(method) or donothing | |
| 204 elseif obj then | |
| 205 orig = obj[method] | |
| 206 else | |
| 207 orig = _G[method] | |
| 208 end | |
| 209 | |
| 210 if not orig then | |
| 211 error(format("%s: Attempting to hook a non existing target", usage), 3) | |
| 212 end | |
| 213 | |
| 214 uid = createHook(self, handler, orig, secure, not (raw or secure)) | |
| 215 | |
| 216 if obj then | |
| 217 self.hooks[obj] = self.hooks[obj] or {} | |
| 218 registry[self][obj] = registry[self][obj] or {} | |
| 219 registry[self][obj][method] = uid | |
| 220 | |
| 221 if not secure then | |
| 222 self.hooks[obj][method] = orig | |
| 223 end | |
| 224 | |
| 225 if script then | |
| 226 -- If the script is empty before, HookScript will not work, so use SetScript instead | |
| 227 -- This will make the hook insecure, but shouldnt matter, since it was empty before. | |
| 228 -- It does not taint the full frame. | |
| 229 if not secure or orig == donothing then | |
| 230 obj:SetScript(method, uid) | |
| 231 elseif secure then | |
| 232 obj:HookScript(method, uid) | |
| 233 end | |
| 234 else | |
| 235 if not secure then | |
| 236 obj[method] = uid | |
| 237 else | |
| 238 hooksecurefunc(obj, method, uid) | |
| 239 end | |
| 240 end | |
| 241 else | |
| 242 registry[self][method] = uid | |
| 243 | |
| 244 if not secure then | |
| 245 _G[method] = uid | |
| 246 self.hooks[method] = orig | |
| 247 else | |
| 248 hooksecurefunc(method, uid) | |
| 249 end | |
| 250 end | |
| 251 | |
| 252 actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil | |
| 253 end | |
| 254 | |
| 255 --- Hook a function or a method on an object. | |
| 256 -- The hook created will be a "safe hook", that means that your handler will be called | |
| 257 -- before the hooked function ("Pre-Hook"), and you don't have to call the original function yourself, | |
| 258 -- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\ | |
| 259 -- This type of hook is typically used if you need to know if some function got called, and don't want to modify it. | |
| 260 -- @paramsig [object], method, [handler], [hookSecure] | |
| 261 -- @param object The object to hook a method from | |
| 262 -- @param method If object was specified, the name of the method, or the name of the function to hook. | |
| 263 -- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function) | |
| 264 -- @param hookSecure If true, AceHook will allow hooking of secure functions. | |
| 265 -- @usage | |
| 266 -- -- create an addon with AceHook embeded | |
| 267 -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0") | |
| 268 -- | |
| 269 -- function MyAddon:OnEnable() | |
| 270 -- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status | |
| 271 -- self:Hook("ActionButton_UpdateHotkeys", true) | |
| 272 -- end | |
| 273 -- | |
| 274 -- function MyAddon:ActionButton_UpdateHotkeys(button, type) | |
| 275 -- print(button:GetName() .. " is updating its HotKey") | |
| 276 -- end | |
| 277 function AceHook:Hook(object, method, handler, hookSecure) | |
| 278 if type(object) == "string" then | |
| 279 method, handler, hookSecure, object = object, method, handler, nil | |
| 280 end | |
| 281 | |
| 282 if handler == true then | |
| 283 handler, hookSecure = nil, true | |
| 284 end | |
| 285 | |
| 286 hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])") | |
| 287 end | |
| 288 | |
| 289 --- RawHook a function or a method on an object. | |
| 290 -- The hook created will be a "raw hook", that means that your handler will completly replace | |
| 291 -- the original function, and your handler has to call the original function (or not, depending on your intentions).\\ | |
| 292 -- The original function will be stored in `self.hooks[object][method]` or `self.hooks[functionName]` respectively.\\ | |
| 293 -- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments | |
| 294 -- or want to control execution of the original function. | |
| 295 -- @paramsig [object], method, [handler], [hookSecure] | |
| 296 -- @param object The object to hook a method from | |
| 297 -- @param method If object was specified, the name of the method, or the name of the function to hook. | |
| 298 -- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function) | |
| 299 -- @param hookSecure If true, AceHook will allow hooking of secure functions. | |
| 300 -- @usage | |
| 301 -- -- create an addon with AceHook embeded | |
| 302 -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0") | |
| 303 -- | |
| 304 -- function MyAddon:OnEnable() | |
| 305 -- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status | |
| 306 -- self:RawHook("ActionButton_UpdateHotkeys", true) | |
| 307 -- end | |
| 308 -- | |
| 309 -- function MyAddon:ActionButton_UpdateHotkeys(button, type) | |
| 310 -- if button:GetName() == "MyButton" then | |
| 311 -- -- do stuff here | |
| 312 -- else | |
| 313 -- self.hooks.ActionButton_UpdateHotkeys(button, type) | |
| 314 -- end | |
| 315 -- end | |
| 316 function AceHook:RawHook(object, method, handler, hookSecure) | |
| 317 if type(object) == "string" then | |
| 318 method, handler, hookSecure, object = object, method, handler, nil | |
| 319 end | |
| 320 | |
| 321 if handler == true then | |
| 322 handler, hookSecure = nil, true | |
| 323 end | |
| 324 | |
| 325 hook(self, object, method, handler, false, false, true, hookSecure or false, "Usage: RawHook([object], method, [handler], [hookSecure])") | |
| 326 end | |
| 327 | |
| 328 --- SecureHook a function or a method on an object. | |
| 329 -- This function is a wrapper around the `hooksecurefunc` function in the WoW API. Using AceHook | |
| 330 -- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't | |
| 331 -- required anymore, or the addon is being disabled.\\ | |
| 332 -- Secure Hooks should be used if the secure-status of the function is vital to its function, | |
| 333 -- and taint would block execution. Secure Hooks are always called after the original function was called | |
| 334 -- ("Post Hook"), and you cannot modify the arguments, return values or control the execution. | |
| 335 -- @paramsig [object], method, [handler] | |
| 336 -- @param object The object to hook a method from | |
| 337 -- @param method If object was specified, the name of the method, or the name of the function to hook. | |
| 338 -- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function) | |
| 339 function AceHook:SecureHook(object, method, handler) | |
| 340 if type(object) == "string" then | |
| 341 method, handler, object = object, method, nil | |
| 342 end | |
| 343 | |
| 344 hook(self, object, method, handler, false, true, false, false, "Usage: SecureHook([object], method, [handler])") | |
| 345 end | |
| 346 | |
| 347 --- Hook a script handler on a frame. | |
| 348 -- The hook created will be a "safe hook", that means that your handler will be called | |
| 349 -- before the hooked script ("Pre-Hook"), and you don't have to call the original function yourself, | |
| 350 -- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\ | |
| 351 -- This is the frame script equivalent of the :Hook safe-hook. It would typically be used to be notified | |
| 352 -- when a certain event happens to a frame. | |
| 353 -- @paramsig frame, script, [handler] | |
| 354 -- @param frame The Frame to hook the script on | |
| 355 -- @param script The script to hook | |
| 356 -- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script) | |
| 357 -- @usage | |
| 358 -- -- create an addon with AceHook embeded | |
| 359 -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0") | |
| 360 -- | |
| 361 -- function MyAddon:OnEnable() | |
| 362 -- -- Hook the OnShow of FriendsFrame | |
| 363 -- self:HookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow") | |
| 364 -- end | |
| 365 -- | |
| 366 -- function MyAddon:FriendsFrameOnShow(frame) | |
| 367 -- print("The FriendsFrame was shown!") | |
| 368 -- end | |
| 369 function AceHook:HookScript(frame, script, handler) | |
| 370 hook(self, frame, script, handler, true, false, false, false, "Usage: HookScript(object, method, [handler])") | |
| 371 end | |
| 372 | |
| 373 --- RawHook a script handler on a frame. | |
| 374 -- The hook created will be a "raw hook", that means that your handler will completly replace | |
| 375 -- the original script, and your handler has to call the original script (or not, depending on your intentions).\\ | |
| 376 -- The original script will be stored in `self.hooks[frame][script]`.\\ | |
| 377 -- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments | |
| 378 -- or want to control execution of the original script. | |
| 379 -- @paramsig frame, script, [handler] | |
| 380 -- @param frame The Frame to hook the script on | |
| 381 -- @param script The script to hook | |
| 382 -- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script) | |
| 383 -- @usage | |
| 384 -- -- create an addon with AceHook embeded | |
| 385 -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0") | |
| 386 -- | |
| 387 -- function MyAddon:OnEnable() | |
| 388 -- -- Hook the OnShow of FriendsFrame | |
| 389 -- self:RawHookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow") | |
| 390 -- end | |
| 391 -- | |
| 392 -- function MyAddon:FriendsFrameOnShow(frame) | |
| 393 -- -- Call the original function | |
| 394 -- self.hooks[frame].OnShow(frame) | |
| 395 -- -- Do our processing | |
| 396 -- -- .. stuff | |
| 397 -- end | |
| 398 function AceHook:RawHookScript(frame, script, handler) | |
| 399 hook(self, frame, script, handler, true, false, true, false, "Usage: RawHookScript(object, method, [handler])") | |
| 400 end | |
| 401 | |
| 402 --- SecureHook a script handler on a frame. | |
| 403 -- This function is a wrapper around the `frame:HookScript` function in the WoW API. Using AceHook | |
| 404 -- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't | |
| 405 -- required anymore, or the addon is being disabled.\\ | |
| 406 -- Secure Hooks should be used if the secure-status of the function is vital to its function, | |
| 407 -- and taint would block execution. Secure Hooks are always called after the original function was called | |
| 408 -- ("Post Hook"), and you cannot modify the arguments, return values or control the execution. | |
| 409 -- @paramsig frame, script, [handler] | |
| 410 -- @param frame The Frame to hook the script on | |
| 411 -- @param script The script to hook | |
| 412 -- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script) | |
| 413 function AceHook:SecureHookScript(frame, script, handler) | |
| 414 hook(self, frame, script, handler, true, true, false, false, "Usage: SecureHookScript(object, method, [handler])") | |
| 415 end | |
| 416 | |
| 417 --- Unhook from the specified function, method or script. | |
| 418 -- @paramsig [obj], method | |
| 419 -- @param obj The object or frame to unhook from | |
| 420 -- @param method The name of the method, function or script to unhook from. | |
| 421 function AceHook:Unhook(obj, method) | |
| 422 local usage = "Usage: Unhook([obj], method)" | |
| 423 if type(obj) == "string" then | |
| 424 method, obj = obj, nil | |
| 425 end | |
| 426 | |
| 427 if obj and type(obj) ~= "table" then | |
| 428 error(format("%s: 'obj' - expecting nil or table got %s", usage, type(obj)), 2) | |
| 429 end | |
| 430 if type(method) ~= "string" then | |
| 431 error(format("%s: 'method' - expeting string got %s", usage, type(method)), 2) | |
| 432 end | |
| 433 | |
| 434 local uid | |
| 435 if obj then | |
| 436 uid = registry[self][obj] and registry[self][obj][method] | |
| 437 else | |
| 438 uid = registry[self][method] | |
| 439 end | |
| 440 | |
| 441 if not uid or not actives[uid] then | |
| 442 -- Declining to error on an unneeded unhook since the end effect is the same and this would just be annoying. | |
| 443 return false | |
| 444 end | |
| 445 | |
| 446 actives[uid], handlers[uid] = nil, nil | |
| 447 | |
| 448 if obj then | |
| 449 registry[self][obj][method] = nil | |
| 450 registry[self][obj] = next(registry[self][obj]) and registry[self][obj] or nil | |
| 451 | |
| 452 -- if the hook reference doesnt exist, then its a secure hook, just bail out and dont do any unhooking | |
| 453 if not self.hooks[obj] or not self.hooks[obj][method] then return true end | |
| 454 | |
| 455 if scripts[uid] and obj:GetScript(method) == uid then -- unhooks scripts | |
| 456 obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil) | |
| 457 scripts[uid] = nil | |
| 458 elseif obj and self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then -- unhooks methods | |
| 459 obj[method] = self.hooks[obj][method] | |
| 460 end | |
| 461 | |
| 462 self.hooks[obj][method] = nil | |
| 463 self.hooks[obj] = next(self.hooks[obj]) and self.hooks[obj] or nil | |
| 464 else | |
| 465 registry[self][method] = nil | |
| 466 | |
| 467 -- if self.hooks[method] doesn't exist, then this is a SecureHook, just bail out | |
| 468 if not self.hooks[method] then return true end | |
| 469 | |
| 470 if self.hooks[method] and _G[method] == uid then -- unhooks functions | |
| 471 _G[method] = self.hooks[method] | |
| 472 end | |
| 473 | |
| 474 self.hooks[method] = nil | |
| 475 end | |
| 476 return true | |
| 477 end | |
| 478 | |
| 479 --- Unhook all existing hooks for this addon. | |
| 480 function AceHook:UnhookAll() | |
| 481 for key, value in pairs(registry[self]) do | |
| 482 if type(key) == "table" then | |
| 483 for method in pairs(value) do | |
| 484 self:Unhook(key, method) | |
| 485 end | |
| 486 else | |
| 487 self:Unhook(key) | |
| 488 end | |
| 489 end | |
| 490 end | |
| 491 | |
| 492 --- Check if the specific function, method or script is already hooked. | |
| 493 -- @paramsig [obj], method | |
| 494 -- @param obj The object or frame to unhook from | |
| 495 -- @param method The name of the method, function or script to unhook from. | |
| 496 function AceHook:IsHooked(obj, method) | |
| 497 -- we don't check if registry[self] exists, this is done by evil magicks in the metatable | |
| 498 if type(obj) == "string" then | |
| 499 if registry[self][obj] and actives[registry[self][obj]] then | |
| 500 return true, handlers[registry[self][obj]] | |
| 501 end | |
| 502 else | |
| 503 if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then | |
| 504 return true, handlers[registry[self][obj][method]] | |
| 505 end | |
| 506 end | |
| 507 | |
| 508 return false, nil | |
| 509 end | |
| 510 | |
| 511 --- Upgrade our old embeded | |
| 512 for target, v in pairs( AceHook.embeded ) do | |
| 513 AceHook:Embed( target ) | |
| 514 end |
