mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Revised the implementation for the command system to be safer in situations that could lead to the destruction of the listener instance while still used.
Also changed the command system to store the commands in a contiguous container since commands are only inserted once and constantly accessed after. Documented the command listener member functions. Various other fixes and improvements.
This commit is contained in:
parent
bab8146c89
commit
acaf826498
@ -14,7 +14,36 @@
|
|||||||
namespace SqMod {
|
namespace SqMod {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
CmdManager * _Cmd = NULL;
|
CmdManager * _Cmd = nullptr;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
SQInteger CmdListener::Typename(HSQUIRRELVM vm)
|
||||||
|
{
|
||||||
|
static SQChar name[] = _SC("SqCmdListener");
|
||||||
|
sq_pushstring(vm, name, sizeof(name));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
static void ValidateName(CSStr name)
|
||||||
|
{
|
||||||
|
// Is the name empty?
|
||||||
|
if (!name || *name == '\0')
|
||||||
|
{
|
||||||
|
SqThrowF("Invalid or empty command name");
|
||||||
|
}
|
||||||
|
// Inspect name characters
|
||||||
|
while (*name != '\0')
|
||||||
|
{
|
||||||
|
// Does it contain spaces?
|
||||||
|
if (isspace(*name) != 0)
|
||||||
|
{
|
||||||
|
SqThrowF("Command names cannot contain spaces");
|
||||||
|
}
|
||||||
|
// Move to the next character
|
||||||
|
++name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
CSStr CmdArgSpecToStr(Uint8 spec)
|
CSStr CmdArgSpecToStr(Uint8 spec)
|
||||||
@ -38,8 +67,8 @@ CmdManager::CmdManager()
|
|||||||
: m_Buffer(512)
|
: m_Buffer(512)
|
||||||
, m_Commands()
|
, m_Commands()
|
||||||
, m_Invoker(SQMOD_UNKNOWN)
|
, m_Invoker(SQMOD_UNKNOWN)
|
||||||
, m_Command()
|
, m_Command(64, '\0')
|
||||||
, m_Argument()
|
, m_Argument(512, '\0')
|
||||||
, m_Argv()
|
, m_Argv()
|
||||||
, m_Argc(0)
|
, m_Argc(0)
|
||||||
{
|
{
|
||||||
@ -52,21 +81,160 @@ CmdManager::~CmdManager()
|
|||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
Object & CmdManager::Attach(const String & name, CmdListener * ptr, bool autorel)
|
||||||
|
{
|
||||||
|
// Obtain the unique identifier of the specified name
|
||||||
|
const std::size_t hash = std::hash< String >()(name);
|
||||||
|
// Make sure the command doesn't already exist
|
||||||
|
for (const auto & cmd : m_Commands)
|
||||||
|
{
|
||||||
|
// Are the hashes identical?
|
||||||
|
if (cmd.mHash == hash)
|
||||||
|
{
|
||||||
|
// Do we have to release this listener instance our self?
|
||||||
|
if (autorel)
|
||||||
|
{
|
||||||
|
delete ptr; // Let's avoid memory leaks!
|
||||||
|
}
|
||||||
|
// Now it's safe to throw the exception
|
||||||
|
// (include information necessary to help identify hash collisions!)
|
||||||
|
SqThrowF("Command (%s:%zu) already exists as (%s:%zu)",
|
||||||
|
name.c_str(), hash, cmd.mName.c_str(), cmd.mHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Obtain the initial stack size
|
||||||
|
const StackGuard sg;
|
||||||
|
// Push this instance on the stack
|
||||||
|
ClassType< CmdListener >::PushInstance(DefaultVM::Get(), ptr);
|
||||||
|
// Attempt to insert the command
|
||||||
|
m_Commands.emplace_back(hash, name, Var< Object >(DefaultVM::Get(), -1).value);
|
||||||
|
// Return the script object of the listener
|
||||||
|
return m_Commands.back().mObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void CmdManager::Detach(const String & name)
|
||||||
|
{
|
||||||
|
// Obtain the unique identifier of the specified name
|
||||||
|
const std::size_t hash = std::hash< String >()(name);
|
||||||
|
// Iterator to the found command, if any
|
||||||
|
CmdList::const_iterator itr = m_Commands.cbegin();
|
||||||
|
// Attempt to find the specified command
|
||||||
|
for (; itr != m_Commands.cend(); ++itr)
|
||||||
|
{
|
||||||
|
// Are the hashes identical?
|
||||||
|
if (itr->mHash == hash)
|
||||||
|
{
|
||||||
|
break; // We found our command!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Make sure the command exist before attempting to remove it
|
||||||
|
if (itr != m_Commands.end())
|
||||||
|
{
|
||||||
|
m_Commands.erase(itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void CmdManager::Detach(CmdListener * ptr)
|
||||||
|
{
|
||||||
|
// Iterator to the found command, if any
|
||||||
|
CmdList::const_iterator itr = m_Commands.cbegin();
|
||||||
|
// Attempt to find the specified command
|
||||||
|
for (; itr != m_Commands.cend(); ++itr)
|
||||||
|
{
|
||||||
|
// Are the instances identical?
|
||||||
|
if (itr->mPtr == ptr)
|
||||||
|
{
|
||||||
|
break; // We found our command!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Make sure the command exists before attempting to remove it
|
||||||
|
if (itr != m_Commands.end())
|
||||||
|
{
|
||||||
|
m_Commands.erase(itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool CmdManager::Attached(const String & name) const
|
||||||
|
{
|
||||||
|
// Obtain the unique identifier of the specified name
|
||||||
|
const std::size_t hash = std::hash< String >()(name);
|
||||||
|
// Attempt to find the specified command
|
||||||
|
for (const auto & cmd : m_Commands)
|
||||||
|
{
|
||||||
|
// Are the hashes identical?
|
||||||
|
if (cmd.mHash == hash)
|
||||||
|
{
|
||||||
|
return true; // We found our command!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No such command exists
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool CmdManager::Attached(const CmdListener * ptr) const
|
||||||
|
{
|
||||||
|
// Attempt to find the specified command
|
||||||
|
for (const auto & cmd : m_Commands)
|
||||||
|
{
|
||||||
|
// Are the instances identical?
|
||||||
|
if (cmd.mPtr == ptr)
|
||||||
|
{
|
||||||
|
return true; // We found our command!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No such command exists
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void CmdManager::Sort()
|
||||||
|
{
|
||||||
|
std::sort(m_Commands.begin(), m_Commands.end(),
|
||||||
|
[](CmdList::const_reference a, CmdList::const_reference b) -> bool {
|
||||||
|
return (b.mName < a.mName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
const Object & CmdManager::FindByName(const String & name)
|
||||||
|
{
|
||||||
|
// Obtain the unique identifier of the specified name
|
||||||
|
const std::size_t hash = std::hash< String >()(name);
|
||||||
|
// Attempt to find the specified command
|
||||||
|
for (const auto & cmd : m_Commands)
|
||||||
|
{
|
||||||
|
// Are the hashes identical?
|
||||||
|
if (cmd.mHash == hash)
|
||||||
|
{
|
||||||
|
return cmd.mObj; // We found our command!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No such command exist
|
||||||
|
return NullObject();
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CmdManager::Terminate()
|
void CmdManager::Terminate()
|
||||||
{
|
{
|
||||||
// Release the script resources from command instances
|
// Release the script resources from command instances
|
||||||
for (CmdList::iterator itr = m_Commands.begin(); itr != m_Commands.end(); ++itr)
|
for (const auto & cmd : m_Commands)
|
||||||
{
|
{
|
||||||
if (itr->second)
|
if (cmd.mPtr)
|
||||||
{
|
{
|
||||||
// Release the local command callbacks
|
// Release the local command callbacks
|
||||||
itr->second->m_OnExec.ReleaseGently();
|
cmd.mPtr->m_OnExec.ReleaseGently();
|
||||||
itr->second->m_OnAuth.ReleaseGently();
|
cmd.mPtr->m_OnAuth.ReleaseGently();
|
||||||
itr->second->m_OnPost.ReleaseGently();
|
cmd.mPtr->m_OnPost.ReleaseGently();
|
||||||
itr->second->m_OnFail.ReleaseGently();
|
cmd.mPtr->m_OnFail.ReleaseGently();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Clear the command list and release all references
|
||||||
|
m_Commands.clear();
|
||||||
// Release the script resources from this class
|
// Release the script resources from this class
|
||||||
m_Argv.clear();
|
m_Argv.clear();
|
||||||
// Release the global callbacks
|
// Release the global callbacks
|
||||||
@ -78,7 +246,7 @@ void CmdManager::Terminate()
|
|||||||
Int32 CmdManager::Run(Int32 invoker, CCStr command)
|
Int32 CmdManager::Run(Int32 invoker, CCStr command)
|
||||||
{
|
{
|
||||||
// Validate the string command
|
// Validate the string command
|
||||||
if (!command || *command == 0)
|
if (!command || *command == '\0')
|
||||||
{
|
{
|
||||||
// Tell the script callback to deal with the error
|
// Tell the script callback to deal with the error
|
||||||
SqError(CMDERR_EMPTY_COMMAND, _SC("Invalid or empty command name"), invoker);
|
SqError(CMDERR_EMPTY_COMMAND, _SC("Invalid or empty command name"), invoker);
|
||||||
@ -89,10 +257,20 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command)
|
|||||||
m_Invoker = invoker;
|
m_Invoker = invoker;
|
||||||
// Skip white-space until the command name
|
// Skip white-space until the command name
|
||||||
while (isspace(*command)) ++command;
|
while (isspace(*command)) ++command;
|
||||||
|
// Anything left to process?
|
||||||
|
if (*command == '\0')
|
||||||
|
{
|
||||||
|
// Tell the script callback to deal with the error
|
||||||
|
SqError(CMDERR_EMPTY_COMMAND, _SC("Invalid or empty command name"), invoker);
|
||||||
|
// Execution failed!
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Where the name ends and argument begins
|
||||||
|
CCStr split = command;
|
||||||
// Find where the command name ends
|
// Find where the command name ends
|
||||||
CCStr split = strchr(command, ' ');
|
while (isspace(*split)) ++split;
|
||||||
// Are there any arguments specified?
|
// Are there any arguments specified?
|
||||||
if (split != NULL)
|
if (split != nullptr)
|
||||||
{
|
{
|
||||||
// Save the command name
|
// Save the command name
|
||||||
m_Command.assign(command, (split - command));
|
m_Command.assign(command, (split - command));
|
||||||
@ -104,11 +282,17 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command)
|
|||||||
// No arguments specified
|
// No arguments specified
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Save the command name
|
||||||
m_Command.assign(command);
|
m_Command.assign(command);
|
||||||
|
// Leave argument empty
|
||||||
m_Argument.assign("");
|
m_Argument.assign("");
|
||||||
}
|
}
|
||||||
// Did anything remain after cleaning?
|
// Do we have a valid command name?
|
||||||
if (m_Command.empty())
|
try
|
||||||
|
{
|
||||||
|
ValidateName(m_Command.c_str());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
{
|
{
|
||||||
// Tell the script callback to deal with the error
|
// Tell the script callback to deal with the error
|
||||||
SqError(CMDERR_INVALID_COMMAND, _SC("Cannot execute invalid command name"), invoker);
|
SqError(CMDERR_INVALID_COMMAND, _SC("Cannot execute invalid command name"), invoker);
|
||||||
@ -116,29 +300,25 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// Attempt to find the specified command
|
// Attempt to find the specified command
|
||||||
CmdList::iterator itr = m_Commands.find(m_Command);
|
Object obj = FindByName(m_Command);
|
||||||
// Have we found anything?
|
// Have we found anything?
|
||||||
if (itr == m_Commands.end())
|
if (obj.IsNull())
|
||||||
{
|
{
|
||||||
// Tell the script callback to deal with the error
|
// Tell the script callback to deal with the error
|
||||||
SqError(CMDERR_UNKNOWN_COMMAND, _SC("Unable to find the specified command"), m_Command);
|
SqError(CMDERR_UNKNOWN_COMMAND, _SC("Unable to find the specified command"), m_Command);
|
||||||
// Execution failed!
|
// Execution failed!
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
// Save the command instance
|
||||||
|
m_Instance = obj.Cast< CmdListener * >();
|
||||||
// Is the command instance valid? (just in case)
|
// Is the command instance valid? (just in case)
|
||||||
else if (!itr->second)
|
if (!m_Instance)
|
||||||
{
|
{
|
||||||
// There's no point in keeping this command anymore
|
|
||||||
m_Commands.erase(itr);
|
|
||||||
// Tell the script callback to deal with the error
|
// 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.c_str());
|
||||||
// Execution failed!
|
// Execution failed!
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// Save the command instance
|
|
||||||
m_Instance = itr->second;
|
|
||||||
// Place a lock on the command
|
|
||||||
m_Instance->m_Locked = true;
|
|
||||||
// Value returned by the command
|
// Value returned by the command
|
||||||
Int32 ret = -1;
|
Int32 ret = -1;
|
||||||
// Attempt to execute the command
|
// Attempt to execute the command
|
||||||
@ -151,10 +331,8 @@ Int32 CmdManager::Run(Int32 invoker, CCStr command)
|
|||||||
// Tell the script callback to deal with the error
|
// Tell the script callback to deal with the error
|
||||||
SqError(CMDERR_EXECUTION_FAILED, _SC("Exceptions occurred during execution"), m_Invoker);
|
SqError(CMDERR_EXECUTION_FAILED, _SC("Exceptions occurred during execution"), m_Invoker);
|
||||||
}
|
}
|
||||||
// Remove the lock from the command
|
|
||||||
m_Instance->m_Locked = false;
|
|
||||||
// Release the command instance
|
// Release the command instance
|
||||||
m_Instance = NULL;
|
m_Instance = nullptr;
|
||||||
// Return the result
|
// Return the result
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -487,7 +665,7 @@ bool CmdManager::Parse()
|
|||||||
if (!identified)
|
if (!identified)
|
||||||
{
|
{
|
||||||
// Let's us know if the whole argument was part of the resulted value
|
// Let's us know if the whole argument was part of the resulted value
|
||||||
CStr next = NULL;
|
CStr next = nullptr;
|
||||||
// Attempt to extract the integer value from the string
|
// Attempt to extract the integer value from the string
|
||||||
LongI value = strtol(m_Buffer.Data(), &next, 10);
|
LongI value = strtol(m_Buffer.Data(), &next, 10);
|
||||||
// See if this whole string was indeed an integer
|
// See if this whole string was indeed an integer
|
||||||
@ -507,7 +685,7 @@ bool CmdManager::Parse()
|
|||||||
if (!identified)
|
if (!identified)
|
||||||
{
|
{
|
||||||
// Let's us know if the whole argument was part of the resulted value
|
// Let's us know if the whole argument was part of the resulted value
|
||||||
CStr next = NULL;
|
CStr next = nullptr;
|
||||||
// Attempt to extract the floating point value from the string
|
// Attempt to extract the floating point value from the string
|
||||||
#ifdef SQUSEDOUBLE
|
#ifdef SQUSEDOUBLE
|
||||||
Float64 value = strtod(m_Buffer.Data(), &next);
|
Float64 value = strtod(m_Buffer.Data(), &next);
|
||||||
@ -597,6 +775,32 @@ bool CmdManager::Parse()
|
|||||||
return good;
|
return good;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
Object & CmdManager::Create(CSStr name)
|
||||||
|
{
|
||||||
|
return Attach(name, new CmdListener(name), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object & CmdManager::Create(CSStr name, CSStr spec)
|
||||||
|
{
|
||||||
|
return Attach(name, new CmdListener(name, spec), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object & CmdManager::Create(CSStr name, CSStr spec, Array & tags)
|
||||||
|
{
|
||||||
|
return Attach(name, new CmdListener(name, spec, tags), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object & CmdManager::Create(CSStr name, CSStr spec, Uint8 min, Uint8 max)
|
||||||
|
{
|
||||||
|
return Attach(name, new CmdListener(name, spec, min, max), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object & CmdManager::Create(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 max)
|
||||||
|
{
|
||||||
|
return Attach(name, new CmdListener(name, spec, tags, min, max), true);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CmdListener::Init(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 max)
|
void CmdListener::Init(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 max)
|
||||||
{
|
{
|
||||||
@ -614,8 +818,6 @@ void CmdListener::Init(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 ma
|
|||||||
m_Spec.assign("");
|
m_Spec.assign("");
|
||||||
m_Help.assign("");
|
m_Help.assign("");
|
||||||
m_Info.assign("");
|
m_Info.assign("");
|
||||||
// Use the global authentication inspector
|
|
||||||
m_OnAuth = _Cmd->GetOnAuth();
|
|
||||||
// Default to no authority check
|
// Default to no authority check
|
||||||
m_Authority = -1;
|
m_Authority = -1;
|
||||||
// Default to unprotected command
|
// Default to unprotected command
|
||||||
@ -624,8 +826,6 @@ void CmdListener::Init(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 ma
|
|||||||
m_Suspended = false;
|
m_Suspended = false;
|
||||||
// Default to non-associative arguments
|
// Default to non-associative arguments
|
||||||
m_Associate = false;
|
m_Associate = false;
|
||||||
// The command is unlocked to further changes
|
|
||||||
m_Locked = false;
|
|
||||||
// Set the specified minimum and maximum allowed arguments
|
// Set the specified minimum and maximum allowed arguments
|
||||||
SetMinArgC(min);
|
SetMinArgC(min);
|
||||||
SetMaxArgC(max);
|
SetMaxArgC(max);
|
||||||
@ -666,9 +866,8 @@ CmdListener::CmdListener(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8
|
|||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
CmdListener::~CmdListener()
|
CmdListener::~CmdListener()
|
||||||
{
|
{
|
||||||
// See the instance must be detached
|
// Detach this command (shouldn't be necessary!)
|
||||||
if (!m_Name.empty())
|
_Cmd->Detach(this);
|
||||||
_Cmd->Detach(m_Name);
|
|
||||||
// Release callbacks
|
// Release callbacks
|
||||||
m_OnExec.ReleaseGently();
|
m_OnExec.ReleaseGently();
|
||||||
m_OnAuth.ReleaseGently();
|
m_OnAuth.ReleaseGently();
|
||||||
@ -693,6 +892,30 @@ CSStr CmdListener::ToString() const
|
|||||||
return m_Name.c_str();
|
return m_Name.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void CmdListener::Attach()
|
||||||
|
{
|
||||||
|
// Is the associated name even valid?
|
||||||
|
if (m_Name.empty())
|
||||||
|
{
|
||||||
|
SqThrowF("Invalid or empty command name");
|
||||||
|
}
|
||||||
|
// Are we already attached?
|
||||||
|
else if (_Cmd->Attached(this))
|
||||||
|
{
|
||||||
|
SqThrowF("Command is already attached");
|
||||||
|
}
|
||||||
|
// Attempt to attach this command
|
||||||
|
_Cmd->Attach(m_Name, this, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void CmdListener::Detach()
|
||||||
|
{
|
||||||
|
// Detach this command
|
||||||
|
_Cmd->Detach(this);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Uint8 CmdListener::GetArgFlags(Uint32 idx) const
|
Uint8 CmdListener::GetArgFlags(Uint32 idx) const
|
||||||
{
|
{
|
||||||
@ -710,19 +933,23 @@ CSStr CmdListener::GetName() const
|
|||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CmdListener::SetName(CSStr name)
|
void CmdListener::SetName(CSStr name)
|
||||||
{
|
{
|
||||||
// Is this command locked because it's being executed now?
|
// Validate the specified name
|
||||||
if (m_Locked)
|
ValidateName(name);
|
||||||
SqThrowF("Cannot rename locked command: %s", m_Name.c_str());
|
// Is this command already attached to a name?
|
||||||
// Is the command name even valid?
|
if (_Cmd->Attached(this))
|
||||||
else if (!name || *name == 0)
|
{
|
||||||
SqThrowF("Invalid command name: null/empty");
|
// Detach from the current name if necessary
|
||||||
// Detach from the current name if necessary
|
_Cmd->Detach(this);
|
||||||
if (!m_Name.empty())
|
// Now it's safe to assign the new name
|
||||||
_Cmd->Detach(name);
|
m_Name.assign(name);
|
||||||
// Now it's safe to assign the new name
|
// We know the new name is valid
|
||||||
m_Name.assign(name);
|
_Cmd->Attach(m_Name, this, false);
|
||||||
// We know the new name is valid
|
}
|
||||||
_Cmd->Attach(m_Name, this);
|
else
|
||||||
|
{
|
||||||
|
// Just assign the name
|
||||||
|
m_Name.assign(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -747,7 +974,9 @@ Array CmdListener::GetArgTags() const
|
|||||||
Array arr(DefaultVM::Get(), SQMOD_MAX_CMD_ARGS);
|
Array arr(DefaultVM::Get(), SQMOD_MAX_CMD_ARGS);
|
||||||
// Put the tags to the allocated array
|
// Put the tags to the allocated array
|
||||||
for (Uint32 arg = 0; arg < SQMOD_MAX_CMD_ARGS; ++arg)
|
for (Uint32 arg = 0; arg < SQMOD_MAX_CMD_ARGS; ++arg)
|
||||||
|
{
|
||||||
arr.SetValue(arg, m_ArgTags[arg]);
|
arr.SetValue(arg, m_ArgTags[arg]);
|
||||||
|
}
|
||||||
// Return the array with the tags
|
// Return the array with the tags
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
@ -761,14 +990,26 @@ void CmdListener::SetArgTags(Array & tags)
|
|||||||
if (tags.IsNull() || max == 0)
|
if (tags.IsNull() || max == 0)
|
||||||
{
|
{
|
||||||
for (Uint8 n = 0; n < SQMOD_MAX_CMD_ARGS; ++n)
|
for (Uint8 n = 0; n < SQMOD_MAX_CMD_ARGS; ++n)
|
||||||
|
{
|
||||||
m_ArgTags[n].assign("");
|
m_ArgTags[n].assign("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// See if we're in range
|
// See if we're in range
|
||||||
else if (max < SQMOD_MAX_CMD_ARGS)
|
else if (max < SQMOD_MAX_CMD_ARGS)
|
||||||
|
{
|
||||||
// Attempt to get all arguments in one go
|
// Attempt to get all arguments in one go
|
||||||
tags.GetArray(m_ArgTags, max);
|
tags.GetArray(m_ArgTags, max);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
SqThrowF("Argument tag (%u) is out of range (%u)", max, SQMOD_MAX_CMD_ARGS);
|
SqThrowF("Argument tag (%u) is out of range (%u)", max, SQMOD_MAX_CMD_ARGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool CmdListener::Attached() const
|
||||||
|
{
|
||||||
|
return _Cmd->Attached(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -854,9 +1095,13 @@ void CmdListener::SetMinArgC(Uint8 val)
|
|||||||
{
|
{
|
||||||
// Perform a range check on the specified argument index
|
// Perform a range check on the specified argument index
|
||||||
if (val >= SQMOD_MAX_CMD_ARGS)
|
if (val >= SQMOD_MAX_CMD_ARGS)
|
||||||
|
{
|
||||||
SqThrowF("Argument (%u) is out of total range (%u)", val, SQMOD_MAX_CMD_ARGS);
|
SqThrowF("Argument (%u) is out of total range (%u)", val, SQMOD_MAX_CMD_ARGS);
|
||||||
|
}
|
||||||
else if (val > m_MaxArgc)
|
else if (val > m_MaxArgc)
|
||||||
|
{
|
||||||
SqThrowF("Minimum argument (%u) exceeds maximum (%u)", val, m_MaxArgc);
|
SqThrowF("Minimum argument (%u) exceeds maximum (%u)", val, m_MaxArgc);
|
||||||
|
}
|
||||||
// Apply the specified value
|
// Apply the specified value
|
||||||
m_MinArgc = val;
|
m_MinArgc = val;
|
||||||
}
|
}
|
||||||
@ -872,19 +1117,17 @@ void CmdListener::SetMaxArgC(Uint8 val)
|
|||||||
{
|
{
|
||||||
// Perform a range check on the specified argument index
|
// Perform a range check on the specified argument index
|
||||||
if (val >= SQMOD_MAX_CMD_ARGS)
|
if (val >= SQMOD_MAX_CMD_ARGS)
|
||||||
|
{
|
||||||
SqThrowF("Argument (%u) is out of total range (%u)", val, SQMOD_MAX_CMD_ARGS);
|
SqThrowF("Argument (%u) is out of total range (%u)", val, SQMOD_MAX_CMD_ARGS);
|
||||||
|
}
|
||||||
else if (val < m_MinArgc)
|
else if (val < m_MinArgc)
|
||||||
|
{
|
||||||
SqThrowF("Minimum argument (%u) exceeds maximum (%u)", m_MinArgc, val);
|
SqThrowF("Minimum argument (%u) exceeds maximum (%u)", m_MinArgc, val);
|
||||||
|
}
|
||||||
// Apply the specified value
|
// Apply the specified value
|
||||||
m_MaxArgc = val;
|
m_MaxArgc = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
bool CmdListener::GetLocked() const
|
|
||||||
{
|
|
||||||
return m_Locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Function & CmdListener::GetOnExec()
|
Function & CmdListener::GetOnExec()
|
||||||
{
|
{
|
||||||
@ -896,7 +1139,9 @@ void CmdListener::SetOnExec(Object & env, Function & func)
|
|||||||
{
|
{
|
||||||
// Make sure that we are allowed to store script resources
|
// Make sure that we are allowed to store script resources
|
||||||
if (m_Name.empty())
|
if (m_Name.empty())
|
||||||
|
{
|
||||||
SqThrowF("Invalid commands cannot store script resources");
|
SqThrowF("Invalid commands cannot store script resources");
|
||||||
|
}
|
||||||
// Apply the specified information
|
// Apply the specified information
|
||||||
m_OnExec = Function(env.GetVM(), env.GetObject(), func.GetFunc());
|
m_OnExec = Function(env.GetVM(), env.GetObject(), func.GetFunc());
|
||||||
}
|
}
|
||||||
@ -912,7 +1157,9 @@ void CmdListener::SetOnAuth(Object & env, Function & func)
|
|||||||
{
|
{
|
||||||
// Make sure that we are allowed to store script resources
|
// Make sure that we are allowed to store script resources
|
||||||
if (m_Name.empty())
|
if (m_Name.empty())
|
||||||
|
{
|
||||||
SqThrowF("Invalid commands cannot store script resources");
|
SqThrowF("Invalid commands cannot store script resources");
|
||||||
|
}
|
||||||
// Apply the specified information
|
// Apply the specified information
|
||||||
m_OnAuth = Function(env.GetVM(), env.GetObject(), func.GetFunc());
|
m_OnAuth = Function(env.GetVM(), env.GetObject(), func.GetFunc());
|
||||||
}
|
}
|
||||||
@ -928,7 +1175,9 @@ void CmdListener::SetOnPost(Object & env, Function & func)
|
|||||||
{
|
{
|
||||||
// Make sure that we are allowed to store script resources
|
// Make sure that we are allowed to store script resources
|
||||||
if (m_Name.empty())
|
if (m_Name.empty())
|
||||||
|
{
|
||||||
SqThrowF("Invalid commands cannot store script resources");
|
SqThrowF("Invalid commands cannot store script resources");
|
||||||
|
}
|
||||||
// Apply the specified information
|
// Apply the specified information
|
||||||
m_OnPost = Function(env.GetVM(), env.GetObject(), func.GetFunc());
|
m_OnPost = Function(env.GetVM(), env.GetObject(), func.GetFunc());
|
||||||
}
|
}
|
||||||
@ -944,7 +1193,9 @@ void CmdListener::SetOnFail(Object & env, Function & func)
|
|||||||
{
|
{
|
||||||
// Make sure that we are allowed to store script resources
|
// Make sure that we are allowed to store script resources
|
||||||
if (m_Name.empty())
|
if (m_Name.empty())
|
||||||
|
{
|
||||||
SqThrowF("Invalid commands cannot store script resources");
|
SqThrowF("Invalid commands cannot store script resources");
|
||||||
|
}
|
||||||
// Apply the specified information
|
// Apply the specified information
|
||||||
m_OnFail = Function(env.GetVM(), env.GetObject(), func.GetFunc());
|
m_OnFail = Function(env.GetVM(), env.GetObject(), func.GetFunc());
|
||||||
}
|
}
|
||||||
@ -954,7 +1205,9 @@ CSStr CmdListener::GetArgTag(Uint32 arg) const
|
|||||||
{
|
{
|
||||||
// Perform a range check on the specified argument index
|
// Perform a range check on the specified argument index
|
||||||
if (arg >= SQMOD_MAX_CMD_ARGS)
|
if (arg >= SQMOD_MAX_CMD_ARGS)
|
||||||
|
{
|
||||||
SqThrowF("Argument (%u) is out of total range (%u)", arg, SQMOD_MAX_CMD_ARGS);
|
SqThrowF("Argument (%u) is out of total range (%u)", arg, SQMOD_MAX_CMD_ARGS);
|
||||||
|
}
|
||||||
// Return the requested information
|
// Return the requested information
|
||||||
return m_ArgTags[arg].c_str();
|
return m_ArgTags[arg].c_str();
|
||||||
}
|
}
|
||||||
@ -964,10 +1217,14 @@ void CmdListener::SetArgTag(Uint32 arg, CSStr name)
|
|||||||
{
|
{
|
||||||
// Perform a range check on the specified argument index
|
// Perform a range check on the specified argument index
|
||||||
if (arg >= SQMOD_MAX_CMD_ARGS)
|
if (arg >= SQMOD_MAX_CMD_ARGS)
|
||||||
|
{
|
||||||
SqThrowF("Argument (%u) is out of total range (%u)", arg, SQMOD_MAX_CMD_ARGS);
|
SqThrowF("Argument (%u) is out of total range (%u)", arg, SQMOD_MAX_CMD_ARGS);
|
||||||
|
}
|
||||||
// The string type doesn't appreciate null values
|
// The string type doesn't appreciate null values
|
||||||
else if (name)
|
else if (name)
|
||||||
|
{
|
||||||
m_ArgTags[arg].assign(name);
|
m_ArgTags[arg].assign(name);
|
||||||
|
}
|
||||||
// Clear previous name in this case
|
// Clear previous name in this case
|
||||||
else
|
else
|
||||||
m_ArgTags[arg].clear();
|
m_ArgTags[arg].clear();
|
||||||
@ -1000,14 +1257,17 @@ void CmdListener::GenerateInfo(bool full)
|
|||||||
}
|
}
|
||||||
// Is there any argument left?
|
// Is there any argument left?
|
||||||
if (stop)
|
if (stop)
|
||||||
// Stop the main loop as well
|
{
|
||||||
break;
|
break; // Stop the main loop as well
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Begin the argument block
|
// Begin the argument block
|
||||||
m_Info.push_back('<');
|
m_Info.push_back('<');
|
||||||
// If the current argument is beyond minimum then mark it as optional
|
// If the current argument is beyond minimum then mark it as optional
|
||||||
if (arg >= m_MinArgc)
|
if (arg >= m_MinArgc)
|
||||||
|
{
|
||||||
m_Info.push_back('*');
|
m_Info.push_back('*');
|
||||||
|
}
|
||||||
// If the argument has a tag/name associated then add it as well
|
// If the argument has a tag/name associated then add it as well
|
||||||
if (!m_ArgTags[arg].empty())
|
if (!m_ArgTags[arg].empty())
|
||||||
{
|
{
|
||||||
@ -1020,19 +1280,25 @@ void CmdListener::GenerateInfo(bool full)
|
|||||||
const Uint8 spec = m_ArgSpec[arg];
|
const Uint8 spec = m_ArgSpec[arg];
|
||||||
// Is this a greedy argument?
|
// Is this a greedy argument?
|
||||||
if (spec & CMDARG_GREEDY)
|
if (spec & CMDARG_GREEDY)
|
||||||
|
{
|
||||||
m_Info.append("...");
|
m_Info.append("...");
|
||||||
|
}
|
||||||
// If the argument has any explicit types specified
|
// If the argument has any explicit types specified
|
||||||
else if (spec != CMDARG_ANY)
|
else if (spec != CMDARG_ANY)
|
||||||
{
|
{
|
||||||
// Does it support integers?
|
// Does it support integers?
|
||||||
if (spec & CMDARG_INTEGER)
|
if (spec & CMDARG_INTEGER)
|
||||||
|
{
|
||||||
m_Info.append("integer");
|
m_Info.append("integer");
|
||||||
|
}
|
||||||
// Does it support floats?
|
// Does it support floats?
|
||||||
if (spec & CMDARG_FLOAT)
|
if (spec & CMDARG_FLOAT)
|
||||||
{
|
{
|
||||||
// Add a separator if this is not the first enabled type!
|
// Add a separator if this is not the first enabled type!
|
||||||
if (m_Info.back() != ':' && m_Info.back() != '<')
|
if (m_Info.back() != ':' && m_Info.back() != '<')
|
||||||
|
{
|
||||||
m_Info.push_back(',');
|
m_Info.push_back(',');
|
||||||
|
}
|
||||||
// Now add the type name
|
// Now add the type name
|
||||||
m_Info.append("float");
|
m_Info.append("float");
|
||||||
}
|
}
|
||||||
@ -1041,7 +1307,9 @@ void CmdListener::GenerateInfo(bool full)
|
|||||||
{
|
{
|
||||||
// Add a separator if this is not the first enabled type!
|
// Add a separator if this is not the first enabled type!
|
||||||
if (m_Info.back() != ':' && m_Info.back() != '<')
|
if (m_Info.back() != ':' && m_Info.back() != '<')
|
||||||
|
{
|
||||||
m_Info.push_back(',');
|
m_Info.push_back(',');
|
||||||
|
}
|
||||||
// Now add the type name
|
// Now add the type name
|
||||||
m_Info.append("boolean");
|
m_Info.append("boolean");
|
||||||
}
|
}
|
||||||
@ -1050,22 +1318,30 @@ void CmdListener::GenerateInfo(bool full)
|
|||||||
{
|
{
|
||||||
// Add a separator if this is not the first enabled type?
|
// Add a separator if this is not the first enabled type?
|
||||||
if (m_Info.back() != ':' && m_Info.back() != '<')
|
if (m_Info.back() != ':' && m_Info.back() != '<')
|
||||||
|
{
|
||||||
m_Info.push_back(',');
|
m_Info.push_back(',');
|
||||||
|
}
|
||||||
// Now add the type name
|
// Now add the type name
|
||||||
m_Info.append("string");
|
m_Info.append("string");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Any kind of value is supported by this argument
|
// Any kind of value is supported by this argument
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_Info.append("any");
|
m_Info.append("any");
|
||||||
|
}
|
||||||
// Terminate the argument block
|
// Terminate the argument block
|
||||||
m_Info.push_back('>');
|
m_Info.push_back('>');
|
||||||
// Don't process anything after greedy arguments
|
// Don't process anything after greedy arguments
|
||||||
if (spec & CMDARG_GREEDY)
|
if (spec & CMDARG_GREEDY)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// If this is not the last argument then add a separator
|
// If this is not the last argument then add a separator
|
||||||
else if (arg+1 != m_MaxArgc)
|
else if (arg+1 != m_MaxArgc)
|
||||||
|
{
|
||||||
m_Info.push_back(' ');
|
m_Info.push_back(' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1074,7 +1350,9 @@ bool CmdListener::ArgCheck(Uint32 arg, Uint8 flag) const
|
|||||||
{
|
{
|
||||||
// Perform a range check on the specified argument index
|
// Perform a range check on the specified argument index
|
||||||
if (arg >= SQMOD_MAX_CMD_ARGS)
|
if (arg >= SQMOD_MAX_CMD_ARGS)
|
||||||
|
{
|
||||||
SqThrowF("Argument (%u) is out of total range (%u)", arg, SQMOD_MAX_CMD_ARGS);
|
SqThrowF("Argument (%u) is out of total range (%u)", arg, SQMOD_MAX_CMD_ARGS);
|
||||||
|
}
|
||||||
// Retrieve the argument flags
|
// Retrieve the argument flags
|
||||||
const Uint8 f = m_ArgSpec[arg];
|
const Uint8 f = m_ArgSpec[arg];
|
||||||
// Perform the requested check
|
// Perform the requested check
|
||||||
@ -1094,7 +1372,9 @@ bool CmdListener::AuthCheckID(Int32 id)
|
|||||||
{
|
{
|
||||||
// Do we need explicit authority verification?
|
// Do we need explicit authority verification?
|
||||||
if (!m_Protected)
|
if (!m_Protected)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
// Allow execution by default
|
// Allow execution by default
|
||||||
bool allow = true;
|
bool allow = true;
|
||||||
// Was there a custom authority inspector specified?
|
// Was there a custom authority inspector specified?
|
||||||
@ -1105,9 +1385,19 @@ bool CmdListener::AuthCheckID(Int32 id)
|
|||||||
// See what the custom authority inspector said or default to disallow
|
// See what the custom authority inspector said or default to disallow
|
||||||
allow = (!ret ? false : *ret);
|
allow = (!ret ? false : *ret);
|
||||||
}
|
}
|
||||||
|
// Was there a global authority inspector specified?
|
||||||
|
else if (!_Cmd->GetOnAuth().IsNull())
|
||||||
|
{
|
||||||
|
// Ask the specified authority inspector if this execution should be allowed
|
||||||
|
SharedPtr< bool > ret = _Cmd->GetOnAuth().Evaluate< bool, Object & >(_Core->GetPlayer(id).mObj);
|
||||||
|
// See what the custom authority inspector said or default to disallow
|
||||||
|
allow = (!ret ? false : *ret);
|
||||||
|
}
|
||||||
// Can we use the default authority system?
|
// Can we use the default authority system?
|
||||||
else if (m_Authority >= 0)
|
else if (m_Authority >= 0)
|
||||||
|
{
|
||||||
allow = (_Core->GetPlayer(id).mAuthority >= m_Authority);
|
allow = (_Core->GetPlayer(id).mAuthority >= m_Authority);
|
||||||
|
}
|
||||||
// Return result
|
// Return result
|
||||||
return allow;
|
return allow;
|
||||||
}
|
}
|
||||||
@ -1274,6 +1564,21 @@ void TerminateCommand()
|
|||||||
_Cmd->Terminate();
|
_Cmd->Terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
static void Cmd_Sort()
|
||||||
|
{
|
||||||
|
_Cmd->Sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
static const Object & Cmd_FindByName(CSStr name)
|
||||||
|
{
|
||||||
|
// Validate the specified name
|
||||||
|
ValidateName(name);
|
||||||
|
// Now perform the requested search
|
||||||
|
return _Cmd->FindByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static Function & Cmd_GetOnError()
|
static Function & Cmd_GetOnError()
|
||||||
{
|
{
|
||||||
@ -1322,22 +1627,44 @@ static CSStr Cmd_GetArgument()
|
|||||||
return _Cmd->GetArgument();
|
return _Cmd->GetArgument();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
Object & Cmd_Create(CSStr name)
|
||||||
|
{
|
||||||
|
return _Cmd->Create(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object & Cmd_Create(CSStr name, CSStr spec)
|
||||||
|
{
|
||||||
|
return _Cmd->Create(name, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object & Cmd_Create(CSStr name, CSStr spec, Array & tags)
|
||||||
|
{
|
||||||
|
return _Cmd->Create(name, spec, tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object & Cmd_Create(CSStr name, CSStr spec, Uint8 min, Uint8 max)
|
||||||
|
{
|
||||||
|
return _Cmd->Create(name,spec, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object & Cmd_Create(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 max)
|
||||||
|
{
|
||||||
|
return _Cmd->Create(name, spec, tags, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
// ================================================================================================
|
// ================================================================================================
|
||||||
void Register_Command(HSQUIRRELVM vm)
|
void Register_Command(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
Table cmdns(vm);
|
Table cmdns(vm);
|
||||||
|
|
||||||
cmdns.Bind(_SC("Listener"), Class< CmdListener, NoCopy< CmdListener > >(vm, _SC("Listener"))
|
cmdns.Bind(_SC("Listener"), Class< CmdListener, NoConstructor< CmdListener > >(vm, _SC("SqCmdListener"))
|
||||||
/* Constructors */
|
|
||||||
.Ctor< CSStr >()
|
|
||||||
.Ctor< CSStr, CSStr >()
|
|
||||||
.Ctor< CSStr, CSStr, Array & >()
|
|
||||||
.Ctor< CSStr, CSStr, Uint8, Uint8 >()
|
|
||||||
.Ctor< CSStr, CSStr, Array &, Uint8, Uint8 >()
|
|
||||||
/* Metamethods */
|
/* Metamethods */
|
||||||
.Func(_SC("_cmp"), &CmdListener::Cmp)
|
.Func(_SC("_cmp"), &CmdListener::Cmp)
|
||||||
|
.SquirrelFunc(_SC("_typename"), &CmdListener::Typename)
|
||||||
.Func(_SC("_tostring"), &CmdListener::ToString)
|
.Func(_SC("_tostring"), &CmdListener::ToString)
|
||||||
/* Properties */
|
/* Properties */
|
||||||
|
.Prop(_SC("Attached"), &CmdListener::Attached)
|
||||||
.Prop(_SC("Name"), &CmdListener::GetName, &CmdListener::SetName)
|
.Prop(_SC("Name"), &CmdListener::GetName, &CmdListener::SetName)
|
||||||
.Prop(_SC("Spec"), &CmdListener::GetSpec, &CmdListener::SetSpec)
|
.Prop(_SC("Spec"), &CmdListener::GetSpec, &CmdListener::SetSpec)
|
||||||
.Prop(_SC("Specifier"), &CmdListener::GetSpec, &CmdListener::SetSpec)
|
.Prop(_SC("Specifier"), &CmdListener::GetSpec, &CmdListener::SetSpec)
|
||||||
@ -1350,12 +1677,13 @@ void Register_Command(HSQUIRRELVM vm)
|
|||||||
.Prop(_SC("Associate"), &CmdListener::GetAssociate, &CmdListener::SetAssociate)
|
.Prop(_SC("Associate"), &CmdListener::GetAssociate, &CmdListener::SetAssociate)
|
||||||
.Prop(_SC("MinArgs"), &CmdListener::GetMinArgC, &CmdListener::SetMinArgC)
|
.Prop(_SC("MinArgs"), &CmdListener::GetMinArgC, &CmdListener::SetMinArgC)
|
||||||
.Prop(_SC("MaxArgs"), &CmdListener::GetMaxArgC, &CmdListener::SetMaxArgC)
|
.Prop(_SC("MaxArgs"), &CmdListener::GetMaxArgC, &CmdListener::SetMaxArgC)
|
||||||
.Prop(_SC("Locked"), &CmdListener::GetLocked)
|
|
||||||
.Prop(_SC("OnExec"), &CmdListener::GetOnExec)
|
.Prop(_SC("OnExec"), &CmdListener::GetOnExec)
|
||||||
.Prop(_SC("OnAuth"), &CmdListener::GetOnAuth)
|
.Prop(_SC("OnAuth"), &CmdListener::GetOnAuth)
|
||||||
.Prop(_SC("OnPost"), &CmdListener::GetOnPost)
|
.Prop(_SC("OnPost"), &CmdListener::GetOnPost)
|
||||||
.Prop(_SC("OnFail"), &CmdListener::GetOnFail)
|
.Prop(_SC("OnFail"), &CmdListener::GetOnFail)
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
.Func(_SC("Attach"), &CmdListener::Attach)
|
||||||
|
.Func(_SC("Detach"), &CmdListener::Detach)
|
||||||
.Func(_SC("BindExec"), &CmdListener::SetOnExec)
|
.Func(_SC("BindExec"), &CmdListener::SetOnExec)
|
||||||
.Func(_SC("BindAuth"), &CmdListener::SetOnAuth)
|
.Func(_SC("BindAuth"), &CmdListener::SetOnAuth)
|
||||||
.Func(_SC("BindPost"), &CmdListener::SetOnPost)
|
.Func(_SC("BindPost"), &CmdListener::SetOnPost)
|
||||||
@ -1368,6 +1696,8 @@ void Register_Command(HSQUIRRELVM vm)
|
|||||||
.Func(_SC("AuthCheckID"), &CmdListener::AuthCheckID)
|
.Func(_SC("AuthCheckID"), &CmdListener::AuthCheckID)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
cmdns.Func(_SC("Sort"), &Cmd_Sort);
|
||||||
|
cmdns.Func(_SC("FindByName"), &Cmd_FindByName);
|
||||||
cmdns.Func(_SC("GetOnError"), &Cmd_GetOnError);
|
cmdns.Func(_SC("GetOnError"), &Cmd_GetOnError);
|
||||||
cmdns.Func(_SC("SetOnError"), &Cmd_SetOnError);
|
cmdns.Func(_SC("SetOnError"), &Cmd_SetOnError);
|
||||||
cmdns.Func(_SC("BindError"), &Cmd_SetOnError);
|
cmdns.Func(_SC("BindError"), &Cmd_SetOnError);
|
||||||
@ -1378,6 +1708,11 @@ void Register_Command(HSQUIRRELVM vm)
|
|||||||
cmdns.Func(_SC("GetInvokerID"), &Cmd_GetInvokerID);
|
cmdns.Func(_SC("GetInvokerID"), &Cmd_GetInvokerID);
|
||||||
cmdns.Func(_SC("GetName"), &Cmd_GetCommand);
|
cmdns.Func(_SC("GetName"), &Cmd_GetCommand);
|
||||||
cmdns.Func(_SC("GetText"), &Cmd_GetArgument);
|
cmdns.Func(_SC("GetText"), &Cmd_GetArgument);
|
||||||
|
cmdns.Overload< Object & (CSStr) >(_SC("Create"), &Cmd_Create);
|
||||||
|
cmdns.Overload< Object & (CSStr, CSStr) >(_SC("Create"), &Cmd_Create);
|
||||||
|
cmdns.Overload< Object & (CSStr, CSStr, Array &) >(_SC("Create"), &Cmd_Create);
|
||||||
|
cmdns.Overload< Object & (CSStr, CSStr, Uint8, Uint8) >(_SC("Create"), &Cmd_Create);
|
||||||
|
cmdns.Overload< Object & (CSStr, CSStr, Array &, Uint8, Uint8) >(_SC("Create"), &Cmd_Create);
|
||||||
|
|
||||||
RootTable(vm).Bind(_SC("SqCmd"), cmdns);
|
RootTable(vm).Bind(_SC("SqCmd"), cmdns);
|
||||||
|
|
||||||
|
@ -33,11 +33,67 @@ class CmdManager
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
typedef std::map< String, CmdListener * > CmdList;
|
* Structure that represents a unique command in the pool.
|
||||||
|
*/
|
||||||
|
struct Command
|
||||||
|
{
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
std::size_t mHash; // The unique hash that identifies this command.
|
||||||
|
String mName; // The unique name that identifies this command.
|
||||||
|
CmdListener* mPtr; // The listener that reacts to this command.
|
||||||
|
Object mObj; // A strong reference to the script object.
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------------------
|
||||||
|
* Construct a command and the also create a script object from the specified listener.
|
||||||
|
*/
|
||||||
|
Command(std::size_t hash, const String & name, CmdListener * ptr)
|
||||||
|
: mHash(hash), mName(name), mPtr(ptr), mObj(ptr)
|
||||||
|
{
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------------------
|
||||||
|
* Construct a command and extract the listener from the specified script object.
|
||||||
|
*/
|
||||||
|
Command(std::size_t hash, const String & name, const Object & obj)
|
||||||
|
: mHash(hash), mName(name), mPtr(obj.Cast< CmdListener * >()), mObj(obj)
|
||||||
|
{
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------------------
|
||||||
|
* Copy constructor.
|
||||||
|
*/
|
||||||
|
Command(const Command & o) = default;
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------------------
|
||||||
|
* Move constructor.
|
||||||
|
*/
|
||||||
|
Command(Command && o) = default;
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------------------
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
~Command() = default;
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------------------
|
||||||
|
* Copy assignment operator.
|
||||||
|
*/
|
||||||
|
Command & operator = (const Command & o) = default;
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------------------
|
||||||
|
* Move assignment operator.
|
||||||
|
*/
|
||||||
|
Command & operator = (Command && o) = default;
|
||||||
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
typedef std::vector< std::pair< Uint8, Object > > CmdArgs;
|
typedef std::vector< Command > CmdList;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
typedef std::pair< Uint8, Object > CmdArg;
|
||||||
|
typedef std::vector< CmdArg > CmdArgs;
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
@ -57,10 +113,27 @@ private:
|
|||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Attach a command listener to a certain name.
|
* Attach a command listener to a certain name.
|
||||||
*/
|
*/
|
||||||
void Attach(const String & name, CmdListener * cmd)
|
Object & Attach(const String & name, CmdListener * ptr, bool autorel);
|
||||||
{
|
|
||||||
m_Commands[name] = cmd;
|
/* --------------------------------------------------------------------------------------------
|
||||||
}
|
* Detach a command listener from a certain name.
|
||||||
|
*/
|
||||||
|
void Detach(const String & name);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Detach a command listener from a certain name.
|
||||||
|
*/
|
||||||
|
void Detach(CmdListener * ptr);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether a certain name exist in the command list.
|
||||||
|
*/
|
||||||
|
bool Attached(const String & name) const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether a certain instance exist in the command list.
|
||||||
|
*/
|
||||||
|
bool Attached(const CmdListener * ptr) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -82,19 +155,21 @@ public:
|
|||||||
return _Cmd;
|
return _Cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Sort the command list in an ascending order.
|
||||||
|
*/
|
||||||
|
void Sort();
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Sort the command list in an ascending order.
|
||||||
|
*/
|
||||||
|
const Object & FindByName(const String & name);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Terminate current session.
|
* Terminate current session.
|
||||||
*/
|
*/
|
||||||
void Terminate();
|
void Terminate();
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Dettach a command listener from a certain name.
|
|
||||||
*/
|
|
||||||
void Detach(const String & name)
|
|
||||||
{
|
|
||||||
m_Commands.erase(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Retrieve the error callback.
|
* Retrieve the error callback.
|
||||||
*/
|
*/
|
||||||
@ -144,7 +219,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Retrieve the argument of the last executed coommand.
|
* Retrieve the argument of the last executed command.
|
||||||
*/
|
*/
|
||||||
CSStr GetArgument() const
|
CSStr GetArgument() const
|
||||||
{
|
{
|
||||||
@ -152,7 +227,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Run a command under a speciffic player.
|
* Run a command under a specific player.
|
||||||
*/
|
*/
|
||||||
Int32 Run(Int32 invoker, CSStr command);
|
Int32 Run(Int32 invoker, CSStr command);
|
||||||
|
|
||||||
@ -194,7 +269,7 @@ private:
|
|||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
Buffer m_Buffer; /* Internal buffer used for parsing commands. */
|
Buffer m_Buffer; /* Internal buffer used for parsing commands. */
|
||||||
CmdList m_Commands; /* List of attached commands. */
|
CmdList m_Commands; /* List of created commands. */
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
Int32 m_Invoker; /* Current command invoker. */
|
Int32 m_Invoker; /* Current command invoker. */
|
||||||
@ -209,6 +284,17 @@ private:
|
|||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
Function m_OnError; /* Error handler. */
|
Function m_OnError; /* Error handler. */
|
||||||
Function m_OnAuth; /* Authentication handler. */
|
Function m_OnAuth; /* Authentication handler. */
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Create command instances and obtain the associated object.
|
||||||
|
*/
|
||||||
|
Object & Create(CSStr name);
|
||||||
|
Object & Create(CSStr name, CSStr spec);
|
||||||
|
Object & Create(CSStr name, CSStr spec, Array & tags);
|
||||||
|
Object & Create(CSStr name, CSStr spec, Uint8 min, Uint8 max);
|
||||||
|
Object & Create(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 max);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
@ -219,6 +305,15 @@ class CmdListener
|
|||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
friend class CmdManager;
|
friend class CmdManager;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Base constructors.
|
||||||
|
*/
|
||||||
|
CmdListener(CSStr name);
|
||||||
|
CmdListener(CSStr name, CSStr spec);
|
||||||
|
CmdListener(CSStr name, CSStr spec, Array & tags);
|
||||||
|
CmdListener(CSStr name, CSStr spec, Uint8 min, Uint8 max);
|
||||||
|
CmdListener(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 max);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Copy constructor. (disabled)
|
* Copy constructor. (disabled)
|
||||||
*/
|
*/
|
||||||
@ -236,15 +331,6 @@ class CmdListener
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Base constructors.
|
|
||||||
*/
|
|
||||||
CmdListener(CSStr name);
|
|
||||||
CmdListener(CSStr name, CSStr spec);
|
|
||||||
CmdListener(CSStr name, CSStr spec, Array & tags);
|
|
||||||
CmdListener(CSStr name, CSStr spec, Uint8 min, Uint8 max);
|
|
||||||
CmdListener(CSStr name, CSStr spec, Array & tags, Uint8 min, Uint8 max);
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Destructor.
|
* Destructor.
|
||||||
*/
|
*/
|
||||||
@ -260,84 +346,203 @@ public:
|
|||||||
*/
|
*/
|
||||||
CSStr ToString() const;
|
CSStr ToString() const;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Used by the script engine to retrieve the name from instances of this type.
|
||||||
|
*/
|
||||||
|
static SQInteger Typename(HSQUIRRELVM vm);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Attach the listener instance to the associated command name.
|
||||||
|
*/
|
||||||
|
void Attach();
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Detach the listener instance from the associated command name.
|
||||||
|
*/
|
||||||
|
void Detach();
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether the listener instance is attached to the associated command name.
|
||||||
|
*/
|
||||||
|
bool Attached() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the flags of the specified argument.
|
||||||
|
*/
|
||||||
Uint8 GetArgFlags(Uint32 idx) const;
|
Uint8 GetArgFlags(Uint32 idx) const;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the name that triggers this command listener instance.
|
||||||
|
*/
|
||||||
CSStr GetName() const;
|
CSStr GetName() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the name that triggers this command listener instance.
|
||||||
|
*/
|
||||||
void SetName(CSStr name);
|
void SetName(CSStr name);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the argument specification string.
|
||||||
|
*/
|
||||||
CSStr GetSpec() const;
|
CSStr GetSpec() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the argument specification string.
|
||||||
|
*/
|
||||||
void SetSpec(CSStr spec);
|
void SetSpec(CSStr spec);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the argument tags array.
|
||||||
|
*/
|
||||||
Array GetArgTags() const;
|
Array GetArgTags() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the argument tags array.
|
||||||
|
*/
|
||||||
void SetArgTags(Array & tags);
|
void SetArgTags(Array & tags);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the help message associated with this command listener instance.
|
||||||
|
*/
|
||||||
CSStr GetHelp() const;
|
CSStr GetHelp() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the help message associated with this command listener instance.
|
||||||
|
*/
|
||||||
void SetHelp(CSStr help);
|
void SetHelp(CSStr help);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the informational message associated with this command listener instance.
|
||||||
|
*/
|
||||||
CSStr GetInfo() const;
|
CSStr GetInfo() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the informational message associated with this command listener instance.
|
||||||
|
*/
|
||||||
void SetInfo(CSStr info);
|
void SetInfo(CSStr info);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the authority level required to execute this command listener instance.
|
||||||
|
*/
|
||||||
Int32 GetAuthority() const;
|
Int32 GetAuthority() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the authority level required to execute this command listener instance.
|
||||||
|
*/
|
||||||
void SetAuthority(Int32 level);
|
void SetAuthority(Int32 level);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether this command listener instance requires explicit authority inspection.
|
||||||
|
*/
|
||||||
bool GetProtected() const;
|
bool GetProtected() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Set whether this command listener instance requires explicit authority inspection.
|
||||||
|
*/
|
||||||
void SetProtected(bool toggle);
|
void SetProtected(bool toggle);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether this command listener instance is currently ignoring calls.
|
||||||
|
*/
|
||||||
bool GetSuspended() const;
|
bool GetSuspended() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Set whether this command listener instance should start ignoring calls.
|
||||||
|
*/
|
||||||
void SetSuspended(bool toggle);
|
void SetSuspended(bool toggle);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether this command listener instance receives arguments in an associative container.
|
||||||
|
*/
|
||||||
bool GetAssociate() const;
|
bool GetAssociate() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Set whether this command listener instance receives arguments in an associative container.
|
||||||
|
*/
|
||||||
void SetAssociate(bool toggle);
|
void SetAssociate(bool toggle);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the maximum arguments supported by this command listener.
|
||||||
|
*/
|
||||||
Uint8 GetMinArgC() const;
|
Uint8 GetMinArgC() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the minimum arguments supported by this command listener.
|
||||||
|
*/
|
||||||
void SetMinArgC(Uint8 val);
|
void SetMinArgC(Uint8 val);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the maximum arguments supported by this command listener.
|
||||||
|
*/
|
||||||
Uint8 GetMaxArgC() const;
|
Uint8 GetMaxArgC() const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the maximum arguments supported by this command listener.
|
||||||
|
*/
|
||||||
void SetMaxArgC(Uint8 val);
|
void SetMaxArgC(Uint8 val);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
bool GetLocked() const;
|
* Retrieve the function that must be called when this command listener is executed.
|
||||||
|
*/
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
Function & GetOnExec();
|
Function & GetOnExec();
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the function that must be called when this command listener is executed.
|
||||||
|
*/
|
||||||
void SetOnExec(Object & env, Function & func);
|
void SetOnExec(Object & env, Function & func);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the function that must be called when this command listener needs to authenticate.
|
||||||
|
*/
|
||||||
Function & GetOnAuth();
|
Function & GetOnAuth();
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the function that must be called when this command listener needs to authenticate.
|
||||||
|
*/
|
||||||
void SetOnAuth(Object & env, Function & func);
|
void SetOnAuth(Object & env, Function & func);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the function that must be called when this command listener finished execution.
|
||||||
|
*/
|
||||||
Function & GetOnPost();
|
Function & GetOnPost();
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the function that must be called when this command listener finished execution.
|
||||||
|
*/
|
||||||
void SetOnPost(Object & env, Function & func);
|
void SetOnPost(Object & env, Function & func);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
Function & GetOnFail();
|
Function & GetOnFail();
|
||||||
void SetOnFail(Object & env, Function & func);
|
void SetOnFail(Object & env, Function & func);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Retrieve the function that must be called when this command listener failed to execute.
|
||||||
|
*/
|
||||||
CSStr GetArgTag(Uint32 arg) const;
|
CSStr GetArgTag(Uint32 arg) const;
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the function that must be called when this command listener failed to execute.
|
||||||
|
*/
|
||||||
void SetArgTag(Uint32 arg, CSStr name);
|
void SetArgTag(Uint32 arg, CSStr name);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Use the command listener argument properties to generate an informational message.
|
||||||
|
*/
|
||||||
void GenerateInfo(bool full);
|
void GenerateInfo(bool full);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether whether the specified argument can be used on this command listener instance.
|
||||||
|
*/
|
||||||
bool ArgCheck(Uint32 arg, Uint8 flag) const;
|
bool ArgCheck(Uint32 arg, Uint8 flag) const;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether the specified player entity has the proper authority to run this command.
|
||||||
|
*/
|
||||||
bool AuthCheck(CPlayer & player);
|
bool AuthCheck(CPlayer & player);
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether the specified player entity has the proper authority to run this command.
|
||||||
|
*/
|
||||||
bool AuthCheckID(Int32 id);
|
bool AuthCheckID(Int32 id);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -347,17 +552,17 @@ protected:
|
|||||||
typedef String ArgTags[SQMOD_MAX_CMD_ARGS];
|
typedef String ArgTags[SQMOD_MAX_CMD_ARGS];
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
*
|
* Execute the designated callback by passing the arguments in their specified order.
|
||||||
*/
|
*/
|
||||||
SQInteger Execute(Object & invoker, Array & args);
|
SQInteger Execute(Object & invoker, Array & args);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
*
|
* Execute the designated callback by passing the arguments using an associative container.
|
||||||
*/
|
*/
|
||||||
SQInteger Execute(Object & invoker, Table & args);
|
SQInteger Execute(Object & invoker, Table & args);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
*
|
* Process the specified string and extract the argument properties in it.
|
||||||
*/
|
*/
|
||||||
void ProcSpec(CSStr spec);
|
void ProcSpec(CSStr spec);
|
||||||
|
|
||||||
@ -392,7 +597,6 @@ private:
|
|||||||
bool m_Protected;
|
bool m_Protected;
|
||||||
bool m_Suspended;
|
bool m_Suspended;
|
||||||
bool m_Associate;
|
bool m_Associate;
|
||||||
bool m_Locked;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace:: SqMod
|
} // Namespace:: SqMod
|
||||||
|
@ -95,6 +95,7 @@ Object Routine::Associate(Routine * routine)
|
|||||||
// If the iterator still points to a null element then we failed
|
// If the iterator still points to a null element then we failed
|
||||||
if (itr == s_Objects.end())
|
if (itr == s_Objects.end())
|
||||||
{
|
{
|
||||||
|
// NOTE: Routine instance is destroyed by the script object if necessary!
|
||||||
SqThrowF("Unable to remember routine instance");
|
SqThrowF("Unable to remember routine instance");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user