1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-09-15 16:57:19 +02:00

17 Commits

Author SHA1 Message Date
Sandu Liviu Catalin
483ac37bdb Update CMakeLists.txt
Some checks reported errors
continuous-integration/drone/push Build was killed
2022-10-04 02:29:05 +03:00
Sandu Liviu Catalin
78dc76e6b4 Object to typename helper. 2022-10-03 18:32:06 +03:00
Sandu Liviu Catalin
e29070af49 Update Official.cpp 2022-10-03 18:31:48 +03:00
Sandu Liviu Catalin
1f25b3ea60 Update sqratUtil.h 2022-10-03 18:31:36 +03:00
Sandu Liviu Catalin
52cfa235be Update JSON.hpp
Some checks reported errors
continuous-integration/drone/push Build was killed
2022-10-02 21:47:20 +03:00
Sandu Liviu Catalin
ec7f1183d8 Basic hooking into json parsing.
Also allow customization of the fallback meta-method.
2022-10-02 21:24:12 +03:00
Sandu Liviu Catalin
a788e059a5 Implement _tojson meta-method for base types. 2022-09-18 15:02:39 +03:00
Sandu Liviu Catalin
5f20ffc4de Remove the manual comma. 2022-09-17 23:49:37 +03:00
Sandu Liviu Catalin
08106156c4 Don't add comma for the root container. 2022-09-17 23:42:48 +03:00
Sandu Liviu Catalin
60119ff8fa Include comma after separator braces. 2022-09-17 23:41:43 +03:00
Sandu Liviu Catalin
f4720ae77a Implement custom types in JSON. 2022-09-17 23:25:16 +03:00
Sandu Liviu Catalin
c9fb257f48 Update ThreadPool.hpp 2022-09-15 23:03:50 +03:00
Sandu Liviu Catalin
475a428366 Update Data.hpp 2022-09-15 23:03:44 +03:00
Sandu Liviu Catalin
42ac0e32b7 Implement JSON serialization.
Just the basics.
2022-09-15 23:03:38 +03:00
Sandu Liviu Catalin
3e75e36cdf Add auto-close option for web-socket client.
Some checks reported errors
continuous-integration/drone/push Build was killed
2022-08-14 21:00:57 +03:00
Sandu Liviu Catalin
ac7d18f297 Allow chaining in traversal methods for buffer type. 2022-08-14 21:00:30 +03:00
Sandu Liviu Catalin
39473a68f4 Fix formatting in buffer type. 2022-08-14 21:00:10 +03:00
35 changed files with 1439 additions and 169 deletions

View File

@@ -4,6 +4,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
@@ -300,6 +301,21 @@ String AABB::ToString() const
return fmt::format("{},{},{},{},{},{}", min.x, min.y, min.z, max.x, max.y, max.z); return fmt::format("{},{},{},{},{},{}", min.x, min.y, min.z, max.x, max.y, max.z);
} }
// ------------------------------------------------------------------------------------------------
void AABB::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{min:{{x:{},y:{},z:{}}},max:{{x:{},y:{},z:{}}},",
min.x, min.y, min.z, max.x, max.y, max.z);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{min:[{},{},{}],max:[{},{},{}]}},",
min.x, min.y, min.z, max.x, max.y, max.z);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void AABB::SetStr(SQChar delim, StackStrF & values) void AABB::SetStr(SQChar delim, StackStrF & values)
{ {
@@ -793,6 +809,7 @@ void Register_AABB(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &AABB::ToString) .Func(_SC("_tostring"), &AABB::ToString)
.Func(_SC("_tojson"), &AABB::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >)

View File

@@ -304,6 +304,11 @@ struct AABB
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter. * Set the values extracted from the specified string using the specified delimiter.
*/ */

View File

@@ -3,6 +3,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -360,6 +361,19 @@ String Circle::ToString() const
return fmt::format("{},{},{}", pos.x, pos.y, rad); return fmt::format("{},{},{}", pos.x, pos.y, rad);
} }
// ------------------------------------------------------------------------------------------------
void Circle::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{x:{},y:{},r:{}}},", pos.x, pos.y, rad);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{},{}],", pos.x, pos.y, rad);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Circle::SetRadius(Value nr) void Circle::SetRadius(Value nr)
{ {
@@ -552,6 +566,7 @@ void Register_Circle(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Circle::ToString) .Func(_SC("_tostring"), &Circle::ToString)
.Func(_SC("_toJSON"), &Circle::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >)

View File

@@ -341,6 +341,11 @@ struct Circle
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set the specified radius. * Set the specified radius.
*/ */

View File

@@ -4,6 +4,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -481,6 +482,19 @@ String Color3::ToString() const
return fmt::format("{},{},{}", r, g, b); return fmt::format("{},{},{}", r, g, b);
} }
// ------------------------------------------------------------------------------------------------
void Color3::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{r:{},g:{},b:{}}},", r, g, b);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{},{}],", r, g, b);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Color3::SetScalar(Value ns) void Color3::SetScalar(Value ns)
{ {
@@ -741,6 +755,7 @@ void Register_Color3(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Color3::ToString) .Func(_SC("_tostring"), &Color3::ToString)
.Func(_SC("_tojson"), &Color3::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >)

View File

@@ -405,6 +405,11 @@ struct Color3
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value. * Set all components to the specified scalar value.
*/ */

View File

@@ -4,6 +4,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -506,6 +507,19 @@ String Color4::ToString() const
return fmt::format("{},{},{},{}", r, g, b, a); return fmt::format("{},{},{},{}", r, g, b, a);
} }
// ------------------------------------------------------------------------------------------------
void Color4::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{r:{},g:{},b:{},a:{}}},", r, g, b, a);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{},{},{}],", r, g, b, a);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Color4::SetScalar(Value ns) void Color4::SetScalar(Value ns)
{ {
@@ -781,6 +795,7 @@ void Register_Color4(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Color4::ToString) .Func(_SC("_tostring"), &Color4::ToString)
.Func(_SC("_tojson"), &Color4::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >)

View File

@@ -405,6 +405,11 @@ struct Color4
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value. * Set all components to the specified scalar value.
*/ */

View File

@@ -5,6 +5,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -349,6 +350,19 @@ String Quaternion::ToString() const
return fmt::format("{},{},{},{}", x, y, z, w); return fmt::format("{},{},{},{}", x, y, z, w);
} }
// ------------------------------------------------------------------------------------------------
void Quaternion::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{x:{},y:{},z:{},w:{}}},", x, y, z, w);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{},{},{}],", x, y, z, w);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Quaternion::SetScalar(Value ns) void Quaternion::SetScalar(Value ns)
{ {
@@ -775,6 +789,7 @@ void Register_Quaternion(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Quaternion::ToString) .Func(_SC("_tostring"), &Quaternion::ToString)
.Func(_SC("_tojson"), &Quaternion::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >)

View File

@@ -296,6 +296,11 @@ struct Quaternion
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value. * Set all components to the specified scalar value.
*/ */

View File

@@ -6,6 +6,9 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
// ------------------------------------------------------------------------------------------------
struct CtxJSON;
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Helper constants used by the bas types. * Helper constants used by the bas types.
*/ */

View File

@@ -3,6 +3,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -360,6 +361,19 @@ String Sphere::ToString() const
return fmt::format("{},{},{},{}", pos.x, pos.y, pos.z, rad); return fmt::format("{},{},{},{}", pos.x, pos.y, pos.z, rad);
} }
// ------------------------------------------------------------------------------------------------
void Sphere::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{x:{},y:{},z:{},r:{}}},", pos.x, pos.y, pos.z, rad);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{},{},{}],", pos.x, pos.y, pos.z, rad);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Sphere::SetRadius(Value nr) void Sphere::SetRadius(Value nr)
{ {
@@ -527,6 +541,7 @@ void Register_Sphere(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Sphere::ToString) .Func(_SC("_tostring"), &Sphere::ToString)
.Func(_SC("_tojson"), &Sphere::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >)

View File

@@ -341,6 +341,11 @@ struct Sphere
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set the specified radius. * Set the specified radius.
*/ */

View File

@@ -4,6 +4,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -295,6 +296,19 @@ String Vector2::ToString() const
return fmt::format("{},{}", x, y); return fmt::format("{},{}", x, y);
} }
// ------------------------------------------------------------------------------------------------
void Vector2::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{x:{},y:{}}},", x, y);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{}],", x, y);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Vector2::SetScalar(Value ns) void Vector2::SetScalar(Value ns)
{ {
@@ -428,6 +442,7 @@ void Register_Vector2(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Vector2::ToString) .Func(_SC("_tostring"), &Vector2::ToString)
.Func(_SC("_tojson"), &Vector2::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >)

View File

@@ -285,6 +285,11 @@ struct Vector2
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value. * Set all components to the specified scalar value.
*/ */

View File

@@ -4,6 +4,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -441,6 +442,19 @@ String Vector2i::ToString() const
return fmt::format("{},{}", x, y); return fmt::format("{},{}", x, y);
} }
// ------------------------------------------------------------------------------------------------
void Vector2i::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{x:{},y:{}}},", x, y);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{}],", x, y);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Vector2i::SetScalar(Value ns) void Vector2i::SetScalar(Value ns)
{ {
@@ -574,6 +588,7 @@ void Register_Vector2i(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Vector2i::ToString) .Func(_SC("_tostring"), &Vector2i::ToString)
.Func(_SC("_tojson"), &Vector2i::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >)

View File

@@ -390,6 +390,11 @@ struct Vector2i
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value. * Set all components to the specified scalar value.
*/ */

View File

@@ -5,6 +5,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -331,6 +332,19 @@ String Vector3::ToString() const
return fmt::format("{},{},{}", x, y, z); return fmt::format("{},{},{}", x, y, z);
} }
// ------------------------------------------------------------------------------------------------
void Vector3::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{x:{},y:{},z:{}}},", x, y, z);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{},{}],", x, y, z);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Vector3::SetScalar(Value ns) void Vector3::SetScalar(Value ns)
{ {
@@ -696,6 +710,7 @@ void Register_Vector3(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Vector3::ToString) .Func(_SC("_tostring"), &Vector3::ToString)
.Func(_SC("_tojson"), &Vector3::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >)

View File

@@ -297,6 +297,11 @@ struct Vector3
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value. * Set all components to the specified scalar value.
*/ */

View File

@@ -5,6 +5,7 @@
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Core/Buffer.hpp" #include "Core/Buffer.hpp"
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Library/JSON.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -344,6 +345,19 @@ String Vector4::ToString() const
return fmt::format("{},{},{},{}", x, y, z, w); return fmt::format("{},{},{},{}", x, y, z, w);
} }
// ------------------------------------------------------------------------------------------------
void Vector4::ToJSON(CtxJSON & ctx) const
{
if (ctx.mObjectOverArray)
{
fmt::format_to(std::back_inserter(ctx.mOutput), "{{x:{},y:{},z:{},w:{}}},", x, y, z, w);
}
else
{
fmt::format_to(std::back_inserter(ctx.mOutput), "[{},{},{},{}],", x, y, z, w);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Vector4::SetScalar(Value ns) void Vector4::SetScalar(Value ns)
{ {
@@ -526,6 +540,7 @@ void Register_Vector4(HSQUIRRELVM vm)
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >) .SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn) .SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Vector4::ToString) .Func(_SC("_tostring"), &Vector4::ToString)
.Func(_SC("_tojson"), &Vector4::ToJSON)
// Meta-methods // Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >) .SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >) .SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >)

View File

@@ -295,6 +295,11 @@ struct Vector4
*/ */
SQMOD_NODISCARD String ToString() const; SQMOD_NODISCARD String ToString() const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a JSON string.
*/
void ToJSON(CtxJSON & ctx) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value. * Set all components to the specified scalar value.
*/ */

View File

@@ -227,7 +227,7 @@ if(WIN32 AND MINGW AND COPY_DEPENDENCIES)
file(COPY "${MINGW_BIN_PATH}/libpq.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps") file(COPY "${MINGW_BIN_PATH}/libpq.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps")
file(COPY "${MINGW_BIN_PATH}/libzstd.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps") file(COPY "${MINGW_BIN_PATH}/libzstd.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps")
file(COPY "${MINGW_BIN_PATH}/libpsl-5.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps") file(COPY "${MINGW_BIN_PATH}/libpsl-5.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps")
file(COPY "${MINGW_BIN_PATH}/libffi-7.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps") file(COPY "${MINGW_BIN_PATH}/libffi-8.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps")
file(COPY "${MINGW_BIN_PATH}/libcurl-4.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps") file(COPY "${MINGW_BIN_PATH}/libcurl-4.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps")
file(COPY "${MINGW_BIN_PATH}/libssh2-1.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps") file(COPY "${MINGW_BIN_PATH}/libssh2-1.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps")
file(COPY "${MINGW_BIN_PATH}/libidn2-0.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps") file(COPY "${MINGW_BIN_PATH}/libidn2-0.dll" DESTINATION "${PROJECT_SOURCE_DIR}/bin/deps")

View File

@@ -285,13 +285,13 @@ public:
// Make sure that the buffer can host at least one element of this type // Make sure that the buffer can host at least one element of this type
if (m_Cap < sizeof(T)) if (m_Cap < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host an element of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host an element of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Make sure that the specified element is withing buffer range // Make sure that the specified element is withing buffer range
else if (n > (m_Cap - sizeof(T))) else if (n > (m_Cap - sizeof(T)))
{ {
ThrowMemExcept(fmt::runtime("Element of size (%d) at index (%u) is out of buffer capacity (%u)"), ThrowMemExcept(fmt::runtime("Element of size ({}) at index ({}) is out of buffer capacity ({})"),
sizeof(T), n, m_Cap); sizeof(T), n, m_Cap);
} }
// Return the requested element // Return the requested element
@@ -306,13 +306,13 @@ public:
// Make sure that the buffer can host at least one element of this type // Make sure that the buffer can host at least one element of this type
if (m_Cap < sizeof(T)) if (m_Cap < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host an element of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host an element of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Make sure that the specified element is withing buffer range // Make sure that the specified element is withing buffer range
else if (n > (m_Cap - sizeof(T))) else if (n > (m_Cap - sizeof(T)))
{ {
ThrowMemExcept(fmt::runtime("Element of size (%d) at index (%u) is out of buffer capacity (%u)"), ThrowMemExcept(fmt::runtime("Element of size ({}) at index ({}) is out of buffer capacity ({})"),
sizeof(T), n, m_Cap); sizeof(T), n, m_Cap);
} }
// Return the requested element // Return the requested element
@@ -359,7 +359,7 @@ public:
// Make sure that the buffer can host at least one element of this type // Make sure that the buffer can host at least one element of this type
if (m_Cap < sizeof(T)) if (m_Cap < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host an element of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host an element of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Return the requested element // Return the requested element
@@ -374,7 +374,7 @@ public:
// Make sure that the buffer can host at least one element of this type // Make sure that the buffer can host at least one element of this type
if (m_Cap < sizeof(T)) if (m_Cap < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host an element of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host an element of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Return the requested element // Return the requested element
@@ -389,7 +389,7 @@ public:
// Make sure that the buffer can host at least two elements of this type // Make sure that the buffer can host at least two elements of this type
if (m_Cap < (sizeof(T) * 2)) if (m_Cap < (sizeof(T) * 2))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host two elements of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host two elements of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Return the requested element // Return the requested element
@@ -404,7 +404,7 @@ public:
// Make sure that the buffer can host at least two elements of this type // Make sure that the buffer can host at least two elements of this type
if (m_Cap < (sizeof(T) * 2)) if (m_Cap < (sizeof(T) * 2))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host two elements of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host two elements of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Return the requested element // Return the requested element
@@ -419,7 +419,7 @@ public:
// Make sure that the buffer can host at least one element of this type // Make sure that the buffer can host at least one element of this type
if (m_Cap < sizeof(T)) if (m_Cap < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host an element of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host an element of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Return the requested element // Return the requested element
@@ -434,7 +434,7 @@ public:
// Make sure that the buffer can host at least one element of this type // Make sure that the buffer can host at least one element of this type
if (m_Cap < sizeof(T)) if (m_Cap < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host an element of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host an element of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Return the requested element // Return the requested element
@@ -449,7 +449,7 @@ public:
// Make sure that the buffer can host at least two elements of this type // Make sure that the buffer can host at least two elements of this type
if (m_Cap < (sizeof(T) * 2)) if (m_Cap < (sizeof(T) * 2))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host two elements of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host two elements of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Return the requested element // Return the requested element
@@ -464,7 +464,7 @@ public:
// Make sure that the buffer can host at least two elements of this type // Make sure that the buffer can host at least two elements of this type
if (m_Cap < (sizeof(T) * 2)) if (m_Cap < (sizeof(T) * 2))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host two elements of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host two elements of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// Return the requested element // Return the requested element
@@ -540,7 +540,7 @@ public:
// Make sure that at least one element of this type exists after the cursor // Make sure that at least one element of this type exists after the cursor
if ((m_Cur + sizeof(T)) > m_Cap) if ((m_Cur + sizeof(T)) > m_Cap)
{ {
ThrowMemExcept(fmt::runtime("Element of size (%u) starting at (%u) exceeds buffer capacity (%u)"), ThrowMemExcept(fmt::runtime("Element of size ({}) starting at ({}) exceeds buffer capacity ({})"),
sizeof(T), m_Cur, m_Cap); sizeof(T), m_Cur, m_Cap);
} }
// Return the requested element // Return the requested element
@@ -555,7 +555,7 @@ public:
// Make sure that at least one element of this type exists after the cursor // Make sure that at least one element of this type exists after the cursor
if ((m_Cur + sizeof(T)) > m_Cap) if ((m_Cur + sizeof(T)) > m_Cap)
{ {
ThrowMemExcept(fmt::runtime("Element of size (%u) starting at (%u) exceeds buffer capacity (%u)"), ThrowMemExcept(fmt::runtime("Element of size ({}) starting at ({}) exceeds buffer capacity ({})"),
sizeof(T), m_Cur, m_Cap); sizeof(T), m_Cur, m_Cap);
} }
// Return the requested element // Return the requested element
@@ -570,7 +570,7 @@ public:
// The cursor must have at least one element of this type behind // The cursor must have at least one element of this type behind
if (m_Cur < sizeof(T)) if (m_Cur < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Cannot read an element of size (%u) before the cursor at (%u)"), ThrowMemExcept(fmt::runtime("Cannot read an element of size ({}) before the cursor at ({})"),
sizeof(T), m_Cur); sizeof(T), m_Cur);
} }
// Return the requested element // Return the requested element
@@ -585,7 +585,7 @@ public:
// The cursor must have at least one element of this type behind // The cursor must have at least one element of this type behind
if (m_Cur < sizeof(T)) if (m_Cur < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Cannot read an element of size (%u) before the cursor at (%u)"), ThrowMemExcept(fmt::runtime("Cannot read an element of size ({}) before the cursor at ({})"),
sizeof(T), m_Cur); sizeof(T), m_Cur);
} }
// Return the requested element // Return the requested element
@@ -600,13 +600,13 @@ public:
// Make sure that the buffer can host at least one element of this type // Make sure that the buffer can host at least one element of this type
if (m_Cap < sizeof(T)) if (m_Cap < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host an element of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host an element of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// There must be buffer left for at least two elements of this type after the cursor // There must be buffer left for at least two elements of this type after the cursor
else if ((m_Cur + (sizeof(T) * 2)) > m_Cap) else if ((m_Cur + (sizeof(T) * 2)) > m_Cap)
{ {
ThrowMemExcept(fmt::runtime("Element of size (%u) starting at (%u) exceeds buffer capacity (%u)"), ThrowMemExcept(fmt::runtime("Element of size ({}) starting at ({}) exceeds buffer capacity ({})"),
sizeof(T), m_Cur + sizeof(T), m_Cap); sizeof(T), m_Cur + sizeof(T), m_Cap);
} }
// Return the requested element // Return the requested element
@@ -621,13 +621,13 @@ public:
// Make sure that the buffer can host at least one element of this type // Make sure that the buffer can host at least one element of this type
if (m_Cap < sizeof(T)) if (m_Cap < sizeof(T))
{ {
ThrowMemExcept(fmt::runtime("Buffer capacity of (%u) is unable to host an element of size (%u)"), ThrowMemExcept(fmt::runtime("Buffer capacity of ({}) is unable to host an element of size ({})"),
m_Cap, sizeof(T)); m_Cap, sizeof(T));
} }
// There must be buffer left for at least two elements of this type after the cursor // There must be buffer left for at least two elements of this type after the cursor
else if ((m_Cur + (sizeof(T) * 2)) > m_Cap) else if ((m_Cur + (sizeof(T) * 2)) > m_Cap)
{ {
ThrowMemExcept(fmt::runtime("Element of size (%u) starting at (%u) exceeds buffer capacity (%u)"), ThrowMemExcept(fmt::runtime("Element of size ({}) starting at ({}) exceeds buffer capacity ({})"),
sizeof(T), m_Cur + sizeof(T), m_Cap); sizeof(T), m_Cur + sizeof(T), m_Cap);
} }
// Return the requested element // Return the requested element
@@ -708,7 +708,7 @@ public:
// See if the requested capacity doesn't exceed the limit // See if the requested capacity doesn't exceed the limit
if (n > Max< T >()) if (n > Max< T >())
{ {
ThrowMemExcept(fmt::runtime("Requested buffer of (%u) elements exceeds the (%u) limit"), n, Max< T >()); ThrowMemExcept(fmt::runtime("Requested buffer of ({}) elements exceeds the ({}) limit"), n, Max< T >());
} }
// Is there an existing buffer? // Is there an existing buffer?
else if (n && !m_Cap) else if (n && !m_Cap)

View File

@@ -248,6 +248,14 @@ String SqTypeName(HSQUIRRELVM vm, SQInteger idx)
return String(val.mPtr, static_cast< size_t >(val.mLen)); return String(val.mPtr, static_cast< size_t >(val.mLen));
} }
// ------------------------------------------------------------------------------------------------
String SqTypeName(HSQUIRRELVM vm, LightObj & obj)
{
const StackGuard sg(vm);
sq_pushobject(vm, obj);
return SqTypeName(vm, -1);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
LightObj BufferToStrObj(const Buffer & b) LightObj BufferToStrObj(const Buffer & b)
{ {

View File

@@ -242,6 +242,11 @@ SQMOD_NODISCARD const SQChar * SqTypeName(SQObjectType type);
*/ */
SQMOD_NODISCARD String SqTypeName(HSQUIRRELVM vm, SQInteger idx); SQMOD_NODISCARD String SqTypeName(HSQUIRRELVM vm, SQInteger idx);
/* ------------------------------------------------------------------------------------------------
* Retrieve the string representation of a certain type from a script object.
*/
SQMOD_NODISCARD String SqTypeName(HSQUIRRELVM vm, LightObj & obj);
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Create a script string instance from a buffer. * Create a script string instance from a buffer.
*/ */

View File

@@ -80,7 +80,7 @@ struct ThreadPoolItem
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Invoked in main thread by the thread pool after the task was completed. * Invoked in main thread by the thread pool after the task was completed.
* If it returns true then it will be put back into the queue to be processed again. * If it returns true then it will be put back into the queue to be processed again.
* If the boolean parameter is trye then the thread-pool is in the process of shutting down. * If the boolean parameter is true then the thread-pool is in the process of shutting down.
*/ */
SQMOD_NODISCARD virtual bool OnCompleted(bool SQ_UNUSED_ARG(stop)) { return false; } SQMOD_NODISCARD virtual bool OnCompleted(bool SQ_UNUSED_ARG(stop)) { return false; }
@@ -110,13 +110,13 @@ private:
* Destructor. * Destructor.
*/ */
~ThreadPool(); ~ThreadPool();
public:
// --------------------------------------------------------------------------------------------
using Item = std::unique_ptr< ThreadPoolItem >; // Owning pointer of an item.
private: private:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
using Pool = std::vector< std::thread >; // Worker container. using Pool = std::vector< std::thread >; // Worker container.
using Item = std::unique_ptr< ThreadPoolItem >; // Owning pointer of an item.
// --------------------------------------------------------------------------------------------
using Finished = moodycamel::ConcurrentQueue< Item >; // Finished items. using Finished = moodycamel::ConcurrentQueue< Item >; // Finished items.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@@ -190,6 +190,14 @@ public:
Enqueue(Item{item}); Enqueue(Item{item});
} }
/* --------------------------------------------------------------------------------------------
* Queue an item to be processed. Will take ownership of the given pointer!
*/
template < class T > void CastEnqueue(std::unique_ptr< T > && item)
{
Enqueue(Item{std::forward< std::unique_ptr< T > >(item)});
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Queue an item to be processed. Will take ownership of the given pointer! * Queue an item to be processed. Will take ownership of the given pointer!
*/ */

View File

@@ -294,33 +294,41 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to the specified number of elements ahead. * Reposition the edit cursor to the specified number of elements ahead.
*/ */
void Advance(SQInteger n) const SqBuffer & Advance(SQInteger n)
{ {
Valid().Advance(ConvTo< SzType >::From(n)); Valid().Advance(ConvTo< SzType >::From(n));
// Allow chaining
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to the specified number of elements behind. * Reposition the edit cursor to the specified number of elements behind.
*/ */
void Retreat(SQInteger n) const SqBuffer & Retreat(SQInteger n)
{ {
Valid().Retreat(ConvTo< SzType >::From(n)); Valid().Retreat(ConvTo< SzType >::From(n));
// Allow chaining
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to a fixed position within the buffer. * Reposition the edit cursor to a fixed position within the buffer.
*/ */
void Move(SQInteger n) const SqBuffer & Move(SQInteger n)
{ {
Valid().Move(ConvTo< SzType >::From(n)); Valid().Move(ConvTo< SzType >::From(n));
// Allow chaining
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Append a value to the current cursor location and advance the cursor. * Append a value to the current cursor location and advance the cursor.
*/ */
void Push(SQInteger v) const SqBuffer & Push(SQInteger v)
{ {
Valid().Push(ConvTo< Value >::From(v)); Valid().Push(ConvTo< Value >::From(v));
// Allow chaining
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -414,15 +422,17 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Grow the size of the internal buffer by the specified amount of bytes. * Grow the size of the internal buffer by the specified amount of bytes.
*/ */
void Grow(SQInteger n) const SqBuffer & Grow(SQInteger n)
{ {
return Valid().Grow(ConvTo< SzType >::From(n) * sizeof(Value)); Valid().Grow(ConvTo< SzType >::From(n) * sizeof(Value));
// Allow chaining
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Makes sure there is enough capacity to hold the specified element count. * Makes sure there is enough capacity to hold the specified element count.
*/ */
void Adjust(SQInteger n) SqBuffer & Adjust(SQInteger n)
{ {
// Validate the managed buffer reference // Validate the managed buffer reference
Validate(); Validate();
@@ -438,6 +448,8 @@ public:
{ {
STHROWF("{}", e.what()); // Re-package STHROWF("{}", e.what()); // Re-package
} }
// Allow chaining
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------

View File

@@ -2,6 +2,7 @@
#include "Library/JSON.hpp" #include "Library/JSON.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include <sajson.h>
#include <sqratConst.h> #include <sqratConst.h>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -11,13 +12,10 @@
namespace SqMod { namespace SqMod {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static SQInteger SqToJSON(HSQUIRRELVM vm) noexcept SQMOD_DECL_TYPENAME(SqCtxJSON, _SC("SqCtxJSON"))
{
return sq_throwerror(vm, _SC("Not implemented yet!"));
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static SQInteger SqFromJson_Push(HSQUIRRELVM vm, const sajson::value & node) noexcept static SQInteger SqFromJson_Push(HSQUIRRELVM vm, const sajson::value & node) noexcept // NOLINT(misc-no-recursion)
{ {
// Operation result // Operation result
SQInteger r = SQ_OK; SQInteger r = SQ_OK;
@@ -151,11 +149,600 @@ static SQInteger SqFromJSON(HSQUIRRELVM vm) noexcept
return SQ_SUCCEEDED(r) ? 1 : r; return SQ_SUCCEEDED(r) ? 1 : r;
} }
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::OpenArray()
{
// Add the array-begin character
mOutput.push_back('[');
// Go forward one level
Advance();
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::CloseArray()
{
// If the last character is a comma then replace it
if (mOutput.back() == ',')
{
mOutput.back() = ']';
}
// Append the array-end character
else
{
mOutput.push_back(']');
}
// Move the comma after the closing character
mOutput.push_back(',');
// Go back one level
Retreat();
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::ReopenArray()
{
// If the last character is a comma then remove it
if (mOutput.back() == ',')
{
mOutput.pop_back();
}
// If the last character is the array-end character then replace it with a comma
if (mOutput.back() == ']')
{
mOutput.back() = ',';
}
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::OpenObject()
{
// Add the object-begin character
mOutput.push_back('{');
// Go forward one level
Advance();
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::CloseObject()
{
// If the last character is a comma then replace it
if (mOutput.back() == ',')
{
mOutput.back() = '}';
}
// Append the object-end character
else
{
mOutput.push_back('}');
}
// Move the comma after the closing character
mOutput.push_back(',');
// Go back one level
Retreat();
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::ReopenObject()
{
// If the last character is a comma then remove it
if (mOutput.back() == ',')
{
mOutput.pop_back();
}
// If the last character is the object-end character then replace it with a comma
if (mOutput.back() == '}')
{
mOutput.back() = ',';
}
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::MakeKey()
{
// If the last character is a comma then replace it
if (mOutput.back() == ',')
{
mOutput.back() = ':';
}
// Append the array-end character
else
{
mOutput.push_back(':');
}
// Allow the hook to react
if (mKeyHook)
{
mKeyHook(*this);
}
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
bool CtxJSON::CheckWeakRefWrap(HSQUIRRELVM vm, SQInteger idx) noexcept
{
SQRESULT r = sq_getweakrefval(vm, idx);
// Whether the type doesn't have to be wrapped
bool w = true;
// Attempt to grab the value pointed by the weak reference
if (SQ_SUCCEEDED(r))
{
// Attempt to serialize the actual value
w = sq_gettype(vm, -1) != OT_TABLE && sq_gettype(vm, -1) != OT_ARRAY && sq_gettype(vm, -1) == OT_INSTANCE;
// Pop the referenced value
sq_poptop(vm);
}
// Wrap the value by default
return w;
}
// ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::SerializeParams(HSQUIRRELVM vm)
{
bool wrap_everything_in_array = false;
// Clear the output buffer if necessary
mOutput.clear();
mDepth = 0;
// Fetch the number of objects on the stack
const auto top = sq_gettop(vm);
// If there's more than one argument then they all get wrapped inside an array
// If there is one argument and is not an array, table or instance then do the same
if (top > 2 || (sq_gettype(vm, 2) != OT_TABLE &&
sq_gettype(vm, 2) != OT_ARRAY &&
sq_gettype(vm, 2) != OT_INSTANCE &&
CheckWeakRefWrap(vm, 2)))
{
wrap_everything_in_array = true;
// Open an array
OpenArray();
}
// Serialize every specified argument
for (SQInteger i = 2; i <= top; ++i)
{
if (SQRESULT r = SerializeAt(vm, i); SQ_FAILED(r))
{
return r; // Propagate the error
}
}
// Was everything wrapped inside an array?
if (wrap_everything_in_array)
{
CloseArray();
}
// Remove trailing separator, if any
if (mOutput.back() == ',')
{
mOutput.pop_back();
}
// Push the output string on the stack
sq_pushstring(vm, mOutput.c_str(), static_cast< SQInteger >(mOutput.size()));
// Specify that we have a value on the stack
return 1;
}
// ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::SerializeAt(HSQUIRRELVM vm, SQInteger idx) // NOLINT(misc-no-recursion)
{
// Identify object type
switch (sq_gettype(vm, idx))
{
case OT_NULL: {
PushNull();
} break;
case OT_INTEGER: {
SQInteger v;
// Attempt to retrieve the value from the stack
if (SQRESULT r = sq_getinteger(vm, idx, &v); SQ_FAILED(r))
{
return r; // Propagate the error
}
// Write the value in the output
PushInteger(v);
} break;
case OT_FLOAT: {
SQFloat v;
// Attempt to retrieve the value from the stack
if (SQRESULT r = sq_getfloat(vm, idx, &v); SQ_FAILED(r))
{
return r; // Propagate the error
}
// Write the value in the output
#ifdef SQUSEDOUBLE
PushDouble(v);
#else
PushFloat(v);
#endif
} break;
case OT_BOOL: {
SQBool v;
// Attempt to retrieve the value from the stack
if (SQRESULT r = sq_getbool(vm, idx, &v); SQ_FAILED(r))
{
return r; // Propagate the error
}
// Write the value in the output
PushBool(v != SQFalse);
} break;
case OT_STRING: {
const SQChar * v = nullptr;
SQInteger n = 0;
// Attempt to retrieve and convert the string
if (SQRESULT r = sq_getstringandsize(vm, idx, &v, &n); SQ_FAILED(r))
{
return r; // Propagate the error
}
// Write the value in the output
PushString(v, static_cast< size_t >(n));
} break;
case OT_TABLE: {
if (SQRESULT r = SerializeTable(vm, idx); SQ_FAILED(r))
{
return r; // Propagate the error
}
} break;
case OT_ARRAY: {
if (SQRESULT r = SerializeArray(vm, idx); SQ_FAILED(r))
{
return r; // Propagate the error
}
} break;
case OT_INSTANCE: {
if (SQRESULT r = SerializeInstance(vm, idx); SQ_FAILED(r))
{
return r; // Propagate the error
}
} break;
case OT_WEAKREF: {
if (SQRESULT r = SerializeWeakRef(vm, idx); SQ_FAILED(r))
{
return r; // Propagate the error
}
} break;
case OT_USERDATA:
case OT_CLOSURE:
case OT_NATIVECLOSURE:
case OT_GENERATOR:
case OT_USERPOINTER:
case OT_THREAD:
case OT_FUNCPROTO:
case OT_CLASS:
case OT_OUTER:
return sq_throwerrorf(vm, _SC("Type (%s) is not serializable"), SqTypeName(sq_gettype(vm, 2)));
}
// Serialization was successful
return SQ_OK;
}
// ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::SerializeArray(HSQUIRRELVM vm, SQInteger idx) // NOLINT(misc-no-recursion)
{
// Begin array scope
OpenArray();
// Push null to initiate iteration
sq_pushnull(vm);
// So we can use absolute stack indexes to avoid errors
const auto top = sq_gettop(vm);
// Start iterating the array at the specified position in the stack
for(SQRESULT r = SQ_OK; SQ_SUCCEEDED(sq_next(vm, idx));)
{
// Attempt serialization of the currently iterated value
r = SerializeAt(vm, top + 2);
// Check for failures
if (SQ_FAILED(r))
{
// Pop the null iterator, key and value from the stack
sq_pop(vm, 3);
// Propagate the error
return r;
}
// Pop the key and value from the stack (i.e. cleanup after `sq_next`)
sq_pop(vm, 2);
}
// Pop the null iterator
sq_poptop(vm);
// Close array scope
CloseArray();
// Serialization was successful
return SQ_OK;
}
// ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::SerializeTable(HSQUIRRELVM vm, SQInteger idx) // NOLINT(misc-no-recursion)
{
// Begin object scope
OpenObject();
// Push null to initiate iteration
sq_pushnull(vm);
// So we can use absolute stack indexes to avoid errors
const auto top = sq_gettop(vm);
// Start iterating the object at the specified position in the stack
for(SQRESULT r = SQ_OK; SQ_SUCCEEDED(sq_next(vm, idx));)
{
if (sq_gettype(vm, -2) == OT_STRING)
{
// Attempt serialization of the currently iterated element key
r = SerializeAt(vm, top + 1);
// Can we proceed with the value?
if (SQ_SUCCEEDED(r))
{
// Mark the value above as the key of this element and
// attempt serialization of the currently iterated element value
r = MakeKey().SerializeAt(vm, top + 2);
}
}
else
{
r = sq_throwerror(vm, _SC("Only string values are accepted as object keys"));
}
// Check for failures
if (SQ_FAILED(r))
{
// Pop the null iterator, key and value from the stack
sq_pop(vm, 3);
// Propagate the error
return r;
}
// Pop the key and value from the stack (i.e. cleanup after `sq_next`)
sq_pop(vm, 2);
}
// Pop the null iterator
sq_poptop(vm);
// Close object scope
CloseObject();
// Serialization was successful
return SQ_OK;
}
// ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::SerializeInstance(HSQUIRRELVM vm, SQInteger idx)
{
sq_pushstring(vm, mMetaMethod.c_str(), static_cast< SQInteger >(mMetaMethod.size()));
// Attempt to retrieve the meta-method from the instance
if(SQRESULT r = sq_get(vm, idx); SQ_FAILED(r))
{
return r; // Propagate the error
}
// Make sure this is actually a closure/function that we can invoke
else if (const auto t = sq_gettype(vm, -1); t != OT_CLOSURE && t != OT_NATIVECLOSURE)
{
// Remove whatever is on the stack
sq_poptop(vm);
// Abort the operation as we can't do anything about it
return sq_throwerrorf(vm, _SC("`_tojson` meta-method is not a closure for type (%s)"), SqTypeName(vm, idx).c_str());
}
// Push the instance itself the stack (the environment)
sq_push(vm, idx);
// Push this instance on the stack (the json context)
ClassType< CtxJSON >::PushInstance(vm, this);
// Invoke the function to perform the conversion in this context
SQRESULT r = sq_call(vm, 2, SQFalse, SQFalse);
// Remove the closure from the stack
sq_poptop(vm);
// Propagate the result, whatever that is
return r;
}
// ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::SerializeWeakRef(HSQUIRRELVM vm, SQInteger idx) // NOLINT(misc-no-recursion)
{
SQRESULT r = sq_getweakrefval(vm, idx);
// Attempt to grab the value pointed by the weak reference
if (SQ_SUCCEEDED(r))
{
// Attempt to serialize the actual value
r = SerializeAt(vm, sq_gettop(vm));
// Pop the referenced value
sq_poptop(vm);
}
// Propagate the error, if any
return r;
}
// ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::PushValues(HSQUIRRELVM vm)
{
// Fetch the number of objects on the stack
const auto top = sq_gettop(vm);
// Do we have a value?
if (top < 2)
{
return sq_throwerror(vm, _SC("Must specify at least one value to be pushed"));
}
// Serialize every specified argument
for (SQInteger i = 2; i <= top; ++i)
{
if (SQRESULT r = SerializeAt(vm, i); SQ_FAILED(r))
{
return r; // Propagate the error
}
}
// Allow chaining
sq_push(vm, 1);
// Specify that a value was returned
return 1;
}
// ------------------------------------------------------------------------------------------------
SQRESULT CtxJSON::PushElement(HSQUIRRELVM vm)
{
// Fetch the number of objects on the stack
const auto top = sq_gettop(vm);
// Do we have a value?
if (top < 3)
{
return sq_throwerrorf(vm, _SC("Not enough parameters. Received %lld but %lld needed"), top-1, 2);
}
else if (sq_gettype(vm, 2) != OT_STRING)
{
return sq_throwerrorf(vm, _SC("Element key must be a string"));
}
// Attempt serialization of the currently iterated element key
if (SQRESULT r = SerializeAt(vm, 2); SQ_SUCCEEDED(r))
{
// Mark the value above as the key of this element and
// attempt serialization of the currently iterated element value
r = MakeKey().SerializeAt(vm, 3);
// Check for failures
if (SQ_FAILED(r))
{
return r; // Propagate the error
}
}
// Allow chaining
sq_push(vm, 1);
// Specify that a value was returned
return 1;
}
// ------------------------------------------------------------------------------------------------
CtxJSON & CtxJSON::PushKey(StackStrF & key)
{
// Validate the string value
if (key.mLen >= 0 && SQ_SUCCEEDED(key.mRes))
{
PushString(key.mPtr, static_cast< size_t >(key.mLen));
MakeKey();
}
else
{
STHROWF("Invalid object key");
}
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
void CtxJSON::PushNull()
{
mOutput.append("null,");
}
// ------------------------------------------------------------------------------------------------
void CtxJSON::PushInteger(SQInteger value)
{
fmt::format_int f(value);
// Append the formatted integer to the buffer
mOutput.append(f.data(), f.size());
mOutput.push_back(',');
}
// ------------------------------------------------------------------------------------------------
void CtxJSON::PushFloat(float value)
{
fmt::format_to(std::back_inserter(mOutput), "{},", value);
}
// ------------------------------------------------------------------------------------------------
void CtxJSON::PushDouble(double value)
{
fmt::format_to(std::back_inserter(mOutput), "{},", value);
}
// ------------------------------------------------------------------------------------------------
void CtxJSON::PushBool(bool value)
{
if (value)
{
mOutput.append("true,", 5);
}
else
{
mOutput.append("false,", 6);
}
}
// ------------------------------------------------------------------------------------------------
void CtxJSON::PushString(const SQChar * str)
{
mOutput.push_back('"');
mOutput.append(str);
mOutput.push_back('"');
mOutput.push_back(',');
// Allow the hook to know
mString.assign(str);
}
// ------------------------------------------------------------------------------------------------
void CtxJSON::PushString(const SQChar * str, size_t length)
{
mOutput.push_back('"');
mOutput.append(str, length);
mOutput.push_back('"');
mOutput.push_back(',');
// Allow the hook to know
mString.assign(str, length);
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqToJSON(HSQUIRRELVM vm) noexcept
{
// Make sure the instance is cleaned up even in the case of exceptions
DeleteGuard< CtxJSON > sq_dg(new CtxJSON());
// Remember the instance, so we don't have to cast the script object back
auto ctx = sq_dg.Get();
// Turn it into a script object because it may be passed as a parameter to `_tojson` meta-methods
LightObj obj(sq_dg, vm);
// Proceed with the serialization
return ctx->SerializeParams(vm);
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqToCompactJSON(HSQUIRRELVM vm) noexcept
{
// Make sure the instance is cleaned up even in the case of exceptions
DeleteGuard< CtxJSON > sq_dg(new CtxJSON(false));
// Remember the instance, so we don't have to cast the script object back
auto ctx = sq_dg.Get();
// Turn it into a script object because it may be passed as a parameter to `_tojson` meta-methods
LightObj obj(sq_dg, vm);
// Proceed with the serialization
return ctx->SerializeParams(vm);
}
// ================================================================================================ // ================================================================================================
void Register_JSON(HSQUIRRELVM vm) void Register_JSON(HSQUIRRELVM vm)
{ {
RootTable(vm).SquirrelFunc(_SC("SqToJSON"), SqToJSON); RootTable(vm).SquirrelFunc(_SC("SqToJSON"), SqToJSON);
RootTable(vm).SquirrelFunc(_SC("SqToCompactJSON"), SqToCompactJSON);
RootTable(vm).SquirrelFunc(_SC("SqFromJSON"), SqFromJSON); RootTable(vm).SquirrelFunc(_SC("SqFromJSON"), SqFromJSON);
// --------------------------------------------------------------------------------------------
RootTable(vm).Bind(_SC("SqCtxJSON"),
Class< CtxJSON, NoCopy< CtxJSON > >(vm, SqCtxJSON::Str)
// Constructors
.Ctor()
.Ctor< bool >()
.Ctor< bool, StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqCtxJSON::Fn)
// Properties
.Prop(_SC("Output"), &CtxJSON::GetOutput)
.Prop(_SC("Depth"), &CtxJSON::GetDepth)
.Prop(_SC("OOA"), &CtxJSON::GetObjectOverArray, &CtxJSON::SetObjectOverArray)
.Prop(_SC("ObjectOverArray"), &CtxJSON::GetObjectOverArray, &CtxJSON::SetObjectOverArray)
// Member Methods
.SquirrelMethod< CtxJSON, &CtxJSON::SerializeParams >(_SC("Serialize"))
.SquirrelMethod< CtxJSON, &CtxJSON::PushValues >(_SC("PushValues"))
.SquirrelMethod< CtxJSON, &CtxJSON::PushElement >(_SC("PushElement"))
.Func(_SC("OpenArray"), &CtxJSON::OpenArray)
.Func(_SC("CloseArray"), &CtxJSON::CloseArray)
.Func(_SC("OpenObject"), &CtxJSON::OpenObject)
.Func(_SC("CloseObject"), &CtxJSON::CloseObject)
.Func(_SC("MakeKey"), &CtxJSON::MakeKey)
.FmtFunc(_SC("PushKey"), &CtxJSON::PushKey)
.Func(_SC("SetOOA"), &CtxJSON::SetObjectOverArray)
.Func(_SC("SetObjectOverArray"), &CtxJSON::SetObjectOverArray)
);
} }
} // Namespace:: SqMod } // Namespace:: SqMod

View File

@@ -5,12 +5,281 @@
#include "Library/IO/Buffer.hpp" #include "Library/IO/Buffer.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include <sajson.h> #include <functional>
// ------------------------------------------------------------------------------------------------
#include <fmt/args.h>
#include <fmt/format.h>
#include <fmt/xchar.h>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
// ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* JSON serializer. The generated JSON output is always minified for efficiency reasons.
*/
struct CtxJSON
{
/* --------------------------------------------------------------------------------------------
* Output string.
*/
String mOutput{};
/* --------------------------------------------------------------------------------------------
* Prefer a table with named members even when a simple array would do the job.
* Take a Vector3 for example. Compact array [x, y, z] or named object {x: #.#, y: #.#, z: #.#}
*/
bool mObjectOverArray{true};
/* --------------------------------------------------------------------------------------------
* How nested are we currently.
*/
uint32_t mDepth{0};
/* --------------------------------------------------------------------------------------------
* The meta-method name to use on objects.
*/
String mMetaMethod{"_tojson"};
/* --------------------------------------------------------------------------------------------
* Last pushed string value. Can be used to heck for key name in the hook.
*/
String mString{};
/* --------------------------------------------------------------------------------------------
* Internal utility used to monitor the existence of certain keys to allow overloading.
*/
std::function< void(CtxJSON&) > mKeyHook{};
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
CtxJSON() = default;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit CtxJSON(bool ooa)
: CtxJSON()
{
mObjectOverArray = ooa;
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
CtxJSON(bool ooa, StackStrF & mmname)
: CtxJSON()
{
mObjectOverArray = ooa;
// Allow custom metamethod names
mMetaMethod.assign(mmname.mPtr, static_cast< size_t >(mmname.mLen));
}
/* --------------------------------------------------------------------------------------------
* Internal constructor.
*/
explicit CtxJSON(std::function< void(CtxJSON&) > && kh)
: CtxJSON()
{
mKeyHook = std::move(kh);
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
CtxJSON(const CtxJSON &) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
CtxJSON(CtxJSON &&) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CtxJSON() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
CtxJSON & operator = (const CtxJSON &) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
CtxJSON & operator = (CtxJSON &&) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Retrieve the current depth.
*/
SQMOD_NODISCARD const String & GetOutput() const noexcept
{
return mOutput;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the current depth.
*/
SQMOD_NODISCARD SQInteger GetDepth() const noexcept
{
return mDepth;
}
/* --------------------------------------------------------------------------------------------
* Retrieve whether objects are preferred over arrays.
*/
SQMOD_NODISCARD bool GetObjectOverArray() const noexcept
{
return mObjectOverArray;
}
/* --------------------------------------------------------------------------------------------
* Retrieve whether objects are preferred over arrays.
*/
CtxJSON & SetObjectOverArray(bool toggle) noexcept
{
mObjectOverArray = toggle;
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* Increase indentation by one level.
*/
void Advance() noexcept
{
++mDepth;
}
/* --------------------------------------------------------------------------------------------
* Decrease indentation by one level.
*/
void Retreat() noexcept
{
assert(mDepth > 0);
if (mDepth) --mDepth;
}
/* --------------------------------------------------------------------------------------------
* Begin writing an array.
*/
CtxJSON & OpenArray();
/* --------------------------------------------------------------------------------------------
* Stop writing an array.
*/
CtxJSON & CloseArray();
/* --------------------------------------------------------------------------------------------
* Resume writing an array.
*/
CtxJSON & ReopenArray();
/* --------------------------------------------------------------------------------------------
* Begin writing an object.
*/
CtxJSON & OpenObject();
/* --------------------------------------------------------------------------------------------
* Stop writing an object.
*/
CtxJSON & CloseObject();
/* --------------------------------------------------------------------------------------------
* Resume writing an object.
*/
CtxJSON & ReopenObject();
/* --------------------------------------------------------------------------------------------
* Begin writing a key value.
*/
CtxJSON & MakeKey();
/* --------------------------------------------------------------------------------------------
* Check whether the specified weak-ref points to a type of value that must be wrapped.
*/
SQMOD_NODISCARD static bool CheckWeakRefWrap(HSQUIRRELVM vm, SQInteger idx) noexcept;
/* --------------------------------------------------------------------------------------------
* Serialize given arguments.
*/
SQRESULT SerializeParams(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Serialize the value a specific position in the stack.
*/
SQRESULT SerializeAt(HSQUIRRELVM vm, SQInteger idx);
/* --------------------------------------------------------------------------------------------
* Serialize the array a specific position in the stack. Stack index must be absolute!
*/
SQRESULT SerializeArray(HSQUIRRELVM vm, SQInteger idx);
/* --------------------------------------------------------------------------------------------
* Serialize the table a specific position in the stack. Stack index must be absolute!
*/
SQRESULT SerializeTable(HSQUIRRELVM vm, SQInteger idx);
/* --------------------------------------------------------------------------------------------
* Serialize the instance a specific position in the stack. Stack index must be absolute!
*/
SQRESULT SerializeInstance(HSQUIRRELVM vm, SQInteger idx);
/* --------------------------------------------------------------------------------------------
* Serialize the weak-ref a specific position in the stack. Stack index must be absolute!
*/
SQRESULT SerializeWeakRef(HSQUIRRELVM vm, SQInteger idx);
/* --------------------------------------------------------------------------------------------
* Serialize a value to the current container. It assumes an array or object is currently open.
*/
SQRESULT PushValues(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Serialize a key/value pair to the current object. It assumes an object is currently open.
*/
SQRESULT PushElement(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Push a key in the output. It assumes an object was open and previous element closed properly.
*/
CtxJSON & PushKey(StackStrF & key);
/* --------------------------------------------------------------------------------------------
* Write a null value to the output.
*/
void PushNull();
/* --------------------------------------------------------------------------------------------
* Write an integer value to the output.
*/
void PushInteger(SQInteger value);
/* --------------------------------------------------------------------------------------------
* Write a single precision floating point value to the output.
*/
void PushFloat(float value);
/* --------------------------------------------------------------------------------------------
* Write a double precision floating point value to the output.
*/
void PushDouble(double value);
/* --------------------------------------------------------------------------------------------
* Write a boolean value to the output.
*/
void PushBool(bool value);
/* --------------------------------------------------------------------------------------------
* Write a string value to the output.
*/
void PushString(const SQChar * str);
/* --------------------------------------------------------------------------------------------
* Write a string value to the output.
*/
void PushString(const SQChar * str, size_t length);
};
} // Namespace:: SqMod } // Namespace:: SqMod

View File

@@ -22,6 +22,8 @@ void InitializeNet()
#endif #endif
#ifndef NO_SSL #ifndef NO_SSL
f |= MG_FEATURES_SSL; f |= MG_FEATURES_SSL;
#else
OutputMessage("Network compiled without SSL support.");
#endif #endif
#ifndef NO_CGI #ifndef NO_CGI
f |= MG_FEATURES_CGI; f |= MG_FEATURES_CGI;
@@ -135,6 +137,11 @@ int WebSocketClient::DataHandler(int flags, char * data, size_t data_len) noexce
{ {
LogFtl("Failed to queue web-socket data"); LogFtl("Failed to queue web-socket data");
} }
// Should we auto-close the connection
if (((flags & 0xF) == MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE) && mAutoClose.load() == true)
{
return 0;
}
// Return 1 to keep the connection open // Return 1 to keep the connection open
return 1; return 1;
} }
@@ -173,6 +180,7 @@ void Register_Net(HSQUIRRELVM vm)
.Prop(_SC("OnClose"), &WebSocketClient::GetOnClose, &WebSocketClient::SetOnClose) .Prop(_SC("OnClose"), &WebSocketClient::GetOnClose, &WebSocketClient::SetOnClose)
.Prop(_SC("Valid"), &WebSocketClient::IsValid) .Prop(_SC("Valid"), &WebSocketClient::IsValid)
.Prop(_SC("Closing"), &WebSocketClient::IsClosing) .Prop(_SC("Closing"), &WebSocketClient::IsClosing)
.Prop(_SC("AutoClose"), &WebSocketClient::GetAutoClose, &WebSocketClient::SetAutoClose)
// Member Methods // Member Methods
.FmtFunc(_SC("SetTag"), &WebSocketClient::ApplyTag) .FmtFunc(_SC("SetTag"), &WebSocketClient::ApplyTag)
.FmtFunc(_SC("SetData"), &WebSocketClient::ApplyData) .FmtFunc(_SC("SetData"), &WebSocketClient::ApplyData)

View File

@@ -159,6 +159,13 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
*/ */
std::atomic< bool > mClosed{false}; std::atomic< bool > mClosed{false};
/* --------------------------------------------------------------------------------------------
* Whether to not keep the connection open after receiving the close event.
* Internally this event is ignored but if set to true the connection is immediatelly closed
* in the internal event handler, before the event may reach the script callback.
*/
std::atomic< bool > mAutoClose{false};
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Server host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost". * Server host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost".
*/ */
@@ -184,7 +191,8 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
*/ */
WebSocketClient() WebSocketClient()
: Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData()
, mPort(0), mSecure(false), mClosing(false), mClosed(false), mHost(), mPath(), mOrigin(), mExtensions() , mPort(0), mSecure(false), mClosing(false), mClosed(false), mAutoClose(false)
, mHost(), mPath(), mOrigin(), mExtensions()
{ {
ChainInstance(); // Remember this instance ChainInstance(); // Remember this instance
} }
@@ -194,7 +202,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
*/ */
WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path) WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path)
: Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData()
, mPort(port), mSecure(false), mClosing(false), mClosed(false) , mPort(port), mSecure(false), mClosing(false), mClosed(false), mAutoClose(false)
, mHost(host.mPtr, host.GetSize()) , mHost(host.mPtr, host.GetSize())
, mPath(path.mPtr, path.GetSize()) , mPath(path.mPtr, path.GetSize())
, mOrigin(), mExtensions() , mOrigin(), mExtensions()
@@ -207,7 +215,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
*/ */
WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure) WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure)
: Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData()
, mPort(port), mSecure(secure), mClosing(false), mClosed(false) , mPort(port), mSecure(secure), mClosing(false), mClosed(false), mAutoClose(false)
, mHost(host.mPtr, host.GetSize()) , mHost(host.mPtr, host.GetSize())
, mPath(path.mPtr, path.GetSize()) , mPath(path.mPtr, path.GetSize())
, mOrigin(), mExtensions() , mOrigin(), mExtensions()
@@ -220,7 +228,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
*/ */
WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure, StackStrF & origin) WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure, StackStrF & origin)
: Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData()
, mPort(port), mSecure(secure), mClosing(false), mClosed(false) , mPort(port), mSecure(secure), mClosing(false), mClosed(false), mAutoClose(false)
, mHost(host.mPtr, host.GetSize()) , mHost(host.mPtr, host.GetSize())
, mPath(path.mPtr, path.GetSize()) , mPath(path.mPtr, path.GetSize())
, mOrigin(origin.mPtr, origin.GetSize()) , mOrigin(origin.mPtr, origin.GetSize())
@@ -234,7 +242,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
*/ */
WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure, StackStrF & origin, StackStrF & ext) WebSocketClient(StackStrF & host, uint16_t port, StackStrF & path, bool secure, StackStrF & origin, StackStrF & ext)
: Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData() : Base(), mHandle(nullptr), mQueue(1024), mOnData(), mOnClose(), mTag(), mData()
, mPort(port), mSecure(secure), mClosing(false), mClosed(false) , mPort(port), mSecure(secure), mClosing(false), mClosed(false), mAutoClose(false)
, mHost(host.mPtr, host.GetSize()) , mHost(host.mPtr, host.GetSize())
, mPath(path.mPtr, path.GetSize()) , mPath(path.mPtr, path.GetSize())
, mOrigin(origin.mPtr, origin.GetSize()) , mOrigin(origin.mPtr, origin.GetSize())
@@ -294,6 +302,22 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
return mClosing.load(); return mClosing.load();
} }
/* --------------------------------------------------------------------------------------------
* Retrieve whether auto-closing is enabled or not.
*/
SQMOD_NODISCARD bool GetAutoClose() const
{
return mAutoClose.load();
}
/* --------------------------------------------------------------------------------------------
* Modify whether auto-closing is enabled or not.
*/
void SetAutoClose(bool toggle)
{
mAutoClose.store(toggle);
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the associated user tag. * Retrieve the associated user tag.
*/ */

View File

@@ -55,40 +55,60 @@ SQMOD_DECL_TYPENAME(CVehicleTn, _SC("CVehicle"))
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Used to fetch the legacy entity instance even if a native one was specified. * Used to fetch the legacy entity instance even if a native one was specified.
*/ */
template < class T, class U > inline T & GetLgEnt(LightObj & o) template < class LEGACY, class NATIVE > inline LEGACY & GetLgEnt(LightObj & o)
{ {
auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag()); const auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag());
// Legacy entity type? // Legacy entity type?
if (type == StaticClassTypeTag< T >::Get()) if (type == StaticClassTypeTag< LEGACY >::Get())
{ {
return *o.CastI< T >(); return *o.CastI< LEGACY >();
} }
// Native entity type? // Native entity type?
if (type == StaticClassTypeTag< U >::Get()) if (type == StaticClassTypeTag< NATIVE >::Get())
{ {
return *EntityInstSelect< U >(o.CastI< U >()->GetID()).mLgInst; return *EntityInstSelect< NATIVE >::Get(o.CastI< NATIVE >()->GetID()).mLgInst;
} }
STHROWF("Invalid entity type"); STHROWF("Invalid entity type: {}", SqTypeName(SqVM(), o));
SQ_UNREACHABLE
}
/* ------------------------------------------------------------------------------------------------
* Used to fetch the native entity instance even if a legacy one was specified.
*/
template < class LEGACY, class NATIVE > inline NATIVE & GetNativeEnt(LightObj & o)
{
const auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag());
// Legacy entity type?
if (type == StaticClassTypeTag< LEGACY >::Get())
{
return o.CastI< LEGACY >()->Get();
}
// Native entity type?
if (type == StaticClassTypeTag< NATIVE >::Get())
{
return *EntityInstSelect< NATIVE >::Get(o.CastI< NATIVE >()->GetID()).mInst;
}
STHROWF("Invalid entity type: {}", SqTypeName(SqVM(), o));
SQ_UNREACHABLE SQ_UNREACHABLE
} }
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Used to fetch the legacy entity identifier even if a native one was specified. * Used to fetch the legacy entity identifier even if a native one was specified.
*/ */
template < class T, class U > SQMOD_NODISCARD inline int32_t GetLgEntID(LightObj & o) template < class LEGACY, class NATIVE > SQMOD_NODISCARD inline int32_t GetLgEntID(LightObj & o)
{ {
auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag()); const auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag());
// Legacy entity type? // Legacy entity type?
if (type == StaticClassTypeTag< T >::Get()) if (type == StaticClassTypeTag< LEGACY >::Get())
{ {
return o.CastI< T >()->mID; return o.CastI< LEGACY >()->mID;
} }
// Native entity type? // Native entity type?
if (type == StaticClassTypeTag< U >::Get()) if (type == StaticClassTypeTag< NATIVE >::Get())
{ {
return o.CastI< U >()->GetID(); return o.CastI< NATIVE >()->GetID();
} }
STHROWF("Invalid entity type"); STHROWF("Invalid entity type: {}", SqTypeName(SqVM(), o));
SQ_UNREACHABLE SQ_UNREACHABLE
} }
@@ -478,14 +498,14 @@ struct LgCheckpoint
SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); } SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); }
SQMOD_NODISCARD LgARGB GetColor() const { const Color4 c = Get().GetColor(); return LgARGB{c.a, c.r, c.g, c.b}; } SQMOD_NODISCARD LgARGB GetColor() const { const Color4 c = Get().GetColor(); return LgARGB{c.a, c.r, c.g, c.b}; }
SQMOD_NODISCARD LgEntityVector GetPos() const SQMOD_NODISCARD LgEntityVector GetPos() const
{ return LgEntityVector(mID, LgEntityType::Checkpoint, 0, Get().GetPosition()); } { return {mID, LgEntityType::Checkpoint, 0, Get().GetPosition()}; }
SQMOD_NODISCARD float GetRadius() const { return Get().GetRadius(); } SQMOD_NODISCARD float GetRadius() const { return Get().GetRadius(); }
SQMOD_NODISCARD int GetID() const { return mID; } SQMOD_NODISCARD int GetID() const { return mID; }
SQMOD_NODISCARD LgPlayer * GetOwner() const SQMOD_NODISCARD LgPlayer * GetOwner() const
{ const int id = Get().GetOwnerID(); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; } { const int id = Get().GetOwnerID(); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; }
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
void Delete() const { _Func->DeleteCheckPoint(GetIdentifier()); } void Delete() const { _Func->DeleteCheckPoint(GetIdentifier()); }
SQMOD_NODISCARD bool StreamedToPlayer(LgPlayer & player) const; SQMOD_NODISCARD bool StreamedToPlayer(LightObj & player) const;
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -546,11 +566,11 @@ struct LgObject
SQMOD_NODISCARD int GetAlpha() const { return Get().GetAlpha(); } SQMOD_NODISCARD int GetAlpha() const { return Get().GetAlpha(); }
SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); } SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); }
SQMOD_NODISCARD LgEntityVector GetPos() const SQMOD_NODISCARD LgEntityVector GetPos() const
{ return LgEntityVector(mID, LgEntityType::Object, LgObjectVectorFlag::Pos, Get().GetPosition()); } { return {mID, LgEntityType::Object, LgObjectVectorFlag::Pos, Get().GetPosition()}; }
SQMOD_NODISCARD LgEntityQuaternion GetRotation() const SQMOD_NODISCARD LgEntityQuaternion GetRotation() const
{ return LgEntityQuaternion(mID, LgEntityType::Object, 0, Get().GetRotation()); } { return {mID, LgEntityType::Object, 0, Get().GetRotation()}; }
SQMOD_NODISCARD LgEntityVector GetRotationEuler() const SQMOD_NODISCARD LgEntityVector GetRotationEuler() const
{ return LgEntityVector(mID, LgEntityType::Object, LgObjectVectorFlag::Rotation, Get().GetRotationEuler()); } { return {mID, LgEntityType::Object, LgObjectVectorFlag::Rotation, Get().GetRotationEuler()}; }
SQMOD_NODISCARD int GetID() const { return mID; } SQMOD_NODISCARD int GetID() const { return mID; }
SQMOD_NODISCARD bool GetReportingShots() const { return Get().GetShotReport(); } SQMOD_NODISCARD bool GetReportingShots() const { return Get().GetShotReport(); }
SQMOD_NODISCARD bool GetReportingBumps() const { return Get().GetTouchedReport(); } SQMOD_NODISCARD bool GetReportingBumps() const { return Get().GetTouchedReport(); }
@@ -563,7 +583,7 @@ struct LgObject
void RotateToEuler(const Vector3 & rotation, int time) const { Get().RotateToEuler(rotation, static_cast< uint32_t >(time)); } void RotateToEuler(const Vector3 & rotation, int time) const { Get().RotateToEuler(rotation, static_cast< uint32_t >(time)); }
void RotateByEuler(const Vector3 & rotOffset, int time) const { Get().RotateByEuler(rotOffset, static_cast< uint32_t >(time)); } void RotateByEuler(const Vector3 & rotOffset, int time) const { Get().RotateByEuler(rotOffset, static_cast< uint32_t >(time)); }
void SetAlpha(int alpha, int fadeTime) const { Get().SetAlphaEx(alpha, static_cast< uint32_t >(fadeTime)); } void SetAlpha(int alpha, int fadeTime) const { Get().SetAlphaEx(alpha, static_cast< uint32_t >(fadeTime)); }
SQMOD_NODISCARD bool StreamedToPlayer(LgPlayer & player) const; SQMOD_NODISCARD bool StreamedToPlayer(LightObj & player) const;
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -627,7 +647,7 @@ struct LgPickup
SQMOD_NODISCARD bool GetAuto() const { return Get().GetAutomatic(); } SQMOD_NODISCARD bool GetAuto() const { return Get().GetAutomatic(); }
SQMOD_NODISCARD int GetAutoTimer() const { return Get().GetAutoTimer(); } SQMOD_NODISCARD int GetAutoTimer() const { return Get().GetAutoTimer(); }
SQMOD_NODISCARD LgEntityVector GetPos() const SQMOD_NODISCARD LgEntityVector GetPos() const
{ return LgEntityVector(mID, LgEntityType::Pickup, 0, Get().GetPosition()); } { return {mID, LgEntityType::Pickup, 0, Get().GetPosition()}; }
SQMOD_NODISCARD int GetModel() const { return Get().GetModel(); } SQMOD_NODISCARD int GetModel() const { return Get().GetModel(); }
SQMOD_NODISCARD int GetQuantity() const { return Get().GetQuantity(); } SQMOD_NODISCARD int GetQuantity() const { return Get().GetQuantity(); }
SQMOD_NODISCARD int GetID() const { return mID; } SQMOD_NODISCARD int GetID() const { return mID; }
@@ -635,7 +655,7 @@ struct LgPickup
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
void Delete() const { _Func->DeletePickup(GetIdentifier()); } void Delete() const { _Func->DeletePickup(GetIdentifier()); }
void Respawn() const { Get().Refresh(); } void Respawn() const { Get().Refresh(); }
SQMOD_NODISCARD bool StreamedToPlayer(LgPlayer & player) const; SQMOD_NODISCARD bool StreamedToPlayer(LightObj & player) const;
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -703,7 +723,7 @@ struct LgPlayer
void SetScore(int score) const { Get().SetScore(score); } void SetScore(int score) const { Get().SetScore(score); }
void SetImmunity(uint32_t immunity) const { Get().SetImmunity(immunity); } void SetImmunity(uint32_t immunity) const { Get().SetImmunity(immunity); }
void SetHeading(float heading) const { Get().SetHeading(heading); } void SetHeading(float heading) const { Get().SetHeading(heading); }
void SetVehicle(LgVehicle & vehicle) const; void SetVehicle(LightObj & vehicle) const;
void SetFrozen(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionControllable, static_cast< uint8_t >(!toggle)); } void SetFrozen(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionControllable, static_cast< uint8_t >(!toggle)); }
void SetDriveByEnabled(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDriveBy, static_cast< uint8_t >(toggle)); } void SetDriveByEnabled(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDriveBy, static_cast< uint8_t >(toggle)); }
void SetWhiteScanLines(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionWhiteScanlines, static_cast< uint8_t >(toggle)); } void SetWhiteScanLines(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionWhiteScanlines, static_cast< uint8_t >(toggle)); }
@@ -720,7 +740,7 @@ struct LgPlayer
void SetWantedLevel(int level) const { Get().SetWantedLevel(level); } void SetWantedLevel(int level) const { Get().SetWantedLevel(level); }
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
SQMOD_NODISCARD LgEntityVector GetPosition() const SQMOD_NODISCARD LgEntityVector GetPosition() const
{ return LgEntityVector(mID, LgEntityType::Player, LgPlayerVectorFlag::Pos, Get().GetPosition()); } { return {mID, LgEntityType::Player, LgPlayerVectorFlag::Pos, Get().GetPosition()}; }
SQMOD_NODISCARD int GetClass() const { return Get().GetClass(); } SQMOD_NODISCARD int GetClass() const { return Get().GetClass(); }
SQMOD_NODISCARD bool GetAdmin() const { return Get().GetAdmin(); } SQMOD_NODISCARD bool GetAdmin() const { return Get().GetAdmin(); }
SQMOD_NODISCARD const SQChar * GetIP() const { return Get().GetIP(); } SQMOD_NODISCARD const SQChar * GetIP() const { return Get().GetIP(); }
@@ -732,7 +752,7 @@ struct LgPlayer
SQMOD_NODISCARD const SQChar * GetName() const { return Get().GetName(); } SQMOD_NODISCARD const SQChar * GetName() const { return Get().GetName(); }
SQMOD_NODISCARD int GetTeam() const { return Get().GetTeam(); } SQMOD_NODISCARD int GetTeam() const { return Get().GetTeam(); }
SQMOD_NODISCARD int GetSkin() const { return Get().GetSkin(); } SQMOD_NODISCARD int GetSkin() const { return Get().GetSkin(); }
SQMOD_NODISCARD LgEntityRGB GetColour() const { return LgEntityRGB(mID, LgEntityType::Player, 0, Get().GetColor()); } SQMOD_NODISCARD LgEntityRGB GetColour() const { return {mID, LgEntityType::Player, 0, Get().GetColor()}; }
SQMOD_NODISCARD int GetMoney() const { return Get().GetMoney(); } SQMOD_NODISCARD int GetMoney() const { return Get().GetMoney(); }
SQMOD_NODISCARD int GetScore() const { return Get().GetScore(); } SQMOD_NODISCARD int GetScore() const { return Get().GetScore(); }
SQMOD_NODISCARD int GetPing() const { return Get().GetPing(); } SQMOD_NODISCARD int GetPing() const { return Get().GetPing(); }
@@ -764,7 +784,7 @@ struct LgPlayer
SQMOD_NODISCARD LgPlayer * GetSpectateTarget() const SQMOD_NODISCARD LgPlayer * GetSpectateTarget() const
{ const int id = _Func->GetPlayerSpectateTarget(GetIdentifier()); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; } { const int id = _Func->GetPlayerSpectateTarget(GetIdentifier()); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; }
SQMOD_NODISCARD LgEntityVector GetSpeed() const SQMOD_NODISCARD LgEntityVector GetSpeed() const
{ return LgEntityVector(mID, LgEntityType::Player, LgPlayerVectorFlag::Speed, Get().GetSpeed()); } { return {mID, LgEntityType::Player, LgPlayerVectorFlag::Speed, Get().GetSpeed()}; }
SQMOD_NODISCARD bool GetCanUseColors() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionChatTagsEnabled) >= 1; } SQMOD_NODISCARD bool GetCanUseColors() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionChatTagsEnabled) >= 1; }
SQMOD_NODISCARD bool GetMarkerVisible() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker) >= 1; } SQMOD_NODISCARD bool GetMarkerVisible() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker) >= 1; }
SQMOD_NODISCARD bool GetDrunkStatus() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects) >= 1; } SQMOD_NODISCARD bool GetDrunkStatus() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects) >= 1; }
@@ -801,8 +821,8 @@ struct LgPlayer
SQMOD_NODISCARD int GetWeaponAtSlot(int slot) const { return Get().GetWeaponAtSlot(slot); } SQMOD_NODISCARD int GetWeaponAtSlot(int slot) const { return Get().GetWeaponAtSlot(slot); }
SQMOD_NODISCARD int GetAmmoAtSlot(int slot) const { return Get().GetAmmoAtSlot(slot); } SQMOD_NODISCARD int GetAmmoAtSlot(int slot) const { return Get().GetAmmoAtSlot(slot); }
void SetAlpha(int alpha, int fadeTime) const { Get().SetAlphaEx(alpha, fadeTime); } void SetAlpha(int alpha, int fadeTime) const { Get().SetAlphaEx(alpha, fadeTime); }
SQMOD_NODISCARD bool StreamedToPlayer(const LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } SQMOD_NODISCARD bool StreamedToPlayer(LightObj & player) const { return Get().IsStreamedFor(GetNativeEnt< LgPlayer, CPlayer >(player)); }
void SetVehicleSlot(const LgVehicle & vehicle, int slot) const; void SetVehicleSlot(LightObj & vehicle, int slot) const;
void Select() const { Get().ForceSelect(); } void Select() const { Get().ForceSelect(); }
void RestoreCamera() const { Get().RestoreCamera(); } void RestoreCamera() const { Get().RestoreCamera(); }
void RemoveMarker() const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, 0); } void RemoveMarker() const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, 0); }
@@ -915,13 +935,13 @@ struct LgVehicle
SQMOD_NODISCARD int GetModel() const { return Get().GetModel(); } SQMOD_NODISCARD int GetModel() const { return Get().GetModel(); }
SQMOD_NODISCARD uint32_t GetImmunity() const { return Get().GetImmunity(); } SQMOD_NODISCARD uint32_t GetImmunity() const { return Get().GetImmunity(); }
SQMOD_NODISCARD LgEntityVector GetPosition() const SQMOD_NODISCARD LgEntityVector GetPosition() const
{ return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Pos, Get().GetPosition()); } { return {mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Pos, Get().GetPosition()}; }
SQMOD_NODISCARD LgEntityVector GetSpawnPos() const SQMOD_NODISCARD LgEntityVector GetSpawnPos() const
{ return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::SpawnPos, Get().GetSpawnPosition()); } { return {mID, LgEntityType::Vehicle, LgVehicleVectorFlag::SpawnPos, Get().GetSpawnPosition()}; }
SQMOD_NODISCARD LgEntityQuaternion GetSpawnAngle() const SQMOD_NODISCARD LgEntityQuaternion GetSpawnAngle() const
{ return LgEntityQuaternion(mID, LgEntityType::Vehicle, LgVehicleQuaternionFlag::SpawnAngle, Get().GetSpawnRotation()); } { return {mID, LgEntityType::Vehicle, LgVehicleQuaternionFlag::SpawnAngle, Get().GetSpawnRotation()}; }
SQMOD_NODISCARD LgEntityVector GetSpawnAngleEuler() const SQMOD_NODISCARD LgEntityVector GetSpawnAngleEuler() const
{ return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::SpawnAngle, Get().GetSpawnRotationEuler()); } { return {mID, LgEntityType::Vehicle, LgVehicleVectorFlag::SpawnAngle, Get().GetSpawnRotationEuler()}; }
SQMOD_NODISCARD uint32_t GetIdleRespawnTimer() const { return Get().GetIdleRespawnTimer(); } SQMOD_NODISCARD uint32_t GetIdleRespawnTimer() const { return Get().GetIdleRespawnTimer(); }
SQMOD_NODISCARD float GetHealth() const { return Get().GetHealth(); } SQMOD_NODISCARD float GetHealth() const { return Get().GetHealth(); }
SQMOD_NODISCARD int GetColour1() const { return Get().GetPrimaryColor(); } SQMOD_NODISCARD int GetColour1() const { return Get().GetPrimaryColor(); }
@@ -939,21 +959,21 @@ struct LgVehicle
SQMOD_NODISCARD int GetSyncType() const { return Get().GetSyncType(); } SQMOD_NODISCARD int GetSyncType() const { return Get().GetSyncType(); }
SQMOD_NODISCARD bool GetWrecked() const { return Get().IsWrecked(); } SQMOD_NODISCARD bool GetWrecked() const { return Get().IsWrecked(); }
SQMOD_NODISCARD LgEntityQuaternion GetRotation() const SQMOD_NODISCARD LgEntityQuaternion GetRotation() const
{ return LgEntityQuaternion(mID, LgEntityType::Vehicle, LgVehicleQuaternionFlag::Angle, Get().GetRotation()); } { return {mID, LgEntityType::Vehicle, LgVehicleQuaternionFlag::Angle, Get().GetRotation()}; }
SQMOD_NODISCARD LgEntityVector GetEulerRotation() const SQMOD_NODISCARD LgEntityVector GetEulerRotation() const
{ return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Angle, Get().GetRotationEuler()); } { return {mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Angle, Get().GetRotationEuler()}; }
SQMOD_NODISCARD LgEntityVector GetSpeed() const SQMOD_NODISCARD LgEntityVector GetSpeed() const
{ return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Speed, Get().GetSpeed()); } { return {mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Speed, Get().GetSpeed()}; }
SQMOD_NODISCARD LgEntityVector GetRelativeSpeed() const SQMOD_NODISCARD LgEntityVector GetRelativeSpeed() const
{ return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::RelSpeed, Get().GetRelativeSpeed()); } { return {mID, LgEntityType::Vehicle, LgVehicleVectorFlag::RelSpeed, Get().GetRelativeSpeed()}; }
SQMOD_NODISCARD LgEntityVector GetTurnSpeed() const SQMOD_NODISCARD LgEntityVector GetTurnSpeed() const
{ return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::TurnSpeed, Get().GetTurnSpeed()); } { return {mID, LgEntityType::Vehicle, LgVehicleVectorFlag::TurnSpeed, Get().GetTurnSpeed()}; }
SQMOD_NODISCARD LgEntityVector GetRelativeTurnSpeed() const SQMOD_NODISCARD LgEntityVector GetRelativeTurnSpeed() const
{ return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::RelTurnSpeed, Get().GetRelativeTurnSpeed()); } { return {mID, LgEntityType::Vehicle, LgVehicleVectorFlag::RelTurnSpeed, Get().GetRelativeTurnSpeed()}; }
SQMOD_NODISCARD int GetRadio() const { return Get().GetRadio(); } SQMOD_NODISCARD int GetRadio() const { return Get().GetRadio(); }
SQMOD_NODISCARD bool GetRadioLockStatus() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionRadioLocked) >= 1; } SQMOD_NODISCARD bool GetRadioLockStatus() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionRadioLocked) >= 1; }
SQMOD_NODISCARD bool GetGhost() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionGhost) >= 1; } SQMOD_NODISCARD bool GetGhost() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionGhost) >= 1; }
SQMOD_NODISCARD LgVector GetTurretRotation() const { const Vector2 v = Get().GetTurretRotation(); return LgVector(v.x, v.y, 0); } SQMOD_NODISCARD LgVector GetTurretRotation() const { const Vector2 v = Get().GetTurretRotation(); return {v.x, v.y, 0}; }
SQMOD_NODISCARD bool GetSingleUse() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionSingleUse) >= 1; } SQMOD_NODISCARD bool GetSingleUse() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionSingleUse) >= 1; }
SQMOD_NODISCARD bool GetTaxiLight() const { return (_Func->GetVehicleLightsData(GetIdentifier()) & (1 << 8)) != 0; } SQMOD_NODISCARD bool GetTaxiLight() const { return (_Func->GetVehicleLightsData(GetIdentifier()) & (1 << 8)) != 0; }
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@@ -966,7 +986,7 @@ struct LgVehicle
void SetPartStatus(int part, int status) const { Get().SetPartStatus(part, status); } void SetPartStatus(int part, int status) const { Get().SetPartStatus(part, status); }
SQMOD_NODISCARD int GetTyreStatus(int tyre) const { return Get().GetTyreStatus(tyre); } SQMOD_NODISCARD int GetTyreStatus(int tyre) const { return Get().GetTyreStatus(tyre); }
void SetTyreStatus(int part, int status) const { Get().SetTyreStatus(part, status); } void SetTyreStatus(int part, int status) const { Get().SetTyreStatus(part, status); }
SQMOD_NODISCARD bool GetStreamedForPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } SQMOD_NODISCARD bool GetStreamedForPlayer(LightObj & player) const { return Get().IsStreamedFor(GetNativeEnt< LgPlayer, CPlayer >(player)); }
SQMOD_NODISCARD LgPlayer * GetOccupant(int slot) const SQMOD_NODISCARD LgPlayer * GetOccupant(int slot) const
{ const int id = _Func->GetVehicleOccupant(GetIdentifier(), slot); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; } { const int id = _Func->GetVehicleOccupant(GetIdentifier(), slot); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; }
void SetHandlingData(int rule, float value) const { Get().SetHandlingRule(rule, value); } void SetHandlingData(int rule, float value) const { Get().SetHandlingRule(rule, value); }
@@ -982,11 +1002,11 @@ struct LgVehicle
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline bool LgCheckpoint::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } inline bool LgCheckpoint::StreamedToPlayer(LightObj & player) const { return Get().IsStreamedFor(GetNativeEnt< LgPlayer, CPlayer >(player)); }
inline bool LgObject::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } inline bool LgObject::StreamedToPlayer(LightObj & player) const { return Get().IsStreamedFor(GetNativeEnt< LgPlayer, CPlayer >(player)); }
inline bool LgPickup::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } inline bool LgPickup::StreamedToPlayer(LightObj & player) const { return Get().IsStreamedFor(GetNativeEnt< LgPlayer, CPlayer >(player)); }
inline void LgPlayer::SetVehicle(LgVehicle & vehicle) const { Get().Embark(vehicle.Get()); } inline void LgPlayer::SetVehicle(LightObj & vehicle) const { Get().Embark(GetNativeEnt< LgVehicle, CVehicle >(vehicle)); }
inline void LgPlayer::SetVehicleSlot(const LgVehicle & vehicle, int slot) const { Get().EmbarkEx(vehicle.Get(), slot, true, false); } inline void LgPlayer::SetVehicleSlot(LightObj & vehicle, int slot) const { Get().EmbarkEx(GetNativeEnt< LgVehicle, CVehicle >(vehicle), slot, true, false); }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LgCheckpointSetID(LgCheckpoint * inst, int32_t id) { assert(inst); if (inst) inst->mID = id; } void LgCheckpointSetID(LgCheckpoint * inst, int32_t id) { assert(inst); if (inst) inst->mID = id; }
@@ -1434,8 +1454,8 @@ static void LgUnbanIP(StackStrF & ip) { _Func->UnbanIP(const_cast< SQChar * >(ip
SQMOD_NODISCARD static bool LgIsIPBanned(StackStrF & ip) { return _Func->IsIPBanned(const_cast< SQChar * >(ip.mPtr)) >= 1; } SQMOD_NODISCARD static bool LgIsIPBanned(StackStrF & ip) { return _Func->IsIPBanned(const_cast< SQChar * >(ip.mPtr)) >= 1; }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static int LgGetPlayerIDFromName(StackStrF & name) { return _Func->GetPlayerIdFromName(name.mPtr); } SQMOD_NODISCARD static int LgGetPlayerIDFromName(StackStrF & name) { return _Func->GetPlayerIdFromName(name.mPtr); }
SQMOD_NODISCARD static bool LgIsWorldCompatibleWithPlayer (LgPlayer & player, int world) SQMOD_NODISCARD static bool LgIsWorldCompatibleWithPlayer(LightObj & player, int world)
{ return _Func->IsPlayerWorldCompatible(player.GetIdentifier(), world) >= 1; } { return _Func->IsPlayerWorldCompatible(GetLgEntID< LgPlayer, CPlayer >(player), world) >= 1; }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static LightObj & LgCreatePickupCompat(int model, const Vector3 & pos) static LightObj & LgCreatePickupCompat(int model, const Vector3 & pos)
{ return Core::Get().NewPickup(model, 1, 0, pos.x, pos.y, pos.z, 255, false, SQMOD_CREATE_DEFAULT, NullLightObj()).mLgObj; } { return Core::Get().NewPickup(model, 1, 0, pos.x, pos.y, pos.z, 255, false, SQMOD_CREATE_DEFAULT, NullLightObj()).mLgObj; }
@@ -1449,7 +1469,7 @@ static LightObj & LgCreatePickup(int model, int world, int quantity, const Vecto
static LightObj & LgCreateObject(int model, int world, const Vector3 & pos, int alpha) static LightObj & LgCreateObject(int model, int world, const Vector3 & pos, int alpha)
{ return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha, SQMOD_CREATE_DEFAULT, NullLightObj()).mLgObj; } { return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha, SQMOD_CREATE_DEFAULT, NullLightObj()).mLgObj; }
static LightObj & LgCreateCheckpoint(LightObj & player, int world, bool sphere, const Vector3 & pos, const Color4 & col, float radius) { static LightObj & LgCreateCheckpoint(LightObj & player, int world, bool sphere, const Vector3 & pos, const Color4 & col, float radius) {
const int32_t id = player.IsNull() ? -1 : player.CastI< LgPlayer >()->GetIdentifier(); const int32_t id = player.IsNull() ? -1 : GetLgEntID< LgPlayer, CPlayer >(player);
return Core::Get().NewCheckpoint(id, world, sphere, pos.x, pos.y, pos.z, col.r, col.g, col.b, col.a, radius, SQMOD_CREATE_DEFAULT, NullLightObj()).mLgObj; return Core::Get().NewCheckpoint(id, world, sphere, pos.x, pos.y, pos.z, col.r, col.g, col.b, col.a, radius, SQMOD_CREATE_DEFAULT, NullLightObj()).mLgObj;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1507,30 +1527,30 @@ SQMOD_NODISCARD static int LgBindKey(bool down, int key1, int key2, int key3)
SQMOD_NODISCARD static bool LgRemoveKeybind(int id) { return _Func->RemoveKeyBind(id) == vcmpErrorNone; } SQMOD_NODISCARD static bool LgRemoveKeybind(int id) { return _Func->RemoveKeyBind(id) == vcmpErrorNone; }
static void LgRemoveAllKeybinds() { _Func->RemoveAllKeyBinds(); } static void LgRemoveAllKeybinds() { _Func->RemoveAllKeyBinds(); }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static bool LgGetCinematicBorder(LgPlayer & player) { return _Func->GetPlayerOption(player.GetIdentifier(), vcmpPlayerOptionWidescreen) >= 1; } SQMOD_NODISCARD static bool LgGetCinematicBorder(LightObj & player) { return _Func->GetPlayerOption(GetLgEntID< LgPlayer, CPlayer >(player), vcmpPlayerOptionWidescreen) >= 1; }
SQMOD_NODISCARD static bool LgGetGreenScanLines(LgPlayer & player) { return _Func->GetPlayerOption(player.GetIdentifier(), vcmpPlayerOptionGreenScanlines) >= 1; } SQMOD_NODISCARD static bool LgGetGreenScanLines(LightObj & player) { return _Func->GetPlayerOption(GetLgEntID< LgPlayer, CPlayer >(player), vcmpPlayerOptionGreenScanlines) >= 1; }
SQMOD_NODISCARD static bool LgGetWhiteScanLines(LgPlayer & player) { return _Func->GetPlayerOption(player.GetIdentifier(), vcmpPlayerOptionWhiteScanlines) >= 1; } SQMOD_NODISCARD static bool LgGetWhiteScanLines(LightObj & player) { return _Func->GetPlayerOption(GetLgEntID< LgPlayer, CPlayer >(player), vcmpPlayerOptionWhiteScanlines) >= 1; }
static void LgSetCinematicBorder(LgPlayer & player, bool toggle) { _Func->SetPlayerOption(player.GetIdentifier(), vcmpPlayerOptionWidescreen, static_cast< uint8_t >(toggle)); } static void LgSetCinematicBorder(LightObj & player, bool toggle) { _Func->SetPlayerOption(GetLgEntID< LgPlayer, CPlayer >(player), vcmpPlayerOptionWidescreen, static_cast< uint8_t >(toggle)); }
static void LgSetGreenScanLines(LgPlayer & player, bool toggle) { _Func->SetPlayerOption(player.GetIdentifier(), vcmpPlayerOptionGreenScanlines, static_cast< uint8_t >(toggle)); } static void LgSetGreenScanLines(LightObj & player, bool toggle) { _Func->SetPlayerOption(GetLgEntID< LgPlayer, CPlayer >(player), vcmpPlayerOptionGreenScanlines, static_cast< uint8_t >(toggle)); }
static void LgSetWhiteScanLines(LgPlayer & player, bool toggle) { _Func->SetPlayerOption(player.GetIdentifier(), vcmpPlayerOptionWhiteScanlines, static_cast< uint8_t >(toggle)); } static void LgSetWhiteScanLines(LightObj & player, bool toggle) { _Func->SetPlayerOption(GetLgEntID< LgPlayer, CPlayer >(player), vcmpPlayerOptionWhiteScanlines, static_cast< uint8_t >(toggle)); }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void LgKickPlayer(LgPlayer & player) { _Func->KickPlayer(player.GetIdentifier()); } static void LgKickPlayer(LightObj & player) { _Func->KickPlayer(GetLgEntID< LgPlayer, CPlayer >(player)); }
static void LgBanPlayer(LgPlayer & player) { _Func->BanPlayer(player.GetIdentifier()); } static void LgBanPlayer(LightObj & player) { _Func->BanPlayer(GetLgEntID< LgPlayer, CPlayer >(player)); }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void LgMessage(StackStrF & msg) { _Func->SendClientMessage(-1, 0x0b5fa5ff, "%s", msg.mPtr); } static void LgMessage(StackStrF & msg) { _Func->SendClientMessage(-1, 0x0b5fa5ff, "%s", msg.mPtr); }
static void LgMessagePlayer(StackStrF & msg, LgPlayer & player) { _Func->SendClientMessage(player.GetIdentifier(), 0x0b5fa5ff, "%s", msg.mPtr); } static void LgMessagePlayer(StackStrF & msg, LightObj & player) { _Func->SendClientMessage(GetLgEntID< LgPlayer, CPlayer >(player), 0x0b5fa5ff, "%s", msg.mPtr); }
static void LgMessageAllExcept(StackStrF & msg, LgPlayer & player) { static void LgMessageAllExcept(StackStrF & msg, LightObj & player) {
const int32_t p = player.GetIdentifier(); const auto p = GetLgEntID< LgPlayer, CPlayer >(player);
const SQChar * m = msg.mPtr; const SQChar * m = msg.mPtr;
ForeachConnectedPlayer([=](int32_t id) { if (id != p) _Func->SendClientMessage(id, 0x0b5fa5ff, "%s", m); }); ForeachConnectedPlayer([=](int32_t id) { if (id != p) _Func->SendClientMessage(id, 0x0b5fa5ff, "%s", m); });
} }
static void LgPrivMessage(LgPlayer & player, StackStrF & msg) { _Func->SendClientMessage(player.GetIdentifier(), 0x007f16ff, "** pm >> %s", msg.mPtr); } static void LgPrivMessage(LightObj & player, StackStrF & msg) { _Func->SendClientMessage(GetLgEntID< LgPlayer, CPlayer >(player), 0x007f16ff, "** pm >> %s", msg.mPtr); }
static void LgPrivMessageAll(StackStrF & msg) { static void LgPrivMessageAll(StackStrF & msg) {
const SQChar * m = msg.mPtr; const SQChar * m = msg.mPtr;
ForeachConnectedPlayer([=](int32_t id) { _Func->SendClientMessage(id, 0x007f16ff, "** pm >> %s", m); }); ForeachConnectedPlayer([=](int32_t id) { _Func->SendClientMessage(id, 0x007f16ff, "** pm >> %s", m); });
} }
static void LgSendPlayerMessage(LgPlayer & source, LgPlayer & target, StackStrF & msg) { static void LgSendPlayerMessage(LightObj & source, LightObj & target, StackStrF & msg) {
_Func->SendClientMessage(target.GetIdentifier(), 0x007f16ff, "** pm from %s >> %s", source.Get().GetName(), msg.mPtr); _Func->SendClientMessage(GetLgEntID< LgPlayer, CPlayer >(target), 0x007f16ff, "** pm from %s >> %s",GetNativeEnt< LgPlayer, CPlayer >(source).GetName(), msg.mPtr);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static const SQChar * LgGetWeaponName(int id) { return GetWeaponName(static_cast< uint32_t >(id)); } SQMOD_NODISCARD static const SQChar * LgGetWeaponName(int id) { return GetWeaponName(static_cast< uint32_t >(id)); }
@@ -2302,8 +2322,8 @@ struct LgStream {
int32_t id; int32_t id;
if (target.IsNull()) id = -1; if (target.IsNull()) id = -1;
else if (target.GetType() == OT_INTEGER || target.GetType() == OT_FLOAT) id = target.Cast< int32_t >(); else if (target.GetType() == OT_INTEGER || target.GetType() == OT_FLOAT) id = target.Cast< int32_t >();
else if (static_cast< AbstractStaticClassData * >(target.GetTypeTag()) == StaticClassTypeTag< LgPlayer >::Get()) { else if (target.GetType() == OT_INSTANCE) {
id = target.CastI< LgPlayer >()->GetIdentifier(); id = GetLgEntID< LgPlayer, CPlayer >(target);
} else STHROWF("Invalid target type"); } else STHROWF("Invalid target type");
if (id >= SQMOD_PLAYER_POOL) STHROWF("Invalid player ID"); if (id >= SQMOD_PLAYER_POOL) STHROWF("Invalid player ID");
_Func->SendClientScriptData(id, m_OutputStreamData, m_OutputStreamEnd); _Func->SendClientScriptData(id, m_OutputStreamData, m_OutputStreamEnd);

View File

@@ -2146,12 +2146,12 @@ struct SqDataAsyncBuilder
SqDataAsyncBuilder & operator = (SqDataAsyncBuilder && o) = default; SqDataAsyncBuilder & operator = (SqDataAsyncBuilder && o) = default;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Create the task with the suplied information and submit it to the worker pool. * Create the task with the supplied information and submit it to the worker pool.
*/ */
void Submit() { Submit_(NullLightObj()); } void Submit() { Submit_(NullLightObj()); }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Create the task with the suplied information and submit it to the worker pool. * Create the task with the supplied information and submit it to the worker pool.
*/ */
void Submit_(LightObj & ctx); void Submit_(LightObj & ctx);

View File

@@ -195,21 +195,7 @@ struct LightObj {
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T, class... A> template<class T, class... A>
LightObj(SqTypeIdentity< T > SQ_UNUSED_ARG(t), HSQUIRRELVM vm, A&&... a) { LightObj(SqTypeIdentity< T > SQ_UNUSED_ARG(t), HSQUIRRELVM vm, A&&... a) : LightObj(DeleteGuard< T >(new T(std::forward< A >(a)...))) {
// Create the instance and guard it to make sure it gets deleted in case of exceptions
DeleteGuard< T > instance(new T(std::forward< A >(a)...));
// Preserve the stack state
const StackGuard sg(vm);
// Push the instance on the stack
ClassType<T>::PushInstance(vm, instance);
// Attempt to retrieve it
if (SQ_FAILED(sq_getstackobj(vm, -1, &mObj))) {
sq_resetobject(&mObj);
} else {
sq_addref(vm, &mObj);
}
// Stop guarding the instance
instance.Release();
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -246,7 +232,21 @@ struct LightObj {
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T> template<class T>
LightObj(DeleteGuard<T> guard, HSQUIRRELVM v = SqVM()) : LightObj(guard.Get(), v) { LightObj(DeleteGuard<T> && guard, HSQUIRRELVM v = SqVM()) : LightObj(guard.Get(), v) {
guard.Release();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Constructs an LightObj from a C++ instance wrapped inside a DeleteGuard
///
/// \param instance Pointer to a C++ class instance that has been bound already
/// \param v VM that the object will exist in
///
/// \tparam T Type of instance
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
LightObj(DeleteGuard<T> & guard, HSQUIRRELVM v = SqVM()) : LightObj(guard.Get(), v) {
guard.Release(); guard.Release();
} }

View File

@@ -35,6 +35,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <exception> #include <exception>
#include <type_traits>
#include <unordered_map> #include <unordered_map>
#include <Poco/Exception.h> #include <Poco/Exception.h>
@@ -1580,12 +1581,31 @@ public:
} }
}; };
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Helper structure for one element from the top of stack. Uses default global VM instead.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct SqPopTopGuardLite
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Base constructor.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SqPopTopGuardLite() noexcept = default;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Destructor. Pops the specified elements from the stack.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
~SqPopTopGuardLite()
{
sq_poptop(SqVM());
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Helper structure for one element from the top of stack. /// Helper structure for one element from the top of stack.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct SqPopTopGuard struct SqPopTopGuard
{ {
HSQUIRRELVM mVM; // The VM from which the elements must be popped. HSQUIRRELVM mVM; // The VM from which the elements must be popped.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Base constructor. /// Base constructor.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1603,13 +1623,70 @@ struct SqPopTopGuard
} }
}; };
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Helper structure for popping elements from the stack. Uses default global VM instead.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct SqPopGuardLite
{
SQInteger mNum{0}; // The number of elements to be popped.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Base constructor.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
explicit SqPopGuardLite(SQInteger num) noexcept
: mNum(num)
{
//...
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Destructor. Pops the specified elements from the stack.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
~SqPopGuardLite()
{
sq_pop(SqVM(), mNum);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Increment the number of elements to be popped.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SqPopGuardLite & operator ++ ()
{
++mNum;
return *this;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Decrement the number of elements to be popped.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SqPopGuardLite & operator -- ()
{
--mNum;
return *this;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Increase the number of elements to be popped.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SqPopGuardLite & operator += (SQInteger n)
{
mNum += n;
return *this;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Decrease the number of elements to be popped.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SqPopGuardLite & operator -= (SQInteger n)
{
mNum -= n;
return *this;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Helper structure for popping elements from the stack. /// Helper structure for popping elements from the stack.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct SqPopGuard struct SqPopGuard
{ {
HSQUIRRELVM mVM; // The VM from which the elements must be popped. HSQUIRRELVM mVM{nullptr}; // The VM from which the elements must be popped.
SQInteger mNum; // The number of elements to be popped. SQInteger mNum{0}; // The number of elements to be popped.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Base constructor. /// Base constructor.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1659,17 +1736,79 @@ struct SqPopGuard
} }
}; };
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Implements RAII to restore the VM stack to it's initial size on function exit. Uses default global VM instead.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct StackGuardLite
{
SQInteger mTop{0}; ///< The top of the stack when this instance was created.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Default constructor.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StackGuardLite() noexcept
: mTop(sq_gettop(SqVM()))
{
/* ... */
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copy constructor. (disabled)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StackGuardLite(const StackGuardLite &) = delete;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Move constructor. (disabled)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StackGuardLite(StackGuardLite &&) = delete;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Destructor.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
~StackGuardLite()
{
Restore();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copy assignment operator. (disabled)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StackGuardLite & operator = (const StackGuardLite &) = delete;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Move assignment operator. (disabled)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StackGuardLite & operator = (StackGuardLite &&) = delete;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Restore the stack to what was known to be.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Restore() const
{
auto vm = SqVM();
// Retrieve the new stack top
const SQInteger top = sq_gettop(vm);
// Did the stack size change?
if (top > mTop)
{
sq_pop(vm, top - mTop); // Trim the stack
}
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Implements RAII to restore the VM stack to it's initial size on function exit. /// Implements RAII to restore the VM stack to it's initial size on function exit.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct StackGuard struct StackGuard
{ {
HSQUIRRELVM mVM{nullptr}; ///< The VM where the stack should be restored.
SQInteger mTop{0}; ///< The top of the stack when this instance was created.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Default constructor. /// Default constructor.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StackGuard() StackGuard()
: m_VM(SqVM()), m_Top(sq_gettop(m_VM)) : mVM(SqVM()), mTop(sq_gettop(mVM))
{ {
/* ... */ /* ... */
} }
@@ -1677,8 +1816,8 @@ struct StackGuard
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Base constructor. /// Base constructor.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StackGuard(HSQUIRRELVM vm) explicit StackGuard(HSQUIRRELVM vm)
: m_VM(vm), m_Top(sq_gettop(vm)) : mVM(vm), mTop(sq_gettop(vm))
{ {
/* ... */ /* ... */
} }
@@ -1717,18 +1856,13 @@ struct StackGuard
void Restore() const void Restore() const
{ {
// Retrieve the new stack top // Retrieve the new stack top
const SQInteger top = sq_gettop(m_VM); const SQInteger top = sq_gettop(mVM);
// Did the stack size change? // Did the stack size change?
if (top > m_Top) if (top > mTop)
{ {
sq_pop(m_VM, top - m_Top); // Trim the stack sq_pop(mVM, top - mTop); // Trim the stack
} }
} }
private:
HSQUIRRELVM m_VM; ///< The VM where the stack should be restored.
SQInteger m_Top; ///< The top of the stack when this instance was created.
}; };
@@ -2131,18 +2265,13 @@ inline void ErrorToException(HSQUIRRELVM vm, bool keep = false) {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template < typename T > struct DeleteGuard template < typename T > struct DeleteGuard
{ {
private: T * mPtr; // Pointer to the instance to manage.
// --------------------------------------------------------------------------------------------
T * m_Ptr; // Pointer to the instance to manage.
public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Default constructor. /// Default constructor.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
explicit DeleteGuard(T * ptr) explicit DeleteGuard(T * ptr)
: m_Ptr(ptr) : mPtr(ptr)
{ {
/* ... */ /* ... */
} }
@@ -2152,7 +2281,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class... A> template<class... A>
explicit DeleteGuard(SqInPlace SQ_UNUSED_ARG(t), A&&... a) explicit DeleteGuard(SqInPlace SQ_UNUSED_ARG(t), A&&... a)
: m_Ptr(new T(std::forward< A >(a)...)) : mPtr(new T(std::forward< A >(a)...))
{ {
/* ... */ /* ... */
} }
@@ -2166,9 +2295,9 @@ public:
/// Move constructor. /// Move constructor.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DeleteGuard(DeleteGuard && o) noexcept DeleteGuard(DeleteGuard && o) noexcept
: m_Ptr(o.m_Ptr) : mPtr(o.mPtr)
{ {
o.m_Ptr = nullptr; o.mPtr = nullptr;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2176,9 +2305,9 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
~DeleteGuard() ~DeleteGuard()
{ {
if (m_Ptr) if (mPtr)
{ {
delete m_Ptr; delete mPtr;
} }
} }
@@ -2197,7 +2326,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
operator T * () const operator T * () const
{ {
return m_Ptr; return mPtr;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2205,7 +2334,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
T * Get() const T * Get() const
{ {
return m_Ptr; return mPtr;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2213,7 +2342,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Release() void Release()
{ {
m_Ptr = nullptr; mPtr = nullptr;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2221,8 +2350,8 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
T * Grab() T * Grab()
{ {
T * ptr = m_Ptr; T * ptr = mPtr;
m_Ptr = nullptr; mPtr = nullptr;
return ptr; return ptr;
} }
}; };
@@ -2320,18 +2449,13 @@ template < typename T > T * SqChainedInstances< T >::sHead = nullptr;
/// @cond DEV /// @cond DEV
/// Used internally to get and manipulate the underlying type of variables - retrieved from cppreference.com /// Used internally to get and manipulate the underlying type of variables - retrieved from cppreference.com
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T> struct remove_const {typedef T type;}; template<class T> using remove_const = std::remove_const< T >;
template<class T> struct remove_const<const T> {typedef T type;}; template<class T> using remove_volatile = std::remove_volatile< T >;
template<class T> struct remove_volatile {typedef T type;}; template<class T> using remove_cv = std::remove_cv< T >;
template<class T> struct remove_volatile<volatile T> {typedef T type;}; template<class T> struct is_pointer : public std::is_pointer< T > { };
template<class T> struct remove_cv {typedef typename remove_volatile<typename remove_const<T>::type>::type type;}; template<class T,class D> struct is_pointer<SharedPtr<T,D> > : public std::true_type { };
template<class T> struct is_pointer_helper {static constexpr bool value = false;}; template<class T,class D> struct is_pointer<WeakPtr<T,D> > : public std::true_type { };
template<class T> struct is_pointer_helper<T*> {static constexpr bool value = true;}; template<class T> using is_reference = std::is_lvalue_reference< T >;
template<class T,class D> struct is_pointer_helper<SharedPtr<T,D> > {static constexpr bool value = true;};
template<class T,class D> struct is_pointer_helper<WeakPtr<T,D> > {static constexpr bool value = true;};
template<class T> struct is_pointer : is_pointer_helper<typename remove_cv<T>::type> {};
template<class T> struct is_reference {static constexpr bool value = false;};
template<class T> struct is_reference<T&> {static constexpr bool value = true;};
/// @endcond /// @endcond