mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-28 07:45:29 +03:00
Merge pull request #6 from ReDucTor/wip/vscript_support
Various vscript improvements
This commit is contained in:
commit
1f8e32ef66
@ -504,6 +504,19 @@ namespace SQVector
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQInteger ToKVString(HSQUIRRELVM vm)
|
||||||
|
{
|
||||||
|
Vector* v1 = nullptr;
|
||||||
|
|
||||||
|
if (sq_gettop(vm) != 1 ||
|
||||||
|
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Expected (Vector)");
|
||||||
|
}
|
||||||
|
|
||||||
|
sqstd_pushstringf(vm, "%f %f %f", v1->x, v1->y, v1->z);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
SQInteger Cross(HSQUIRRELVM vm)
|
SQInteger Cross(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
@ -527,6 +540,70 @@ namespace SQVector
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQInteger ToString(HSQUIRRELVM vm)
|
||||||
|
{
|
||||||
|
Vector* v1 = nullptr;
|
||||||
|
|
||||||
|
if (sq_gettop(vm) != 1 ||
|
||||||
|
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Expected (Vector)");
|
||||||
|
}
|
||||||
|
|
||||||
|
sqstd_pushstringf(vm, "(vector: (%f, %f, %f))", v1->x, v1->y, v1->z);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQInteger TypeOf(HSQUIRRELVM vm)
|
||||||
|
{
|
||||||
|
sq_pushstring(vm, "Vector", -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQInteger Nexti(HSQUIRRELVM vm)
|
||||||
|
{
|
||||||
|
Vector* v1 = nullptr;
|
||||||
|
|
||||||
|
if (sq_gettop(vm) != 2 ||
|
||||||
|
SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&v1, TYPETAG_VECTOR)))
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Expected (Vector)");
|
||||||
|
}
|
||||||
|
|
||||||
|
HSQOBJECT obj;
|
||||||
|
sq_resetobject(&obj);
|
||||||
|
sq_getstackobj(vm, 2, &obj);
|
||||||
|
|
||||||
|
const char* curkey = nullptr;
|
||||||
|
|
||||||
|
if (sq_isnull(obj))
|
||||||
|
{
|
||||||
|
curkey = "w";
|
||||||
|
}
|
||||||
|
else if (sq_isstring(obj))
|
||||||
|
{
|
||||||
|
curkey = sq_objtostring(&obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, "Invalid iteartor");
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(curkey && curkey[0] >= 'w' && curkey[0] <= 'z');
|
||||||
|
|
||||||
|
if (curkey[0] == 'z')
|
||||||
|
{
|
||||||
|
// Reached the end
|
||||||
|
sq_pushnull(vm);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char newkey = curkey[0] + 1;
|
||||||
|
sq_pushstring(vm, &newkey, 1);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static const SQRegFunction funcs[] = {
|
static const SQRegFunction funcs[] = {
|
||||||
{_SC("constructor"), Construct,0,nullptr},
|
{_SC("constructor"), Construct,0,nullptr},
|
||||||
{_SC("_get"), Get, 2, _SC(".s")},
|
{_SC("_get"), Get, 2, _SC(".s")},
|
||||||
@ -540,9 +617,14 @@ namespace SQVector
|
|||||||
{_SC("Length2D"), Length2D, 1, _SC(".")},
|
{_SC("Length2D"), Length2D, 1, _SC(".")},
|
||||||
{_SC("Length2DSqr"), Length2DSqr, 1, _SC(".")},
|
{_SC("Length2DSqr"), Length2DSqr, 1, _SC(".")},
|
||||||
{_SC("Normalized"), Normalized, 1, _SC(".")},
|
{_SC("Normalized"), Normalized, 1, _SC(".")},
|
||||||
|
{_SC("Norm"), Normalized, 1, _SC(".")},
|
||||||
{_SC("_div"), Divide, 2, _SC("..")},
|
{_SC("_div"), Divide, 2, _SC("..")},
|
||||||
{_SC("Dot"), Dot, 2, _SC("..")},
|
{_SC("Dot"), Dot, 2, _SC("..")},
|
||||||
{_SC("Cross"), Cross, 2, _SC("..")},
|
{_SC("Cross"), Cross, 2, _SC("..")},
|
||||||
|
{_SC("ToKVString"), ToKVString, 1, _SC(".")},
|
||||||
|
{_SC("_tostring"), ToString, 1, _SC(".")},
|
||||||
|
{_SC("_typeof"), TypeOf, 1, _SC(".")},
|
||||||
|
{_SC("_nexti"), Nexti, 2, _SC("..")},
|
||||||
|
|
||||||
{nullptr,(SQFUNCTION)0,0,nullptr}
|
{nullptr,(SQFUNCTION)0,0,nullptr}
|
||||||
};
|
};
|
||||||
@ -735,7 +817,6 @@ bool getVariant(HSQUIRRELVM vm, SQInteger idx, ScriptVariant_t& variant)
|
|||||||
tag == TYPETAG_VECTOR &&
|
tag == TYPETAG_VECTOR &&
|
||||||
SQ_SUCCEEDED(sq_getinstanceup(vm, idx, (SQUserPointer*)&v, TYPETAG_VECTOR)))
|
SQ_SUCCEEDED(sq_getinstanceup(vm, idx, (SQUserPointer*)&v, TYPETAG_VECTOR)))
|
||||||
{
|
{
|
||||||
// TODO: This actually ends up pointing to the same data it seems error prone
|
|
||||||
variant = new Vector(*v);
|
variant = new Vector(*v);
|
||||||
variant.m_flags |= SV_FREE;
|
variant.m_flags |= SV_FREE;
|
||||||
return true;
|
return true;
|
||||||
@ -945,6 +1026,36 @@ SQInteger constructor_stub(HSQUIRRELVM vm)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQInteger tostring_stub(HSQUIRRELVM vm)
|
||||||
|
{
|
||||||
|
ClassInstanceData* classInstanceData = nullptr;
|
||||||
|
sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0);
|
||||||
|
|
||||||
|
char buffer[128] = "";
|
||||||
|
|
||||||
|
if (classInstanceData &&
|
||||||
|
classInstanceData->instance &&
|
||||||
|
classInstanceData->desc->pHelper &&
|
||||||
|
classInstanceData->desc->pHelper->ToString(classInstanceData->instance, buffer, sizeof(buffer)))
|
||||||
|
{
|
||||||
|
sq_pushstring(vm, buffer, -1);
|
||||||
|
}
|
||||||
|
else if (classInstanceData)
|
||||||
|
{
|
||||||
|
sqstd_pushstringf(vm, "(%s : 0x%p)", classInstanceData->desc->m_pszScriptName, classInstanceData->instance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HSQOBJECT obj;
|
||||||
|
sq_resetobject(&obj);
|
||||||
|
sq_getstackobj(vm, 1, &obj);
|
||||||
|
// Semi-based on SQVM::ToString default case
|
||||||
|
sqstd_pushstringf(vm, "(%s: 0x%p)", IdType2Name(obj._type), (void*)_rawval(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct SquirrelSafeCheck
|
struct SquirrelSafeCheck
|
||||||
{
|
{
|
||||||
SquirrelSafeCheck(HSQUIRRELVM vm, int outputCount = 0) :
|
SquirrelSafeCheck(HSQUIRRELVM vm, int outputCount = 0) :
|
||||||
@ -976,17 +1087,18 @@ void printfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* format, ...)
|
|||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
vsprintf(buffer, format, args);
|
vsprintf(buffer, format, args);
|
||||||
Msg("vscript: %s\n", buffer);
|
Msg("%s", buffer);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void errorfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* format, ...)
|
void errorfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* format, ...)
|
||||||
{
|
{
|
||||||
|
// NOTE: This is only separate from printfunc to make it easier to add breakpoints
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
vsprintf(buffer, format, args);
|
vsprintf(buffer, format, args);
|
||||||
Msg("vscript: (ERRORR) %s\n", buffer);
|
Msg("%s", buffer);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1031,40 +1143,48 @@ bool SquirrelVM::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Run(
|
if (Run(
|
||||||
"class CSimpleCallChainer\n"
|
R"script(
|
||||||
"{\n"
|
function printl( text )
|
||||||
" function constructor(prefixString, scopeForThis, exactMatch)\n"
|
{
|
||||||
" {\n"
|
return print(text + "\n");
|
||||||
" prefix = prefixString;\n"
|
}
|
||||||
" scope = scopeForThis;\n"
|
|
||||||
" chain = [];\n"
|
class CSimpleCallChainer
|
||||||
" scope[\"Dispatch\" + prefixString] <- Call.bindenv(this);\n"
|
{
|
||||||
" }\n"
|
function constructor(prefixString, scopeForThis, exactMatch)
|
||||||
"\n"
|
{
|
||||||
" function PostScriptExecute()\n"
|
prefix = prefixString;
|
||||||
" {\n"
|
scope = scopeForThis;
|
||||||
" local func = null;\n"
|
chain = [];
|
||||||
" try {\n"
|
scope["Dispatch" + prefixString] <- Call.bindenv(this);
|
||||||
" func = scope[prefix];\n"
|
}
|
||||||
" } catch(e) {\n"
|
|
||||||
" return;\n"
|
function PostScriptExecute()
|
||||||
" }\n"
|
{
|
||||||
" if (typeof(func) != \"function\")\n"
|
local func = null;
|
||||||
" return;\n"
|
try {
|
||||||
" chain.push(func);\n"
|
func = scope[prefix];
|
||||||
" }\n"
|
} catch(e) {
|
||||||
"\n"
|
return;
|
||||||
" function Call()\n"
|
}
|
||||||
" {\n"
|
if (typeof(func) != "function")
|
||||||
" foreach (func in chain)\n"
|
return;
|
||||||
" {\n"
|
chain.push(func);
|
||||||
" func.pcall(scope);\n"
|
}
|
||||||
" }\n"
|
|
||||||
" }\n"
|
function Call()
|
||||||
" prefix = null;\n"
|
{
|
||||||
" scope= null;\n"
|
foreach (func in chain)
|
||||||
" chain = [];\n"
|
{
|
||||||
"}") != SCRIPT_DONE)
|
func.pcall(scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prefix = null;
|
||||||
|
scope= null;
|
||||||
|
chain = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
)script") != SCRIPT_DONE)
|
||||||
{
|
{
|
||||||
this->Shutdown();
|
this->Shutdown();
|
||||||
return false;
|
return false;
|
||||||
@ -1085,11 +1205,13 @@ void SquirrelVM::Shutdown()
|
|||||||
|
|
||||||
bool SquirrelVM::ConnectDebugger()
|
bool SquirrelVM::ConnectDebugger()
|
||||||
{
|
{
|
||||||
|
// TODO: Debugger support
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SquirrelVM::DisconnectDebugger()
|
void SquirrelVM::DisconnectDebugger()
|
||||||
{
|
{
|
||||||
|
// TODO: Debugger support
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptLanguage_t SquirrelVM::GetLanguage()
|
ScriptLanguage_t SquirrelVM::GetLanguage()
|
||||||
@ -1104,10 +1226,12 @@ const char* SquirrelVM::GetLanguageName()
|
|||||||
|
|
||||||
void SquirrelVM::AddSearchPath(const char* pszSearchPath)
|
void SquirrelVM::AddSearchPath(const char* pszSearchPath)
|
||||||
{
|
{
|
||||||
|
// TODO: Search path support
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SquirrelVM::Frame(float simTime)
|
bool SquirrelVM::Frame(float simTime)
|
||||||
{
|
{
|
||||||
|
// TODO: Frame support
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1133,7 +1257,7 @@ ScriptStatus_t SquirrelVM::Run(const char* pszScript, bool bWait)
|
|||||||
HSCRIPT SquirrelVM::CompileScript(const char* pszScript, const char* pszId)
|
HSCRIPT SquirrelVM::CompileScript(const char* pszScript, const char* pszId)
|
||||||
{
|
{
|
||||||
SquirrelSafeCheck safeCheck(vm_);
|
SquirrelSafeCheck safeCheck(vm_);
|
||||||
// TODO: sq_setcompilererrorhandler
|
|
||||||
Assert(vm_);
|
Assert(vm_);
|
||||||
if (pszId == nullptr) pszId = "<unnamed>";
|
if (pszId == nullptr) pszId = "<unnamed>";
|
||||||
if (SQ_FAILED(sq_compilebuffer(vm_, pszScript, strlen(pszScript), pszId, SQTrue)))
|
if (SQ_FAILED(sq_compilebuffer(vm_, pszScript, strlen(pszScript), pszId, SQTrue)))
|
||||||
@ -1179,7 +1303,6 @@ ScriptStatus_t SquirrelVM::Run(HSCRIPT hScript, HSCRIPT hScope, bool bWait)
|
|||||||
sq_pop(vm_, 1);
|
sq_pop(vm_, 1);
|
||||||
if (SQ_FAILED(result))
|
if (SQ_FAILED(result))
|
||||||
{
|
{
|
||||||
// TODO: sq_getlasterror
|
|
||||||
return SCRIPT_ERROR;
|
return SCRIPT_ERROR;
|
||||||
}
|
}
|
||||||
return SCRIPT_DONE;
|
return SCRIPT_DONE;
|
||||||
@ -1195,7 +1318,6 @@ ScriptStatus_t SquirrelVM::Run(HSCRIPT hScript, bool bWait)
|
|||||||
sq_pop(vm_, 1);
|
sq_pop(vm_, 1);
|
||||||
if (SQ_FAILED(result))
|
if (SQ_FAILED(result))
|
||||||
{
|
{
|
||||||
// TODO: sq_getlasterror
|
|
||||||
return SCRIPT_ERROR;
|
return SCRIPT_ERROR;
|
||||||
}
|
}
|
||||||
return SCRIPT_DONE;
|
return SCRIPT_DONE;
|
||||||
@ -1428,6 +1550,11 @@ bool SquirrelVM::RegisterClass(ScriptClassDesc_t* pClassDesc)
|
|||||||
sq_newclosure(vm_, constructor_stub, 0);
|
sq_newclosure(vm_, constructor_stub, 0);
|
||||||
sq_newslot(vm_, -3, SQFalse);
|
sq_newslot(vm_, -3, SQFalse);
|
||||||
|
|
||||||
|
sq_pushstring(vm_, "_tostring", -1);
|
||||||
|
sq_newclosure(vm_, tostring_stub, 0);
|
||||||
|
sq_newslot(vm_, -3, SQFalse);
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < pClassDesc->m_FunctionBindings.Count(); ++i)
|
for (int i = 0; i < pClassDesc->m_FunctionBindings.Count(); ++i)
|
||||||
{
|
{
|
||||||
auto& scriptFunction = pClassDesc->m_FunctionBindings[i];
|
auto& scriptFunction = pClassDesc->m_FunctionBindings[i];
|
||||||
@ -1710,13 +1837,40 @@ int SquirrelVM::GetNumTableEntries(HSCRIPT hScope)
|
|||||||
int SquirrelVM::GetKeyValue(HSCRIPT hScope, int nIterator, ScriptVariant_t* pKey, ScriptVariant_t* pValue)
|
int SquirrelVM::GetKeyValue(HSCRIPT hScope, int nIterator, ScriptVariant_t* pKey, ScriptVariant_t* pValue)
|
||||||
{
|
{
|
||||||
SquirrelSafeCheck safeCheck(vm_);
|
SquirrelSafeCheck safeCheck(vm_);
|
||||||
// TODO: How does this work does it expect to output to pKey and pValue as an array from nIterator
|
|
||||||
// elements or does it expect nIterator to be an index in hScrope, if so how does that work without
|
if (hScope)
|
||||||
// without depending on squirrel internals not public API for getting the iterator (which is opaque)
|
{
|
||||||
// or do you iterate until that point and output the value? If it should be iterator then this should
|
Assert(hScope != INVALID_HSCRIPT);
|
||||||
// be a HSCRIPT for ease of use.
|
HSQOBJECT* scope = (HSQOBJECT*)hScope;
|
||||||
Assert(!"GetKeyValue is not implemented");
|
sq_pushobject(vm_, *scope);
|
||||||
return 0;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sq_pushroottable(vm_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nIterator == -1)
|
||||||
|
{
|
||||||
|
sq_pushnull(vm_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sq_pushinteger(vm_, nIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
SQInteger nextiter = -1;
|
||||||
|
|
||||||
|
if (SQ_SUCCEEDED(sq_next(vm_, -2)))
|
||||||
|
{
|
||||||
|
if (pKey) getVariant(vm_, -2, *pKey);
|
||||||
|
if (pValue) getVariant(vm_, -1, *pValue);
|
||||||
|
|
||||||
|
sq_getinteger(vm_, -3, &nextiter);
|
||||||
|
sq_pop(vm_, 2);
|
||||||
|
}
|
||||||
|
sq_pop(vm_, 2);
|
||||||
|
|
||||||
|
return nextiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SquirrelVM::GetValue(HSCRIPT hScope, const char* pszKey, ScriptVariant_t* pValue)
|
bool SquirrelVM::GetValue(HSCRIPT hScope, const char* pszKey, ScriptVariant_t* pValue)
|
||||||
@ -2504,8 +2658,6 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (typetag == TYPETAG_VECTOR)
|
if (typetag == TYPETAG_VECTOR)
|
||||||
{
|
{
|
||||||
float x = pBuffer->GetFloat();
|
float x = pBuffer->GetFloat();
|
||||||
@ -2647,16 +2799,19 @@ void SquirrelVM::RemoveOrphanInstances()
|
|||||||
void SquirrelVM::DumpState()
|
void SquirrelVM::DumpState()
|
||||||
{
|
{
|
||||||
SquirrelSafeCheck safeCheck(vm_);
|
SquirrelSafeCheck safeCheck(vm_);
|
||||||
|
// TODO: Dump state
|
||||||
}
|
}
|
||||||
|
|
||||||
void SquirrelVM::SetOutputCallback(ScriptOutputFunc_t pFunc)
|
void SquirrelVM::SetOutputCallback(ScriptOutputFunc_t pFunc)
|
||||||
{
|
{
|
||||||
SquirrelSafeCheck safeCheck(vm_);
|
SquirrelSafeCheck safeCheck(vm_);
|
||||||
|
// TODO: Support output callbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
void SquirrelVM::SetErrorCallback(ScriptErrorFunc_t pFunc)
|
void SquirrelVM::SetErrorCallback(ScriptErrorFunc_t pFunc)
|
||||||
{
|
{
|
||||||
SquirrelSafeCheck safeCheck(vm_);
|
SquirrelSafeCheck safeCheck(vm_);
|
||||||
|
// TODO: Support error callbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SquirrelVM::RaiseException(const char* pszExceptionText)
|
bool SquirrelVM::RaiseException(const char* pszExceptionText)
|
||||||
|
Loading…
Reference in New Issue
Block a user