mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01: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:
parent
98b2ddfda6
commit
839c3c3434
@ -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);
|
||||
|
@ -95,6 +95,45 @@ private:
|
||||
typedef std::pair< Uint8, Object > CmdArg;
|
||||
typedef std::vector< CmdArg > CmdArgs;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Helper class implementing RAII to release the command object and instance.
|
||||
*/
|
||||
struct Guard
|
||||
{
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Guard() = default;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
Guard(const Guard & o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
Guard(Guard && o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Guard();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Guard & operator = (const Guard & o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Guard & operator = (Guard && o) = delete;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Guard;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
@ -173,6 +212,14 @@ public:
|
||||
*/
|
||||
const Object & FindByName(const String & name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the currently active command object.
|
||||
*/
|
||||
const Object & Current() const
|
||||
{
|
||||
return m_Object;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Terminate current session.
|
||||
*/
|
||||
@ -276,22 +323,23 @@ protected:
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Buffer m_Buffer; /* Internal buffer used for parsing commands. */
|
||||
CmdList m_Commands; /* List of created commands. */
|
||||
Buffer m_Buffer; // Internal buffer used for parsing commands.
|
||||
CmdList m_Commands; // List of created commands.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Int32 m_Invoker; /* Current command invoker. */
|
||||
String m_Command; /* Current command name. */
|
||||
String m_Argument; /* Current command argument. */
|
||||
CmdListener* m_Instance; /* Current command instance. */
|
||||
Int32 m_Invoker; // Current command invoker.
|
||||
String m_Command; // Current command name.
|
||||
String m_Argument; // Current command argument.
|
||||
CmdListener* m_Instance; // Current command instance.
|
||||
Object m_Object; // Current command script object.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
CmdArgs m_Argv; /* Extracted command arguments. */
|
||||
Uint32 m_Argc; /* Extracted arguments count. */
|
||||
CmdArgs m_Argv; // Extracted command arguments.
|
||||
Uint32 m_Argc; // Extracted arguments count.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Function m_OnError; /* Error handler. */
|
||||
Function m_OnAuth; /* Authentication handler. */
|
||||
Function m_OnError; // Error handler.
|
||||
Function m_OnAuth; // Authentication handler.
|
||||
|
||||
public:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user