annotate libs/AceHook-2.0/AceHook-2.0.lua @ 1:c11ca1d8ed91

Version 0.1
author Flick <flickerstreak@gmail.com>
date Tue, 20 Mar 2007 21:03:57 +0000
parents
children
rev   line source
flickerstreak@1 1 --[[
flickerstreak@1 2 Name: AceHook-2.0
flickerstreak@1 3 Revision: $Rev: 18708 $
flickerstreak@1 4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
flickerstreak@1 5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
flickerstreak@1 6 Website: http://www.wowace.com/
flickerstreak@1 7 Documentation: http://www.wowace.com/index.php/AceHook-2.0
flickerstreak@1 8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceHook-2.0
flickerstreak@1 9 Description: Mixin to allow for safe hooking of functions, methods, and scripts.
flickerstreak@1 10 Dependencies: AceLibrary, AceOO-2.0
flickerstreak@1 11 ]]
flickerstreak@1 12
flickerstreak@1 13 local MAJOR_VERSION = "AceHook-2.0"
flickerstreak@1 14 local MINOR_VERSION = "$Revision: 18708 $"
flickerstreak@1 15
flickerstreak@1 16 -- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
flickerstreak@1 17 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
flickerstreak@1 18 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
flickerstreak@1 19
flickerstreak@1 20 local lua51 = loadstring("return function(...) return ... end") and true or false
flickerstreak@1 21
flickerstreak@1 22 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
flickerstreak@1 23
flickerstreak@1 24 --[[---------------------------------------------------------------------------------
flickerstreak@1 25 Create the library object
flickerstreak@1 26 ----------------------------------------------------------------------------------]]
flickerstreak@1 27
flickerstreak@1 28 local AceOO = AceLibrary:GetInstance("AceOO-2.0")
flickerstreak@1 29 local AceHook = AceOO.Mixin {
flickerstreak@1 30 "Hook",
flickerstreak@1 31 "Unhook",
flickerstreak@1 32 "UnhookAll",
flickerstreak@1 33 "HookReport",
flickerstreak@1 34 "IsHooked",
flickerstreak@1 35 "HookScript",
flickerstreak@1 36 }
flickerstreak@1 37
flickerstreak@1 38 local table_setn = lua51 and function() end or table.setn
flickerstreak@1 39
flickerstreak@1 40 if lua51 then
flickerstreak@1 41 AceHook.__deprecated = MAJOR_VERSION .. " is deprecated in WoW 2.0"
flickerstreak@1 42 end
flickerstreak@1 43
flickerstreak@1 44 --[[---------------------------------------------------------------------------------
flickerstreak@1 45 Library Definitions
flickerstreak@1 46 ----------------------------------------------------------------------------------]]
flickerstreak@1 47
flickerstreak@1 48 local protFuncs = {
flickerstreak@1 49 CameraOrSelectOrMoveStart = true, CameraOrSelectOrMoveStop = true,
flickerstreak@1 50 TurnOrActionStart = true, TurnOrActionStop = true,
flickerstreak@1 51 PitchUpStart = true, PitchUpStop = true,
flickerstreak@1 52 PitchDownStart = true, PitchDownStop = true,
flickerstreak@1 53 MoveBackwardStart = true, MoveBackwardStop = true,
flickerstreak@1 54 MoveForwardStart = true, MoveForwardStop = true,
flickerstreak@1 55 Jump = true, StrafeLeftStart = true,
flickerstreak@1 56 StrafeLeftStop = true, StrafeRightStart = true,
flickerstreak@1 57 StrafeRightStop = true, ToggleMouseMove = true,
flickerstreak@1 58 ToggleRun = true, TurnLeftStart = true,
flickerstreak@1 59 TurnLeftStop = true, TurnRightStart = true,
flickerstreak@1 60 TurnRightStop = true,
flickerstreak@1 61 }
flickerstreak@1 62
flickerstreak@1 63 local _G = getfenv(0)
flickerstreak@1 64
flickerstreak@1 65 local handlers, funcs, scripts, actives
flickerstreak@1 66
flickerstreak@1 67 --[[---------------------------------------------------------------------------------
flickerstreak@1 68 Private definitions (Not exposed)
flickerstreak@1 69 ----------------------------------------------------------------------------------]]
flickerstreak@1 70
flickerstreak@1 71 --[[----------------------------------------------------------------------
flickerstreak@1 72 _debug - Internal Method
flickerstreak@1 73 -------------------------------------------------------------------------]]
flickerstreak@1 74 local function print(text)
flickerstreak@1 75 DEFAULT_CHAT_FRAME:AddMessage(text)
flickerstreak@1 76 end
flickerstreak@1 77
flickerstreak@1 78 local function _debug(self, msg)
flickerstreak@1 79 local name = self.hooks.name
flickerstreak@1 80 if name then
flickerstreak@1 81 print(string.format("[%s]: %s", name, msg))
flickerstreak@1 82 else
flickerstreak@1 83 print(msg)
flickerstreak@1 84 end
flickerstreak@1 85 end
flickerstreak@1 86
flickerstreak@1 87 local new, del
flickerstreak@1 88 do
flickerstreak@1 89 local list = setmetatable({}, {__mode = "k"})
flickerstreak@1 90 function new()
flickerstreak@1 91 local t = next(list)
flickerstreak@1 92 if not t then
flickerstreak@1 93 return {}
flickerstreak@1 94 end
flickerstreak@1 95 list[t] = nil
flickerstreak@1 96 return t
flickerstreak@1 97 end
flickerstreak@1 98
flickerstreak@1 99 function del(t)
flickerstreak@1 100 setmetatable(t, nil)
flickerstreak@1 101 table_setn(t, 0)
flickerstreak@1 102 for k in pairs(t) do
flickerstreak@1 103 t[k] = nil
flickerstreak@1 104 end
flickerstreak@1 105 list[t] = true
flickerstreak@1 106 end
flickerstreak@1 107 end
flickerstreak@1 108
flickerstreak@1 109 local origMetatable = {
flickerstreak@1 110 __call = function(self, ...)
flickerstreak@1 111 return self.orig(...)
flickerstreak@1 112 end
flickerstreak@1 113 }
flickerstreak@1 114
flickerstreak@1 115 --[[----------------------------------------------------------------------
flickerstreak@1 116 AceHook:_getFunctionHook- internal method
flickerstreak@1 117 -------------------------------------------------------------------------]]
flickerstreak@1 118
flickerstreak@1 119 local function _getFunctionHook(self, func, handler, orig)
flickerstreak@1 120 if type(handler) == "string" then
flickerstreak@1 121 -- The handler is a method, need to self it
flickerstreak@1 122 return function(...)
flickerstreak@1 123 if actives[orig] then
flickerstreak@1 124 return self[handler](self, ...)
flickerstreak@1 125 else
flickerstreak@1 126 return orig(...)
flickerstreak@1 127 end
flickerstreak@1 128 end
flickerstreak@1 129 else
flickerstreak@1 130 -- The handler is a function, just call it
flickerstreak@1 131 return function(...)
flickerstreak@1 132 if actives[orig] then
flickerstreak@1 133 return handler(...)
flickerstreak@1 134 else
flickerstreak@1 135 return orig(...)
flickerstreak@1 136 end
flickerstreak@1 137 end
flickerstreak@1 138 end
flickerstreak@1 139 end
flickerstreak@1 140
flickerstreak@1 141 --[[----------------------------------------------------------------------
flickerstreak@1 142 AceHook:_getMethodHook - Internal Method
flickerstreak@1 143 -------------------------------------------------------------------------]]
flickerstreak@1 144 local function _getMethodHook(self, object, method, handler, orig, script)
flickerstreak@1 145 if type(handler) == "string" then
flickerstreak@1 146 -- The handler is a method, need to self it
flickerstreak@1 147 if script then
flickerstreak@1 148 return function()
flickerstreak@1 149 if actives[orig] then
flickerstreak@1 150 return self[handler](self, object)
flickerstreak@1 151 else
flickerstreak@1 152 return orig()
flickerstreak@1 153 end
flickerstreak@1 154 end
flickerstreak@1 155 else
flickerstreak@1 156 return function(obj,...)
flickerstreak@1 157 if actives[orig] then
flickerstreak@1 158 return self[handler](self, obj, ...)
flickerstreak@1 159 else
flickerstreak@1 160 return orig(obj, ...)
flickerstreak@1 161 end
flickerstreak@1 162 end
flickerstreak@1 163 end
flickerstreak@1 164 else
flickerstreak@1 165 -- The handler is a function, just call it
flickerstreak@1 166 if script then
flickerstreak@1 167 return function()
flickerstreak@1 168 if actives[orig] then
flickerstreak@1 169 return handler(object)
flickerstreak@1 170 else
flickerstreak@1 171 return orig()
flickerstreak@1 172 end
flickerstreak@1 173 end
flickerstreak@1 174 else
flickerstreak@1 175 return function(obj, ...)
flickerstreak@1 176 if actives[orig] then
flickerstreak@1 177 return handler(obj, ...)
flickerstreak@1 178 else
flickerstreak@1 179 return orig(obj, ...)
flickerstreak@1 180 end
flickerstreak@1 181 end
flickerstreak@1 182 end
flickerstreak@1 183 end
flickerstreak@1 184 end
flickerstreak@1 185
flickerstreak@1 186 --[[----------------------------------------------------------------------
flickerstreak@1 187 AceHook:HookFunc - internal method.
flickerstreak@1 188 o You can only hook each function once from each source.
flickerstreak@1 189 o If there is an inactive hook for this func/handler pair, we reactivate it
flickerstreak@1 190 o If there is an inactive hook for another handler, we error out.
flickerstreak@1 191 o Looks for handler as a method of the calling class, error if not available
flickerstreak@1 192 o If handler is a function, it just uses it directly through the wrapper
flickerstreak@1 193 -------------------------------------------------------------------------]]
flickerstreak@1 194 local function _hookFunc(self, func, handler)
flickerstreak@1 195 local orig = _G[func]
flickerstreak@1 196
flickerstreak@1 197 if not orig or type(orig) ~= "function" then
flickerstreak@1 198 _debug(self, string.format("Attempt to hook a non-existant function %q", func),3)
flickerstreak@1 199 return
flickerstreak@1 200 end
flickerstreak@1 201
flickerstreak@1 202 if not handler then handler = func end
flickerstreak@1 203
flickerstreak@1 204 if self.hooks[func] then
flickerstreak@1 205 local orig = self.hooks[func].orig
flickerstreak@1 206 -- We have an active hook from this source. Don't multi-hook
flickerstreak@1 207 if actives[orig] then
flickerstreak@1 208 _debug(self, string.format("%q already has an active hook from this source.", func))
flickerstreak@1 209 return
flickerstreak@1 210 end
flickerstreak@1 211 -- The hook is inactive, so reactivate it
flickerstreak@1 212 if handlers[orig] == handler then
flickerstreak@1 213 actives[orig] = true
flickerstreak@1 214 return
flickerstreak@1 215 else
flickerstreak@1 216 AceHook:error("There is a stale hook for %q can't hook or reactivate.", func)
flickerstreak@1 217 end
flickerstreak@1 218 end
flickerstreak@1 219
flickerstreak@1 220 if type(handler) == "string" then
flickerstreak@1 221 if type(self[handler]) ~= "function" then
flickerstreak@1 222 AceHook:error("Could not find the the handler %q when hooking function %q", handler, func)
flickerstreak@1 223 end
flickerstreak@1 224 elseif type(handler) ~= "function" then
flickerstreak@1 225 AceHook:error("Could not find the handler you supplied when hooking %q", func)
flickerstreak@1 226 end
flickerstreak@1 227
flickerstreak@1 228 local t = setmetatable(new(), origMetatable)
flickerstreak@1 229 self.hooks[func] = t
flickerstreak@1 230 t.orig = orig
flickerstreak@1 231
flickerstreak@1 232 actives[orig] = true
flickerstreak@1 233 handlers[orig] = handler
flickerstreak@1 234 local newFunc = _getFunctionHook(self, func, handler, orig)
flickerstreak@1 235 funcs[orig] = newFunc
flickerstreak@1 236
flickerstreak@1 237 _G[func] = newFunc
flickerstreak@1 238 end
flickerstreak@1 239
flickerstreak@1 240 --[[----------------------------------------------------------------------
flickerstreak@1 241 AceHook:UnhookFunc - internal method
flickerstreak@1 242 o If you attempt to unhook a function that has never been hooked, or to unhook in a
flickerstreak@1 243 system that has never had a hook before, the system will error with a stack trace
flickerstreak@1 244 o If we own the global function, then put the original back in its place and remove
flickerstreak@1 245 all references to the Hooks[func] structure.
flickerstreak@1 246 o If we don't own the global function (we've been hooked) we deactivate the hook,
flickerstreak@1 247 forcing the handler to passthrough.
flickerstreak@1 248 -------------------------------------------------------------------------]]
flickerstreak@1 249 local function _unhookFunc(self, func)
flickerstreak@1 250 if not self.hooks[func] or not funcs[self.hooks[func].orig] then
flickerstreak@1 251 _debug(self, string.format("Tried to unhook %q which is not currently hooked.", func))
flickerstreak@1 252 return
flickerstreak@1 253 end
flickerstreak@1 254
flickerstreak@1 255 local orig = self.hooks[func].orig
flickerstreak@1 256
flickerstreak@1 257 if actives[orig] then
flickerstreak@1 258 -- See if we own the global function
flickerstreak@1 259 if _G[func] == funcs[orig] then
flickerstreak@1 260 _G[func] = orig
flickerstreak@1 261 self.hooks[func] = del(self.hooks[func])
flickerstreak@1 262 handlers[orig] = nil
flickerstreak@1 263 funcs[orig] = nil
flickerstreak@1 264 scripts[orig] = nil
flickerstreak@1 265 actives[orig] = nil
flickerstreak@1 266 -- Magically all-done
flickerstreak@1 267 else
flickerstreak@1 268 actives[orig] = nil
flickerstreak@1 269 end
flickerstreak@1 270 end
flickerstreak@1 271 end
flickerstreak@1 272
flickerstreak@1 273 --[[----------------------------------------------------------------------
flickerstreak@1 274 AceHook:HookMeth - Takes an optional fourth argument
flickerstreak@1 275 o script - Signifies whether this is a script hook or not
flickerstreak@1 276 -------------------------------------------------------------------------]]
flickerstreak@1 277
flickerstreak@1 278 local function _hookMeth(self, obj, method, handler, script)
flickerstreak@1 279 if not handler then handler = method end
flickerstreak@1 280 if (not obj or type(obj) ~= "table") then
flickerstreak@1 281 AceHook:error("The object you supplied could not be found, or isn't a table.")
flickerstreak@1 282 end
flickerstreak@1 283
flickerstreak@1 284 if self.hooks[obj] and self.hooks[obj][method] then
flickerstreak@1 285 local orig = self.hooks[obj][method].orig
flickerstreak@1 286 -- We have an active hook from this source. Don't multi-hook
flickerstreak@1 287 if actives[orig] then
flickerstreak@1 288 _debug(self, string.format("%q already has an active hook from this source.", method))
flickerstreak@1 289 return
flickerstreak@1 290 end
flickerstreak@1 291 -- The hook is inactive, so reactivate it.
flickerstreak@1 292 if handlers[orig] == handler then
flickerstreak@1 293 actives[orig] = true
flickerstreak@1 294 return
flickerstreak@1 295 else
flickerstreak@1 296 AceHook:error("There is a stale hook for %q can't hook or reactivate.", method)
flickerstreak@1 297 end
flickerstreak@1 298 end
flickerstreak@1 299 -- We're clear to try the hook, let's make some checks first
flickerstreak@1 300 if type(handler) == "string" then
flickerstreak@1 301 if type(self[handler]) ~= "function" then
flickerstreak@1 302 AceHook:error("Could not find the handler %q you supplied when hooking method %q", handler, method)
flickerstreak@1 303 end
flickerstreak@1 304 elseif type(handler) ~= "function" then
flickerstreak@1 305 AceHook:error("Could not find the handler you supplied when hooking method %q", method)
flickerstreak@1 306 end
flickerstreak@1 307 -- Handler has been found, so now try to find the method we're trying to hook
flickerstreak@1 308 local orig
flickerstreak@1 309 -- Script
flickerstreak@1 310 if script then
flickerstreak@1 311 if not obj.GetScript then
flickerstreak@1 312 AceHook:error("The object you supplied does not have a GetScript method.")
flickerstreak@1 313 end
flickerstreak@1 314 if not obj:HasScript(method) then
flickerstreak@1 315 AceHook:error("The object you supplied doesn't allow the %q method.", method)
flickerstreak@1 316 end
flickerstreak@1 317 -- Sometimes there is not a original function for a script.
flickerstreak@1 318 orig = obj:GetScript(method)
flickerstreak@1 319 if not orig then
flickerstreak@1 320 orig = function() end
flickerstreak@1 321 end
flickerstreak@1 322 -- Method
flickerstreak@1 323 else
flickerstreak@1 324 orig = obj[method]
flickerstreak@1 325 end
flickerstreak@1 326 if not orig then
flickerstreak@1 327 AceHook:error("Could not find the method or script %q you are trying to hook.", method)
flickerstreak@1 328 end
flickerstreak@1 329 if not self.hooks[obj] then
flickerstreak@1 330 self.hooks[obj] = new()
flickerstreak@1 331 end
flickerstreak@1 332 local t = setmetatable(new(), origMetatable)
flickerstreak@1 333 self.hooks[obj][method] = t
flickerstreak@1 334 t.orig = orig
flickerstreak@1 335
flickerstreak@1 336 actives[orig] = true
flickerstreak@1 337 handlers[orig] = handler
flickerstreak@1 338 scripts[orig] = script and true or nil
flickerstreak@1 339 local newFunc = _getMethodHook(self, obj, method, handler, orig, script)
flickerstreak@1 340 funcs[orig] = newFunc
flickerstreak@1 341
flickerstreak@1 342 if script then
flickerstreak@1 343 obj:SetScript(method, newFunc)
flickerstreak@1 344 else
flickerstreak@1 345 obj[method] = newFunc
flickerstreak@1 346 end
flickerstreak@1 347 end
flickerstreak@1 348
flickerstreak@1 349 --[[----------------------------------------------------------------------
flickerstreak@1 350 AceHook:UnhookMeth - Internal method
flickerstreak@1 351 o If you attempt to unhook a method that has never been hooked, or to unhook in a
flickerstreak@1 352 system that has never had a hook before, the system will error with a stack trace
flickerstreak@1 353 o If we own the global method, then put the original back in its place and remove
flickerstreak@1 354 all references to the Hooks[obj][method] structure.
flickerstreak@1 355 o If we don't own the global method (we've been hooked) we deactivate the hook,
flickerstreak@1 356 forcing the handler to passthrough.
flickerstreak@1 357 -------------------------------------------------------------------------]]
flickerstreak@1 358 local function _unhookMeth(self, obj, method)
flickerstreak@1 359 if not self.hooks[obj] or not self.hooks[obj][method] or not funcs[self.hooks[obj][method].orig] then
flickerstreak@1 360 _debug(self, string.format("Attempt to unhook a method %q that is not currently hooked.", method))
flickerstreak@1 361 return
flickerstreak@1 362 end
flickerstreak@1 363
flickerstreak@1 364 local orig = self.hooks[obj][method].orig
flickerstreak@1 365
flickerstreak@1 366 if actives[orig] then
flickerstreak@1 367 -- If this is a script
flickerstreak@1 368 if scripts[orig] then
flickerstreak@1 369 if obj:GetScript(method) == funcs[orig] then
flickerstreak@1 370 -- We own the script. Kill it.
flickerstreak@1 371 obj:SetScript(method, orig)
flickerstreak@1 372 self.hooks[obj][method] = del(self.hooks[obj][method])
flickerstreak@1 373 handlers[orig] = nil
flickerstreak@1 374 funcs[orig] = nil
flickerstreak@1 375 scripts[orig] = nil
flickerstreak@1 376 actives[orig] = nil
flickerstreak@1 377 else
flickerstreak@1 378 actives[orig] = nil
flickerstreak@1 379 end
flickerstreak@1 380 else
flickerstreak@1 381 if obj[method] == funcs[orig] then
flickerstreak@1 382 -- We own the method. Kill it.
flickerstreak@1 383 obj[method] = orig
flickerstreak@1 384 self.hooks[obj][method] = del(self.hooks[obj][method])
flickerstreak@1 385 handlers[orig] = nil
flickerstreak@1 386 funcs[orig] = nil
flickerstreak@1 387 scripts[orig] = nil
flickerstreak@1 388 actives[orig] = nil
flickerstreak@1 389 else
flickerstreak@1 390 actives[orig] = nil
flickerstreak@1 391 end
flickerstreak@1 392 end
flickerstreak@1 393 end
flickerstreak@1 394 if not next(self.hooks[obj]) then
flickerstreak@1 395 -- Spank the table
flickerstreak@1 396 self.hooks[obj] = del(self.hooks[obj])
flickerstreak@1 397 end
flickerstreak@1 398 end
flickerstreak@1 399
flickerstreak@1 400 function AceHook:OnInstanceInit(object)
flickerstreak@1 401 if not object.hooks then
flickerstreak@1 402 object.hooks = new()
flickerstreak@1 403 end
flickerstreak@1 404
flickerstreak@1 405 local name
flickerstreak@1 406
flickerstreak@1 407 if type(rawget(object, 'GetLibraryVersion')) == "function" then
flickerstreak@1 408 name = object:GetLibraryVersion()
flickerstreak@1 409 end
flickerstreak@1 410 if not name and type(object.GetName) == "function" then
flickerstreak@1 411 name = object:GetName()
flickerstreak@1 412 end
flickerstreak@1 413 if not name and type(object.name) == "string" then
flickerstreak@1 414 name = object.name
flickerstreak@1 415 end
flickerstreak@1 416 if not name then
flickerstreak@1 417 for k,v in pairs(_G) do
flickerstreak@1 418 if v == object then
flickerstreak@1 419 name = tostring(k)
flickerstreak@1 420 break
flickerstreak@1 421 end
flickerstreak@1 422 end
flickerstreak@1 423 end
flickerstreak@1 424
flickerstreak@1 425 object.hooks.name = name
flickerstreak@1 426 end
flickerstreak@1 427
flickerstreak@1 428 AceHook.OnManualEmbed = AceHook.OnInstanceInit
flickerstreak@1 429
flickerstreak@1 430 --[[----------------------------------------------------------------------
flickerstreak@1 431 AceHook:Hook
flickerstreak@1 432 self:Hook("functionName", ["handlerName" | handler])
flickerstreak@1 433 self:Hook(ObjectName, "Method", ["Handler" | handler])
flickerstreak@1 434 -------------------------------------------------------------------------]]
flickerstreak@1 435 function AceHook:Hook(arg1, arg2, arg3)
flickerstreak@1 436 if type(arg1)== "string" then
flickerstreak@1 437 if protFuncs[arg1] then
flickerstreak@1 438 if self.hooks.name then
flickerstreak@1 439 AceHook:error("%s tried to hook %q, which is a Blizzard protected function.", self.hooks.name, arg1)
flickerstreak@1 440 else
flickerstreak@1 441 _debug(self, string.format("An Addon tried to hook %q, which is a Blizzard protected function.", arg1))
flickerstreak@1 442 end
flickerstreak@1 443 else
flickerstreak@1 444 _hookFunc(self, arg1, arg2)
flickerstreak@1 445 end
flickerstreak@1 446 else
flickerstreak@1 447 _hookMeth(self, arg1, arg2, arg3)
flickerstreak@1 448 end
flickerstreak@1 449 end
flickerstreak@1 450
flickerstreak@1 451 function AceHook:HookScript(arg1, arg2, arg3)
flickerstreak@1 452 _hookMeth(self, arg1, arg2, arg3, true)
flickerstreak@1 453 end
flickerstreak@1 454
flickerstreak@1 455 --[[----------------------------------------------------------------------
flickerstreak@1 456 AceHook:IsHooked()
flickerstreak@1 457 self:Hook("functionName")
flickerstreak@1 458 self:Hook(ObjectName, "Method")
flickerstreak@1 459
flickerstreak@1 460 Returns whether or not the given function is hooked in the current
flickerstreak@1 461 namespace. A hooked, but inactive function is considered NOT
flickerstreak@1 462 hooked in this context.
flickerstreak@1 463 -------------------------------------------------------------------------]]
flickerstreak@1 464 function AceHook:IsHooked(obj, method)
flickerstreak@1 465 if method and obj then
flickerstreak@1 466 if self.hooks and self.hooks[obj] and self.hooks[obj][method] and actives[self.hooks[obj][method].orig] then
flickerstreak@1 467 return true, handlers[self.hooks[obj][method].orig]
flickerstreak@1 468 end
flickerstreak@1 469 else
flickerstreak@1 470 if self.hooks and self.hooks[obj] and actives[self.hooks[obj].orig] then
flickerstreak@1 471 return true, handlers[self.hooks[obj].orig]
flickerstreak@1 472 end
flickerstreak@1 473 end
flickerstreak@1 474
flickerstreak@1 475 return false, nil
flickerstreak@1 476 end
flickerstreak@1 477
flickerstreak@1 478 --[[----------------------------------------------------------------------
flickerstreak@1 479 AceHook:Unhook
flickerstreak@1 480 self:Unhook("functionName")
flickerstreak@1 481 self:Unhook(ObjectName, "Method")
flickerstreak@1 482 -------------------------------------------------------------------------]]
flickerstreak@1 483 function AceHook:Unhook(arg1, arg2)
flickerstreak@1 484 if type(arg1) == "string" then
flickerstreak@1 485 _unhookFunc(self, arg1)
flickerstreak@1 486 else
flickerstreak@1 487 _unhookMeth(self, arg1, arg2)
flickerstreak@1 488 end
flickerstreak@1 489 end
flickerstreak@1 490
flickerstreak@1 491 --[[----------------------------------------------------------------------
flickerstreak@1 492 AceHook:UnhookAll - Unhooks all active hooks from the calling source
flickerstreak@1 493 -------------------------------------------------------------------------]]
flickerstreak@1 494 function AceHook:UnhookAll()
flickerstreak@1 495 for key, value in pairs(self.hooks) do
flickerstreak@1 496 if type(key) == "table" then
flickerstreak@1 497 for method in pairs(value) do
flickerstreak@1 498 self:Unhook(key, method)
flickerstreak@1 499 end
flickerstreak@1 500 else
flickerstreak@1 501 self:Unhook(key)
flickerstreak@1 502 end
flickerstreak@1 503 end
flickerstreak@1 504 end
flickerstreak@1 505
flickerstreak@1 506
flickerstreak@1 507 function AceHook:OnEmbedDisable(target)
flickerstreak@1 508 self.UnhookAll(target)
flickerstreak@1 509 end
flickerstreak@1 510
flickerstreak@1 511 --[[----------------------------------------------------------------------
flickerstreak@1 512 AceHook:HookReport - Lists registered hooks from this source
flickerstreak@1 513 -------------------------------------------------------------------------]]
flickerstreak@1 514
flickerstreak@1 515 function AceHook:HookReport()
flickerstreak@1 516 _debug(self, "This is a list of all active hooks for this object:")
flickerstreak@1 517 if not self.hooks then _debug(self, "No registered hooks.") return end
flickerstreak@1 518
flickerstreak@1 519 for key, value in pairs(self.hooks) do
flickerstreak@1 520 if type(value) == "table" then
flickerstreak@1 521 for method in pairs(value) do
flickerstreak@1 522 _debug(self, string.format("key: %s method: %q |cff%s|r", tostring(key), method, self.hooks[key][method].active and "00ff00Active" or "ffff00Inactive"))
flickerstreak@1 523 end
flickerstreak@1 524 else
flickerstreak@1 525 _debug(self, string.format("key: %s value: %q |cff%s|r", tostring(key), tostring(value), self.hooks[key].active and "00ff00Active" or "ffff00Inactive"))
flickerstreak@1 526 end
flickerstreak@1 527 end
flickerstreak@1 528 end
flickerstreak@1 529
flickerstreak@1 530 --[[---------------------------------------------------------------------------------
flickerstreak@1 531 Stub and Library registration
flickerstreak@1 532 ----------------------------------------------------------------------------------]]
flickerstreak@1 533
flickerstreak@1 534 local function activate(self, oldLib, oldDeactivate)
flickerstreak@1 535 AceHook = self
flickerstreak@1 536
flickerstreak@1 537 self.handlers = oldLib and oldLib.handlers or {}
flickerstreak@1 538 self.funcs = oldLib and oldLib.funcs or {}
flickerstreak@1 539 self.scripts = oldLib and oldLib.scripts or {}
flickerstreak@1 540 self.actives = oldLib and oldLib.actives or {}
flickerstreak@1 541
flickerstreak@1 542 handlers = self.handlers
flickerstreak@1 543 funcs = self.funcs
flickerstreak@1 544 scripts = self.scripts
flickerstreak@1 545 actives = self.actives
flickerstreak@1 546
flickerstreak@1 547 self:activate(oldLib, oldDeactivate)
flickerstreak@1 548
flickerstreak@1 549 if oldDeactivate then
flickerstreak@1 550 oldDeactivate(oldLib)
flickerstreak@1 551 end
flickerstreak@1 552 end
flickerstreak@1 553
flickerstreak@1 554 AceLibrary:Register(AceHook, MAJOR_VERSION, MINOR_VERSION, activate)