diff LibFarmbuyer.lua @ 6:df3e27edbd60

Much work on history tab.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Wed, 15 Jun 2011 03:59:13 +0000
parents 822b6ca3ef89
children 5ee4edd24c13
line wrap: on
line diff
--- a/LibFarmbuyer.lua	Wed Apr 27 04:02:02 2011 +0000
+++ b/LibFarmbuyer.lua	Wed Jun 15 03:59:13 2011 +0000
@@ -44,9 +44,16 @@
   Runs F on the next frame refresh cycle.  Multiple calls in one cycle will
   stack LIFO.  Calls *while* processing the stack are safe, and will be stacked
   up for the next cycle.
+
+- safecall (func, ...)
+  A modified copy of the xpcall wrapper duplicated in every Ace3 file in the
+  whole damn library.
+
+- new(...), del(t), copy(t), clear()
+  Ditto for table recycling.
 ]]
 
-local MAJOR, MINOR = "LibFarmbuyer", 7
+local MAJOR, MINOR = "LibFarmbuyer", 9
 assert(LibStub,MAJOR.." requires LibStub")
 local lib = LibStub:NewLibrary(MAJOR, MINOR)
 if not lib then return end
@@ -54,7 +61,40 @@
 _G[MAJOR] = lib
 
 ----------------------------------------------------------------------
+--[[
+	Recycling functions yoinked from AceConfigDialog and tweaked
+]]
 local new, del, copy, clear
+do
+	local pool = setmetatable({},{__mode="k"})
+	function clear()
+		wipe(pool)
+	end
+	function new(...)  -- slightly modified variant, takes optional initializers
+		local t = next(pool)
+		if t then
+			pool[t] = nil
+			for i = 1, select('#',...) do
+				t[i] = select(i,...)
+			end
+			return t
+		else
+			return {...}
+		end
+	end
+	function copy(t)
+		local c = new()
+		for k, v in pairs(t) do
+			c[k] = v
+		end
+		return c
+	end
+	function del(t)
+		wipe(t)
+		pool[t] = true
+	end
+end
+lib.new, lib.del, lib.copy, lib.clear = new, del, copy, clear
 
 
 ----------------------------------------------------------------------
@@ -214,35 +254,60 @@
 
 
 ----------------------------------------------------------------------
--- Recycling functions yoinked from AceConfigDialog and tweaked
+--[[
+	safecall
+]]
 do
-	local pool = setmetatable({},{__mode="k"})
-	function clear()
-		wipe(pool)
+	local xpcall = xpcall
+
+	local function errorhandler(err)
+		--return geterrorhandler()(err)
+		--print("in error handler", err)
+		return err
 	end
-	function new(...)  -- slightly modified variant, takes optional initializers
-		local t = next(pool)
-		if t then
-			pool[t] = nil
-			for i = 1, select('#',...) do
-				t[i] = select(i,...)
-			end
-			return t
-		else
-			return {...}
+
+	local template = ([[
+		local xpcall, eh = ...
+		local method, ARGS
+		local function call() return method(ARGS) end
+
+		local function dispatch (func, ...)
+			 method = func
+			 if not method then return end
+			 ARGS = ...
+			 return xpcall (call, eh)
 		end
+
+		return dispatch
+	]]):gsub('\t','  ')
+
+	local function CreateDispatcher(argCount)
+		local ARGS = {}
+		for i = 1, argCount do ARGS[i] = "arg"..i end
+		local code = template:gsub("ARGS", table.concat(ARGS, ", "))
+		return assert(loadstring(code, "LibF/safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
 	end
-	function copy(t)
-		local c = new()
-		for k, v in pairs(t) do
-			c[k] = v
+
+	local Dispatchers = setmetatable({
+		[0] = function(func)
+			return xpcall (func, errorhandler)
 		end
-		return c
-	end
-	function del(t)
-		wipe(t)
-		pool[t] = true
+	}, {
+		__index = function (Ds, argCount)
+			local dispatcher = CreateDispatcher(argCount)
+			Ds[argCount] = dispatcher
+			return dispatcher
+		end
+	})
+
+	function lib.safecall (func, ...)
+		if type(func) == 'function' then
+			return Dispatchers[select('#', ...)](func, ...)
+		end
 	end
 end
 
+
+----------------------------------------------------------------------
+
 -- vim: noet