1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-30 22:17:13 +02:00

Allow the retrieval of the currently executed command from the command system.

Also improve the way errors during the execution are handled and resources are released.
This commit is contained in:
Sandu Liviu Catalin
2016-03-16 19:11:42 +02:00
parent 98b2ddfda6
commit 839c3c3434
2 changed files with 93 additions and 21 deletions

View File

@ -62,6 +62,15 @@ CSStr CmdArgSpecToStr(Uint8 spec)
}
}
// ------------------------------------------------------------------------------------------------
CmdManager::Guard::~Guard()
{
// Release the command instance
_Cmd->m_Instance = nullptr;
// Release the reference to the script object
_Cmd->m_Object.Release();
}
// ------------------------------------------------------------------------------------------------
CmdManager::CmdManager()
: m_Buffer(512)
@ -69,8 +78,12 @@ CmdManager::CmdManager()
, m_Invoker(SQMOD_UNKNOWN)
, m_Command(64, '\0')
, m_Argument(512, '\0')
, m_Instance(nullptr)
, m_Object()
, m_Argv()
, m_Argc(0)
, m_OnError()
, m_OnAuth()
{
/* ... */
}
@ -299,10 +312,12 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command)
// Execution failed!
return -1;
}
// Make sure resources are released at the end of this function
Guard g;
// Attempt to find the specified command
Object obj = FindByName(m_Command);
m_Object = FindByName(m_Command);
// Have we found anything?
if (obj.IsNull())
if (m_Object.IsNull())
{
// Tell the script callback to deal with the error
SqError(CMDERR_UNKNOWN_COMMAND, _SC("Unable to find the specified command"), m_Command);
@ -310,31 +325,27 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command)
return -1;
}
// Save the command instance
m_Instance = obj.Cast< CmdListener * >();
m_Instance = m_Object.Cast< CmdListener * >();
// Is the command instance valid? (just in case)
if (!m_Instance)
{
// Tell the script callback to deal with the error
SqError(CMDERR_UNKNOWN_COMMAND, _SC("Unable to find the specified command"), m_Command.c_str());
SqError(CMDERR_UNKNOWN_COMMAND, _SC("Unable to find the specified command"), m_Command);
// Execution failed!
return -1;
}
// Value returned by the command
Int32 ret = -1;
// Attempt to execute the command
try
{
ret = Exec();
return Exec();
}
catch (...)
{
// Tell the script callback to deal with the error
SqError(CMDERR_EXECUTION_FAILED, _SC("Exceptions occurred during execution"), m_Invoker);
}
// Release the command instance
m_Instance = nullptr;
// Return the result
return ret;
// Execution failed
return -1;
}
// ------------------------------------------------------------------------------------------------
@ -409,10 +420,14 @@ Int32 CmdManager::Exec()
{
// Do we have use the argument index as the key?
if (m_Instance->m_ArgTags[arg].empty())
{
args.SetValue(SQInteger(arg), m_Argv[arg].second);
}
// Nope, we have a name for this argument!
else
{
args.SetValue(m_Instance->m_ArgTags[arg].c_str(), m_Argv[arg].second);
}
}
// Attempt to execute the command with the specified arguments
try
@ -433,7 +448,9 @@ Int32 CmdManager::Exec()
Array args(DefaultVM::Get(), m_Argc);
// Copy the arguments into the array
for (Uint32 arg = 0; arg < m_Argc; ++arg)
{
args.Bind(SQInteger(arg), m_Argv[arg].second);
}
// Attempt to execute the command with the specified arguments
try
{
@ -1585,6 +1602,12 @@ static const Object & Cmd_FindByName(CSStr name)
return _Cmd->FindByName(name);
}
// ------------------------------------------------------------------------------------------------
static const Object & Cmd_Current()
{
return _Cmd->Current();
}
// ------------------------------------------------------------------------------------------------
static Function & Cmd_GetOnError()
{
@ -1704,6 +1727,7 @@ void Register_Command(HSQUIRRELVM vm)
cmdns.Func(_SC("Sort"), &Cmd_Sort);
cmdns.Func(_SC("Count"), &Cmd_Count);
cmdns.Func(_SC("Current"), &Cmd_Current);
cmdns.Func(_SC("FindByName"), &Cmd_FindByName);
cmdns.Func(_SC("GetOnError"), &Cmd_GetOnError);
cmdns.Func(_SC("SetOnError"), &Cmd_SetOnError);