PDA

View Full Version : LUA Plugin Helper Functions


MicroByte
07-01-2009, 05:49 PM
with all the plugins that are likely to show up soon, i thought someone had better address the subject of error checking, as 1 or 2 of you might produce something i can use, id rather it had proper plugin style error checking so i dont waist my time looking for errors in the wrong places

i ported the IRLUA_PLUGIN_* functions to lua to assist in error checking and to provide detailed description of the error, please use them in your scripts, this will save time for other users while debugging code.

the helper functions
--################################################## ################################################## #####
-- IRLUA PLUGIN HELPER FUNCTIONS By MicroByte
--################################################## ################################################## #####

--################################################## ################################################## #####
-- Sets a Global error message in the runtime engine.
local IRLUA_PLUGIN_SetGlobalErrorMessage = function(nCode, sMessage)
if _tblErrorMessages[nCode] then
error("Error code "..nCode.." already in use, please use another.")
else
_tblErrorMessages[nCode]=sMessage
end
end
--################################################## ################################################## #####
-- Checks the number of arguments in the table nd throws a syntax error If there are Not enough.
-- This is useful For checking the number of arguments available To your aciton.
local IRLUA_PLUGIN_CheckNumArgs = function(tbArgs,nArgs)
local nCount=table.getn(tbArgs)
if nCount < nArgs then
error(nArgs.." Arguments expected, "..nCount.." Arguments passed.")
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a string.
-- If Not, it tries To convert it To a string. If it can't it throws a syntax error.
local IRLUA_PLUGIN_CheckString = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType == "string" then
return tbArgs[nArg]
else
if tostring(tbArgs[nArg]) then
return tbArgs[nArg]
else
error("Argument " .. nArg .. " must be a string.")
end
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a string.
-- If Not, it tries To convert it To a string. If it can't it throws a syntax error.
local IRLUA_PLUGIN_CheckNumber = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType == "number" then
return tbArgs[nArg]
else
if tonumber(tbArgs[nArg]) then
return tbArgs[nArg]
else
error("Argument " .. nArg .. " must be a number.")
end
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a boolean,.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckBoolean = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "boolean" then
error("Argument " .. nArg .. " must be a boolean.")
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a function.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckFunction = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "function" then
error("Argument " .. nArg .. " must be a function.")
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a thread.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckThread = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "thread" then
error("Argument " .. nArg .. " must be a thread.")
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a userdata.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckUserData = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "userdata" then
error("Argument " .. nArg .. " must be a userdata.")
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- END IRLUA PLUGIN HELPER FUNCTIONS
--################################################## ################################################## #####

example use
function MyFunction(...)

-- this function requires 3 arguments, a string, a number and a callback function.

-- check the number of arguments
IRLUA_PLUGIN_CheckNumArgs(arg,3)


local sString=IRLUA_PLUGIN_CheckString(arg,1)
local nNumber=IRLUA_PLUGIN_CheckNumber(arg,2)
local fFunction=IRLUA_PLUGIN_CheckFunction(arg,3)

-- your function code below


end


dont think its worth it ?, give it a try and you soon change your mind.

MicroByte
07-02-2009, 03:21 AM
i really should not write scripts while tired,

replace the below 2 functions
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a string.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckString = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType == "string" then
return tbArgs[nArg]
else
error("Argument " .. nArg .. " must be a string.")
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a number.
-- If Not, it tries To convert it To a string. If it can't it throws a syntax error.
local IRLUA_PLUGIN_CheckNumber = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType == "number" then
return tbArgs[nArg]
else
if tonumber(tbArgs[nArg]) then
return tonumber(tbArgs[nArg])
else
error("Argument " .. nArg .. " must be a number.")
end
end
end

the checkstring was returning the wrong value if boolean value paassed, instead of it throwing a error it simply returned "true" or "false", and i forgot the tonumber() on the check number function.

good luck and happy coding.


EDIT: I forgot to mention, also make heavy use of Application.SetLastError in your actions, try and use predefined error codes but if you need to add error codes use IRLUA_PLUGIN_SetGlobalErrorMessage with a unique number range


example ( if you run the below script the message will read "Some error message"
IRLUA_PLUGIN_SetGlobalErrorMessage(0023114, "Some error message")
IRLUA_PLUGIN_SetGlobalErrorMessage(0023113, "Some other error message")


Application.SetLastError(0023114)


-- Test for error
error = Application.GetLastError();
if (error ~= 0) then
Dialog.Message("Error", _tblErrorMessages[error], MB_OK, MB_ICONEXCLAMATION);
end

Imagine Programming
07-02-2009, 03:49 AM
Nice, thanks! :)

MicroByte
07-02-2009, 08:03 AM
OMG, this is a real good example of not properly testing code, its displaying the wrong line number, i did not set the error level in the error function, slight oversight, huge mistake, also its not showing the path to the object that caused the error "Page 1 >> Plugin 1" etc.

I am preparing a error script that does work.

EDIT: i cant format the error message to include the event context on one line, this values needs to pushed onto the lua stack on the C++ side, i can get the right error line and event, just not the event context, so i added it below the error message (only useful when testing projects with many pages that look the same, etc)

the script should be ready in a hour or so.

Imagine Programming
07-02-2009, 12:39 PM
OMG, this is a real good example of not properly testing code, its displaying the wrong line number, i did not set the error level in the error function, slight oversight, huge mistake, also its not showing the path to the object that caused the error "Page 1 >> Plugin 1" etc.

I am preparing a error script that does work.

EDIT: i cant format the error message to include the event context on one line, this values needs to pushed onto the lua stack on the C++ side, i can get the right error line and event, just not the event context, so i added it below the error message (only useful when testing projects with many pages that look the same, etc)

the script should be ready in a hour or so.

Does using error("message", 4) help?

MicroByte
07-02-2009, 03:35 PM
"error("message", 3)" and "error("message", 2)" got them working, but still cant get the event context right, after all, it is designed to be used in a C++ environment, not lua.

iv got it as good as its goner get,
--################################################## ################################################## #####
-- IRLUA PLUGIN HELPER FUNCTIONS By MicroByte
--################################################## ################################################## #####
_ShowErrorEventContext=true-- set this to false to disable 'EventContext' display
--################################################## ################################################## #####
-- Sets a Global error message in the runtime engine.
IRLUA_PLUGIN_SetGlobalErrorMessage = function(nCode, sMessage)
if _tblErrorMessages[nCode] then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("Error code "..nCode.." already in use, please use another.\r\n\r\nEventContext: "..sEventContext,2)
else
error("Error code "..nCode.." already in use, please use another.",2)
end
else
_tblErrorMessages[nCode]=sMessage
end
end
--################################################## ################################################## #####
-- Checks the number of arguments in the table nd throws a syntax error If there are Not enough.
-- This is useful For checking the number of arguments available To your aciton.
local IRLUA_PLUGIN_CheckNumArgs = function(tbArgs,nArgs)
local nCount=table.getn(tbArgs)
if nCount < nArgs then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error(nArgs.." Arguments expected, "..nCount.." Arguments passed.\r\n\r\nEventContext: "..sEventContext,3)
else
error(nArgs.." Arguments expected, "..nCount.." Arguments passed.",3)
end
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a string.
-- If Not it throws a syntax error.
local IRLUA_PLUGIN_CheckString = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "string" then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a string, you passed a "..type(tbArgs[nArg])..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a string, you passed a "..type(tbArgs[nArg])..".",3)
end
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a number.
-- If Not, it tries To convert it To a number. this is to save use of "tonumber" and "String.ToNumber" while retriveing your functions arguments.
-- If it can't convert it To a number it throws a syntax error.
local IRLUA_PLUGIN_CheckNumber = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "number" then
if tonumber(tbArgs[nArg]) then
return tonumber(tbArgs[nArg]);
else
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a number, you passed a "..type(tbArgs[nArg])..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a number, you passed a "..type(tbArgs[nArg])..".",3)
end
end
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a boolean,.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckBoolean = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "boolean" then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a boolean, you passed a "..type(tbArgs[nArg])..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a boolean, you passed a "..type(tbArgs[nArg])..".",3)
end
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a function.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckFunction = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "function" then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a function, you passed a "..type(tbArgs[nArg])..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a function, you passed a "..type(tbArgs[nArg])..".",3)
end
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a thread.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckThread = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "thread" then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a thread, you passed a "..type(tbArgs[nArg])..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a thread, you passed a "..type(tbArgs[nArg])..".",3)
end
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a userdata.
-- If not it throws a syntax error and exits the function.
local IRLUA_PLUGIN_CheckUserData = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "userdata" then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a userdata, you passed a "..type(tbArgs[nArg])..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a userdata, you passed a "..type(tbArgs[nArg])..".",3)
end
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
-- END IRLUA PLUGIN HELPER FUNCTIONS
--################################################## ################################################## #####

Centauri Soldier
07-19-2009, 02:34 AM
Hey I just wanted to drop by and say thank you, MicroByte. I have just had the opportunity to use your Helper Functions in some of my code and it is, now, indispensable in my book. Well done!:yes:yes:D

MicroByte
07-19-2009, 06:29 AM
ah, im glad you now see the usefulness of these functions :yes

Centauri Soldier
07-20-2009, 02:46 AM
Hey MicroByte,
How do i accept either a string or a number for an argument?

I have a function that can take either a string or a number as an argument and I still want to use the LUA helper functions with my function.

MicroByte
07-20-2009, 03:44 AM
just a slight edit of one of the functions

(Untested but should work)
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a string or a number.
-- If Not it throws a syntax error.
local IRLUA_PLUGIN_CheckNumString = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "string" or sType ~= "number" then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a string or a number, you passed a "..type(tbArgs[nArg])..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a string or a number, you passed a "..type(tbArgs[nArg])..".",3)
end
else
return tbArgs[nArg]
end
end

Centauri Soldier
07-20-2009, 11:46 AM
Cool, thanks! :D

EDIT: I found a bug but a simple word replace fixed it.

--################################################## ################################################## #####
-- Checks the value at a given argument table position To see If it is a string or a number.
-- If Not it throws a syntax error.
local IRLUA_PLUGIN_CheckNumString = function(tbArgs,nArg)
local sType=type(tbArgs[nArg])
if sType ~= "string" and sType ~= "number" then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a string or a number, you passed a "..type(tbArgs[nArg])..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a string or a number, you passed a "..type(tbArgs[nArg])..".",3)
end
else
return tbArgs[nArg]
end
end

Centauri Soldier
08-31-2009, 02:58 AM
A little something for custom error messages in your plugin.

--################################################## ################################################## #####
--ERROR PLUGIN DETAILS
local ERROR_PLUGIN_NAME = "";
--################################################## ################################################## #####
--Displays a custom error message using the plugin and function name and lists the event context as well.
local function ERROR(sFunctionName, sMessage)
if type(sFunctionName) ~= "string" then
sFunctionName = "";
end
Dialog.Message("Error in \""..ERROR_PLUGIN_NAME.."\" plugin", "Error in function \""..sFunctionName.."()\"\r\n"..Debug.GetEventContext().."\r\n\r\n"..sMessage, MB_OK, MB_ICONSTOP, MB_DEFBUTTON1);
end
--[[
add the following to each function...
local sCallingFunction = "MyFunction";
..where "MyFunction" is the name of the calling function.
NOTE: the sCallingFunction variable can be called whatever you like. It is argument number one for the ERROR function
EXAMPLE: ERROR("GlobalPaths.SaveWorld", "The world cannot be saved by a plugin");
]]
--################################################## ################################################## #####

This makes quick error reporting easy.

Centauri Soldier
08-31-2009, 03:43 AM
OK, found a better way to do it already...

--################################################## ################################################## #####
--ERROR PLUGIN DETAILS
local ERROR_PLUGIN_NAME = "";
--################################################## ################################################## #####
--Displays a custom error message using the plugin and function name and lists the event context as well.
local function ERROR(sFunctionName, sMessage)
if type(sFunctionName) ~= "string" then
sFunctionName = "";
end
local sDebugContext = Debug.GetEventContext();
local nEndPoint = String.Find(sDebugContext, "->", 1, false);
if nEndPoint ~= -1 then
sDebugContext = "["..String.Left(sDebugContext, nEndPoint - 2).."]";
else
sDebugContext = "";
end
error(sDebugContext.."\r\n\r\nError in \""..ERROR_PLUGIN_NAME.."\" plugin\r\n\r\nError in function \""..sFunctionName.."()\"\r\n\r\n"..sMessage, 1);
end
--[[
add the following to each function...
local sCallingFunction = "MyFunction";
..where "MyFunction" is the name of the calling function.
NOTE: the sCallingFunction variable can be called whatever you like. It is argument number one for the ERROR function
EXAMPLE: ERROR(sCallingFunction, "The world cannot be saved by a plugin");
]]
--################################################## ################################################## #####

Centauri Soldier
09-07-2009, 04:21 AM
I was not getting the desired event context line number returned when calling the error code so I did some reading into the lua error function and figured it out.

I was calling the ERROR function from a function within another function and it was returning the line number of the parent function rather than the line number of the code that called the parent function.

So, I have updated the ERROR function and it now accepts a number for the third argument that is the depth of the ERROR call (set to 0 or simply do not use a third argument if you don't need to call from an embedded function). I also prettied the ERROR function up a bit as well.

This Helper Code was a fantastic idea, MicroByte. It's in every plugin that I've made. I'd like to see some more add-ons for it if anyone else has made any.

--################################################## ################################################## #####
--ERROR PLUGIN DETAILS
local ERROR_PLUGIN_NAME = "";
--################################################## ################################################## #####
--Displays a custom error message using the plugin and function name and lists the event context as well.
local ERROR = function(sFunctionName,sMessage,nEmbedLevel)

if not nEmbedLevel then
nEmbedLevel = 0;
elseif type(nEmbedLevel) ~= "number" then
nEmbedLevel = 0;
end

if type(sFunctionName) ~= "string" then
sFunctionName = "";
end
error("\r\nError in \""..ERROR_PLUGIN_NAME.."\" plugin, function \""..sFunctionName.."()\"\r\n\r\n"..sMessage.."\r\n\r\nEventContext: "..Debug.GetEventContext(),3 + nEmbedLevel);
end
--[[
add the following to each function...
local sCallingFunction = "MyFunction";
..where "MyFunction" is the name of the calling function.
NOTE: the sCallingFunction variable can be called whatever you like. It is argument number one for the ERROR function
EXAMPLE: ERROR(sCallingFunction, "The world cannot be saved by a plugin");

If the error is inside an embedded function (a function within a function) then use a number for the third agument.
The number is the depth of the ERROR message call (o for being inside one function, 1 for being inside a function within another function and so on).
If you are not calling the ERROR function from within an ebedded function then you do not need the third argument, it can be nil.
]]

Centauri Soldier
09-08-2009, 05:25 AM
I can't keep my paws of off this code...don't crucify me MicroByte but I reduced your code by like 70% or so :eek:. There is only one variable type checking function now. It accepts three arguments, the third which is a table of allowed variable types.

I kept creating more functions for allowed types (CheckTableNil, CheckFunctionNil, CheckNumberTable etc.) and my globals page was filling up quick so I decided to rethink my approach to the expansion of the helper functions and here is the result of that consideration.

--################################################## ################################################## #####
-- IRLUA PLUGIN HELPER FUNCTIONS By MicroByte
--################################################## ################################################## #####
_ShowErrorEventContext=true-- set this to false to disable 'EventContext' display
--################################################## ################################################## #####
-- Sets a Global error message in the runtime engine.
IRLUA_PLUGIN_SetGlobalErrorMessage = function(nCode, sMessage)
if _tblErrorMessages[nCode] then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("Error code "..nCode.." already in use, please use another.\r\n\r\nEventContext: "..sEventContext,2)
else
error("Error code "..nCode.." already in use, please use another.",2)
end
else
_tblErrorMessages[nCode]=sMessage
end
end
--################################################## ################################################## #####
-- Checks the number of arguments in the table nd throws a syntax error If there are Not enough.
-- This is useful For checking the number of arguments available To your aciton.
local IRLUA_PLUGIN_CheckNumArgs = function(tbArgs,nArgs)
local nCount=table.getn(tbArgs)
if nCount < nArgs then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error(nArgs.." Arguments expected, "..nCount.." Arguments passed.\r\n\r\nEventContext: "..sEventContext,3)
else
error(nArgs.." Arguments expected, "..nCount.." Arguments passed.",3)
end
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see if it is any of the specified types.
-- If Not it throws a syntax error.
--Possible variable types[ boolean, function, nil, number, string, table, thread, userdata]
local IRLUA_PLUGIN_CheckTypes = function(tbArgs,nArg,tTypes)
local sType = type(tbArgs[nArg]);
local nTotalTypes = Table.Count(tTypes);
local nStrikes = 0;
local sAllowedTypes = "";

for nIndex, sAllowedType in tTypes do

if nIndex < (nTotalTypes - 1) then
sAllowedTypes = sAllowedTypes.." "..sAllowedType..",";
elseif nIndex == nTotalTypes - 1 then
sAllowedTypes = sAllowedTypes.." "..sAllowedType;
else
sAllowedTypes = sAllowedTypes.." or "..sAllowedType;
end

if sType ~= String.Lower(sAllowedType) then
nStrikes = nStrikes + 1;
end
end

if nStrikes == nTotalTypes then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a"..sAllowedTypes..", you passed a "..sType..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a"..sAllowedTypes..", you passed a "..sType..".",3)
end
end
end
--################################################## ################################################## #####
--ERROR PLUGIN DETAILS
local ERROR_PLUGIN_NAME = "";
--################################################## ################################################## #####
--Displays a custom error message using the plugin and function name and lists the event context as well.
local ERROR = function(sFunctionName,sMessage,nEmbedLevel)

if not nEmbedLevel then
nEmbedLevel = 0;
elseif type(nEmbedLevel) ~= "number" then
nEmbedLevel = 0;
end

if type(sFunctionName) ~= "string" then
sFunctionName = "";
end
error("\r\nError in \""..ERROR_PLUGIN_NAME.."\" plugin, function \""..sFunctionName.."()\"\r\n\r\n"..sMessage.."\r\n\r\nEventContext: "..Debug.GetEventContext(),3 + nEmbedLevel);
end
--################################################## ################################################## #####
-- END IRLUA PLUGIN HELPER FUNCTIONS
--################################################## ################################################## #####



--[[
--Example Usage

function TEST(...)
-- this function requires 3 arguments of differenet types.
-- check the number of arguments
IRLUA_PLUGIN_CheckNumArgs(arg,3);

local junk1 = IRLUA_PLUGIN_CheckTypes(arg,1,{"string", "table"});
local junk2 = IRLUA_PLUGIN_CheckTypes(arg,2,{"number", "table"});
local junk3 = IRLUA_PLUGIN_CheckTypes(arg,3,{"nil", "number"});
Dialog.Message("Test", "Run Through");
end




NOTES ON ERROR FUNCTION
add the following to each function...
local sCallingFunction = "MyFunction";
..where "MyFunction" is the name of the calling function.
NOTE: the sCallingFunction variable can be called whatever you like. It is argument number one for the ERROR function
EXAMPLE: ERROR(sCallingFunction, "The world cannot be saved by a plugin");

If the error is inside an embedded function (a function within a function) then use a number for the third agument.
The number is the depth of the ERROR message call (o for being inside one function, 1 for being inside a function within another function and so on).
If you are not calling the ERROR function from within an ebedded function then you do not need the third argument, it can be nil.



NOTES ON ERROR CODE IMPLEMENTATION
--EDIT: I forgot to mention, also make heavy use of Application.SetLastError in your actions, try and use predefined error codes but if you need to add error codes use IRLUA_PLUGIN_SetGlobalErrorMessage with a unique number range

--example ( if you run the below script the message will read "Some error message"
--Code:

IRLUA_PLUGIN_SetGlobalErrorMessage(0023114, "Some error message")
IRLUA_PLUGIN_SetGlobalErrorMessage(0023113, "Some other error message")

Application.SetLastError(0023114)


-- Test for error
error = Application.GetLastError();
if (error ~= 0) then
Dialog.Message("Error", _tblErrorMessages[error], MB_OK, MB_ICONEXCLAMATION);
end
]]

Please let me know if you find any bugs in it guys. :D

Centauri Soldier
09-08-2009, 06:00 AM
Oops, I found an error...:o. But not in time to edit my post....revised code below.

--################################################## ################################################## #####
-- IRLUA PLUGIN HELPER FUNCTIONS By MicroByte
--################################################## ################################################## #####
_ShowErrorEventContext=true-- set this to false to disable 'EventContext' display
--################################################## ################################################## #####
-- Sets a Global error message in the runtime engine.
IRLUA_PLUGIN_SetGlobalErrorMessage = function(nCode, sMessage)
if _tblErrorMessages[nCode] then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("Error code "..nCode.." already in use, please use another.\r\n\r\nEventContext: "..sEventContext,2)
else
error("Error code "..nCode.." already in use, please use another.",2)
end
else
_tblErrorMessages[nCode]=sMessage
end
end
--################################################## ################################################## #####
-- Checks the number of arguments in the table nd throws a syntax error If there are Not enough.
-- This is useful For checking the number of arguments available To your aciton.
local IRLUA_PLUGIN_CheckNumArgs = function(tbArgs,nArgs)
local nCount=table.getn(tbArgs)
if nCount < nArgs then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error(nArgs.." Arguments expected, "..nCount.." Arguments passed.\r\n\r\nEventContext: "..sEventContext,3)
else
error(nArgs.." Arguments expected, "..nCount.." Arguments passed.",3)
end
end
end
--################################################## ################################################## #####
-- Checks the value at a given argument table position To see if it is any of the specified types.
-- If Not it throws a syntax error.
--Possible variable types[ boolean, function, nil, number, string, table, thread, userdata]
local IRLUA_PLUGIN_CheckTypes = function(tbArgs,nArg,tTypes)
local sType = type(tbArgs[nArg]);
local nTotalTypes = Table.Count(tTypes);
local nStrikes = 0;
local sAllowedTypes = "";

for nIndex, sAllowedType in tTypes do

if nIndex < (nTotalTypes - 1) then
sAllowedTypes = sAllowedTypes.." "..sAllowedType..",";
elseif nIndex == nTotalTypes - 1 then
sAllowedTypes = sAllowedTypes.." "..sAllowedType;
else
sAllowedTypes = sAllowedTypes.." or "..sAllowedType;
end

if sType ~= String.Lower(sAllowedType) then
nStrikes = nStrikes + 1;
end
end

if nStrikes == nTotalTypes then
if _ShowErrorEventContext then
local sEventContext=Debug.GetEventContext()
error("bad argument #" .. nArg .. ", must be a"..sAllowedTypes..", you passed a "..sType..".\r\n\r\nEventContext: "..sEventContext,3)
else
error("bad argument #" .. nArg .. ", must be a"..sAllowedTypes..", you passed a "..sType..".",3)
end
else
return tbArgs[nArg]
end
end
--################################################## ################################################## #####
--ERROR PLUGIN DETAILS
local ERROR_PLUGIN_NAME = "Tempus";
--################################################## ################################################## #####
--Displays a custom error message using the plugin and function name and lists the event context as well.
local ERROR = function(sFunctionName,sMessage,nEmbedLevel)

if not nEmbedLevel then
nEmbedLevel = 0;
elseif type(nEmbedLevel) ~= "number" then
nEmbedLevel = 0;
end

if type(sFunctionName) ~= "string" then
sFunctionName = "";
end
error("\r\nError in \""..ERROR_PLUGIN_NAME.."\" plugin, function \""..sFunctionName.."()\"\r\n\r\n"..sMessage.."\r\n\r\nEventContext: "..Debug.GetEventContext(),3 + nEmbedLevel);
end
--################################################## ################################################## #####
-- END IRLUA PLUGIN HELPER FUNCTIONS
--################################################## ################################################## #####



--[[
--Example Usage

function TEST(...)
-- this function requires 3 arguments of differenet types.
-- check the number of arguments
IRLUA_PLUGIN_CheckNumArgs(arg,3);

local junk1 = IRLUA_PLUGIN_CheckTypes(arg,1,{"string", "table"});
local junk2 = IRLUA_PLUGIN_CheckTypes(arg,2,{"number", "table"});
local junk3 = IRLUA_PLUGIN_CheckTypes(arg,3,{"nil", "number"});
Dialog.Message("Test", "Run Through");
end




NOTES ON ERROR FUNCTION
add the following to each function...
local sCallingFunction = "MyFunction";
..where "MyFunction" is the name of the calling function.
NOTE: the sCallingFunction variable can be called whatever you like. It is argument number one for the ERROR function
EXAMPLE: ERROR(sCallingFunction, "The world cannot be saved by a plugin");

If the error is inside an embedded function (a function within a function) then use a number for the third agument.
The number is the depth of the ERROR message call (o for being inside one function, 1 for being inside a function within another function and so on).
If you are not calling the ERROR function from within an ebedded function then you do not need the third argument, it can be nil.



NOTES ON ERROR CODE IMPLEMENTATION
--EDIT: I forgot to mention, also make heavy use of Application.SetLastError in your actions, try and use predefined error codes but if you need to add error codes use IRLUA_PLUGIN_SetGlobalErrorMessage with a unique number range

--example ( if you run the below script the message will read "Some error message"
--Code:

IRLUA_PLUGIN_SetGlobalErrorMessage(0023114, "Some error message")
IRLUA_PLUGIN_SetGlobalErrorMessage(0023113, "Some other error message")

Application.SetLastError(0023114)


-- Test for error
error = Application.GetLastError();
if (error ~= 0) then
Dialog.Message("Error", _tblErrorMessages[error], MB_OK, MB_ICONEXCLAMATION);
end
]]

MicroByte
09-08-2009, 08:59 AM
Hey, nice work on reducing the code, i may adopt this style for my PB lua system :yes

Centauri Soldier
09-08-2009, 02:24 PM
I updated the code again...I have decided to mirror the code on amspublic.com. You can find the latest version under the Resources/Scripts section.