mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Various.
This commit is contained in:
parent
bc5e5ef45f
commit
0ebdecb75f
@ -283,7 +283,7 @@ const SQChar * ToStringF(const char * fmt, ...) noexcept
|
||||
// Return an empty string
|
||||
buf[0] = '\0';
|
||||
}
|
||||
// Move the buffer back to the buffer pool
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
// The buffer data wasn't destroyed and Squirrel should have time to copy it
|
||||
return buf;
|
||||
@ -359,7 +359,7 @@ const SQChar * InsertStr(const SQChar * f, const std::vector< const SQChar * > &
|
||||
}
|
||||
// Insert the null character
|
||||
buf[n] = '\0';
|
||||
// Move the buffer back to the buffer pool
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
// The buffer data wasn't destroyed and Squirrel should have time to copy it
|
||||
return buf;
|
||||
@ -406,7 +406,7 @@ const SQChar * LeftStr(const SQChar * t, SQChar f, SQUint32 w) noexcept
|
||||
}
|
||||
// Add the terminating character
|
||||
buf[w] = '\0';
|
||||
// Move the buffer back to the buffer pool
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
// The buffer data wasn't destroyed and Squirrel should have time to copy it
|
||||
return buf;
|
||||
@ -446,7 +446,7 @@ const SQChar * LeftStr(const SQChar * t, SQChar f, SQUint32 w, SQUint32 o) noexc
|
||||
}
|
||||
// Add the terminating character
|
||||
buf[w] = '\0';
|
||||
// Move the buffer back to the buffer pool
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
// The buffer data wasn't destroyed and Squirrel should have time to copy it
|
||||
return buf;
|
||||
@ -487,7 +487,7 @@ const SQChar * RightStr(const SQChar * t, SQChar f, SQUint32 w) noexcept
|
||||
}
|
||||
// Add the terminating character
|
||||
buf[w] = '\0';
|
||||
// Move the buffer back to the buffer pool
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
// The buffer data wasn't destroyed and Squirrel should have time to copy it
|
||||
return buf;
|
||||
@ -527,7 +527,7 @@ const SQChar * RightStr(const SQChar * t, SQChar f, SQUint32 w, SQUint32 o) noex
|
||||
}
|
||||
// Add the terminating character
|
||||
buf[w] = '\0';
|
||||
// Move the buffer back to the buffer pool
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
// The buffer data wasn't destroyed and Squirrel should have time to copy it
|
||||
return buf;
|
||||
@ -568,7 +568,7 @@ const SQChar * CenterStr(const SQChar * t, SQChar f, SQUint32 w) noexcept
|
||||
}
|
||||
// Add the terminating character
|
||||
buf[w] = '\0';
|
||||
// Move the buffer back to the buffer pool
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
// The buffer data wasn't destroyed and Squirrel should have time to copy it
|
||||
return buf;
|
||||
|
@ -317,6 +317,7 @@ class LocalEvent;
|
||||
#define _SCF32(v) static_cast<Float32>(v)
|
||||
#define _SCF64(v) static_cast<Float64>(v)
|
||||
#define _SCSQF(v) static_cast<SQFloat>(v)
|
||||
#define _SCSZT(v) static_cast<size_t>(v)
|
||||
|
||||
// Short notation for getting the minimum and maxmimum value of primitives
|
||||
#define _NLMIN(t) std::numeric_limits<t>::min()
|
||||
|
236
source/Core.cpp
236
source/Core.cpp
@ -77,28 +77,28 @@ Core::Pointer Core::Inst() noexcept
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Core::Init() noexcept
|
||||
{
|
||||
_Log->Msg("%s", CenterStr("INITIALIZING", '*'));
|
||||
LogMsg("%s", CenterStr("INITIALIZING", '*'));
|
||||
|
||||
if (!this->Configure() || !this->CreateVM() || !this->LoadScripts())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_Log->Msg("%s", CenterStr("SUCCESS", '*'));
|
||||
LogMsg("%s", CenterStr("SUCCESS", '*'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Core::Load() noexcept
|
||||
{
|
||||
_Log->Msg("%s", CenterStr("LOADING", '*'));
|
||||
LogMsg("%s", CenterStr("LOADING", '*'));
|
||||
|
||||
if (!this->Execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_Log->Msg("%s", CenterStr("SUCCESS", '*'));
|
||||
LogMsg("%s", CenterStr("SUCCESS", '*'));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -203,7 +203,7 @@ void Core::DisconnectPlayer(SQInt32 id, SQInt32 header, SqObj & payload) noexcep
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Core::Configure() noexcept
|
||||
{
|
||||
_Log->Dbg("Attempting to instantiate the configuration file");
|
||||
LogDbg("Attempting to instantiate the configuration file");
|
||||
|
||||
if (g_Config)
|
||||
{
|
||||
@ -216,12 +216,12 @@ bool Core::Configure() noexcept
|
||||
|
||||
if (!g_Config)
|
||||
{
|
||||
_Log->Ftl("Unable to instantiate the configuration class");
|
||||
LogFtl("Unable to instantiate the configuration class");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_Log->Dbg("Attempting to load the configuration file.");
|
||||
LogDbg("Attempting to load the configuration file.");
|
||||
|
||||
SI_Error ini_ret = g_Config->LoadFile(_SC("./sqmod.ini"));
|
||||
|
||||
@ -229,15 +229,15 @@ bool Core::Configure() noexcept
|
||||
{
|
||||
switch (ini_ret)
|
||||
{
|
||||
case SI_FAIL: _Log->Err("Failed to load the configuration file. Probably invalid"); break;
|
||||
case SI_NOMEM: _Log->Err("Run out of memory while loading the configuration file"); break;
|
||||
case SI_FILE: _Log->Err("Failed to load the configuration file. %s", strerror(errno)); break;
|
||||
default: _Log->Err("Failed to load the configuration file for some unforeseen reason");
|
||||
case SI_FAIL: LogErr("Failed to load the configuration file. Probably invalid"); break;
|
||||
case SI_NOMEM: LogErr("Run out of memory while loading the configuration file"); break;
|
||||
case SI_FILE: LogErr("Failed to load the configuration file. %s", strerror(errno)); break;
|
||||
default: LogErr("Failed to load the configuration file for some unforeseen reason");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
_Log->Dbg("Applying the specified logging filters");
|
||||
LogDbg("Applying the specified logging filters");
|
||||
|
||||
if (!SToB(g_Config->GetValue("ConsoleLog", "Debug", "true"))) _Log->DisableConsoleLevel(Logger::LEVEL_DBG);
|
||||
if (!SToB(g_Config->GetValue("ConsoleLog", "Message", "true"))) _Log->DisableConsoleLevel(Logger::LEVEL_MSG);
|
||||
@ -255,13 +255,13 @@ bool Core::Configure() noexcept
|
||||
if (!SToB(g_Config->GetValue("FileLog", "Error", "true"))) _Log->DisableFileLevel(Logger::LEVEL_ERR);
|
||||
if (!SToB(g_Config->GetValue("FileLog", "Fatal", "true"))) _Log->DisableFileLevel(Logger::LEVEL_FTL);
|
||||
|
||||
_Log->Dbg("Reading the options from the general section");
|
||||
LogDbg("Reading the options from the general section");
|
||||
|
||||
CSimpleIniA::TNamesDepend general_options;
|
||||
|
||||
if (g_Config->GetAllKeys("Options", general_options) || general_options.size() > 0)
|
||||
{
|
||||
for (auto const & cfg_option : general_options)
|
||||
for (const auto & cfg_option : general_options)
|
||||
{
|
||||
CSimpleIniA::TNamesDepend option_list;
|
||||
|
||||
@ -272,7 +272,7 @@ bool Core::Configure() noexcept
|
||||
|
||||
option_list.sort(CSimpleIniA::Entry::LoadOrder());
|
||||
|
||||
for (auto const & cfg_value : option_list)
|
||||
for (const auto & cfg_value : option_list)
|
||||
{
|
||||
m_Options[cfg_option.pItem] = cfg_value.pItem;
|
||||
}
|
||||
@ -280,7 +280,7 @@ bool Core::Configure() noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log->Inf("No options specified in the configuration file");
|
||||
LogInf("No options specified in the configuration file");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -289,7 +289,7 @@ bool Core::Configure() noexcept
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Core::CreateVM() noexcept
|
||||
{
|
||||
_Log->Dbg("Acquiring the virtual machine stack size");
|
||||
LogDbg("Acquiring the virtual machine stack size");
|
||||
|
||||
// Start with an unknown stack size
|
||||
SQInteger stack_size = SQMOD_UNKNOWN;
|
||||
@ -297,28 +297,28 @@ bool Core::CreateVM() noexcept
|
||||
// Attempt to get it from the configuration file
|
||||
try
|
||||
{
|
||||
stack_size = SToI<SQInteger>::Fn(GetOption(_SC("VMStackSize")), 0, 10);
|
||||
stack_size = SToI< SQInteger >::Fn(GetOption(_SC("VMStackSize")), 0, 10);
|
||||
}
|
||||
catch (const std::invalid_argument & e)
|
||||
{
|
||||
_Log->Wrn("Unable to extract option value: %s", e.what());
|
||||
LogWrn("Unable to extract option value: %s", e.what());
|
||||
}
|
||||
|
||||
// Validate the stack size
|
||||
if (stack_size <= 0)
|
||||
{
|
||||
_Log->Wrn("Invalid stack size. Reverting to default size");
|
||||
LogWrn("Invalid stack size. Reverting to default size: %d", SQMOD_STACK_SIZE);
|
||||
SetOption(_SC("VMStackSize"), std::to_string(SQMOD_STACK_SIZE));
|
||||
stack_size = SQMOD_STACK_SIZE;
|
||||
}
|
||||
|
||||
_Log->Inf("Creating a virtual machine with a stack size of: %d", stack_size);
|
||||
LogInf("Creating a virtual machine with a stack size of: %d", stack_size);
|
||||
|
||||
m_VM = sq_open(stack_size);
|
||||
|
||||
if (!m_VM)
|
||||
{
|
||||
_Log->Ftl("Unable to create the virtual machine");
|
||||
LogFtl("Unable to open a virtual machine with a stack size: %d", stack_size);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -330,8 +330,8 @@ bool Core::CreateVM() noexcept
|
||||
m_Scripts.clear();
|
||||
}
|
||||
|
||||
_Log->Dbg("Registering the standard libraries");
|
||||
|
||||
LogDbg("Registering the standard libraries");
|
||||
// Register the standard libraries
|
||||
sq_pushroottable(m_VM);
|
||||
sqstd_register_iolib(m_VM);
|
||||
sqstd_register_bloblib(m_VM);
|
||||
@ -340,24 +340,24 @@ bool Core::CreateVM() noexcept
|
||||
sqstd_register_stringlib(m_VM);
|
||||
sq_pop(m_VM, 1);
|
||||
|
||||
_Log->Dbg("Setting the base output function");
|
||||
|
||||
LogDbg("Setting the base output function");
|
||||
// Set the function that handles the text output
|
||||
sq_setprintfunc(m_VM, PrintFunc, ErrorFunc);
|
||||
|
||||
_Log->Dbg("Setting the base error handlers");
|
||||
|
||||
LogDbg("Setting the base error handlers");
|
||||
// Se the error handlers
|
||||
sq_setcompilererrorhandler(m_VM, CompilerErrorHandler);
|
||||
sq_newclosure(m_VM, RuntimeErrorHandler, 0);
|
||||
sq_seterrorhandler(m_VM);
|
||||
|
||||
_Log->Dbg("Registering the plugin API");
|
||||
|
||||
LogDbg("Registering the plugin API");
|
||||
// Register the plugin API
|
||||
if (!RegisterAPI(m_VM))
|
||||
{
|
||||
_Log->Ftl("Unable to register the script API");
|
||||
LogFtl("Unable to register the plugin API");
|
||||
return false;
|
||||
}
|
||||
|
||||
// At this point the VM is ready
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -366,25 +366,29 @@ void Core::DestroyVM() noexcept
|
||||
// See if the Virtual Machine wasn't already destroyed
|
||||
if (m_VM != nullptr)
|
||||
{
|
||||
// Release the reference to the root table
|
||||
m_RootTable.reset();
|
||||
// Let instances know that they should release links to this VM
|
||||
VMClose.Emit();
|
||||
// Release the references to the script objects
|
||||
m_Scripts.clear();
|
||||
// Close the Virtual Machine
|
||||
sq_close(m_VM);
|
||||
// Release the reference to the root table
|
||||
m_RootTable.reset();
|
||||
// Assertions during close may cause double delete
|
||||
HSQUIRRELVM sq_vm = m_VM;
|
||||
// Explicitly set the virtual machine to null
|
||||
m_VM = nullptr;
|
||||
// Close the Virtual Machine
|
||||
sq_close(sq_vm);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Core::LoadScripts() noexcept
|
||||
{
|
||||
_Log->Dbg("Attempting to compile the specified scripts");
|
||||
LogDbg("Attempting to compile the specified scripts");
|
||||
|
||||
if (!g_Config)
|
||||
{
|
||||
_Log->Wrn("Cannot compile any scripts without the configurations");
|
||||
LogWrn("Cannot compile any scripts without the configurations");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -394,7 +398,7 @@ bool Core::LoadScripts() noexcept
|
||||
|
||||
if (script_list.size() <= 0)
|
||||
{
|
||||
_Log->Wrn("No scripts specified in the configuration file");
|
||||
LogWrn("No scripts specified in the configuration file");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -407,7 +411,7 @@ bool Core::LoadScripts() noexcept
|
||||
|
||||
if (m_Scripts.find(path) != m_Scripts.cend())
|
||||
{
|
||||
_Log->Wrn("Script was already loaded: %s", path.c_str());
|
||||
LogWrn("Script was already loaded: %s", path.c_str());
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -417,13 +421,13 @@ bool Core::LoadScripts() noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log->Scs("Successfully compiled script: %s", path.c_str());
|
||||
LogScs("Successfully compiled script: %s", path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Scripts.empty())
|
||||
{
|
||||
_Log->Err("No scripts compiled. No reason to load the plugin");
|
||||
LogErr("No scripts compiled. No reason to load the plugin");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -436,7 +440,7 @@ bool Core::Compile(const string & name) noexcept
|
||||
{
|
||||
if (name.empty())
|
||||
{
|
||||
_Log->Err("Cannot compile script without a valid name");
|
||||
LogErr("Cannot compile script without a valid name");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -449,8 +453,8 @@ bool Core::Compile(const string & name) noexcept
|
||||
|
||||
if (Error::Occurred(m_VM))
|
||||
{
|
||||
_Log->Err("Unable to compile script: %s", name.c_str());
|
||||
_Log->Inf("=> %s", Error::Message(m_VM).c_str());
|
||||
LogErr("Unable to compile script: %s", name.c_str());
|
||||
LogInf("=> %s", Error::Message(m_VM).c_str());
|
||||
m_Scripts.erase(res.first);
|
||||
|
||||
return false;
|
||||
@ -458,7 +462,7 @@ bool Core::Compile(const string & name) noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log->Err("Unable to queue script: %s", name.c_str());
|
||||
LogErr("Unable to queue script: %s", name.c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -468,7 +472,7 @@ bool Core::Compile(const string & name) noexcept
|
||||
|
||||
bool Core::Execute() noexcept
|
||||
{
|
||||
_Log->Dbg("Attempting to execute the specified scripts");
|
||||
LogDbg("Attempting to execute the specified scripts");
|
||||
|
||||
for (auto & elem : m_Scripts)
|
||||
{
|
||||
@ -476,14 +480,14 @@ bool Core::Execute() noexcept
|
||||
|
||||
if (Error::Occurred(m_VM))
|
||||
{
|
||||
_Log->Err("Unable to execute script: %s", elem.first.c_str());
|
||||
_Log->Inf("=> %s", Error::Message(m_VM).c_str());
|
||||
LogErr("Unable to execute script: %s", elem.first.c_str());
|
||||
LogInf("=> %s", Error::Message(m_VM).c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log->Scs("Successfully executed script: %s", elem.first.c_str());
|
||||
LogScs("Successfully executed script: %s", elem.first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,12 +500,12 @@ void Core::PrintCallstack() noexcept
|
||||
SQStackInfos si;
|
||||
|
||||
|
||||
_Log->Msg("%s", CenterStr("CALLSTACK", '*'));
|
||||
LogMsg("%s", CenterStr("CALLSTACK", '*'));
|
||||
|
||||
for (SQInteger level = 1; SQ_SUCCEEDED(sq_stackinfos(m_VM, level, &si)); ++level)
|
||||
{
|
||||
_Log->Inf("FUNCTION %s()", si.funcname ? si.funcname : _SC("unknown"));
|
||||
_Log->SInf("=> [%d] : {%s}", si.line, si.source ? si.source : _SC("unknown"));
|
||||
LogInf("FUNCTION %s()", si.funcname ? si.funcname : _SC("unknown"));
|
||||
LogInf("=> [%d] : {%s}", si.line, si.source ? si.source : _SC("unknown"));
|
||||
}
|
||||
|
||||
const SQChar * s_ = 0, * name = 0;
|
||||
@ -509,7 +513,7 @@ void Core::PrintCallstack() noexcept
|
||||
SQFloat f_;
|
||||
SQUserPointer p_;
|
||||
|
||||
_Log->Msg("%s", CenterStr("LOCALS", '*'));
|
||||
LogMsg("%s", CenterStr("LOCALS", '*'));
|
||||
|
||||
for (SQInteger level = 0; level < 10; level++) {
|
||||
seq = 0;
|
||||
@ -518,60 +522,60 @@ void Core::PrintCallstack() noexcept
|
||||
switch(sq_gettype(m_VM, -1))
|
||||
{
|
||||
case OT_NULL:
|
||||
_Log->Inf("NULL [%s] : ...", name);
|
||||
LogInf("NULL [%s] : ...", name);
|
||||
break;
|
||||
case OT_INTEGER:
|
||||
sq_getinteger(m_VM, -1, &i_);
|
||||
_Log->Inf("INTEGER [%s] : {%d}", name, i_);
|
||||
LogInf("INTEGER [%s] : {%d}", name, i_);
|
||||
break;
|
||||
case OT_FLOAT:
|
||||
sq_getfloat(m_VM, -1, &f_);
|
||||
_Log->Inf("FLOAT [%s] : {%f}", name, f_);
|
||||
LogInf("FLOAT [%s] : {%f}", name, f_);
|
||||
break;
|
||||
case OT_USERPOINTER:
|
||||
sq_getuserpointer(m_VM, -1, &p_);
|
||||
_Log->Inf("USERPOINTER [%s] : {%p}\n", name, p_);
|
||||
LogInf("USERPOINTER [%s] : {%p}\n", name, p_);
|
||||
break;
|
||||
case OT_STRING:
|
||||
sq_getstring(m_VM, -1, &s_);
|
||||
_Log->Inf("STRING [%s] : {%s}", name, s_);
|
||||
LogInf("STRING [%s] : {%s}", name, s_);
|
||||
break;
|
||||
case OT_TABLE:
|
||||
_Log->Inf("TABLE [%s] : ...", name);
|
||||
LogInf("TABLE [%s] : ...", name);
|
||||
break;
|
||||
case OT_ARRAY:
|
||||
_Log->Inf("ARRAY [%s] : ...", name);
|
||||
LogInf("ARRAY [%s] : ...", name);
|
||||
break;
|
||||
case OT_CLOSURE:
|
||||
_Log->Inf("CLOSURE [%s] : ...", name);
|
||||
LogInf("CLOSURE [%s] : ...", name);
|
||||
break;
|
||||
case OT_NATIVECLOSURE:
|
||||
_Log->Inf("NATIVECLOSURE [%s] : ...", name);
|
||||
LogInf("NATIVECLOSURE [%s] : ...", name);
|
||||
break;
|
||||
case OT_GENERATOR:
|
||||
_Log->Inf("GENERATOR [%s] : ...", name);
|
||||
LogInf("GENERATOR [%s] : ...", name);
|
||||
break;
|
||||
case OT_USERDATA:
|
||||
_Log->Inf("USERDATA [%s] : ...", name);
|
||||
LogInf("USERDATA [%s] : ...", name);
|
||||
break;
|
||||
case OT_THREAD:
|
||||
_Log->Inf("THREAD [%s] : ...", name);
|
||||
LogInf("THREAD [%s] : ...", name);
|
||||
break;
|
||||
case OT_CLASS:
|
||||
_Log->Inf("CLASS [%s] : ...", name);
|
||||
LogInf("CLASS [%s] : ...", name);
|
||||
break;
|
||||
case OT_INSTANCE:
|
||||
_Log->Inf("INSTANCE [%s] : ...", name);
|
||||
LogInf("INSTANCE [%s] : ...", name);
|
||||
break;
|
||||
case OT_WEAKREF:
|
||||
_Log->Inf("WEAKREF [%s] : ...", name);
|
||||
LogInf("WEAKREF [%s] : ...", name);
|
||||
break;
|
||||
case OT_BOOL:
|
||||
sq_getinteger(m_VM, -1, &i_);
|
||||
_Log->Inf("BOOL [%s] : {%s}", name, i_ ? _SC("true") : _SC("false"));
|
||||
LogInf("BOOL [%s] : {%s}", name, i_ ? _SC("true") : _SC("false"));
|
||||
break;
|
||||
default:
|
||||
_Log->Err("UNKNOWN [%s] : ...", name);
|
||||
LogErr("UNKNOWN [%s] : ...", name);
|
||||
break;
|
||||
}
|
||||
sq_pop(m_VM, 1);
|
||||
@ -582,44 +586,84 @@ void Core::PrintCallstack() noexcept
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::PrintFunc(HSQUIRRELVM vm, const SQChar * str, ...) noexcept
|
||||
{
|
||||
// Prepare the arguments list
|
||||
va_list args;
|
||||
va_start(args, str);
|
||||
|
||||
std::vector<char> buffer(256);
|
||||
SQInt32 fmt_ret = std::vsnprintf(&buffer[0], buffer.size(), str, args);
|
||||
|
||||
// Acquire a buffer from the buffer pool
|
||||
Core::Buffer vbuf = _Core->PullBuffer();
|
||||
// Attempt to process the specified format string
|
||||
SQInt32 fmt_ret = std::vsnprintf(vbuf.data(), vbuf.size(), str, args);
|
||||
// See if the formatting was successful
|
||||
if (fmt_ret < 0)
|
||||
{
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
LogErr("Format error");
|
||||
return;
|
||||
}
|
||||
else if (static_cast<std::size_t>(fmt_ret) > buffer.size())
|
||||
// See if the buffer was big enough
|
||||
else if (_SCSZT(fmt_ret) > vbuf.size())
|
||||
{
|
||||
buffer.resize(++fmt_ret);
|
||||
vsnprintf(&buffer[0], buffer.size(), str, args);
|
||||
// Resize the buffer to accomodate the required size
|
||||
vbuf.resize(++fmt_ret);
|
||||
// Attempt to process the specified format string again
|
||||
fmt_ret = std::vsnprintf(vbuf.data(), vbuf.size(), str, args);
|
||||
// See if the formatting was successful
|
||||
if (fmt_ret < 0)
|
||||
{
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
LogErr("Format error");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Release the arguments list
|
||||
va_end(args);
|
||||
|
||||
_Log->Msg("%s", buffer.data());
|
||||
// Output the buffer content
|
||||
LogMsg("%s", vbuf.data());
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
}
|
||||
|
||||
void Core::ErrorFunc(HSQUIRRELVM vm, const SQChar * str, ...) noexcept
|
||||
{
|
||||
// Prepare the arguments list
|
||||
va_list args;
|
||||
va_start(args, str);
|
||||
|
||||
std::vector<char> buffer(256);
|
||||
std::size_t buff_sz = static_cast<std::size_t>(vsnprintf(&buffer[0], buffer.size(), str, args));
|
||||
|
||||
if (buff_sz > buffer.size())
|
||||
// Acquire a buffer from the buffer pool
|
||||
Core::Buffer vbuf = _Core->PullBuffer();
|
||||
// Attempt to process the specified format string
|
||||
SQInt32 fmt_ret = std::vsnprintf(vbuf.data(), vbuf.size(), str, args);
|
||||
// See if the formatting was successful
|
||||
if (fmt_ret < 0)
|
||||
{
|
||||
buffer.resize(++buff_sz);
|
||||
vsnprintf(&buffer[0], buffer.size(), str, args);
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
LogErr("Format error");
|
||||
return;
|
||||
}
|
||||
|
||||
// See if the buffer was big enough
|
||||
else if (_SCSZT(fmt_ret) > vbuf.size())
|
||||
{
|
||||
// Resize the buffer to accomodate the required size
|
||||
vbuf.resize(++fmt_ret);
|
||||
// Attempt to process the specified format string again
|
||||
fmt_ret = std::vsnprintf(vbuf.data(), vbuf.size(), str, args);
|
||||
// See if the formatting was successful
|
||||
if (fmt_ret < 0)
|
||||
{
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
LogErr("Format error");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Release the arguments list
|
||||
va_end(args);
|
||||
|
||||
_Log->Err("%s", buffer.data());
|
||||
// Output the buffer content
|
||||
LogErr("%s", vbuf.data());
|
||||
// Return the buffer back to the buffer pool
|
||||
_Core->PushBuffer(std::move(vbuf));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -641,16 +685,16 @@ SQInteger Core::RuntimeErrorHandler(HSQUIRRELVM vm) noexcept
|
||||
_Core->m_ErrorMsg.assign(_SC("An unknown runtime error has occurred"));
|
||||
}
|
||||
|
||||
_Log->Msg("%s", CenterStr("ERROR", '*'));
|
||||
LogMsg("%s", CenterStr("ERROR", '*'));
|
||||
|
||||
_Log->Inf("[MESSAGE] : %s", _Core->m_ErrorMsg.c_str());
|
||||
LogInf("[MESSAGE] : %s", _Core->m_ErrorMsg.c_str());
|
||||
|
||||
if (_Log->GetVerbosity() > 0)
|
||||
{
|
||||
_Core->PrintCallstack();
|
||||
}
|
||||
|
||||
_Log->Msg("%s", CenterStr("CONCLUDED", '*'));
|
||||
LogMsg("%s", CenterStr("CONCLUDED", '*'));
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
@ -663,11 +707,11 @@ void Core::CompilerErrorHandler(HSQUIRRELVM vm, const SQChar * desc, const SQCha
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
_Log->Err("Compiler error: %s", e.what());
|
||||
LogErr("Compiler error: %s", e.what());
|
||||
_Core->m_ErrorMsg.assign(_SC("An unknown compiler error has occurred"));
|
||||
}
|
||||
|
||||
_Log->Err("%s", _Core->m_ErrorMsg.c_str());
|
||||
LogErr("%s", _Core->m_ErrorMsg.c_str());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -622,6 +622,9 @@ public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
ELogMessage LogMessage;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
EVMClose VMClose;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -34,12 +34,16 @@ BasicEvent::BasicEvent(SQInt32 type, bool suspended) noexcept
|
||||
, m_Suspended(suspended)
|
||||
{
|
||||
Attach();
|
||||
// Receive notification when the VM is about to be closed to release object references
|
||||
_Core->VMClose.Connect< BasicEvent, &BasicEvent::VMClose >(this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BasicEvent::~BasicEvent()
|
||||
{
|
||||
Detach();
|
||||
// Stop receiving notification when the VM is about to be closed
|
||||
_Core->VMClose.Disconnect< BasicEvent, &BasicEvent::VMClose >(this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -1901,6 +1905,23 @@ void BasicEvent::Detach() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BasicEvent::VMClose() noexcept
|
||||
{
|
||||
LogInf("[BasicEvent::VMClose() %d %d",
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetEnv()),
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetFunc())
|
||||
);
|
||||
|
||||
// Release the reference to the specified callback
|
||||
m_OnTrigger.Release();
|
||||
|
||||
LogInf("]BasicEvent::VMClose() %d %d",
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetEnv()),
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetFunc())
|
||||
);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
bool Register_BasicEvent(HSQUIRRELVM vm)
|
||||
{
|
||||
@ -1911,8 +1932,8 @@ bool Register_BasicEvent(HSQUIRRELVM vm)
|
||||
// Attempt to register the specified type
|
||||
Sqrat::RootTable(vm).Bind(_SC("BasicEvent"), Sqrat::Class< BasicEvent, Allocator >(vm, _SC("BasicEvent"))
|
||||
.Ctor()
|
||||
.Ctor<SQInt32>()
|
||||
.Ctor<SQInt32, bool>()
|
||||
.Ctor< SQInt32 >()
|
||||
.Ctor< SQInt32, bool >()
|
||||
|
||||
.Func(_SC("_cmp"), &BasicEvent::Cmp)
|
||||
.Func(_SC("_tostring"), &BasicEvent::GetName)
|
||||
|
@ -757,6 +757,11 @@ public:
|
||||
*/
|
||||
void LogMessage(SQInt32 type, const SQChar * message) noexcept;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
void VMClose() noexcept;
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
|
@ -50,6 +50,8 @@ GlobalEvent::GlobalEvent(SQInt32 type, bool suspended) noexcept
|
||||
{
|
||||
// Attach to the specified event signal
|
||||
Attach();
|
||||
// Receive notification when the VM is about to be closed to release object references
|
||||
_Core->VMClose.Connect< GlobalEvent, &GlobalEvent::VMClose >(this);
|
||||
/* Entity filters are empty so there's nothing to hook to! */
|
||||
}
|
||||
|
||||
@ -58,6 +60,8 @@ GlobalEvent::~GlobalEvent()
|
||||
{
|
||||
// Detach from the specified event signal
|
||||
Detach();
|
||||
// Stop receiving notification when the VM is about to be closed
|
||||
_Core->VMClose.Disconnect< GlobalEvent, &GlobalEvent::VMClose >(this);
|
||||
/* We're expecting the entity filters to unhook themselves from the destroy signal! */
|
||||
}
|
||||
|
||||
@ -2059,6 +2063,23 @@ void GlobalEvent::Adaptable(SQInt32 type) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void GlobalEvent::VMClose() noexcept
|
||||
{
|
||||
LogInf("[GlobalEvent::VMClose() %d %d",
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetEnv()),
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetFunc())
|
||||
);
|
||||
|
||||
// Release the reference to the specified callback
|
||||
m_OnTrigger.Release();
|
||||
|
||||
LogInf("]GlobalEvent::VMClose() %d %d",
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetEnv()),
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetFunc())
|
||||
);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
template < class T > static bool Register_GlobalFilter(HSQUIRRELVM vm, const SQChar * cname)
|
||||
{
|
||||
@ -2093,6 +2114,7 @@ template < class T > static bool Register_GlobalFilter(HSQUIRRELVM vm, const SQC
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Register_GlobalEvent(HSQUIRRELVM vm)
|
||||
{
|
||||
// Register dependencies
|
||||
|
@ -1005,6 +1005,11 @@ public:
|
||||
*/
|
||||
void SphereExited(SQInt32 player, SQInt32 sphere) noexcept;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
void VMClose() noexcept;
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
|
@ -48,6 +48,8 @@ LocalEvent::LocalEvent(SQInt32 type, bool suspended) noexcept
|
||||
, m_Textdraws(this)
|
||||
, m_Vehicles(this)
|
||||
{
|
||||
// Receive notification when the VM is about to be closed to release object references
|
||||
_Core->VMClose.Connect< LocalEvent, &LocalEvent::VMClose >(this);
|
||||
/* Entity filters are empty so there's nothing to hook right now! */
|
||||
}
|
||||
|
||||
@ -56,6 +58,8 @@ LocalEvent::~LocalEvent()
|
||||
{
|
||||
// Detach from all attached signals
|
||||
Detach();
|
||||
// Stop receiving notification when the VM is about to be closed
|
||||
_Core->VMClose.Disconnect< LocalEvent, &LocalEvent::VMClose >(this);
|
||||
/* The entity filters should to unhook themselves from the destroy signal! */
|
||||
}
|
||||
|
||||
@ -254,7 +258,7 @@ void LocalEvent::SetInversed(bool toggle) noexcept
|
||||
// Toggle the inversed option
|
||||
m_Inversed = toggle;
|
||||
// Attach back to the new event type
|
||||
Attach();
|
||||
Attach();
|
||||
}
|
||||
// Just set the option to what was requested
|
||||
else
|
||||
@ -2202,6 +2206,23 @@ void LocalEvent::Adaptable(SQInt32 type, bool inversed) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LocalEvent::VMClose() noexcept
|
||||
{
|
||||
LogInf("[LocalEvent::VMClose() %d %d",
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetEnv()),
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetFunc())
|
||||
);
|
||||
|
||||
// Release the reference to the specified callback
|
||||
m_OnTrigger.Release();
|
||||
|
||||
LogInf("]LocalEvent::VMClose() %d %d",
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetEnv()),
|
||||
sq_getrefcount(m_OnTrigger.GetVM(), &m_OnTrigger.GetFunc())
|
||||
);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
template < class T > static bool Register_LocalFilter(HSQUIRRELVM vm, const SQChar * cname)
|
||||
{
|
||||
@ -2236,6 +2257,7 @@ template < class T > static bool Register_LocalFilter(HSQUIRRELVM vm, const SQCh
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Register_LocalEvent(HSQUIRRELVM vm)
|
||||
{
|
||||
// Register dependencies
|
||||
|
@ -1005,6 +1005,11 @@ public:
|
||||
*/
|
||||
void SphereExited(SQInt32 player, SQInt32 sphere) noexcept;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
void VMClose() noexcept;
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
|
@ -386,6 +386,7 @@ enum EventType
|
||||
EVT_WORLDTOGGLE,
|
||||
EVT_SCRIPTRELOAD,
|
||||
EVT_LOGMESSAGE,
|
||||
EVT_VMCLOSE,
|
||||
EVT_COUNT
|
||||
};
|
||||
|
||||
@ -557,6 +558,9 @@ using EScriptReload = Signal< void (SQInt32 /* header */, Object & /*
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
using ELogMessage = Signal< void (SQInt32 /* type */, const SQChar * /* message */), EVT_LOGMESSAGE >;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
using EVMClose = Signal< void (void), EVT_VMCLOSE >;
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SIGNALS_HPP_
|
||||
|
Loading…
Reference in New Issue
Block a user