1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2026-07-17 22:17:10 +02:00

126 Commits

Author SHA1 Message Date
Sandu Liviu Catalin 483ac37bdb Update CMakeLists.txt
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
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.
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
Sandu Liviu Catalin 5a57bf2fbf Prevent double closing event in web-sockets.
continuous-integration/drone/push Build was killed
2022-08-14 20:29:32 +03:00
Sandu Liviu Catalin 15e85f1394 Update Net.hpp 2022-08-14 20:11:53 +03:00
Sandu Liviu Catalin e8fa9e0259 Update sqratLightObj.h 2022-08-14 18:53:36 +03:00
Sandu Liviu Catalin c551390999 Helper Base32/64 methods on SqBufer type. 2022-08-14 18:53:28 +03:00
Sandu Liviu Catalin 804a5abb29 Update Official.cpp
continuous-integration/drone/push Build was killed
2022-07-23 23:17:31 +03:00
Sandu Liviu Catalin 68551e4466 Allow either player type for announcing in legacy mode. 2022-07-23 23:16:53 +03:00
Sandu Liviu Catalin 4618577ae4 Implement .Legacy member for native entity types. 2022-07-23 22:09:30 +03:00
Sandu Liviu Catalin 2f428962c8 Update Official.cpp 2022-07-23 21:55:46 +03:00
Sandu Liviu Catalin 34a78dc166 More work on async statements for SQLite. 2022-07-23 21:41:10 +03:00
Sandu Liviu Catalin 49df7b75ee Asynchronous statements implementation for SQLite.
Extend worker threads to allow tasks to re-queue themselves during completion.
2022-07-23 19:27:40 +03:00
Sandu Liviu Catalin 0d927f5d72 Remove log. 2022-07-23 17:50:58 +03:00
Sandu Liviu Catalin 44243aadd2 Fix removal of non alpha-numeric characters from strings. 2022-07-23 17:42:01 +03:00
Sandu Liviu Catalin aa3952fd45 Update SqBase.hpp
continuous-integration/drone/push Build was killed
2022-07-21 23:45:09 +03:00
Sandu Liviu Catalin ebe60ebf4b Update Data.cpp
continuous-integration/drone/push Build was killed
2022-07-19 20:03:00 +03:00
Sandu Liviu Catalin fa9c3a5821 Check for a valid session pointer. 2022-07-19 19:43:30 +03:00
Sandu Liviu Catalin f238588abe More work on async sql.
Current implementation only provides execution for sqlite queries in worker threads. Statements and MySQL is on the TODO list.
2022-07-19 19:29:32 +03:00
Sandu Liviu Catalin 39524098f1 Extend worker pool.
Task exceptions are caught and they can provide custom information to identify the task that failed.
Take ownership of the task instance sooner.
2022-07-19 19:28:13 +03:00
Sandu Liviu Catalin ea63899c9a Mark unreachable code. 2022-07-04 20:05:21 +03:00
Sandu Liviu Catalin 8f11e08150 Allow session pool to be used with legacy database wrappers (experimental). 2022-07-04 19:39:41 +03:00
Sandu Liviu Catalin b8b5e89216 Update sqmem.cpp 2022-06-25 02:31:05 +03:00
Sandu Liviu Catalin 87387999f3 Remove old POCO RegEx. 2022-06-25 02:30:33 +03:00
Sandu Liviu Catalin d6a56feb87 Update sqmem.cpp 2022-06-25 00:35:57 +03:00
Sandu Liviu Catalin 9c94fb7afc Update CMakeLists.txt 2022-06-25 00:35:53 +03:00
Sandu Liviu Catalin 2f3684e251 Update sqratMemberMethods.h 2022-06-25 00:35:44 +03:00
Sandu Liviu Catalin 7afc05e52b Add rpmalloc as a thread-safe alternative. 2022-06-24 22:51:20 +03:00
Sandu Liviu Catalin eca11b73ba Update SimpleIni.h 2022-06-24 22:49:23 +03:00
Sandu Liviu Catalin 5c54dc6a95 Update sqratClass.h 2022-06-24 22:49:09 +03:00
Sandu Liviu Catalin 9330cd4eb3 Update Weapon.cpp 2022-06-24 22:49:03 +03:00
Sandu Liviu Catalin 7576409ceb Update Vehicle.cpp 2022-06-24 22:48:58 +03:00
Sandu Liviu Catalin f278d151d6 Update Player.cpp 2022-06-24 22:48:54 +03:00
Sandu Liviu Catalin b3b57d5b2b Update VecMap.hpp 2022-06-24 22:48:48 +03:00
Sandu Liviu Catalin c4130c589f Update ThreadPool.hpp 2022-06-23 21:50:23 +03:00
Sandu Liviu Catalin 2d24860905 Update RegEx.hpp 2022-06-23 21:07:52 +03:00
Sandu Liviu Catalin eb90d9bc99 Update Net.hpp 2022-06-23 21:07:48 +03:00
Sandu Liviu Catalin b87e68b9fc Add an extra method to the logger. 2022-06-23 21:07:44 +03:00
Sandu Liviu Catalin a1a71ee031 Validate sub-str range. 2022-06-13 04:00:41 +03:00
Sandu Liviu Catalin c4b9b4c0a5 Basic implementation of PCRE.
Just the foundation is currently implemented. Utilities are to be added with time.
2022-06-13 03:51:39 +03:00
Sandu Liviu Catalin b3f9f9e47a Fix entity quaternion properties.
Vector flag enumeration was used instead of Quaternion flag enumeration.
2022-03-22 21:11:17 +02:00
Sandu Liviu Catalin a2421afca1 Fix player iteration. 2022-03-19 23:51:34 +02:00
Sandu Liviu Catalin e2cbd7d5cf Update SQLite. 2022-03-16 22:37:44 +02:00
Sandu Liviu Catalin 2725387112 Update MySQL.hpp 2022-03-16 22:36:50 +02:00
Sandu Liviu Catalin 7248351469 Update Areas.cpp 2022-03-16 22:36:48 +02:00
Sandu Liviu Catalin e253dc2038 Update formatting library. 2022-03-16 22:36:44 +02:00
Sandu Liviu Catalin 38f0a53cd8 Fix areas with a temporary workaround. 2022-03-16 21:58:00 +02:00
Sandu Liviu Catalin 1c7fee69ea Update RegEx.cpp 2022-03-16 18:33:49 +02:00
Sandu Liviu Catalin 2b85b3a035 Update Signal.cpp 2022-03-16 17:21:53 +02:00
Sandu Liviu Catalin 11fb1fa25c Update Events.inc 2022-03-16 17:02:11 +02:00
Sandu Liviu Catalin 8dc0ca18f5 Minor changes. 2022-03-09 22:59:19 +02:00
Sandu Liviu Catalin 7e39fab21a Reuse method. 2022-03-09 22:41:00 +02:00
Sandu Liviu Catalin da139c6a81 Update XML.hpp 2022-03-09 22:37:06 +02:00
Sandu Liviu Catalin 27521f209d Fix return value. 2022-03-09 22:33:35 +02:00
Sandu Liviu Catalin e6cbdfaf30 Allow XML chaining. 2022-03-09 22:25:51 +02:00
Sandu Liviu Catalin fd62cafe33 Update XML.cpp 2022-03-09 22:11:03 +02:00
Sandu Liviu Catalin d749250e1b Update INI.cpp 2022-03-06 20:02:01 +02:00
Sandu Liviu Catalin c205261ee9 Update INI.cpp 2022-03-06 20:01:13 +02:00
Sandu Liviu Catalin 4af93aff14 Allow tasks to also be identified by their tag.
Change the behavior of DropTask to return boolean.
2022-03-02 18:57:11 +02:00
Sandu Liviu Catalin d246ee8430 Update Dir.hpp 2022-01-28 15:23:48 +02:00
Sandu Liviu Catalin 6419fc0f4d Add Elapsed and Remaining properties to routine.
continuous-integration/drone/push Build was killed
2021-11-10 17:30:21 +02:00
Sandu Liviu Catalin 0213ffe632 Update Official.cpp 2021-11-10 16:58:13 +02:00
Sandu Liviu Catalin 5f364605ab Update Official.cpp 2021-11-10 16:50:38 +02:00
Sandu Liviu Catalin 3e9f25502b Remove DPP.
continuous-integration/drone/push Build was killed
2021-09-23 22:18:24 +03:00
Sandu Liviu Catalin 1d85603dfb Expose DPP message embeds.
continuous-integration/drone/push Build was killed
2021-09-23 22:13:13 +03:00
Sandu Liviu Catalin 259af04d0e Disable Discord until implemented.
continuous-integration/drone/push Build is passing
2021-09-21 21:11:12 +03:00
Sandu Liviu Catalin 4d1971d66b Disable the option by default. 2021-09-21 21:05:08 +03:00
Sandu Liviu Catalin b4bf96ce4b Add MariaDB Connector/C as a built-in alternative (v3.2.3). 2021-09-21 20:59:01 +03:00
Sandu Liviu Catalin f192767853 Update UTF8.cpp 2021-09-19 17:40:55 +03:00
Sandu Liviu Catalin a58b9fe267 Expose more DPP message types. 2021-09-19 14:24:15 +03:00
Sandu Liviu Catalin 4a8a7172d4 Add UTF8 library. 2021-09-19 14:23:47 +03:00
Sandu Liviu Catalin cae745378d Update Utilities.hpp 2021-09-19 14:21:57 +03:00
Sandu Liviu Catalin 62b9504d43 Expose DPP message component. 2021-09-19 01:08:39 +03:00
Sandu Liviu Catalin 26ccfa62b9 Add std::vector proxy type. 2021-09-19 01:08:19 +03:00
Sandu Liviu Catalin 83f2ab79e0 Update Guild.hpp 2021-09-18 21:35:42 +03:00
Sandu Liviu Catalin 57321af0c7 Update Message.hpp 2021-09-18 21:35:38 +03:00
Sandu Liviu Catalin 8d908208f0 Update Other.hpp 2021-09-18 21:35:34 +03:00
Sandu Liviu Catalin 87cb6a2cba Update Role.hpp 2021-09-18 21:35:30 +03:00
Sandu Liviu Catalin 0487f26865 Update User.hpp 2021-09-18 21:35:27 +03:00
Sandu Liviu Catalin e3c32e4788 DPP update fixes. 2021-09-18 21:24:49 +03:00
Sandu Liviu Catalin b978bc5046 Update DPP. 2021-09-18 21:19:56 +03:00
Sandu Liviu Catalin 0f235ff6af Merge pull request #54 from theKAKAN/patch-2
Fix team kill and normal kill swapped
2021-09-12 22:38:01 +03:00
Sandu Liviu Catalin 7057939854 Add more flexible string to integer and float conversion. 2021-09-12 22:28:42 +03:00
KAKAN eb3100de36 Fix team kill and normal kill swapped
onPlayerKill and onPlayerTeamKill were swapped
2021-09-12 19:06:28 +00:00
Sandu Liviu Catalin f72c0f896e Merge pull request #53 from theKAKAN/patch-1
Fixes `SetSpawnCameraLookAtEx` not working as intended
2021-09-12 21:17:14 +03:00
KAKAN 0d323f4a26 Fixes SetSpawnCameraLookAtEx not working as intended
`SetSpawnCameraLookAtEx` was basically the same as `SetSpawnPlayerPositionEx`
2021-09-12 17:46:49 +00:00
Sandu Liviu Catalin 0c4c78da6e Define discord message types. 2021-09-12 19:32:07 +03:00
Sandu Liviu Catalin 2011631e78 Update Constants.cpp 2021-09-12 18:51:25 +03:00
Sandu Liviu Catalin 801ccbd6cd Update Guild.hpp 2021-09-12 18:51:22 +03:00
Sandu Liviu Catalin 9062121cc8 Update Other.hpp 2021-09-12 18:51:19 +03:00
Sandu Liviu Catalin 596da38403 Update Role.hpp 2021-09-12 18:51:16 +03:00
Sandu Liviu Catalin aa2a8f32d1 Update User.hpp 2021-09-12 18:51:13 +03:00
Sandu Liviu Catalin 13fc02e9ca Restructure discord API files. 2021-09-12 17:53:57 +03:00
Sandu Liviu Catalin 17875509c0 Update CMakeLists.txt 2021-09-12 16:12:30 +03:00
Sandu Liviu Catalin 5df55164ee Update Vehicle.cpp 2021-09-12 16:03:38 +03:00
Sandu Liviu Catalin 45570af13b Update Player.cpp 2021-09-12 16:03:31 +03:00
Sandu Liviu Catalin 949e5e61d0 Change the order of custom Pickup events to happen before performing the action. 2021-09-12 16:03:23 +03:00
Sandu Liviu Catalin e4aa96a8c3 Change the order of custom Object events to happen before performing the action. 2021-09-12 16:03:17 +03:00
Sandu Liviu Catalin e60e2958f0 Change the order of custom Checkpoint events to happen before performing the action. 2021-09-12 16:02:46 +03:00
Sandu Liviu Catalin dfee411de5 Emulate embarking event when done from server-side.
Also change the order of other events to happen before performing the action.
2021-09-12 15:55:55 +03:00
Sandu Liviu Catalin 37383b9383 Emulate embarking event when done from server-side.
Also change the order of other events to happen before performing the action.
2021-09-12 15:49:29 +03:00
Sandu Liviu Catalin ba4b8524e5 Update SQLite.cpp 2021-09-12 15:13:20 +03:00
Sandu Liviu Catalin f1ef37bdf3 Fix sqlite3_snprintf not having a room for a null terminator in the buffer. 2021-09-12 15:12:35 +03:00
Sandu Liviu Catalin 9235cb5069 Update Official.cpp
Allow null in `SpectateTarget` property to match official plugin.
2021-09-12 14:52:49 +03:00
Sandu Liviu Catalin 4e27ba4a4f Expose role type. 2021-09-11 23:16:14 +03:00
Sandu Liviu Catalin 19102a9334 Implement base layout for all events. 2021-09-11 22:43:30 +03:00
Sandu Liviu Catalin 1d8d31518c Refactor presence and activity types. 2021-09-11 21:38:46 +03:00
Sandu Liviu Catalin a19a171e0d Expose user type. 2021-09-11 21:18:45 +03:00
Sandu Liviu Catalin 4c3921d88a Update sqratTypes.h 2021-09-11 21:02:05 +03:00
Sandu Liviu Catalin e9f5111a33 Expose guild type.
Refactor constants to be more compile time efficient.
2021-09-11 20:36:19 +03:00
Sandu Liviu Catalin 08a5ba3154 Update sqratObject.h 2021-09-11 20:35:27 +03:00
Sandu Liviu Catalin 13a7a98abe Update sqratArray.h 2021-09-11 20:35:22 +03:00
671 changed files with 120423 additions and 74776 deletions
+2 -2
View File
@@ -12,9 +12,9 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/vendor/POCO/cmake)
# Several plugin options # Several plugin options
option(ENABLE_API21 "Build for 2.1 API." OFF) option(ENABLE_API21 "Build for 2.1 API." OFF)
option(ENABLE_DISCORD "Enable built-in Discord support" ON)
option(ENABLE_DISCORD_VOICE "Enable voice support in Discord library" OFF)
option(ENABLE_OFFICIAL "Enable compatibility with official legacy plug-in" ON) option(ENABLE_OFFICIAL "Enable compatibility with official legacy plug-in" ON)
# As a fall-back for certain situations (mainly some docker ubuntu containers)
option(ENABLE_BUILTIN_MYSQL_C "Enable built-in MySQL connector library" OFF)
#option(FORCE_32BIT_BIN "Create a 32-bit executable binary if the compiler defaults to 64-bit." OFF) #option(FORCE_32BIT_BIN "Create a 32-bit executable binary if the compiler defaults to 64-bit." OFF)
# This option should only be available in certain conditions # This option should only be available in certain conditions
if(WIN32 AND MINGW) if(WIN32 AND MINGW)
+17
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 >)
+5
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.
*/ */
+15
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 >)
+5
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.
*/ */
+15
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 >)
+5
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.
*/ */
+15
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 >)
+5
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.
*/ */
+15
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 >)
+5
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.
*/ */
+3
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.
*/ */
+15
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 >)
+5
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.
*/ */
+15
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 >)
+5
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.
*/ */
+15
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 >)
+5
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.
*/ */
+15
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 >)
+5
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.
*/ */
+15
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 >)
+5
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.
*/ */
+19 -12
View File
@@ -80,11 +80,13 @@ add_library(SqModule MODULE SqBase.hpp Main.cpp
Library/Numeric.cpp Library/Numeric.hpp Library/Numeric.cpp Library/Numeric.hpp
Library/Numeric/Math.cpp Library/Numeric/Math.hpp Library/Numeric/Math.cpp Library/Numeric/Math.hpp
Library/Numeric/Random.cpp Library/Numeric/Random.hpp Library/Numeric/Random.cpp Library/Numeric/Random.hpp
Library/RegEx.cpp Library/RegEx.hpp
Library/String.cpp Library/String.hpp Library/String.cpp Library/String.hpp
Library/System.cpp Library/System.hpp Library/System.cpp Library/System.hpp
Library/System/Dir.cpp Library/System/Dir.hpp Library/System/Dir.cpp Library/System/Dir.hpp
Library/System/Env.cpp Library/System/Env.hpp Library/System/Env.cpp Library/System/Env.hpp
Library/System/Path.cpp Library/System/Path.hpp Library/System/Path.cpp Library/System/Path.hpp
Library/UTF8.cpp Library/UTF8.hpp
Library/Utils.cpp Library/Utils.hpp Library/Utils.cpp Library/Utils.hpp
Library/Utils/Announce.cpp Library/Utils/Announce.hpp Library/Utils/Announce.cpp Library/Utils/Announce.hpp
Library/Utils/String.cpp Library/Utils/String.hpp Library/Utils/String.cpp Library/Utils/String.hpp
@@ -105,7 +107,6 @@ add_library(SqModule MODULE SqBase.hpp Main.cpp
PocoLib/Crypto.cpp PocoLib/Crypto.hpp PocoLib/Crypto.cpp PocoLib/Crypto.hpp
PocoLib/Data.cpp PocoLib/Data.hpp PocoLib/Data.cpp PocoLib/Data.hpp
PocoLib/Net.cpp PocoLib/Net.hpp PocoLib/Net.cpp PocoLib/Net.hpp
PocoLib/RegEx.cpp PocoLib/RegEx.hpp
PocoLib/Register.cpp PocoLib/Register.hpp PocoLib/Register.cpp PocoLib/Register.hpp
PocoLib/Time.cpp PocoLib/Time.hpp PocoLib/Time.cpp PocoLib/Time.hpp
PocoLib/Util.cpp PocoLib/Util.hpp PocoLib/Util.cpp PocoLib/Util.hpp
@@ -131,15 +132,9 @@ if(WIN32 OR MINGW)
target_link_libraries(SqModule wsock32 ws2_32 shlwapi) target_link_libraries(SqModule wsock32 ws2_32 shlwapi)
endif() endif()
# Link to base libraries # Link to base libraries
target_link_libraries(SqModule Squirrel fmt::fmt SimpleINI TinyDir xxHash ConcurrentQueue SAJSON CPR PUGIXML CivetWeb maxminddb libzmq-static) target_link_libraries(SqModule RPMalloc Squirrel fmt::fmt SimpleINI TinyDir xxHash ConcurrentQueue SAJSON CPR UTF8Lib PUGIXML CivetWeb maxminddb libzmq-static)
# Enable built-in Discord support
if(ENABLE_DISCORD)
target_link_libraries(SqModule DPP)
target_compile_definitions(SqModule PRIVATE VCMP_ENABLE_DISCORD=1)
target_sources(SqModule PRIVATE Library/DPP.cpp Library/DPP.hpp Library/DPPEv.cpp Library/DPPEv.hpp Library/DPPTy.cpp Library/DPPTy.hpp)
endif()
# Link to POCO libraries # Link to POCO libraries
target_link_libraries(SqModule Poco::Foundation Poco::Crypto Poco::Data Poco::Net Poco::JSON Poco::XML) target_link_libraries(SqModule Poco::Foundation Poco::Crypto Poco::Data Poco::Net)
# Does POCO have SQLite support? # Does POCO have SQLite support?
if(ENABLE_DATA_SQLITE) if(ENABLE_DATA_SQLITE)
if(NOT POCO_UNBUNDLED) if(NOT POCO_UNBUNDLED)
@@ -154,9 +149,12 @@ if(ENABLE_DATA_SQLITE)
# Include legacy implementation sources # Include legacy implementation sources
target_sources(SqModule PRIVATE Library/SQLite.hpp Library/SQLite.cpp) target_sources(SqModule PRIVATE Library/SQLite.hpp Library/SQLite.cpp)
endif() endif()
# Do we have built-in MYSQL enabled?
if (NOT ENABLE_BUILTIN_MYSQL_C)
find_package(MySQL)
endif()
# Does POCO have MySLQ support? # Does POCO have MySLQ support?
find_package(MySQL) if(ENABLE_BUILTIN_MYSQL_C OR MYSQL_FOUND)
if(MYSQL_FOUND)
message(STATUS "MySQL was enabled") message(STATUS "MySQL was enabled")
# Link the libraries # Link the libraries
target_link_libraries(SqModule Poco::DataMySQL) target_link_libraries(SqModule Poco::DataMySQL)
@@ -205,6 +203,15 @@ endif(WIN32)
target_include_directories(SqModule PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(SqModule PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(SqModule PRIVATE ${CMAKE_CURRENT_LIST_DIR}/VCMP) target_include_directories(SqModule PRIVATE ${CMAKE_CURRENT_LIST_DIR}/VCMP)
target_include_directories(SqModule PRIVATE ${CMAKE_CURRENT_LIST_DIR}/Sqrat) target_include_directories(SqModule PRIVATE ${CMAKE_CURRENT_LIST_DIR}/Sqrat)
# Include PCRE directory in the header search path
if (POCO_UNBUNDLED)
find_package(PCRE REQUIRED)
target_link_libraries(SqModule PRIVATE Pcre::Pcre)
else()
# Get the foundation source folder path
get_target_property(POCO_FOUNDATION_SOURCE_DIR Foundation SOURCE_DIR)
target_include_directories(SqModule PRIVATE "${POCO_FOUNDATION_SOURCE_DIR}/src")
endif()
# Copy module into the plug-ins folder # Copy module into the plug-ins folder
add_custom_command(TARGET SqModule POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:SqModule> "${PROJECT_SOURCE_DIR}/bin/plugins") add_custom_command(TARGET SqModule POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:SqModule> "${PROJECT_SOURCE_DIR}/bin/plugins")
# Copy several dependent DLLs on windows to make distribution easier (used mainly by people that distribute builds) # Copy several dependent DLLs on windows to make distribution easier (used mainly by people that distribute builds)
@@ -220,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")
-8
View File
@@ -49,9 +49,6 @@ extern void TerminateRoutines();
extern void TerminateCommands(); extern void TerminateCommands();
extern void TerminateSignals(); extern void TerminateSignals();
extern void TerminateNet(); extern void TerminateNet();
#ifdef VCMP_ENABLE_DISCORD
extern void TerminateDPP();
#endif
extern void TerminatePocoNet(); extern void TerminatePocoNet();
extern void TerminatePocoData(); extern void TerminatePocoData();
@@ -552,11 +549,6 @@ void Core::Terminate(bool shutdown)
// Release announcers // Release announcers
AnnounceTerminate(); AnnounceTerminate();
cLogDbg(m_Verbosity >= 1, "Announcer terminated"); cLogDbg(m_Verbosity >= 1, "Announcer terminated");
// Release DPP
#ifdef VCMP_ENABLE_DISCORD
TerminateDPP();
cLogDbg(m_Verbosity >= 1, "Discord terminated");
#endif
// Release network // Release network
TerminateNet(); TerminateNet();
cLogDbg(m_Verbosity >= 1, "Network terminated"); cLogDbg(m_Verbosity >= 1, "Network terminated");
+70 -5
View File
@@ -993,28 +993,93 @@ template < class F > inline void ForeachActivePickup(F f) { ForeachActiveEntity(
template < class F > inline void ForeachActivePlayer(F f) { ForeachActiveEntity(Core::Get().GetPlayers(), std::forward< F >(f)); } template < class F > inline void ForeachActivePlayer(F f) { ForeachActiveEntity(Core::Get().GetPlayers(), std::forward< F >(f)); }
template < class F > inline void ForeachActiveVehicle(F f) { ForeachActiveEntity(Core::Get().GetVehicles(), std::forward< F >(f)); } template < class F > inline void ForeachActiveVehicle(F f) { ForeachActiveEntity(Core::Get().GetVehicles(), std::forward< F >(f)); }
/* ------------------------------------------------------------------------------------------------
* Process the identifier of each player slot.
*/
template < class F > inline void ForeachPlayerSlot(F f) {
for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) {
f(i);
}
}
/* ------------------------------------------------------------------------------------------------
* Process the identifier of each player slot and count processed players.
*/
template < class F > SQMOD_NODISCARD inline int32_t ForeachPlayerSlotCount(F f) {
int32_t c = 0;
for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) {
if (f(i)) ++c;
}
return c;
}
/* ------------------------------------------------------------------------------------------------
* Process the identifier of each player slot until a certain criteria is met.
*/
template < class F > SQMOD_NODISCARD inline int32_t ForeachPlayerSlotUntil(F f) {
for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) {
if (f(i)) return i;
}
return -1;
}
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Process the identifier of each connected player. * Process the identifier of each connected player.
*/ */
template < class F > inline void ForeachConnectedPlayer(F f) { template < class F > inline void ForeachConnectedPlayer(F f) {
for (int32_t i = 0, n = _Func->GetMaxPlayers(); i < n; ++i) f(i); for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) {
if (_Func->IsPlayerConnected(i) != 0) f(i);
}
} }
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Process the identifier of each connected player and count processed players. * Process the identifier of each connected player and count processed players.
*/ */
template < class F > SQMOD_NODISCARD inline int32_t ForeachConnectedPlayerCount(F f) { template < class F > SQMOD_NODISCARD inline int32_t ForeachConnectedPlayerCount(F f) {
int32_t c = 0; int32_t c = 0;
for (int32_t i = 0, n = _Func->GetMaxPlayers(); i < n; ++i) for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) {
if (f(i)) ++c; if (_Func->IsPlayerConnected(i) != 0 && f(i)) ++c;
}
return c; return c;
} }
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Process the identifier of each connected player until a certain criteria is met. * Process the identifier of each connected player until a certain criteria is met.
*/ */
template < class F > SQMOD_NODISCARD inline int32_t ForeachConnectedPlayerUntil(F f) { template < class F > SQMOD_NODISCARD inline int32_t ForeachConnectedPlayerUntil(F f) {
for (int32_t i = 0, n = _Func->GetMaxPlayers(); i < n; ++i) for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) {
if (f(i)) return i; if (_Func->IsPlayerConnected(i) != 0 && f(i)) return i;
}
return -1; return -1;
} }
/* ------------------------------------------------------------------------------------------------
* Used to select entity instances based on type.
*/
template < class > struct EntityInstSelect;
// Specialization for blips.
template < > struct EntityInstSelect< CBlip > {
static BlipInst & Get(int32_t id) { return Core::Get().GetBlip(id); }
};
// Specialization for checkpoints.
template < > struct EntityInstSelect< CCheckpoint > {
static CheckpointInst & Get(int32_t id) { return Core::Get().GetCheckpoint(id); }
};
// Specialization for keybinds.
template < > struct EntityInstSelect< CKeyBind > {
static KeyBindInst & Get(int32_t id) { return Core::Get().GetKeyBind(id); }
};
// Specialization for objects.
template < > struct EntityInstSelect< CObject > {
static ObjectInst & Get(int32_t id) { return Core::Get().GetObj(id); }
};
// Specialization for pickups.
template < > struct EntityInstSelect< CPickup > {
static PickupInst & Get(int32_t id) { return Core::Get().GetPickup(id); }
};
// Specialization for players.
template < > struct EntityInstSelect< CPlayer > {
static PlayerInst & Get(int32_t id) { return Core::Get().GetPlayer(id); }
};
// Specialization for vehicles.
template < > struct EntityInstSelect< CVehicle > {
static VehicleInst & Get(int32_t id) { return Core::Get().GetVehicle(id); }
};
} // Namespace:: SqMod } // Namespace:: SqMod
+33 -5
View File
@@ -161,7 +161,7 @@ bool Area::IsInside(float x, float y) const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AreaManager::AreaManager(size_t sz) noexcept AreaManager::AreaManager(size_t sz) noexcept
: m_Queue(), m_ProcList(), m_Grid{} : m_Queue(), m_ProcList(), m_Grid{}, m_Cells{}
{ {
// Negative half grid size (left) // Negative half grid size (left)
int l = (-GRIDH * CELLD); int l = (-GRIDH * CELLD);
@@ -171,21 +171,30 @@ AreaManager::AreaManager(size_t sz) noexcept
int r = (l + CELLD); int r = (l + CELLD);
// Positive half grid size (top) // Positive half grid size (top)
int t = abs(l); int t = abs(l);
// Row/Column of the grid
int row = 0, col = 0;
// Initialize the grid cells // Initialize the grid cells
for (auto & a : m_Grid) for (auto & a : m_Grid)
{ {
// Reset the column
col = 0;
// Process row
for (auto & c : a) for (auto & c : a)
{ {
auto & cx = m_Cells[row][col];
// Grab a reference to the cell // Grab a reference to the cell
// Configure the range of the cell // Configure the range of the cell
c.mL = static_cast< float >(l); c.mL = cx.mL = static_cast< float >(l);
c.mB = static_cast< float >(b); c.mB = cx.mB = static_cast< float >(b);
c.mR = static_cast< float >(r); c.mR = cx.mR = static_cast< float >(r);
c.mT = static_cast< float >(t); c.mT = cx.mT = static_cast< float >(t);
// Reserve area memory if requested // Reserve area memory if requested
c.mAreas.reserve(sz); c.mAreas.reserve(sz);
// Reset the locks on this area // Reset the locks on this area
c.mLocks = 0; c.mLocks = 0;
// Set the row and column
c.mRow = row;
c.mCol = col++;
// Advance the left side // Advance the left side
l = r; l = r;
// Advance the right side // Advance the right side
@@ -203,6 +212,8 @@ AreaManager::AreaManager(size_t sz) noexcept
t -= CELLD; t -= CELLD;
} }
} }
// Advance row
++row;
} }
// Reserve some space in the queue // Reserve some space in the queue
m_Queue.reserve(128); m_Queue.reserve(128);
@@ -340,6 +351,21 @@ void AreaManager::RemoveArea(Area & a)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Vector2i AreaManager::LocateCell(float x, float y) Vector2i AreaManager::LocateCell(float x, float y)
{ {
for (int r = 0; r < GRIDN; ++r)
{
for (int c = 0; c < GRIDN; ++c)
{
auto & bb = m_Cells[r][c];
// Check whether point is inside cell
if (bb.mL <= x && bb.mR >= x && bb.mB <= y && bb.mT >= y)
{
return {r, c}; // Is inside
}
}
}
// Point is out of bounds
return {NOCELL, NOCELL};
/*
// Transform the world coordinates into a cell coordinates // Transform the world coordinates into a cell coordinates
// and cast to integral after rounding the value // and cast to integral after rounding the value
int xc = static_cast< int >(std::round(x / CELLD)); int xc = static_cast< int >(std::round(x / CELLD));
@@ -364,6 +390,7 @@ Vector2i AreaManager::LocateCell(float x, float y)
} }
// Return the identified cell row and column // Return the identified cell row and column
return {GRIDH+xc, GRIDH-yc}; return {GRIDH+xc, GRIDH-yc};
*/
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -469,6 +496,7 @@ void Register_Areas(HSQUIRRELVM vm)
.Func(_SC("TestEx"), &Area::TestEx) .Func(_SC("TestEx"), &Area::TestEx)
.Func(_SC("Manage"), &Area::Manage) .Func(_SC("Manage"), &Area::Manage)
.Func(_SC("Unmanage"), &Area::Unmanage) .Func(_SC("Unmanage"), &Area::Unmanage)
.CbFunc(_SC("EachCell"), &Area::EachCell)
// Static Functions // Static Functions
.StaticFunc(_SC("GlobalTest"), &Areas_TestPoint) .StaticFunc(_SC("GlobalTest"), &Areas_TestPoint)
.StaticFunc(_SC("GlobalTestEx"), &Areas_TestPointEx) .StaticFunc(_SC("GlobalTestEx"), &Areas_TestPointEx)
+28 -4
View File
@@ -29,15 +29,25 @@ struct AreaCell
Areas mAreas; // Areas that intersect with the cell. Areas mAreas; // Areas that intersect with the cell.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
int mLocks; // The amount of locks on the cell. int mLocks; // The amount of locks on the cell.
int mRow; // Row location in the grid.
int mCol; // Column location in the grid.
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Default constructor. * Default constructor.
*/ */
AreaCell() AreaCell()
: mL(0), mB(0), mR(0), mT(0), mAreas(0), mLocks(0) : mL(0), mB(0), mR(0), mT(0), mAreas(0), mLocks(0), mRow(0), mCol(0)
{ {
//... //...
} }
/* --------------------------------------------------------------------------------------------
* Show information (mainly for debug purposes).
*/
String Dump()
{
return fmt::format("({} : {} | {} : {}) {} : {}", mL, mB, mR, mT, mRow, mCol);
}
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -454,6 +464,17 @@ struct Area
*/ */
bool Unmanage(); bool Unmanage();
/* --------------------------------------------------------------------------------------------
* Iterate all managed cells through a functor.
*/
void EachCell(Function & fn) const
{
for (const auto & e : mCells)
{
fn.Execute(static_cast< SQInteger >(e->mRow), static_cast< SQInteger >(e->mCol));
}
}
protected: protected:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -610,7 +631,10 @@ private:
ProcList m_ProcList; // Actions ready to be completed. ProcList m_ProcList; // Actions ready to be completed.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
AreaCell m_Grid[GRIDN][GRIDN]; // A grid of area lists. AreaCell m_Grid[GRIDN][GRIDN]; // A grid of area lists.
// --------------------------------------------------------------------------------------------
struct {
float mL, mB, mR, mT;
} m_Cells[GRIDN][GRIDN];
public: public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -664,7 +688,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Clear all cell lists and release any script references. * Clear all cell lists and release any script references.
*/ */
static Vector2i LocateCell(float x, float y); Vector2i LocateCell(float x, float y);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Test a point to see whether it intersects with any areas * Test a point to see whether it intersects with any areas
@@ -679,7 +703,7 @@ public:
return; // Not our problem return; // Not our problem
} }
// Retrieve a reference to the identified cell // Retrieve a reference to the identified cell
AreaCell & c = m_Grid[cc.y][cc.x]; AreaCell & c = m_Grid[cc.x][cc.y];
// Is this cell empty? // Is this cell empty?
if (c.mAreas.empty()) if (c.mAreas.empty())
{ {
+21 -21
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)
+8
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)
{ {
+97 -2
View File
@@ -40,6 +40,7 @@
#include <sqratTable.h> #include <sqratTable.h>
#include <sqratUtil.h> #include <sqratUtil.h>
#include <fmt/core.h> #include <fmt/core.h>
#include <rpmalloc.h>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
@@ -173,7 +174,7 @@ void OutputError(const char * msg, ...);
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Generate a formatted string and throw it as a Sqrat exception. * Generate a formatted string and throw it as a Sqrat exception.
*/ */
template < class... Args > void SqThrowF(Args &&... args) template < class... Args > inline void SqThrowF(Args &&... args)
{ {
throw Sqrat::Exception(fmt::format(std::forward< Args >(args)...)); throw Sqrat::Exception(fmt::format(std::forward< Args >(args)...));
} }
@@ -181,7 +182,7 @@ template < class... Args > void SqThrowF(Args &&... args)
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Generate a formatted string and throw it as a squirrel exception. * Generate a formatted string and throw it as a squirrel exception.
*/ */
template < class... Args > SQRESULT SqThrowErrorF(HSQUIRRELVM vm, Args &&... args) template < class... Args > inline SQRESULT SqThrowErrorF(HSQUIRRELVM vm, Args &&... args)
{ {
String msg; String msg;
try try
@@ -241,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.
*/ */
@@ -266,4 +272,93 @@ SQMOD_NODISCARD SQFloat PopStackFloat(HSQUIRRELVM vm, SQInteger idx);
*/ */
SQMOD_NODISCARD bool SToB(const SQChar * str); SQMOD_NODISCARD bool SToB(const SQChar * str);
/* ------------------------------------------------------------------------------------------------
* RAII allocator initializer.
*/
struct RPMallocInit
{
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
RPMallocInit()
{
if (rpmalloc_initialize() != 0)
{
OutputError("Failed to initialize memory allocator");
}
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
RPMallocInit(const RPMallocInit &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor (disabled).
*/
RPMallocInit(RPMallocInit &&) noexcept = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~RPMallocInit()
{
if (rpmalloc_is_thread_initialized()) rpmalloc_finalize();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
RPMallocInit & operator = (const RPMallocInit &) = delete;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
RPMallocInit & operator = (RPMallocInit &&) noexcept = delete;
};
/* ------------------------------------------------------------------------------------------------
* RAII allocator thread initializer.
*/
struct RPMallocThreadInit
{
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
RPMallocThreadInit()
{
rpmalloc_thread_initialize();
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
RPMallocThreadInit(const RPMallocThreadInit &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor (disabled).
*/
RPMallocThreadInit(RPMallocThreadInit &&) noexcept = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~RPMallocThreadInit()
{
if (rpmalloc_is_thread_initialized()) rpmalloc_thread_finalize(1);
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
RPMallocThreadInit & operator = (const RPMallocThreadInit &) = delete;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
RPMallocThreadInit & operator = (RPMallocThreadInit &&) noexcept = delete;
};
} // Namespace:: SqMod } // Namespace:: SqMod
+3 -2
View File
@@ -392,7 +392,8 @@ void Core::EmitPlayerRequestSpawn(int32_t player_id)
#ifdef VCMP_ENABLE_OFFICIAL #ifdef VCMP_ENABLE_OFFICIAL
if (IsOfficial()) if (IsOfficial())
{ {
ExecuteLegacyEvent(m_VM, _SC("onPlayerRequestSpawn"), _player.mLgObj); LightObj r = EvaluateLegacyEvent(m_VM, _SC("onPlayerRequestSpawn"), _player.mLgObj);
SetState(r.IsNull() ? 1 : r.Cast< int32_t >());
} }
#endif #endif
} }
@@ -444,7 +445,7 @@ void Core::EmitPlayerKilled(int32_t player_id, int32_t killer_id, int32_t reason
#ifdef VCMP_ENABLE_OFFICIAL #ifdef VCMP_ENABLE_OFFICIAL
if (IsOfficial()) if (IsOfficial())
{ {
if (!team_kill) if (team_kill)
{ {
ExecuteLegacyEvent(m_VM, _SC("onPlayerTeamKill"), _killer.mLgObj, _player.mLgObj, reason, static_cast< int32_t >(body_part)); ExecuteLegacyEvent(m_VM, _SC("onPlayerTeamKill"), _killer.mLgObj, _player.mLgObj, reason, static_cast< int32_t >(body_part));
} }
+2
View File
@@ -549,6 +549,8 @@ void Register_Routine(HSQUIRRELVM vm)
.Prop(_SC("Inactive"), &Routine::GetInactive) .Prop(_SC("Inactive"), &Routine::GetInactive)
.Prop(_SC("Persistent"), &Routine::GetPersistent, &Routine::SetPersistent) .Prop(_SC("Persistent"), &Routine::GetPersistent, &Routine::SetPersistent)
.Prop(_SC("Yields"), &Routine::GetYields, &Routine::SetYields) .Prop(_SC("Yields"), &Routine::GetYields, &Routine::SetYields)
.Prop(_SC("Elapsed"), &Routine::GetElapsed)
.Prop(_SC("Remaining"), &Routine::GetRemaining)
.Prop(_SC("Terminated"), &Routine::GetTerminated) .Prop(_SC("Terminated"), &Routine::GetTerminated)
.Prop(_SC("Arguments"), &Routine::GetArguments) .Prop(_SC("Arguments"), &Routine::GetArguments)
// Member Methods // Member Methods
+27 -1
View File
@@ -408,7 +408,6 @@ public:
} }
// Unable to find such routine // Unable to find such routine
STHROWF("Unable to fetch a routine with tag ({}). No such routine", tag.mPtr); STHROWF("Unable to fetch a routine with tag ({}). No such routine", tag.mPtr);
SQ_UNREACHABLE
// Should not reach this point but if it did, we have to return something // Should not reach this point but if it did, we have to return something
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic push #pragma clang diagnostic push
@@ -418,6 +417,7 @@ public:
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
SQ_UNREACHABLE
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -804,6 +804,32 @@ public:
return (m_Slot == SQMOD_MAX_ROUTINES); return (m_Slot == SQMOD_MAX_ROUTINES);
} }
/* --------------------------------------------------------------------------------------------
* Retrieve the time elapsed since the routine was created or invoked.
*/
SQMOD_NODISCARD SQInteger GetElapsed() const
{
if (m_Slot >= SQMOD_MAX_ROUTINES)
{
STHROWF("This instance does not reference a valid routine");
}
// We know it's valid so let's return it
return s_Instances[m_Slot].mInterval - s_Intervals[m_Slot];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the time remaining until the routine is invoked.
*/
SQMOD_NODISCARD SQInteger GetRemaining() const
{
if (m_Slot >= SQMOD_MAX_ROUTINES)
{
STHROWF("This instance does not reference a valid routine");
}
// We know it's valid so let's return it
return s_Intervals[m_Slot];
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the number of arguments to be forwarded. * Retrieve the number of arguments to be forwarded.
*/ */
+1
View File
@@ -1723,6 +1723,7 @@ void Register_Signal(HSQUIRRELVM vm)
.SquirrelFunc(_SC("Eliminate"), &Signal::SqEliminate) .SquirrelFunc(_SC("Eliminate"), &Signal::SqEliminate)
.SquirrelFunc(_SC("EliminateThis"), &Signal::SqEliminateThis) .SquirrelFunc(_SC("EliminateThis"), &Signal::SqEliminateThis)
.SquirrelFunc(_SC("EliminateFunc"), &Signal::SqEliminateFunc) .SquirrelFunc(_SC("EliminateFunc"), &Signal::SqEliminateFunc)
.SquirrelFunc(_SC("Broadcast"), &Signal::SqEmit)
.SquirrelFunc(_SC("Emit"), &Signal::SqEmit) .SquirrelFunc(_SC("Emit"), &Signal::SqEmit)
.SquirrelFunc(_SC("Query"), &Signal::SqQuery) .SquirrelFunc(_SC("Query"), &Signal::SqQuery)
.SquirrelFunc(_SC("Consume"), &Signal::SqConsume) .SquirrelFunc(_SC("Consume"), &Signal::SqConsume)
+40 -9
View File
@@ -328,17 +328,40 @@ SQInteger Tasks::Find(int32_t id, int32_t type, SQInteger & pos, HSQUIRRELVM vm)
{ {
// Grab the top of the stack // Grab the top of the stack
const SQInteger top = sq_gettop(vm); const SQInteger top = sq_gettop(vm);
// Was there a callback specified? // Was there a callback or tag specified?
if (top <= 1) if (top <= 1)
{ {
return sq_throwerror(vm, "Missing task callback"); return sq_throwerror(vm, "Missing task callback or tag");
} }
SQRESULT res = SQ_OK; SQRESULT res = SQ_OK;
// Grab the hash of the callback object // Fetch the task identifier type
const SQHash chash = sq_gethash(vm, 2); const SQObjectType ot = sq_gettype(vm, 2);
// Are we looking for a task with a specific tag?
if (ot == OT_STRING)
{
// Attempt to retrieve the value from the stack as a string
StackStrF tag(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(tag.Proc(true)))
{
return tag.mRes; // Propagate the error!
}
// Attempt to find the requested task
for (const auto & t : s_Tasks)
{
if (t.mEntity == id && t.mType == type && t.mTag.compare(0, String::npos, tag.mPtr) == 0)
{
pos = static_cast< SQInteger >(&t - s_Tasks); // Store the index of this element
}
}
}
// Validate the callback type
else if (ot != OT_CLOSURE && ot != OT_NATIVECLOSURE)
{
return sq_throwerror(vm, "Invalid callback type");
}
// Should we include the iterations in the criteria? // Should we include the iterations in the criteria?
if (top > 3) else if (top > 3)
{ {
SQInteger intrv = 0; SQInteger intrv = 0;
// Grab the interval from the stack // Grab the interval from the stack
@@ -348,6 +371,8 @@ SQInteger Tasks::Find(int32_t id, int32_t type, SQInteger & pos, HSQUIRRELVM vm)
{ {
return res; // Propagate the error return res; // Propagate the error
} }
// Grab the hash of the callback object
const SQHash chash = sq_gethash(vm, 2);
// Attempt to find the requested task // Attempt to find the requested task
for (const auto & t : s_Tasks) for (const auto & t : s_Tasks)
{ {
@@ -375,6 +400,8 @@ SQInteger Tasks::Find(int32_t id, int32_t type, SQInteger & pos, HSQUIRRELVM vm)
{ {
return res; // Propagate the error return res; // Propagate the error
} }
// Grab the hash of the callback object
const SQHash chash = sq_gethash(vm, 2);
// Cast iterations to the right type // Cast iterations to the right type
const Iterator itr = ConvTo< Iterator >::From(sqitr); const Iterator itr = ConvTo< Iterator >::From(sqitr);
// Attempt to find the requested task // Attempt to find the requested task
@@ -388,6 +415,8 @@ SQInteger Tasks::Find(int32_t id, int32_t type, SQInteger & pos, HSQUIRRELVM vm)
} }
else else
{ {
// Grab the hash of the callback object
const SQHash chash = sq_gethash(vm, 2);
// Attempt to find the requested task // Attempt to find the requested task
for (const auto & t : s_Tasks) for (const auto & t : s_Tasks)
{ {
@@ -416,7 +445,7 @@ SQInteger Tasks::Remove(int32_t id, int32_t type, HSQUIRRELVM vm)
// Did we find anything? // Did we find anything?
else if (pos < 0) else if (pos < 0)
{ {
return sq_throwerror(vm, "Unable to locate such task"); sq_pushbool(vm, SQFalse); // Unable to locate such task
} }
else else
{ {
@@ -424,9 +453,11 @@ SQInteger Tasks::Remove(int32_t id, int32_t type, HSQUIRRELVM vm)
s_Tasks[pos].Terminate(); s_Tasks[pos].Terminate();
// Reset the timer // Reset the timer
s_Intervals[pos] = 0; s_Intervals[pos] = 0;
// A task was successfully removed
sq_pushbool(vm, SQTrue);
} }
// Specify that we don't return anything // Specify that we return a value
return 0; return 1;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
+3 -3
View File
@@ -37,9 +37,9 @@ private:
LightObj mData; // A reference to the arbitrary data associated with this instance. LightObj mData; // A reference to the arbitrary data associated with this instance.
Iterator mIterations; // Number of iterations before self destruct. Iterator mIterations; // Number of iterations before self destruct.
Interval mInterval; // Interval between task invocations. Interval mInterval; // Interval between task invocations.
int16_t mEntity; // The identifier of the entity to which is belongs. int16_t mEntity; // The identifier of the entity to which is belongs.
uint8_t mType; // The type of the entity to which is belongs. uint8_t mType; // The type of the entity to which is belongs.
uint8_t mArgc; // The number of arguments that the task must forward. uint8_t mArgc; // The number of arguments that the task must forward.
Argument mArgv[8]; // The arguments that the task must forward. Argument mArgv[8]; // The arguments that the task must forward.
/* ---------------------------------------------------------------------------------------- /* ----------------------------------------------------------------------------------------
+35 -6
View File
@@ -103,7 +103,7 @@ void ThreadPool::Terminate(bool SQ_UNUSED_ARG(shutdown))
// Is the item valid? // Is the item valid?
if (item) if (item)
{ {
item->OnCompleted(); // Allow the item to finish itself [[maybe_unused]] auto _ = item->OnCompleted(true); // Allow the item to finish itself
} }
// Item processed // Item processed
item.reset(); item.reset();
@@ -125,7 +125,15 @@ void ThreadPool::Process()
// Is the item valid? // Is the item valid?
if (item) if (item)
{ {
item->OnCompleted(); // Allow the item to finish itself try {
// Allow the item to finish itself
if (item->OnCompleted(false))
{
Enqueue(std::move(item)); // Queue again
}
} catch (const std::exception & e) {
LogErr("Exception occured in %s completion stage [%s] for [%s]", item->TypeName(), e.what(), item->IdentifiableInfo());
}
} }
} }
} }
@@ -138,6 +146,8 @@ void ThreadPool::WorkerProc()
bool retry = false; bool retry = false;
// Pointer to the dequeued item // Pointer to the dequeued item
Item item; Item item;
// Initialize third-party allocator for this thread
auto rpmallocinit = std::make_unique< RPMallocThreadInit >();
// Constantly process items from the queue // Constantly process items from the queue
while (true) while (true)
{ {
@@ -147,7 +157,11 @@ void ThreadPool::WorkerProc()
// Is there an item that requested to try again? // Is there an item that requested to try again?
if (item) if (item)
{ {
item->OnAborted(true); // NOLINT(bugprone-use-after-move) There's an `if` condition above idiot! try {
item->OnAborted(true); // NOLINT(bugprone-use-after-move) There's an `if` condition above idiot!
} catch (const std::exception & e) {
LogErr("Exception occured in %s cancelation stage [%s] for [%s]", item->TypeName(), e.what(), item->IdentifiableInfo());
}
} }
// Exit the loop // Exit the loop
break; break;
@@ -173,15 +187,30 @@ void ThreadPool::WorkerProc()
// Is there an item to be processed? // Is there an item to be processed?
if (item) if (item)
{ {
item->OnAborted(false); // It should mark itself as aborted somehow! try {
item->OnAborted(false); // It should mark itself as aborted somehow!
} catch (const std::exception & e) {
LogErr("Exception occured in %s forced cancelation stage [%s] for [%s]", item->TypeName(), e.what(), item->IdentifiableInfo());
}
} }
// Exit the loop // Exit the loop
break; break;
} }
bool r;
// Attempt preparation
try {
r = item->OnPrepare();
} catch (const std::exception & e) {
LogErr("Exception occured in %s preparation stage [%s] for [%s]", item->TypeName(), e.what(), item->IdentifiableInfo());
}
// Perform the task // Perform the task
if (item->OnPrepare()) if (r)
{ {
retry = item->OnProcess(); try {
retry = item->OnProcess();
} catch (const std::exception & e) {
LogErr("Exception occured in %s processing stage [%s] for [%s]", item->TypeName(), e.what(), item->IdentifiableInfo());
}
} }
// The task was performed // The task was performed
if (!retry) if (!retry)
+55 -12
View File
@@ -55,6 +55,16 @@ struct ThreadPoolItem
*/ */
ThreadPoolItem & operator = (ThreadPoolItem && o) = delete; ThreadPoolItem & operator = (ThreadPoolItem && o) = delete;
/* --------------------------------------------------------------------------------------------
* Provide a name to what type of task this is. Mainly for debugging purposes.
*/
SQMOD_NODISCARD virtual const char * TypeName() noexcept { return "worker item"; }
/* --------------------------------------------------------------------------------------------
* Provide unique information that may help identify the task. Mainly for debugging purposes.
*/
SQMOD_NODISCARD virtual const char * IdentifiableInfo() noexcept { return ""; }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Invoked in worker thread by the thread pool after obtaining the task from the queue. * Invoked in worker thread by the thread pool after obtaining the task from the queue.
* Must return true to indicate that the task can be performed. False indicates failure. * Must return true to indicate that the task can be performed. False indicates failure.
@@ -69,8 +79,10 @@ 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 the boolean parameter is true then the thread-pool is in the process of shutting down.
*/ */
virtual void OnCompleted() { } SQMOD_NODISCARD virtual bool OnCompleted(bool SQ_UNUSED_ARG(stop)) { return false; }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Called in worker by the thread pool to let the task know that it will be aborted. * Called in worker by the thread pool to let the task know that it will be aborted.
@@ -98,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.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@@ -171,9 +183,25 @@ public:
void Process(); void Process();
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Queue an item to be processed. * Queue an item to be processed. Will take ownership of the given pointer!
*/ */
void Enqueue(ThreadPoolItem * item) void Enqueue(ThreadPoolItem * 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!
*/
void Enqueue(Item && item)
{ {
// Only queue valid items // Only queue valid items
if (!item || !m_Running) return; if (!item || !m_Running) return;
@@ -183,7 +211,7 @@ public:
// Acquire a lock on the mutex // Acquire a lock on the mutex
std::unique_lock< std::mutex > lock(m_Mutex); std::unique_lock< std::mutex > lock(m_Mutex);
// Push the item in the queue // Push the item in the queue
m_Queue.push(Item(item)); m_Queue.push(std::forward< Item >(item));
// Release the mutex before notifying // Release the mutex before notifying
lock.unlock(); lock.unlock();
// Notify one thread that there's work // Notify one thread that there's work
@@ -191,16 +219,32 @@ public:
} }
else else
{ {
bool r;
// Attempt preparation
try {
r = item->OnPrepare();
} catch (const std::exception & e) {
LogErr("Exception occured in %s preparation stage [%s] for [%s]", item->TypeName(), e.what(), item->IdentifiableInfo());
}
// Perform the task in-place // Perform the task in-place
if (item->OnPrepare()) if (r)
{ {
if (item->OnProcess()) try {
r = item->OnProcess();
} catch (const std::exception & e) {
LogErr("Exception occured in %s processing stage [%s] for [%s]", item->TypeName(), e.what(), item->IdentifiableInfo());
}
if (r)
{ {
item->OnAborted(true); // Not accepted in single thread try {
item->OnAborted(true); // Not accepted in single thread
} catch (const std::exception & e) {
LogErr("Exception occured in %s cancelation stage [%s] for [%s]", item->TypeName(), e.what(), item->IdentifiableInfo());
}
} }
} }
// Item was finished in main thread // Task is completed in processing stage
item->OnCompleted(); m_Finished.enqueue(std::forward< Item >(item));
} }
} }
@@ -211,7 +255,6 @@ public:
{ {
return m_Threads.size(); return m_Threads.size();
} }
}; };
} // Namespace:: SqMod } // Namespace:: SqMod
+14
View File
@@ -251,6 +251,20 @@ template < class Key, class T, class Pred = std::equal_to< Key > > struct VecMap
return m_Storage.back().second; return m_Storage.back().second;
} }
/* --------------------------------------------------------------------------------------------
* Retrieves a reference to the front of the container.
* Available for internal use only.
*/
reference front() { return m_Storage.front(); }
const_reference front() const { return m_Storage.front(); }
/* --------------------------------------------------------------------------------------------
* Retrieves a reference to the back of the container.
* Available for internal use only.
*/
reference back() { return m_Storage.back(); }
const_reference back() const { return m_Storage.back(); }
private: private:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
+18 -5
View File
@@ -157,16 +157,16 @@ void CCheckpoint::SetWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetCheckPointWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & CHECKPOINTCL_EMIT_CHECKPOINT_WORLD)) else if (!(m_CircularLocks & CHECKPOINTCL_EMIT_CHECKPOINT_WORLD))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, CHECKPOINTCL_EMIT_CHECKPOINT_WORLD); BitGuardU32 bg(m_CircularLocks, CHECKPOINTCL_EMIT_CHECKPOINT_WORLD);
// Now forward the event call // Now forward the event call
Core::Get().EmitCheckpointWorld(m_ID, current, world); Core::Get().EmitCheckpointWorld(m_ID, current, world);
} }
// Avoid property unwind from a recursive call
_Func->SetCheckPointWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -257,8 +257,6 @@ void CCheckpoint::SetRadius(float radius)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const float current = _Func->GetCheckPointRadius(m_ID); const float current = _Func->GetCheckPointRadius(m_ID);
// Avoid property unwind from a recursive call
_Func->SetCheckPointRadius(m_ID, radius);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & CHECKPOINTCL_EMIT_CHECKPOINT_RADIUS)) if (!(m_CircularLocks & CHECKPOINTCL_EMIT_CHECKPOINT_RADIUS))
{ {
@@ -267,6 +265,8 @@ void CCheckpoint::SetRadius(float radius)
// Now forward the event call // Now forward the event call
Core::Get().EmitCheckpointRadius(m_ID, current, radius); Core::Get().EmitCheckpointRadius(m_ID, current, radius);
} }
// Avoid property unwind from a recursive call
_Func->SetCheckPointRadius(m_ID, radius);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -468,6 +468,16 @@ void CCheckpoint::SetColorA(int32_t a) const
// Perform the requested operation // Perform the requested operation
_Func->SetCheckPointColour(m_ID, r, g, b, a); _Func->SetCheckPointColour(m_ID, r, g, b, a);
} }
#ifdef VCMP_ENABLE_OFFICIAL
// ------------------------------------------------------------------------------------------------
LightObj & CCheckpoint::GetLegacyObject() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetCheckpoint(m_ID).mLgObj;
}
#endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static LightObj & Checkpoint_CreateEx1a(int32_t world, bool sphere, float x, float y, float z, static LightObj & Checkpoint_CreateEx1a(int32_t world, bool sphere, float x, float y, float z,
@@ -517,6 +527,9 @@ void Register_CCheckpoint(HSQUIRRELVM vm)
.Prop(_SC("Tag"), &CCheckpoint::GetTag, &CCheckpoint::SetTag) .Prop(_SC("Tag"), &CCheckpoint::GetTag, &CCheckpoint::SetTag)
.Prop(_SC("Data"), &CCheckpoint::GetData, &CCheckpoint::SetData) .Prop(_SC("Data"), &CCheckpoint::GetData, &CCheckpoint::SetData)
.Prop(_SC("Active"), &CCheckpoint::IsActive) .Prop(_SC("Active"), &CCheckpoint::IsActive)
#ifdef VCMP_ENABLE_OFFICIAL
.Prop(_SC("Legacy"), &CCheckpoint::GetLegacyObject)
#endif
// Core Methods // Core Methods
.FmtFunc(_SC("SetTag"), &CCheckpoint::ApplyTag) .FmtFunc(_SC("SetTag"), &CCheckpoint::ApplyTag)
.Func(_SC("CustomEvent"), &CCheckpoint::CustomEvent) .Func(_SC("CustomEvent"), &CCheckpoint::CustomEvent)
+6
View File
@@ -320,6 +320,12 @@ public:
* Modify the alpha transparency of the managed checkpoint entity. * Modify the alpha transparency of the managed checkpoint entity.
*/ */
void SetColorA(int32_t a) const; void SetColorA(int32_t a) const;
#ifdef VCMP_ENABLE_OFFICIAL
/* --------------------------------------------------------------------------------------------
* Retrieve legacy object instance for this entity.
*/
LightObj & GetLegacyObject() const;
#endif
}; };
} // Namespace:: SqMod } // Namespace:: SqMod
+25 -12
View File
@@ -163,16 +163,16 @@ void CObject::SetWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetObjectWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_WORLD)) else if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_WORLD))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_WORLD); BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_WORLD);
// Now forward the event call // Now forward the event call
Core::Get().EmitObjectWorld(m_ID, current, world); Core::Get().EmitObjectWorld(m_ID, current, world);
} }
// Avoid property unwind from a recursive call
_Func->SetObjectWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -202,16 +202,16 @@ void CObject::SetAlphaEx(int32_t alpha, uint32_t time)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetObjectAlpha(m_ID, alpha, time);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_ALPHA)) else if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_ALPHA))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_ALPHA); BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_ALPHA);
// Now forward the event call // Now forward the event call
Core::Get().EmitObjectAlpha(m_ID, current, alpha, time); Core::Get().EmitObjectAlpha(m_ID, current, alpha, time);
} }
// Avoid property unwind from a recursive call
_Func->SetObjectAlpha(m_ID, alpha, time);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -400,16 +400,16 @@ void CObject::SetShotReport(bool toggle)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetObjectShotReportEnabled(m_ID, static_cast< uint8_t >(toggle));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_REPORT)) else if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_REPORT))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_REPORT); BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_REPORT);
// Now forward the event call // Now forward the event call
Core::Get().EmitObjectReport(m_ID, current, toggle, false); Core::Get().EmitObjectReport(m_ID, current, toggle, false);
} }
// Avoid property unwind from a recursive call
_Func->SetObjectShotReportEnabled(m_ID, static_cast< uint8_t >(toggle));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -433,16 +433,16 @@ void CObject::SetTouchedReport(bool toggle)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetObjectTouchedReportEnabled(m_ID, static_cast< uint8_t >(toggle));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_REPORT)) else if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_REPORT))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_REPORT); BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_REPORT);
// Now forward the event call // Now forward the event call
Core::Get().EmitObjectReport(m_ID, current, toggle, true); Core::Get().EmitObjectReport(m_ID, current, toggle, true);
} }
// Avoid property unwind from a recursive call
_Func->SetObjectTouchedReportEnabled(m_ID, static_cast< uint8_t >(toggle));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -833,6 +833,16 @@ void CObject::RotateByEulerZ(float z) const
// Perform the requested operation // Perform the requested operation
_Func->RotateObjectByEuler(m_ID, 0.0f, 0.0f, z, mRotateByEulerDuration); _Func->RotateObjectByEuler(m_ID, 0.0f, 0.0f, z, mRotateByEulerDuration);
} }
#ifdef VCMP_ENABLE_OFFICIAL
// ------------------------------------------------------------------------------------------------
LightObj & CObject::GetLegacyObject() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetObj(m_ID).mLgObj;
}
#endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static LightObj & Object_CreateEx1a(int32_t model, int32_t world, float x, float y, float z, static LightObj & Object_CreateEx1a(int32_t model, int32_t world, float x, float y, float z,
@@ -883,6 +893,9 @@ void Register_CObject(HSQUIRRELVM vm)
.Prop(_SC("Tag"), &CObject::GetTag, &CObject::SetTag) .Prop(_SC("Tag"), &CObject::GetTag, &CObject::SetTag)
.Prop(_SC("Data"), &CObject::GetData, &CObject::SetData) .Prop(_SC("Data"), &CObject::GetData, &CObject::SetData)
.Prop(_SC("Active"), &CObject::IsActive) .Prop(_SC("Active"), &CObject::IsActive)
#ifdef VCMP_ENABLE_OFFICIAL
.Prop(_SC("Legacy"), &CObject::GetLegacyObject)
#endif
// Core Methods // Core Methods
.FmtFunc(_SC("SetTag"), &CObject::ApplyTag) .FmtFunc(_SC("SetTag"), &CObject::ApplyTag)
.Func(_SC("CustomEvent"), &CObject::CustomEvent) .Func(_SC("CustomEvent"), &CObject::CustomEvent)
+6
View File
@@ -499,6 +499,12 @@ public:
* Modify the rotation on the z axis of the managed object entity. * Modify the rotation on the z axis of the managed object entity.
*/ */
void RotateByEulerZ(float z) const; void RotateByEulerZ(float z) const;
#ifdef VCMP_ENABLE_OFFICIAL
/* --------------------------------------------------------------------------------------------
* Retrieve legacy object instance for this entity.
*/
LightObj & GetLegacyObject() const;
#endif
}; };
} // Namespace:: SqMod } // Namespace:: SqMod
+41 -26
View File
@@ -145,19 +145,20 @@ void CPickup::SetOption(int32_t option_id, bool toggle)
{ {
// Attempt to obtain the current value of the specified option // Attempt to obtain the current value of the specified option
const bool value = _Func->GetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id)); const bool value = _Func->GetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id));
// Attempt to modify the current value of the specified option // Avoid infinite recursive event loops
if (_Func->SetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id), if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_OPTION))
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
else if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_OPTION))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_OPTION); BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_OPTION);
// Now forward the event call // Now forward the event call
Core::Get().EmitPickupOption(m_ID, option_id, value, 0, NullLightObj()); Core::Get().EmitPickupOption(m_ID, option_id, value, 0, NullLightObj());
} }
// Attempt to modify the current value of the specified option
if (_Func->SetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -165,19 +166,20 @@ void CPickup::SetOptionEx(int32_t option_id, bool toggle, int32_t header, LightO
{ {
// Attempt to obtain the current value of the specified option // Attempt to obtain the current value of the specified option
const bool value = _Func->GetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id)); const bool value = _Func->GetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id));
// Attempt to modify the current value of the specified option // Avoid infinite recursive event loops
if (_Func->SetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id), if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_OPTION))
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
else if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_OPTION))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_OPTION); BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_OPTION);
// Now forward the event call // Now forward the event call
Core::Get().EmitPickupOption(m_ID, option_id, value, header, payload); Core::Get().EmitPickupOption(m_ID, option_id, value, header, payload);
} }
// Attempt to modify the current value of the specified option
if (_Func->SetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -201,16 +203,16 @@ void CPickup::SetWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPickupWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_WORLD)) else if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_WORLD))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_WORLD); BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_WORLD);
// Now forward the event call // Now forward the event call
Core::Get().EmitPickupWorld(m_ID, current, world); Core::Get().EmitPickupWorld(m_ID, current, world);
} }
// Avoid property unwind from a recursive call
_Func->SetPickupWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -234,16 +236,16 @@ void CPickup::SetAlpha(int32_t alpha)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPickupAlpha(m_ID, alpha);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_ALPHA)) else if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_ALPHA))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_ALPHA); BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_ALPHA);
// Now forward the event call // Now forward the event call
Core::Get().EmitPickupAlpha(m_ID, current, alpha); Core::Get().EmitPickupAlpha(m_ID, current, alpha);
} }
// Avoid property unwind from a recursive call
_Func->SetPickupAlpha(m_ID, alpha);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -267,16 +269,16 @@ void CPickup::SetAutomatic(bool toggle)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPickupIsAutomatic(m_ID, static_cast< uint8_t >(toggle));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_AUTOMATIC)) else if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_AUTOMATIC))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_AUTOMATIC); BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_AUTOMATIC);
// Now forward the event call // Now forward the event call
Core::Get().EmitPickupAutomatic(m_ID, current, toggle); Core::Get().EmitPickupAutomatic(m_ID, current, toggle);
} }
// Avoid property unwind from a recursive call
_Func->SetPickupIsAutomatic(m_ID, static_cast< uint8_t >(toggle));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -300,16 +302,16 @@ void CPickup::SetAutoTimer(int32_t timer)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPickupAutoTimer(m_ID, static_cast< uint32_t >(timer));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_AUTOTIMER)) else if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_AUTOTIMER))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_AUTOTIMER); BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_AUTOTIMER);
// Now forward the event call // Now forward the event call
Core::Get().EmitPickupAutoTimer(m_ID, current, timer); Core::Get().EmitPickupAutoTimer(m_ID, current, timer);
} }
// Avoid property unwind from a recursive call
_Func->SetPickupAutoTimer(m_ID, static_cast< uint32_t >(timer));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -447,6 +449,16 @@ void CPickup::SetPositionZ(float z) const
// Perform the requested operation // Perform the requested operation
_Func->SetPickupPosition(m_ID, z, y, z); _Func->SetPickupPosition(m_ID, z, y, z);
} }
#ifdef VCMP_ENABLE_OFFICIAL
// ------------------------------------------------------------------------------------------------
LightObj & CPickup::GetLegacyObject() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetPickup(m_ID).mLgObj;
}
#endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static LightObj & Pickup_CreateEx1a(int32_t model, int32_t world, int32_t quantity, static LightObj & Pickup_CreateEx1a(int32_t model, int32_t world, int32_t quantity,
@@ -494,6 +506,9 @@ void Register_CPickup(HSQUIRRELVM vm)
.Prop(_SC("Tag"), &CPickup::GetTag, &CPickup::SetTag) .Prop(_SC("Tag"), &CPickup::GetTag, &CPickup::SetTag)
.Prop(_SC("Data"), &CPickup::GetData, &CPickup::SetData) .Prop(_SC("Data"), &CPickup::GetData, &CPickup::SetData)
.Prop(_SC("Active"), &CPickup::IsActive) .Prop(_SC("Active"), &CPickup::IsActive)
#ifdef VCMP_ENABLE_OFFICIAL
.Prop(_SC("Legacy"), &CPickup::GetLegacyObject)
#endif
// Core Methods // Core Methods
.FmtFunc(_SC("SetTag"), &CPickup::ApplyTag) .FmtFunc(_SC("SetTag"), &CPickup::ApplyTag)
.Func(_SC("CustomEvent"), &CPickup::CustomEvent) .Func(_SC("CustomEvent"), &CPickup::CustomEvent)
+6
View File
@@ -298,6 +298,12 @@ public:
* Modify the position on the z axis of the managed pickup entity. * Modify the position on the z axis of the managed pickup entity.
*/ */
void SetPositionZ(float z) const; void SetPositionZ(float z) const;
#ifdef VCMP_ENABLE_OFFICIAL
/* --------------------------------------------------------------------------------------------
* Retrieve legacy object instance for this entity.
*/
LightObj & GetLegacyObject() const;
#endif
}; };
} // Namespace:: SqMod } // Namespace:: SqMod
+83 -45
View File
@@ -168,16 +168,16 @@ void CPlayer::SetAdmin(bool toggle)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerAdmin(m_ID, static_cast< uint8_t >(toggle));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_ADMIN)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_ADMIN))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_ADMIN); BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_ADMIN);
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerAdmin(m_ID, current, toggle); Core::Get().EmitPlayerAdmin(m_ID, current, toggle);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerAdmin(m_ID, static_cast< uint8_t >(toggle));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -373,13 +373,6 @@ void CPlayer::SetOptionEx(int32_t option_id, bool toggle, int32_t header, LightO
{ {
return; return;
} }
// Avoid property unwind from a recursive call
else if (_Func->SetPlayerOption(m_ID,
static_cast< vcmpPlayerOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_OPTION)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_OPTION))
{ {
@@ -388,6 +381,13 @@ void CPlayer::SetOptionEx(int32_t option_id, bool toggle, int32_t header, LightO
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerOption(m_ID, option_id, current, header, payload); Core::Get().EmitPlayerOption(m_ID, option_id, current, header, payload);
} }
// Avoid property unwind from a recursive call
if (_Func->SetPlayerOption(m_ID,
static_cast< vcmpPlayerOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
} }
#if SQMOD_SDK_LEAST(2, 1) #if SQMOD_SDK_LEAST(2, 1)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -433,16 +433,16 @@ void CPlayer::SetWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WORLD)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WORLD))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_WORLD); BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_WORLD);
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerWorld(m_ID, current, world, false); Core::Get().EmitPlayerWorld(m_ID, current, world, false);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -466,16 +466,16 @@ void CPlayer::SetSecondaryWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerSecondaryWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WORLD)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WORLD))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_WORLD); BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_WORLD);
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerWorld(m_ID, current, world, true); Core::Get().EmitPlayerWorld(m_ID, current, world, true);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerSecondaryWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -526,11 +526,6 @@ void CPlayer::SetTeam(int32_t team)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
else if (_Func->SetPlayerTeam(m_ID, team) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid team identifier: {}", team);
}
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_TEAM)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_TEAM))
{ {
@@ -539,6 +534,11 @@ void CPlayer::SetTeam(int32_t team)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerTeam(m_ID, current, team); Core::Get().EmitPlayerTeam(m_ID, current, team);
} }
// Avoid property unwind from a recursive call
if (_Func->SetPlayerTeam(m_ID, team) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid team identifier: {}", team);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -562,11 +562,6 @@ void CPlayer::SetSkin(int32_t skin)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
else if (_Func->SetPlayerSkin(m_ID, skin) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid skin identifier: {}", skin);
}
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_SKIN)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_SKIN))
{ {
@@ -575,6 +570,11 @@ void CPlayer::SetSkin(int32_t skin)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerSkin(m_ID, current, skin); Core::Get().EmitPlayerSkin(m_ID, current, skin);
} }
// Avoid property unwind from a recursive call
if (_Func->SetPlayerSkin(m_ID, skin) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid skin identifier: {}", skin);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -665,16 +665,16 @@ void CPlayer::SetMoney(int32_t amount)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerMoney(m_ID, amount);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_MONEY)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_MONEY))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_MONEY); BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_MONEY);
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerMoney(m_ID, current, amount); Core::Get().EmitPlayerMoney(m_ID, current, amount);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerMoney(m_ID, amount);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -684,8 +684,6 @@ void CPlayer::GiveMoney(int32_t amount)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const int32_t current = _Func->GetPlayerMoney(m_ID); const int32_t current = _Func->GetPlayerMoney(m_ID);
// Avoid property unwind from a recursive call
_Func->GivePlayerMoney(m_ID, amount);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_MONEY)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_MONEY))
{ {
@@ -694,6 +692,8 @@ void CPlayer::GiveMoney(int32_t amount)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerMoney(m_ID, current, current + amount); Core::Get().EmitPlayerMoney(m_ID, current, current + amount);
} }
// Avoid property unwind from a recursive call
_Func->GivePlayerMoney(m_ID, amount);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -717,16 +717,16 @@ void CPlayer::SetScore(int32_t score)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerScore(m_ID, score);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_SCORE)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_SCORE))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_SCORE); BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_SCORE);
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerScore(m_ID, current, score); Core::Get().EmitPlayerScore(m_ID, current, score);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerScore(m_ID, score);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -750,16 +750,16 @@ void CPlayer::SetWantedLevel(int32_t level)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerWantedLevel(m_ID, level);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WANTED_LEVEL)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WANTED_LEVEL))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_WANTED_LEVEL); BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_WANTED_LEVEL);
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerWantedLevel(m_ID, current, level); Core::Get().EmitPlayerWantedLevel(m_ID, current, level);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerWantedLevel(m_ID, level);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -832,8 +832,6 @@ void CPlayer::SetImmunity(uint32_t flags)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const uint32_t current = _Func->GetPlayerImmunityFlags(m_ID); const uint32_t current = _Func->GetPlayerImmunityFlags(m_ID);
// Avoid property unwind from a recursive call
_Func->SetPlayerImmunityFlags(m_ID, static_cast< uint32_t >(flags));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_IMMUNITY)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_IMMUNITY))
{ {
@@ -842,6 +840,8 @@ void CPlayer::SetImmunity(uint32_t flags)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerImmunity(m_ID, static_cast< int32_t >(current), static_cast< int32_t >(flags)); Core::Get().EmitPlayerImmunity(m_ID, static_cast< int32_t >(current), static_cast< int32_t >(flags));
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerImmunityFlags(m_ID, static_cast< uint32_t >(flags));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -969,16 +969,16 @@ void CPlayer::SetAlphaEx(int32_t alpha, int32_t fade)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerAlpha(m_ID, alpha, static_cast< uint32_t >(fade));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_ALPHA)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_ALPHA))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_ALPHA); BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_ALPHA);
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerAlpha(m_ID, current, alpha, fade); Core::Get().EmitPlayerAlpha(m_ID, current, alpha, fade);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerAlpha(m_ID, alpha, static_cast< uint32_t >(fade));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1044,7 +1044,7 @@ uint32_t CPlayer::GetGameKeys() const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CPlayer::Embark(CVehicle & vehicle) const bool CPlayer::Embark(CVehicle & vehicle)
{ {
// Is the specified vehicle even valid? // Is the specified vehicle even valid?
if (!vehicle.IsActive()) if (!vehicle.IsActive())
@@ -1053,13 +1053,26 @@ bool CPlayer::Embark(CVehicle & vehicle) const
} }
// Validate the managed identifier // Validate the managed identifier
Validate(); Validate();
// If the player embarks in the same vehicle then ignore
if (_Func->GetPlayerVehicleId(m_ID) == vehicle.GetID())
{
return true; // I guess this is somewhat successful
}
// Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_EMBARK))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_EMBARK);
// Now forward the event call
Core::Get().EmitPlayerEmbarking(m_ID, vehicle.GetID(), 0);
}
// Perform the requested operation // Perform the requested operation
return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), 0, return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), 0,
static_cast< uint8_t >(true), static_cast< uint8_t >(true)) != vcmpErrorRequestDenied); static_cast< uint8_t >(true), static_cast< uint8_t >(true)) != vcmpErrorRequestDenied);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CPlayer::EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool warp) const bool CPlayer::EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool warp)
{ {
// Is the specified vehicle even valid? // Is the specified vehicle even valid?
if (!vehicle.IsActive()) if (!vehicle.IsActive())
@@ -1068,6 +1081,19 @@ bool CPlayer::EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool war
} }
// Validate the managed identifier // Validate the managed identifier
Validate(); Validate();
// If the player embarks in the same vehicle then ignore
if (_Func->GetPlayerVehicleId(m_ID) == vehicle.GetID())
{
return true; // I guess this is somewhat successful
}
// Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_EMBARK))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_EMBARK);
// Now forward the event call
Core::Get().EmitPlayerEmbarking(m_ID, vehicle.GetID(), slot);
}
// Perform the requested operation // Perform the requested operation
return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), slot, return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), slot,
static_cast< uint8_t >(allocate), static_cast< uint8_t >(warp)) != vcmpErrorRequestDenied); static_cast< uint8_t >(allocate), static_cast< uint8_t >(warp)) != vcmpErrorRequestDenied);
@@ -2567,7 +2593,16 @@ SQInteger CPlayer::AnnounceEx(HSQUIRRELVM vm)
// This function does not return a value // This function does not return a value
return 0; return 0;
} }
#ifdef VCMP_ENABLE_OFFICIAL
// ------------------------------------------------------------------------------------------------
LightObj & CPlayer::GetLegacyObject() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetPlayer(m_ID).mLgObj;
}
#endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQInteger Player_FindAuto(HSQUIRRELVM vm) SQInteger Player_FindAuto(HSQUIRRELVM vm)
{ {
@@ -2767,6 +2802,9 @@ void Register_CPlayer(HSQUIRRELVM vm)
.Prop(_SC("Tag"), &CPlayer::GetTag, &CPlayer::SetTag) .Prop(_SC("Tag"), &CPlayer::GetTag, &CPlayer::SetTag)
.Prop(_SC("Data"), &CPlayer::GetData, &CPlayer::SetData) .Prop(_SC("Data"), &CPlayer::GetData, &CPlayer::SetData)
.Prop(_SC("Active"), &CPlayer::IsActive) .Prop(_SC("Active"), &CPlayer::IsActive)
#ifdef VCMP_ENABLE_OFFICIAL
.Prop(_SC("Legacy"), &CPlayer::GetLegacyObject)
#endif
// Core Methods // Core Methods
.FmtFunc(_SC("SetTag"), &CPlayer::ApplyTag) .FmtFunc(_SC("SetTag"), &CPlayer::ApplyTag)
.Func(_SC("CustomEvent"), &CPlayer::CustomEvent) .Func(_SC("CustomEvent"), &CPlayer::CustomEvent)
+10 -3
View File
@@ -21,7 +21,8 @@ enum PlayerCircularLocks
PLAYERCL_EMIT_PLAYER_SCORE = (1u << 6u), PLAYERCL_EMIT_PLAYER_SCORE = (1u << 6u),
PLAYERCL_EMIT_PLAYER_WANTED_LEVEL = (1u << 7u), PLAYERCL_EMIT_PLAYER_WANTED_LEVEL = (1u << 7u),
PLAYERCL_EMIT_PLAYER_IMMUNITY = (1u << 8u), PLAYERCL_EMIT_PLAYER_IMMUNITY = (1u << 8u),
PLAYERCL_EMIT_PLAYER_ALPHA = (1u << 9u) PLAYERCL_EMIT_PLAYER_ALPHA = (1u << 9u),
PLAYERCL_EMIT_PLAYER_EMBARK = (1u << 10u)
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -593,12 +594,12 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Embark the managed player entity into the specified vehicle entity. * Embark the managed player entity into the specified vehicle entity.
*/ */
bool Embark(CVehicle & vehicle) const; bool Embark(CVehicle & vehicle);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Embark the managed player entity into the specified vehicle entity. * Embark the managed player entity into the specified vehicle entity.
*/ */
bool EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool warp) const; bool EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool warp);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Disembark the managed player entity from the currently embarked vehicle entity. * Disembark the managed player entity from the currently embarked vehicle entity.
@@ -1100,6 +1101,12 @@ public:
* Send a formatted announcement message to the managed player entity. * Send a formatted announcement message to the managed player entity.
*/ */
static SQInteger AnnounceEx(HSQUIRRELVM vm); static SQInteger AnnounceEx(HSQUIRRELVM vm);
#ifdef VCMP_ENABLE_OFFICIAL
/* --------------------------------------------------------------------------------------------
* Retrieve legacy object instance for this entity.
*/
LightObj & GetLegacyObject() const;
#endif
}; };
} // Namespace:: SqMod } // Namespace:: SqMod
+78 -37
View File
@@ -148,19 +148,20 @@ void CVehicle::SetOption(int32_t option_id, bool toggle)
{ {
// Attempt to obtain the current value of the specified option // Attempt to obtain the current value of the specified option
const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id)); const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id));
// Attempt to modify the current value of the specified option // Avoid infinite recursive event loops
if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id), if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_OPTION))
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_OPTION))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleOption(m_ID, option_id, value, 0, NullLightObj()); Core::Get().EmitVehicleOption(m_ID, option_id, value, 0, NullLightObj());
} }
// Attempt to modify the current value of the specified option
if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -168,19 +169,20 @@ void CVehicle::SetOptionEx(int32_t option_id, bool toggle, int32_t header, Light
{ {
// Attempt to obtain the current value of the specified option // Attempt to obtain the current value of the specified option
const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id)); const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id));
// Attempt to modify the current value of the specified option // Avoid infinite recursive event loops
if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id), if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_OPTION))
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_OPTION))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleOption(m_ID, option_id, value, header, payload); Core::Get().EmitVehicleOption(m_ID, option_id, value, header, payload);
} }
// Attempt to modify the current value of the specified option
if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -222,16 +224,16 @@ void CVehicle::SetWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_WORLD)) else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_WORLD))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_WORLD); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_WORLD);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleWorld(m_ID, current, world); Core::Get().EmitVehicleWorld(m_ID, current, world);
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -321,8 +323,6 @@ void CVehicle::SetImmunity(uint32_t flags)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const uint32_t current = _Func->GetVehicleImmunityFlags(m_ID); const uint32_t current = _Func->GetVehicleImmunityFlags(m_ID);
// Avoid property unwind from a recursive call
_Func->SetVehicleImmunityFlags(m_ID, static_cast< uint32_t >(flags));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_IMMUNITY)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_IMMUNITY))
{ {
@@ -331,6 +331,8 @@ void CVehicle::SetImmunity(uint32_t flags)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleImmunity(m_ID, static_cast< int32_t >(current), static_cast< int32_t >(flags)); Core::Get().EmitVehicleImmunity(m_ID, static_cast< int32_t >(current), static_cast< int32_t >(flags));
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleImmunityFlags(m_ID, static_cast< uint32_t >(flags));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -914,16 +916,16 @@ void CVehicle::SetPartStatus(int32_t part, int32_t status)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehiclePartStatus(m_ID, part, status);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_PARTSTATUS)) else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_PARTSTATUS))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_PARTSTATUS); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_PARTSTATUS);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehiclePartStatus(m_ID, part, current, status); Core::Get().EmitVehiclePartStatus(m_ID, part, current, status);
} }
// Avoid property unwind from a recursive call
_Func->SetVehiclePartStatus(m_ID, part, status);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -947,16 +949,16 @@ void CVehicle::SetTyreStatus(int32_t tyre, int32_t status)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleTyreStatus(m_ID, tyre, status);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_TYRESTATUS)) else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_TYRESTATUS))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_TYRESTATUS); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_TYRESTATUS);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleTyreStatus(m_ID, tyre, current, status); Core::Get().EmitVehicleTyreStatus(m_ID, tyre, current, status);
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleTyreStatus(m_ID, tyre, status);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -980,16 +982,16 @@ void CVehicle::SetDamageData(uint32_t data)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleDamageData(m_ID, data);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_DAMAGEDATA)) else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_DAMAGEDATA))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_DAMAGEDATA); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_DAMAGEDATA);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleDamageData(m_ID, current, data); Core::Get().EmitVehicleDamageData(m_ID, current, data);
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleDamageData(m_ID, data);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1013,16 +1015,16 @@ void CVehicle::SetRadio(int32_t radio)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleRadio(m_ID, radio);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_RADIO)) else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_RADIO))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_RADIO); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_RADIO);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleRadio(m_ID, current, radio); Core::Get().EmitVehicleRadio(m_ID, current, radio);
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleRadio(m_ID, radio);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1089,8 +1091,6 @@ void CVehicle::SetHandlingRule(int32_t rule, float data)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const auto current = static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule)); const auto current = static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule));
// Avoid property unwind from a recursive call
_Func->SetInstHandlingRule(m_ID, rule, data);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_HANDLINGRULE)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_HANDLINGRULE))
{ {
@@ -1099,6 +1099,8 @@ void CVehicle::SetHandlingRule(int32_t rule, float data)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleHandlingRule(m_ID, rule, current, data); Core::Get().EmitVehicleHandlingRule(m_ID, rule, current, data);
} }
// Avoid property unwind from a recursive call
_Func->SetInstHandlingRule(m_ID, rule, data);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1108,8 +1110,6 @@ void CVehicle::ResetHandlingRule(int32_t rule)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const auto current = static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule)); const auto current = static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule));
// Avoid property unwind from a recursive call
_Func->ResetInstHandlingRule(m_ID, rule);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_HANDLINGRULE)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_HANDLINGRULE))
{ {
@@ -1118,6 +1118,8 @@ void CVehicle::ResetHandlingRule(int32_t rule)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleHandlingRule(m_ID, rule, current, static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule))); Core::Get().EmitVehicleHandlingRule(m_ID, rule, current, static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule)));
} }
// Avoid property unwind from a recursive call
_Func->ResetInstHandlingRule(m_ID, rule);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1148,7 +1150,7 @@ void CVehicle::SetLightsData(int32_t data) const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CVehicle::Embark(CPlayer & player) const bool CVehicle::Embark(CPlayer & player)
{ {
// Is the specified player even valid? // Is the specified player even valid?
if (!player.IsActive()) if (!player.IsActive())
@@ -1157,6 +1159,19 @@ bool CVehicle::Embark(CPlayer & player) const
} }
// Validate the managed identifier // Validate the managed identifier
Validate(); Validate();
// If the player embarks in the same vehicle then ignore
if (_Func->GetPlayerVehicleId(player.GetID()) == m_ID)
{
return true; // I guess this is somewhat successful
}
// Avoid infinite recursive event loops
else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_EMBARK))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_EMBARK);
// Now forward the event call
Core::Get().EmitPlayerEmbarking(player.GetID(), m_ID, 0);
}
// Perform the requested operation // Perform the requested operation
return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, 0, return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, 0,
static_cast< uint8_t >(true), static_cast< uint8_t >(true)) static_cast< uint8_t >(true), static_cast< uint8_t >(true))
@@ -1164,7 +1179,7 @@ bool CVehicle::Embark(CPlayer & player) const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CVehicle::EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp) const bool CVehicle::EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp)
{ {
// Is the specified player even valid? // Is the specified player even valid?
if (!player.IsActive()) if (!player.IsActive())
@@ -1173,6 +1188,19 @@ bool CVehicle::EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp
} }
// Validate the managed identifier // Validate the managed identifier
Validate(); Validate();
// If the player embarks in the same vehicle then ignore
if (_Func->GetPlayerVehicleId(player.GetID()) == m_ID)
{
return true; // I guess this is somewhat successful
}
// Avoid infinite recursive event loops
else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_EMBARK))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_EMBARK);
// Now forward the event call
Core::Get().EmitPlayerEmbarking(player.GetID(), m_ID, 0);
}
// Perform the requested operation // Perform the requested operation
return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, slot, return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, slot,
static_cast< uint8_t >(allocate), static_cast< uint8_t >(warp)) != vcmpErrorRequestDenied); static_cast< uint8_t >(allocate), static_cast< uint8_t >(warp)) != vcmpErrorRequestDenied);
@@ -1987,6 +2015,16 @@ void CVehicle::SetRelativeTurnSpeedZ(float z) const
// Perform the requested operation // Perform the requested operation
_Func->SetVehicleTurnSpeed(m_ID, z, y, z, static_cast< uint8_t >(false), static_cast< uint8_t >(true)); _Func->SetVehicleTurnSpeed(m_ID, z, y, z, static_cast< uint8_t >(false), static_cast< uint8_t >(true));
} }
#ifdef VCMP_ENABLE_OFFICIAL
// ------------------------------------------------------------------------------------------------
LightObj & CVehicle::GetLegacyObject() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetVehicle(m_ID).mLgObj;
}
#endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static LightObj & Vehicle_CreateEx1a(int32_t model, int32_t world, float x, float y, float z, float angle, static LightObj & Vehicle_CreateEx1a(int32_t model, int32_t world, float x, float y, float z, float angle,
@@ -2033,6 +2071,9 @@ void Register_CVehicle(HSQUIRRELVM vm)
.Prop(_SC("ID"), &CVehicle::GetID) .Prop(_SC("ID"), &CVehicle::GetID)
.Prop(_SC("Tag"), &CVehicle::GetTag, &CVehicle::SetTag) .Prop(_SC("Tag"), &CVehicle::GetTag, &CVehicle::SetTag)
.Prop(_SC("Data"), &CVehicle::GetData, &CVehicle::SetData) .Prop(_SC("Data"), &CVehicle::GetData, &CVehicle::SetData)
#ifdef VCMP_ENABLE_OFFICIAL
.Prop(_SC("Legacy"), &CVehicle::GetLegacyObject)
#endif
.Prop(_SC("Active"), &CVehicle::IsActive) .Prop(_SC("Active"), &CVehicle::IsActive)
// Core Methods // Core Methods
.FmtFunc(_SC("SetTag"), &CVehicle::ApplyTag) .FmtFunc(_SC("SetTag"), &CVehicle::ApplyTag)
+10 -3
View File
@@ -18,7 +18,8 @@ enum VehicleCircularLocks
VEHICLECL_EMIT_VEHICLE_TYRESTATUS = (1u << 4u), VEHICLECL_EMIT_VEHICLE_TYRESTATUS = (1u << 4u),
VEHICLECL_EMIT_VEHICLE_DAMAGEDATA = (1u << 5u), VEHICLECL_EMIT_VEHICLE_DAMAGEDATA = (1u << 5u),
VEHICLECL_EMIT_VEHICLE_RADIO = (1u << 6u), VEHICLECL_EMIT_VEHICLE_RADIO = (1u << 6u),
VEHICLECL_EMIT_VEHICLE_HANDLINGRULE = (1u << 7u) VEHICLECL_EMIT_VEHICLE_HANDLINGRULE = (1u << 7u),
VEHICLECL_EMIT_VEHICLE_EMBARK = (1u << 8u) // This should probably be shared with CPlayer
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -615,12 +616,12 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Embark the specified player entity into the managed vehicle entity. * Embark the specified player entity into the managed vehicle entity.
*/ */
bool Embark(CPlayer & player) const; bool Embark(CPlayer & player);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Embark the specified player entity into the managed vehicle entity. * Embark the specified player entity into the managed vehicle entity.
*/ */
bool EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp) const; bool EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp);
#if SQMOD_SDK_LEAST(2, 1) #if SQMOD_SDK_LEAST(2, 1)
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set whether the target player will see an objective arrow over a vehicle. * Set whether the target player will see an objective arrow over a vehicle.
@@ -941,6 +942,12 @@ public:
* Modify the relative turn velocity on the z axis of the managed vehicle entity. * Modify the relative turn velocity on the z axis of the managed vehicle entity.
*/ */
void SetRelativeTurnSpeedZ(float z) const; void SetRelativeTurnSpeedZ(float z) const;
#ifdef VCMP_ENABLE_OFFICIAL
/* --------------------------------------------------------------------------------------------
* Retrieve legacy object instance for this entity.
*/
LightObj & GetLegacyObject() const;
#endif
}; };
} // Namespace:: SqMod } // Namespace:: SqMod
+6 -2
View File
@@ -47,9 +47,11 @@ struct CpBaseAction : public ThreadPoolItem
~CpBaseAction() override = default; ~CpBaseAction() override = default;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Task completed callback. * 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 the boolean parameter is trye then the thread-pool is in the process of shutting down.
*/ */
void OnCompleted() override SQMOD_NODISCARD bool OnCompleted(bool SQ_UNUSED_ARG(stop)) override
{ {
// Is there a callback? // Is there a callback?
if (!mCallback.IsNull()) if (!mCallback.IsNull())
@@ -58,6 +60,8 @@ struct CpBaseAction : public ThreadPoolItem
} }
// Unlock the session // Unlock the session
mInstance->mPending = nullptr; mInstance->mPending = nullptr;
// Don't re-queue
return false;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
-800
View File
@@ -1,800 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Library/DPP.hpp"
#include "Core/Signal.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
// ------------------------------------------------------------------------------------------------
#include <sqratConst.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMOD_DECL_TYPENAME(SqDppCluster, _SC("SqDppCluster"))
// ------------------------------------------------------------------------------------------------
void TerminateDPP()
{
// Go over all clusters and try to terminate them
for (DpCluster * inst = DpCluster::sHead; inst && inst->mNext != DpCluster::sHead; inst = inst->mNext)
{
inst->Terminate(); // Terminate() the cluster
}
}
// ------------------------------------------------------------------------------------------------
void ProcessDPP()
{
// Go over all clusters and allow them to process data
for (DpCluster * inst = DpCluster::sHead; inst && inst->mNext != DpCluster::sHead; inst = inst->mNext)
{
inst->Process();
}
}
// ------------------------------------------------------------------------------------------------
extern void Register_DPPTy(HSQUIRRELVM vm, Table & ns);
extern void Register_DPPEv(HSQUIRRELVM vm, Table & ns);
// ================================================================================================
void Register_DPP(HSQUIRRELVM vm)
{
Table ns(vm);
// --------------------------------------------------------------------------------------------
{
Table ens(vm);
Register_DPPEv(vm, ens);
ns.Bind(_SC("Events"), ens);
}
// Register base types
Register_DPPTy(vm, ns);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("Cluster"),
Class< DpCluster, NoCopy< DpCluster > >(vm, SqDppCluster::Str)
// Constructors
.Ctor< StackStrF & >()
.Ctor< StackStrF &, SQInteger >()
.Ctor< StackStrF &, SQInteger, SQInteger >()
.Ctor< StackStrF &, SQInteger, SQInteger, SQInteger >()
.Ctor< StackStrF &, SQInteger, SQInteger, SQInteger, SQInteger >()
.Ctor< StackStrF &, SQInteger, SQInteger, SQInteger, SQInteger, bool >()
.Ctor< StackStrF &, SQInteger, SQInteger, SQInteger, SQInteger, bool, const DpCachePolicy & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppCluster::Fn)
// Member Properties
.Prop(_SC("On"), &DpCluster::GetEvents)
.Prop(_SC("UpTime"), &DpCluster::UpTime)
// Member Methods
.Func(_SC("Start"), &DpCluster::Start)
.Func(_SC("Log"), &DpCluster::Log)
.Func(_SC("GetDmChannel"), &DpCluster::GetDmChannel)
.Func(_SC("SetDmChannel"), &DpCluster::SetDmChannel)
.Func(_SC("SetPresence"), &DpCluster::SetPresence)
.Func(_SC("EnableEvent"), &DpCluster::EnableEvent)
.Func(_SC("DisableEvent"), &DpCluster::DisableEvent)
);
// --------------------------------------------------------------------------------------------
ns.Func(_SC("HasVoice"), dpp::utility::has_voice);
RootTable(vm).Bind(_SC("SqDiscord"), ns);
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD LightObj EventToScriptObject(uint8_t type, uintptr_t data);
void EventInvokeCleanup(uint8_t type, uintptr_t data);
// ------------------------------------------------------------------------------------------------
void DpCluster::Process(bool force)
{
// Is there a valid connection?
if (!mC && !force)
{
return; // No point in going forward
}
DpInternalEvent event;
// Retrieve each event individually and process it
for (size_t count = mQueue.size_approx(), n = 0; n <= count; ++n)
{
// Try to get an event from the queue
if (mQueue.try_dequeue(event))
{
// Fetch the type of event
const auto type = event.GetType();
// Fetch the event itself
const auto data = event.GetData();
// Is this a valid event and is anyone listening to it?
if (event.mData == 0 || mEvents[type].first == nullptr || mEvents[type].first->IsEmpty())
{
continue; // Move on
}
// Transform the event instance into a script object
LightObj obj = EventToScriptObject(type, data);
// Allow the script to take ownership of the event instance now
event.Reset();
// Forward the call to the associated signal
(*mEvents[type].first)(obj);
// Allow the event instance to clean itself
EventInvokeCleanup(type, data);
}
}
}
/* ================================================================================================
* Event handlers.
*/
void DpCluster::OnVoiceStateUpdate(const dpp::voice_state_update_t & ev)
{
mQueue.enqueue(DpInternalEvent(DpEventID::VoiceStateUpdate, new DpVoiceStateUpdateEvent(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnLog(const dpp::log_t & ev)
{
mQueue.enqueue(DpInternalEvent(DpEventID::Log, new DpLogEvent(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildJoinRequestDelete(const dpp::guild_join_request_delete_t & ev)
{
mQueue.enqueue(DpInternalEvent(DpEventID::GuildJoinRequestDelete, new DpGuildJoinRequestDeleteEvent(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnInteractionCreate(const dpp::interaction_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::InteractionCreate, new dpp::interaction_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnButtonClick(const dpp::button_click_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ButtonClick, new dpp::button_click_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnSelectClick(const dpp::select_click_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::SelectClick, new dpp::select_click_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildDelete(const dpp::guild_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildDelete, new dpp::guild_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnChannelDelete(const dpp::channel_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ChannelDelete, new dpp::channel_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnChannelUpdate(const dpp::channel_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ChannelUpdate, new dpp::channel_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnReady(const dpp::ready_t & ev)
{
mQueue.enqueue(DpInternalEvent(DpEventID::Ready, new DpReadyEvent(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnMessageDelete(const dpp::message_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::MessageDelete, new dpp::message_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnApplicationCommandDelete(const dpp::application_command_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ApplicationCommandDelete, new dpp::application_command_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildMemberRemove(const dpp::guild_member_remove_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildMemberRemove, new dpp::guild_member_remove_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnApplicationCommandCreate(const dpp::application_command_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ApplicationCommandCreate, new dpp::application_command_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnResumed(const dpp::resumed_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::Resumed, new dpp::resumed_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildRoleCreate(const dpp::guild_role_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildRoleCreate, new dpp::guild_role_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnTypingStart(const dpp::typing_start_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::TypingStart, new dpp::typing_start_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnMessageReactionAdd(const dpp::message_reaction_add_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::MessageReactionAdd, new dpp::message_reaction_add_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildMembersChunk(const dpp::guild_members_chunk_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildMembersChunk, new dpp::guild_members_chunk_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnMessageReactionRemove(const dpp::message_reaction_remove_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::MessageReactionRemove, new dpp::message_reaction_remove_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildCreate(const dpp::guild_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildCreate, new dpp::guild_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnChannelCreate(const dpp::channel_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ChannelCreate, new dpp::channel_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnMessageReactionRemoveEmoji(const dpp::message_reaction_remove_emoji_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::MessageReactionRemoveEmoji, new dpp::message_reaction_remove_emoji_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnMessageDeleteBulk(const dpp::message_delete_bulk_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::MessageDeleteBulk, new dpp::message_delete_bulk_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildRoleUpdate(const dpp::guild_role_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildRoleUpdate, new dpp::guild_role_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildRoleDelete(const dpp::guild_role_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildRoleDelete, new dpp::guild_role_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnChannelPinsUpdate(const dpp::channel_pins_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ChannelPinsUpdate, new dpp::channel_pins_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnMessageReactionRemoveAll(const dpp::message_reaction_remove_all_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::MessageReactionRemoveAll, new dpp::message_reaction_remove_all_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnVoiceServerUpdate(const dpp::voice_server_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::VoiceServerUpdate, new dpp::voice_server_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildEmojisUpdate(const dpp::guild_emojis_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildEmojisUpdate, new dpp::guild_emojis_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildStickersUpdate(const dpp::guild_stickers_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildStickersUpdate, new dpp::guild_stickers_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnPresenceUpdate(const dpp::presence_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::PresenceUpdate, new dpp::presence_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnWebhooksUpdate(const dpp::webhooks_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::WebhooksUpdate, new dpp::webhooks_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildMemberAdd(const dpp::guild_member_add_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildMemberAdd, new dpp::guild_member_add_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnInviteDelete(const dpp::invite_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::InviteDelete, new dpp::invite_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildUpdate(const dpp::guild_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildUpdate, new dpp::guild_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildIntegrationsUpdate(const dpp::guild_integrations_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildIntegrationsUpdate, new dpp::guild_integrations_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildMemberUpdate(const dpp::guild_member_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildMemberUpdate, new dpp::guild_member_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnApplicationCommandUpdate(const dpp::application_command_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ApplicationCommandUpdate, new dpp::application_command_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnInviteCreate(const dpp::invite_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::InviteCreate, new dpp::invite_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnMessageUpdate(const dpp::message_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::MessageUpdate, new dpp::message_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnUserUpdate(const dpp::user_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::UserUpdate, new dpp::user_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnMessageCreate(const dpp::message_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::MessageCreate, new dpp::message_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildBanAdd(const dpp::guild_ban_add_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildBanAdd, new dpp::guild_ban_add_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnGuildBanRemove(const dpp::guild_ban_remove_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::GuildBanRemove, new dpp::guild_ban_remove_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnIntegrationCreate(const dpp::integration_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::IntegrationCreate, new dpp::integration_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnIntegrationUpdate(const dpp::integration_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::IntegrationUpdate, new dpp::integration_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnIntegrationDelete(const dpp::integration_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::IntegrationDelete, new dpp::integration_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnThreadCreate(const dpp::thread_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ThreadCreate, new dpp::thread_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnThreadUpdate(const dpp::thread_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ThreadUpdate, new dpp::thread_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnThreadDelete(const dpp::thread_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ThreadDelete, new dpp::thread_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnThreadListSync(const dpp::thread_list_sync_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ThreadListSync, new dpp::thread_list_sync_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnThreadMemberUpdate(const dpp::thread_member_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ThreadMemberUpdate, new dpp::thread_member_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnThreadMembersUpdate(const dpp::thread_members_update_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::ThreadMembersUpdate, new dpp::thread_members_update_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnVoiceBufferSend(const dpp::voice_buffer_send_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::VoiceBufferSend, new dpp::voice_buffer_send_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnVoiceUserTalking(const dpp::voice_user_talking_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::VoiceUserTalking, new dpp::voice_user_talking_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnVoiceReady(const dpp::voice_ready_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::VoiceReady, new dpp::voice_ready_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnVoiceReceive(const dpp::voice_receive_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::VoiceReceive, new dpp::voice_receive_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnVoiceTrackMarker(const dpp::voice_track_marker_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::VoiceTrackMarker, new dpp::voice_track_marker_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnStageInstanceCreate(const dpp::stage_instance_create_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::StageInstanceCreate, new dpp::stage_instance_create_t(ev)));
}
// ------------------------------------------------------------------------------------------------
void DpCluster::OnStageInstanceDelete(const dpp::stage_instance_delete_t & ev)
{
//mQueue.enqueue(DpInternalEvent(DpEventID::StageInstanceDelete, new dpp::stage_instance_delete_t(ev)));
}
// ------------------------------------------------------------------------------------------------
DpCluster & DpCluster::EnableEvent(SQInteger id)
{
switch (id)
{
case DpEventID::VoiceStateUpdate: mC->on_voice_state_update([this](auto && e) { OnVoiceStateUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::Log: mC->on_log([this](auto && e) { OnLog(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildJoinRequestDelete: mC->on_guild_join_request_delete([this](auto && e) { OnGuildJoinRequestDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::InteractionCreate: mC->on_interaction_create([this](auto && e) { OnInteractionCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ButtonClick: mC->on_button_click([this](auto && e) { OnButtonClick(std::forward< decltype(e) >(e)); }); break;
case DpEventID::SelectClick: mC->on_select_click([this](auto && e) { OnSelectClick(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildDelete: mC->on_guild_delete([this](auto && e) { OnGuildDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ChannelDelete: mC->on_channel_delete([this](auto && e) { OnChannelDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ChannelUpdate: mC->on_channel_update([this](auto && e) { OnChannelUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::Ready: mC->on_ready([this](auto && e) { OnReady(std::forward< decltype(e) >(e)); }); break;
case DpEventID::MessageDelete: mC->on_message_delete([this](auto && e) { OnMessageDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ApplicationCommandDelete: mC->on_application_command_delete([this](auto && e) { OnApplicationCommandDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildMemberRemove: mC->on_guild_member_remove([this](auto && e) { OnGuildMemberRemove(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ApplicationCommandCreate: mC->on_application_command_create([this](auto && e) { OnApplicationCommandCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::Resumed: mC->on_resumed([this](auto && e) { OnResumed(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildRoleCreate: mC->on_guild_role_create([this](auto && e) { OnGuildRoleCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::TypingStart: mC->on_typing_start([this](auto && e) { OnTypingStart(std::forward< decltype(e) >(e)); }); break;
case DpEventID::MessageReactionAdd: mC->on_message_reaction_add([this](auto && e) { OnMessageReactionAdd(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildMembersChunk: mC->on_guild_members_chunk([this](auto && e) { OnGuildMembersChunk(std::forward< decltype(e) >(e)); }); break;
case DpEventID::MessageReactionRemove: mC->on_message_reaction_remove([this](auto && e) { OnMessageReactionRemove(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildCreate: mC->on_guild_create([this](auto && e) { OnGuildCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ChannelCreate: mC->on_channel_create([this](auto && e) { OnChannelCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::MessageReactionRemoveEmoji: mC->on_message_reaction_remove_emoji([this](auto && e) { OnMessageReactionRemoveEmoji(std::forward< decltype(e) >(e)); }); break;
case DpEventID::MessageDeleteBulk: mC->on_message_delete_bulk([this](auto && e) { OnMessageDeleteBulk(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildRoleUpdate: mC->on_guild_role_update([this](auto && e) { OnGuildRoleUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildRoleDelete: mC->on_guild_role_delete([this](auto && e) { OnGuildRoleDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ChannelPinsUpdate: mC->on_channel_pins_update([this](auto && e) { OnChannelPinsUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::MessageReactionRemoveAll: mC->on_message_reaction_remove_all([this](auto && e) { OnMessageReactionRemoveAll(std::forward< decltype(e) >(e)); }); break;
case DpEventID::VoiceServerUpdate: mC->on_voice_server_update([this](auto && e) { OnVoiceServerUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildEmojisUpdate: mC->on_guild_emojis_update([this](auto && e) { OnGuildEmojisUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildStickersUpdate: mC->on_guild_stickers_update([this](auto && e) { OnGuildStickersUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::PresenceUpdate: mC->on_presence_update([this](auto && e) { OnPresenceUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::WebhooksUpdate: mC->on_webhooks_update([this](auto && e) { OnWebhooksUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildMemberAdd: mC->on_guild_member_add([this](auto && e) { OnGuildMemberAdd(std::forward< decltype(e) >(e)); }); break;
case DpEventID::InviteDelete: mC->on_invite_delete([this](auto && e) { OnInviteDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildUpdate: mC->on_guild_update([this](auto && e) { OnGuildUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildIntegrationsUpdate: mC->on_guild_integrations_update([this](auto && e) { OnGuildIntegrationsUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildMemberUpdate: mC->on_guild_member_update([this](auto && e) { OnGuildMemberUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ApplicationCommandUpdate: mC->on_application_command_update([this](auto && e) { OnApplicationCommandUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::InviteCreate: mC->on_invite_create([this](auto && e) { OnInviteCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::MessageUpdate: mC->on_message_update([this](auto && e) { OnMessageUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::UserUpdate: mC->on_user_update([this](auto && e) { OnUserUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::MessageCreate: mC->on_message_create([this](auto && e) { OnMessageCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildBanAdd: mC->on_guild_ban_add([this](auto && e) { OnGuildBanAdd(std::forward< decltype(e) >(e)); }); break;
case DpEventID::GuildBanRemove: mC->on_guild_ban_remove([this](auto && e) { OnGuildBanRemove(std::forward< decltype(e) >(e)); }); break;
case DpEventID::IntegrationCreate: mC->on_integration_create([this](auto && e) { OnIntegrationCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::IntegrationUpdate: mC->on_integration_update([this](auto && e) { OnIntegrationUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::IntegrationDelete: mC->on_integration_delete([this](auto && e) { OnIntegrationDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ThreadCreate: mC->on_thread_create([this](auto && e) { OnThreadCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ThreadUpdate: mC->on_thread_update([this](auto && e) { OnThreadUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ThreadDelete: mC->on_thread_delete([this](auto && e) { OnThreadDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ThreadListSync: mC->on_thread_list_sync([this](auto && e) { OnThreadListSync(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ThreadMemberUpdate: mC->on_thread_member_update([this](auto && e) { OnThreadMemberUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::ThreadMembersUpdate: mC->on_thread_members_update([this](auto && e) { OnThreadMembersUpdate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::VoiceBufferSend: mC->on_voice_buffer_send([this](auto && e) { OnVoiceBufferSend(std::forward< decltype(e) >(e)); }); break;
case DpEventID::VoiceUserTalking: mC->on_voice_user_talking([this](auto && e) { OnVoiceUserTalking(std::forward< decltype(e) >(e)); }); break;
case DpEventID::VoiceReady: mC->on_voice_ready([this](auto && e) { OnVoiceReady(std::forward< decltype(e) >(e)); }); break;
case DpEventID::VoiceReceive: mC->on_voice_receive([this](auto && e) { OnVoiceReceive(std::forward< decltype(e) >(e)); }); break;
case DpEventID::VoiceTrackMarker: mC->on_voice_track_marker([this](auto && e) { OnVoiceTrackMarker(std::forward< decltype(e) >(e)); }); break;
case DpEventID::StageInstanceCreate: mC->on_stage_instance_create([this](auto && e) { OnStageInstanceCreate(std::forward< decltype(e) >(e)); }); break;
case DpEventID::StageInstanceDelete: mC->on_stage_instance_delete([this](auto && e) { OnStageInstanceDelete(std::forward< decltype(e) >(e)); }); break;
case DpEventID::Max: // Fall through
default: STHROWF("Invalid discord event identifier {}", id);
}
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
DpCluster & DpCluster::DisableEvent(SQInteger id)
{
switch (id)
{
case DpEventID::VoiceStateUpdate: mC->on_voice_state_update(std::function<void(const dpp::voice_state_update_t&)>{}); break;
case DpEventID::Log: mC->on_log(std::function<void(const dpp::log_t&)>{}); break;
case DpEventID::GuildJoinRequestDelete: mC->on_guild_join_request_delete(std::function<void(const dpp::guild_join_request_delete_t&)>{}); break;
case DpEventID::InteractionCreate: mC->on_interaction_create(std::function<void(const dpp::interaction_create_t&)>{}); break;
case DpEventID::ButtonClick: mC->on_button_click(std::function<void(const dpp::button_click_t&)>{}); break;
case DpEventID::SelectClick: mC->on_select_click(std::function<void(const dpp::select_click_t&)>{}); break;
case DpEventID::GuildDelete: mC->on_guild_delete(std::function<void(const dpp::guild_delete_t&)>{}); break;
case DpEventID::ChannelDelete: mC->on_channel_delete(std::function<void(const dpp::channel_delete_t&)>{}); break;
case DpEventID::ChannelUpdate: mC->on_channel_update(std::function<void(const dpp::channel_update_t&)>{}); break;
case DpEventID::Ready: mC->on_ready(std::function<void(const dpp::ready_t&)>{}); break;
case DpEventID::MessageDelete: mC->on_message_delete(std::function<void(const dpp::message_delete_t&)>{}); break;
case DpEventID::ApplicationCommandDelete: mC->on_application_command_delete(std::function<void(const dpp::application_command_delete_t&)>{}); break;
case DpEventID::GuildMemberRemove: mC->on_guild_member_remove(std::function<void(const dpp::guild_member_remove_t&)>{}); break;
case DpEventID::ApplicationCommandCreate: mC->on_application_command_create(std::function<void(const dpp::application_command_create_t&)>{}); break;
case DpEventID::Resumed: mC->on_resumed(std::function<void(const dpp::resumed_t&)>{}); break;
case DpEventID::GuildRoleCreate: mC->on_guild_role_create(std::function<void(const dpp::guild_role_create_t&)>{}); break;
case DpEventID::TypingStart: mC->on_typing_start(std::function<void(const dpp::typing_start_t&)>{}); break;
case DpEventID::MessageReactionAdd: mC->on_message_reaction_add(std::function<void(const dpp::message_reaction_add_t&)>{}); break;
case DpEventID::GuildMembersChunk: mC->on_guild_members_chunk(std::function<void(const dpp::guild_members_chunk_t&)>{}); break;
case DpEventID::MessageReactionRemove: mC->on_message_reaction_remove(std::function<void(const dpp::message_reaction_remove_t&)>{}); break;
case DpEventID::GuildCreate: mC->on_guild_create(std::function<void(const dpp::guild_create_t&)>{}); break;
case DpEventID::ChannelCreate: mC->on_channel_create(std::function<void(const dpp::channel_create_t&)>{}); break;
case DpEventID::MessageReactionRemoveEmoji: mC->on_message_reaction_remove_emoji(std::function<void(const dpp::message_reaction_remove_emoji_t&)>{}); break;
case DpEventID::MessageDeleteBulk: mC->on_message_delete_bulk(std::function<void(const dpp::message_delete_bulk_t&)>{}); break;
case DpEventID::GuildRoleUpdate: mC->on_guild_role_update(std::function<void(const dpp::guild_role_update_t&)>{}); break;
case DpEventID::GuildRoleDelete: mC->on_guild_role_delete(std::function<void(const dpp::guild_role_delete_t&)>{}); break;
case DpEventID::ChannelPinsUpdate: mC->on_channel_pins_update(std::function<void(const dpp::channel_pins_update_t&)>{}); break;
case DpEventID::MessageReactionRemoveAll: mC->on_message_reaction_remove_all(std::function<void(const dpp::message_reaction_remove_all_t&)>{}); break;
case DpEventID::VoiceServerUpdate: mC->on_voice_server_update(std::function<void(const dpp::voice_server_update_t&)>{}); break;
case DpEventID::GuildEmojisUpdate: mC->on_guild_emojis_update(std::function<void(const dpp::guild_emojis_update_t&)>{}); break;
case DpEventID::GuildStickersUpdate: mC->on_guild_stickers_update(std::function<void(const dpp::guild_stickers_update_t&)>{}); break;
case DpEventID::PresenceUpdate: mC->on_presence_update(std::function<void(const dpp::presence_update_t&)>{}); break;
case DpEventID::WebhooksUpdate: mC->on_webhooks_update(std::function<void(const dpp::webhooks_update_t&)>{}); break;
case DpEventID::GuildMemberAdd: mC->on_guild_member_add(std::function<void(const dpp::guild_member_add_t&)>{}); break;
case DpEventID::InviteDelete: mC->on_invite_delete(std::function<void(const dpp::invite_delete_t&)>{}); break;
case DpEventID::GuildUpdate: mC->on_guild_update(std::function<void(const dpp::guild_update_t&)>{}); break;
case DpEventID::GuildIntegrationsUpdate: mC->on_guild_integrations_update(std::function<void(const dpp::guild_integrations_update_t&)>{}); break;
case DpEventID::GuildMemberUpdate: mC->on_guild_member_update(std::function<void(const dpp::guild_member_update_t&)>{}); break;
case DpEventID::ApplicationCommandUpdate: mC->on_application_command_update(std::function<void(const dpp::application_command_update_t&)>{}); break;
case DpEventID::InviteCreate: mC->on_invite_create(std::function<void(const dpp::invite_create_t&)>{}); break;
case DpEventID::MessageUpdate: mC->on_message_update(std::function<void(const dpp::message_update_t&)>{}); break;
case DpEventID::UserUpdate: mC->on_user_update(std::function<void(const dpp::user_update_t&)>{}); break;
case DpEventID::MessageCreate: mC->on_message_create(std::function<void(const dpp::message_create_t&)>{}); break;
case DpEventID::GuildBanAdd: mC->on_guild_ban_add(std::function<void(const dpp::guild_ban_add_t&)>{}); break;
case DpEventID::GuildBanRemove: mC->on_guild_ban_remove(std::function<void(const dpp::guild_ban_remove_t&)>{}); break;
case DpEventID::IntegrationCreate: mC->on_integration_create(std::function<void(const dpp::integration_create_t&)>{}); break;
case DpEventID::IntegrationUpdate: mC->on_integration_update(std::function<void(const dpp::integration_update_t&)>{}); break;
case DpEventID::IntegrationDelete: mC->on_integration_delete(std::function<void(const dpp::integration_delete_t&)>{}); break;
case DpEventID::ThreadCreate: mC->on_thread_create(std::function<void(const dpp::thread_create_t&)>{}); break;
case DpEventID::ThreadUpdate: mC->on_thread_update(std::function<void(const dpp::thread_update_t&)>{}); break;
case DpEventID::ThreadDelete: mC->on_thread_delete(std::function<void(const dpp::thread_delete_t&)>{}); break;
case DpEventID::ThreadListSync: mC->on_thread_list_sync(std::function<void(const dpp::thread_list_sync_t&)>{}); break;
case DpEventID::ThreadMemberUpdate: mC->on_thread_member_update(std::function<void(const dpp::thread_member_update_t&)>{}); break;
case DpEventID::ThreadMembersUpdate: mC->on_thread_members_update(std::function<void(const dpp::thread_members_update_t&)>{}); break;
case DpEventID::VoiceBufferSend: mC->on_voice_buffer_send(std::function<void(const dpp::voice_buffer_send_t&)>{}); break;
case DpEventID::VoiceUserTalking: mC->on_voice_user_talking(std::function<void(const dpp::voice_user_talking_t&)>{}); break;
case DpEventID::VoiceReady: mC->on_voice_ready(std::function<void(const dpp::voice_ready_t&)>{}); break;
case DpEventID::VoiceReceive: mC->on_voice_receive(std::function<void(const dpp::voice_receive_t&)>{}); break;
case DpEventID::VoiceTrackMarker: mC->on_voice_track_marker(std::function<void(const dpp::voice_track_marker_t&)>{}); break;
case DpEventID::StageInstanceCreate: mC->on_stage_instance_create(std::function<void(const dpp::stage_instance_create_t&)>{}); break;
case DpEventID::StageInstanceDelete: mC->on_stage_instance_delete(std::function<void(const dpp::stage_instance_delete_t&)>{}); break;
case DpEventID::Max: // Fall through
default: STHROWF("Invalid discord event identifier {}", id);
}
// Allow chaining
return *this;
}
// ------------------------------------------------------------------------------------------------
void DpInternalEvent::Release()
{
// Make sure we actually manage something
if (mData == 0) return;
// Fetch the type of data
const auto type = GetType();
// Fetch the data itself
const auto data = GetData();
// Identify data type
switch (type)
{
case DpEventID::VoiceStateUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::Log: delete reinterpret_cast< DpLogEvent * >(data); break;
case DpEventID::GuildJoinRequestDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::InteractionCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ButtonClick: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::SelectClick: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ChannelDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ChannelUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::Ready: delete reinterpret_cast< DpReadyEvent * >(data); break;
case DpEventID::MessageDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ApplicationCommandDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildMemberRemove: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ApplicationCommandCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::Resumed: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildRoleCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::TypingStart: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageReactionAdd: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildMembersChunk: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageReactionRemove: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ChannelCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageReactionRemoveEmoji: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageDeleteBulk: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildRoleUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildRoleDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ChannelPinsUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageReactionRemoveAll: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceServerUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildEmojisUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildStickersUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::PresenceUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::WebhooksUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildMemberAdd: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::InviteDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildIntegrationsUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildMemberUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ApplicationCommandUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::InviteCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::UserUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildBanAdd: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildBanRemove: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::IntegrationCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::IntegrationUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::IntegrationDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadListSync: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadMemberUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadMembersUpdate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceBufferSend: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceUserTalking: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceReady: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceReceive: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceTrackMarker: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::StageInstanceCreate: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::StageInstanceDelete: delete reinterpret_cast< uint8_t * >(data); break;
case DpEventID::Max: // Fall through
default: LogFtl("Unrecognized discord event instance type"); assert(0); break;
}
// Forget about it
Reset();
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD LightObj EventToScriptObject(uint8_t type, uintptr_t data)
{
switch (type)
{
case DpEventID::VoiceStateUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::Log: return LightObj(reinterpret_cast< DpLogEvent * >(data));
case DpEventID::GuildJoinRequestDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::InteractionCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ButtonClick: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::SelectClick: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ChannelDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ChannelUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::Ready: return LightObj(reinterpret_cast< DpReadyEvent * >(data));
case DpEventID::MessageDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ApplicationCommandDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildMemberRemove: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ApplicationCommandCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::Resumed: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildRoleCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::TypingStart: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::MessageReactionAdd: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildMembersChunk: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::MessageReactionRemove: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ChannelCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::MessageReactionRemoveEmoji: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::MessageDeleteBulk: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildRoleUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildRoleDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ChannelPinsUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::MessageReactionRemoveAll: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::VoiceServerUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildEmojisUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildStickersUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::PresenceUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::WebhooksUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildMemberAdd: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::InviteDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildIntegrationsUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildMemberUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ApplicationCommandUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::InviteCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::MessageUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::UserUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::MessageCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildBanAdd: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::GuildBanRemove: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::IntegrationCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::IntegrationUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::IntegrationDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ThreadCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ThreadUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ThreadDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ThreadListSync: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ThreadMemberUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::ThreadMembersUpdate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::VoiceBufferSend: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::VoiceUserTalking: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::VoiceReady: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::VoiceReceive: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::VoiceTrackMarker: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::StageInstanceCreate: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::StageInstanceDelete: return LightObj(reinterpret_cast< uint8_t * >(data));
case DpEventID::Max: // Fall through
default: assert(0); return LightObj{};
}
}
// ------------------------------------------------------------------------------------------------
void EventInvokeCleanup(uint8_t type, uintptr_t data)
{
switch (type)
{
case DpEventID::VoiceStateUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::Log: reinterpret_cast< DpLogEvent * >(data)->Cleanup(); break;
case DpEventID::GuildJoinRequestDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::InteractionCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ButtonClick: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::SelectClick: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ChannelDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ChannelUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::Ready: reinterpret_cast< DpReadyEvent * >(data)->Cleanup(); break;
case DpEventID::MessageDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ApplicationCommandDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildMemberRemove: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ApplicationCommandCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::Resumed: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildRoleCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::TypingStart: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageReactionAdd: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildMembersChunk: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageReactionRemove: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ChannelCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageReactionRemoveEmoji: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageDeleteBulk: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildRoleUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildRoleDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ChannelPinsUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageReactionRemoveAll: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceServerUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildEmojisUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildStickersUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::PresenceUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::WebhooksUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildMemberAdd: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::InviteDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildIntegrationsUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildMemberUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ApplicationCommandUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::InviteCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::UserUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::MessageCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildBanAdd: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::GuildBanRemove: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::IntegrationCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::IntegrationUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::IntegrationDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadListSync: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadMemberUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::ThreadMembersUpdate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceBufferSend: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceUserTalking: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceReady: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceReceive: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::VoiceTrackMarker: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::StageInstanceCreate: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::StageInstanceDelete: reinterpret_cast< uint8_t * >(data); break;
case DpEventID::Max: // Fall through
default: assert(0); return;
}
}
} // Namespace:: SqMod
-428
View File
@@ -1,428 +0,0 @@
#pragma once
// ------------------------------------------------------------------------------------------------
#include "Library/DPPEv.hpp"
#include "Library/DPPTy.hpp"
#include "Core/Signal.hpp"
// ------------------------------------------------------------------------------------------------
#include <chrono>
#include <memory>
#include <functional>
// ------------------------------------------------------------------------------------------------
#include <concurrentqueue.h>
#include <dpp/dpp.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* WebSocket frame.
*/
struct DpInternalEvent
{
/* --------------------------------------------------------------------------------------------
* Event data.
*/
uint64_t mData{0llu};
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
DpInternalEvent() noexcept = default;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpInternalEvent(uint64_t type, void * data) noexcept
: mData((type << 56u) | reinterpret_cast< uint64_t >(data))
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
DpInternalEvent(const DpInternalEvent & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
DpInternalEvent(DpInternalEvent && o) noexcept
: mData(o.mData)
{
o.mData = 0llu; // Take ownership
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~DpInternalEvent()
{
Release();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
DpInternalEvent & operator = (const DpInternalEvent & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
DpInternalEvent & operator = (DpInternalEvent && o) noexcept
{
if (mData != o.mData)
{
// Release current information
Release();
// Replicate members
mData = o.mData;
// Take ownership
o.mData = 0llu;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Forget about the managed event data.
*/
void Reset() noexcept
{
mData = 0llu;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the event type.
*/
SQMOD_NODISCARD uint8_t GetType() const noexcept
{
return static_cast< uint8_t >((mData >> 56u) & 0xFFllu);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the event data.
*/
SQMOD_NODISCARD uintptr_t GetData() const noexcept
{
return static_cast< uintptr_t >((~(0xFFllu << 56u)) & mData);
}
/* --------------------------------------------------------------------------------------------
* Release associated event data, if any.
*/
void Release();
};
/* ------------------------------------------------------------------------------------------------
* The cluster class represents a group of shards and a command queue for sending and receiving
* commands from discord via HTTP.
*/
struct DpCluster : public SqChainedInstances< DpCluster >
{
/* --------------------------------------------------------------------------------------------
* Queue of events generated from other threads.
*/
using EventQueue = moodycamel::ConcurrentQueue< DpInternalEvent >;
/* --------------------------------------------------------------------------------------------
* Managed cluster instance.
*/
std::unique_ptr< dpp::cluster > mC{nullptr};
/* --------------------------------------------------------------------------------------------
* Event queue.
*/
EventQueue mQueue{4096};
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpCluster(StackStrF & token)
: mC(std::make_unique< dpp::cluster >(token.ToStr()))
, mQueue(4096)
{
Initialize();
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpCluster(StackStrF & token, SQInteger intents)
: mC(std::make_unique< dpp::cluster >(token.ToStr(), static_cast< uint32_t >(intents)))
, mQueue(4096)
{
Initialize();
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpCluster(StackStrF & token, SQInteger intents, SQInteger shards)
: mC(std::make_unique< dpp::cluster >(token.ToStr(), static_cast< uint32_t >(intents), static_cast< uint32_t >(shards)))
, mQueue(4096)
{
Initialize();
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpCluster(StackStrF & token, SQInteger intents, SQInteger shards, SQInteger cluster_id)
: mC(std::make_unique< dpp::cluster >(token.ToStr(), static_cast< uint32_t >(intents), static_cast< uint32_t >(shards), static_cast< uint32_t >(cluster_id)))
, mQueue(4096)
{
Initialize();
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpCluster(StackStrF & token, SQInteger intents, SQInteger shards, SQInteger cluster_id, SQInteger max_clusters)
: mC(std::make_unique< dpp::cluster >(token.ToStr(), static_cast< uint32_t >(intents), static_cast< uint32_t >(shards), static_cast< uint32_t >(cluster_id), static_cast< uint32_t >(max_clusters)))
, mQueue(4096)
{
Initialize();
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpCluster(StackStrF & token, SQInteger intents, SQInteger shards, SQInteger cluster_id, SQInteger max_clusters, bool compressed)
: mC(std::make_unique< dpp::cluster >(token.ToStr(), static_cast< uint32_t >(intents), static_cast< uint32_t >(shards), static_cast< uint32_t >(cluster_id), static_cast< uint32_t >(max_clusters), compressed))
, mQueue(4096)
{
Initialize();
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpCluster(StackStrF & token, SQInteger intents, SQInteger shards, SQInteger cluster_id, SQInteger max_clusters, bool compressed, const DpCachePolicy & cp)
: mC(std::make_unique< dpp::cluster >(token.ToStr(), static_cast< uint32_t >(intents), static_cast< uint32_t >(shards), static_cast< uint32_t >(cluster_id), static_cast< uint32_t >(max_clusters), compressed, cp.ToNative()))
, mQueue(4096)
{
Initialize();
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~DpCluster()
{
DropEvents();
// Forget about this instance
UnchainInstance();
}
/* --------------------------------------------------------------------------------------------
* Start the cluster, connecting all its shards. Returns once all shards are connected.
*/
DpCluster & Start()
{
LogInf("Before start...");
mC->start(true);
LogInf("After start...");
return *this;
}
/* --------------------------------------------------------------------------------------------
* Log a message to whatever log the user is using.
*/
DpCluster & Log(SQInteger severity, StackStrF & message)
{
mC->log(static_cast< dpp::loglevel >(severity), message.ToStr());
return *this;
}
/* --------------------------------------------------------------------------------------------
* Get the dm channel for a user id.
*/
SQMOD_NODISCARD dpp::snowflake GetDmChannel(dpp::snowflake user_id) const
{
return mC->get_dm_channel(static_cast< dpp::snowflake >(user_id));
}
/* --------------------------------------------------------------------------------------------
* Set the dm channel id for a user id.
*/
DpCluster & SetDmChannel(dpp::snowflake user_id, dpp::snowflake channel_id)
{
mC->set_dm_channel(user_id, channel_id);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Returns the uptime of the cluster.
*/
SQMOD_NODISCARD dpp::utility::uptime UpTime() const
{
return mC->uptime();
}
/* --------------------------------------------------------------------------------------------
* Returns the uptime of the cluster.
*/
DpCluster & SetPresence(const DpPresence & p)
{
mC->set_presence(p);
return *this;
}
// --------------------------------------------------------------------------------------------
LightObj mSqEvents{}; // Table containing the emitted cluster events.
/* --------------------------------------------------------------------------------------------
* Retrieve the events table of this cluster.
*/
SQMOD_NODISCARD LightObj & GetEvents()
{
return mSqEvents;
}
/* --------------------------------------------------------------------------------------------
* Cluster signals.
*/
std::array< SignalPair, static_cast< size_t >(DpEventID::Max) > mEvents{};
/* --------------------------------------------------------------------------------------------
* Process the cluster.
*/
void Process(bool force = false);
/* --------------------------------------------------------------------------------------------
* Terminate the cluster.
*/
void Terminate()
{
// Delete the cluster instance
mC.reset();
// Release associated script objects
mSqEvents.Release();
// Release event signal objects
DropEvents();
}
/* --------------------------------------------------------------------------------------------
* Enable a certain event for the cluster.
*/
DpCluster & EnableEvent(SQInteger id);
/* --------------------------------------------------------------------------------------------
* Disable a certain event for the cluster.
*/
DpCluster & DisableEvent(SQInteger id);
private:
/* --------------------------------------------------------------------------------------------
* Initialize the cluster.
*/
void Initialize()
{
InitEvents();
// Remember this instance
ChainInstance();
}
/* --------------------------------------------------------------------------------------------
* Signal initialization.
*/
void InitEvents()
{
// Ignore the call if already initialized
if (!mSqEvents.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(SqVM(), 64);
// Grab the table object from the stack
mSqEvents = LightObj(-1, SqVM());
// Pop the table object from the stack
sq_pop(SqVM(), 1);
// Proceed to initializing the events
for (size_t i = 0; i < mEvents.size(); ++i)
{
InitSignalPair(mEvents[i], mSqEvents, DpEventID::NAME[i]);
}
}
/* --------------------------------------------------------------------------------------------
* Signal termination.
*/
void DropEvents()
{
for (auto & e : mEvents)
{
ResetSignalPair(e);
}
}
/* --------------------------------------------------------------------------------------------
* Event handlers.
*/
void OnVoiceStateUpdate(const dpp::voice_state_update_t & ev);
void OnLog(const dpp::log_t & ev);
void OnGuildJoinRequestDelete(const dpp::guild_join_request_delete_t & ev);
void OnInteractionCreate(const dpp::interaction_create_t & ev);
void OnButtonClick(const dpp::button_click_t & ev);
void OnSelectClick(const dpp::select_click_t & ev);
void OnGuildDelete(const dpp::guild_delete_t & ev);
void OnChannelDelete(const dpp::channel_delete_t & ev);
void OnChannelUpdate(const dpp::channel_update_t & ev);
void OnReady(const dpp::ready_t & ev);
void OnMessageDelete(const dpp::message_delete_t & ev);
void OnApplicationCommandDelete(const dpp::application_command_delete_t & ev);
void OnGuildMemberRemove(const dpp::guild_member_remove_t & ev);
void OnApplicationCommandCreate(const dpp::application_command_create_t & ev);
void OnResumed(const dpp::resumed_t & ev);
void OnGuildRoleCreate(const dpp::guild_role_create_t & ev);
void OnTypingStart(const dpp::typing_start_t & ev);
void OnMessageReactionAdd(const dpp::message_reaction_add_t & ev);
void OnGuildMembersChunk(const dpp::guild_members_chunk_t & ev);
void OnMessageReactionRemove(const dpp::message_reaction_remove_t & ev);
void OnGuildCreate(const dpp::guild_create_t & ev);
void OnChannelCreate(const dpp::channel_create_t & ev);
void OnMessageReactionRemoveEmoji(const dpp::message_reaction_remove_emoji_t & ev);
void OnMessageDeleteBulk(const dpp::message_delete_bulk_t & ev);
void OnGuildRoleUpdate(const dpp::guild_role_update_t & ev);
void OnGuildRoleDelete(const dpp::guild_role_delete_t & ev);
void OnChannelPinsUpdate(const dpp::channel_pins_update_t & ev);
void OnMessageReactionRemoveAll(const dpp::message_reaction_remove_all_t & ev);
void OnVoiceServerUpdate(const dpp::voice_server_update_t & ev);
void OnGuildEmojisUpdate(const dpp::guild_emojis_update_t & ev);
void OnGuildStickersUpdate(const dpp::guild_stickers_update_t & ev);
void OnPresenceUpdate(const dpp::presence_update_t & ev);
void OnWebhooksUpdate(const dpp::webhooks_update_t & ev);
void OnGuildMemberAdd(const dpp::guild_member_add_t & ev);
void OnInviteDelete(const dpp::invite_delete_t & ev);
void OnGuildUpdate(const dpp::guild_update_t & ev);
void OnGuildIntegrationsUpdate(const dpp::guild_integrations_update_t & ev);
void OnGuildMemberUpdate(const dpp::guild_member_update_t & ev);
void OnApplicationCommandUpdate(const dpp::application_command_update_t & ev);
void OnInviteCreate(const dpp::invite_create_t & ev);
void OnMessageUpdate(const dpp::message_update_t & ev);
void OnUserUpdate(const dpp::user_update_t & ev);
void OnMessageCreate(const dpp::message_create_t & ev);
void OnGuildBanAdd(const dpp::guild_ban_add_t & ev);
void OnGuildBanRemove(const dpp::guild_ban_remove_t & ev);
void OnIntegrationCreate(const dpp::integration_create_t & ev);
void OnIntegrationUpdate(const dpp::integration_update_t & ev);
void OnIntegrationDelete(const dpp::integration_delete_t & ev);
void OnThreadCreate(const dpp::thread_create_t & ev);
void OnThreadUpdate(const dpp::thread_update_t & ev);
void OnThreadDelete(const dpp::thread_delete_t & ev);
void OnThreadListSync(const dpp::thread_list_sync_t & ev);
void OnThreadMemberUpdate(const dpp::thread_member_update_t & ev);
void OnThreadMembersUpdate(const dpp::thread_members_update_t & ev);
void OnVoiceBufferSend(const dpp::voice_buffer_send_t & ev);
void OnVoiceUserTalking(const dpp::voice_user_talking_t & ev);
void OnVoiceReady(const dpp::voice_ready_t & ev);
void OnVoiceReceive(const dpp::voice_receive_t & ev);
void OnVoiceTrackMarker(const dpp::voice_track_marker_t & ev);
void OnStageInstanceCreate(const dpp::stage_instance_create_t & ev);
void OnStageInstanceDelete(const dpp::stage_instance_delete_t & ev);
};
} // Namespace:: SqMod
-196
View File
@@ -1,196 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Library/DPPEv.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
// ------------------------------------------------------------------------------------------------
#include <sqratConst.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMOD_DECL_TYPENAME(SqDppVoiceStateUpdateEventEvent, _SC("SqDppVoiceStateUpdateEventEvent"))
SQMOD_DECL_TYPENAME(SqDppGuildJoinRequestDeleteEvent, _SC("SqDppGuildJoinRequestDeleteEvent"))
SQMOD_DECL_TYPENAME(SqDppLogEvent, _SC("SqDppLogEvent"))
SQMOD_DECL_TYPENAME(SqDppReadyEvent, _SC("SqDppReadyEvent"))
// ------------------------------------------------------------------------------------------------
const std::array< const char *, static_cast< size_t >(DpEventID::Max) > DpEventID::NAME{
"VoiceStateUpdate",
"Log",
"GuildJoinRequestDelete",
"InteractionCreate",
"ButtonClick",
"SelectClick",
"GuildDelete",
"ChannelDelete",
"ChannelUpdate",
"Ready",
"MessageDelete",
"ApplicationCommandDelete",
"GuildMemberRemove",
"ApplicationCommandCreate",
"Resumed",
"GuildRoleCreate",
"TypingStart",
"MessageReactionAdd",
"GuildMembersChunk",
"MessageReactionRemove",
"GuildCreate",
"ChannelCreate",
"MessageReactionRemoveEmoji",
"MessageDeleteBulk",
"GuildRoleUpdate",
"GuildRoleDelete",
"ChannelPinsUpdate",
"MessageReactionRemoveAll",
"VoiceServerUpdate",
"GuildEmojisUpdate",
"GuildStickersUpdate",
"PresenceUpdate",
"WebhooksUpdate",
"GuildMemberAdd",
"InviteDelete",
"GuildUpdate",
"GuildIntegrationsUpdate",
"GuildMemberUpdate",
"ApplicationCommandUpdate",
"InviteCreate",
"MessageUpdate",
"UserUpdate",
"MessageCreate",
"GuildBanAdd",
"GuildBanRemove",
"IntegrationCreate",
"IntegrationUpdate",
"IntegrationDelete",
"ThreadCreate",
"ThreadUpdate",
"ThreadDelete",
"ThreadListSync",
"ThreadMemberUpdate",
"ThreadMembersUpdate",
"VoiceBufferSend",
"VoiceUserTalking",
"VoiceReady",
"VoiceReceive",
"VoiceTrackMarker",
"StageInstanceCreate",
"StageInstanceDelete"
};
// ------------------------------------------------------------------------------------------------
void Register_DPPEv(HSQUIRRELVM vm, Table & ns)
{
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("VoiceStateUpdate"),
Class< DpVoiceStateUpdateEvent, NoConstructor< DpVoiceStateUpdateEvent > >(vm, SqDppVoiceStateUpdateEventEvent::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppVoiceStateUpdateEventEvent::Fn)
.Func(_SC("_tostring"), &DpVoiceStateUpdateEvent::GetRawEvent)
// Member Properties
.Prop(_SC("State"), &DpVoiceStateUpdateEvent::GetState)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("Log"),
Class< DpLogEvent, NoConstructor< DpLogEvent > >(vm, SqDppLogEvent::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppLogEvent::Fn)
.Func(_SC("_tostring"), &DpLogEvent::GetRawEvent)
// Member Properties
.Prop(_SC("RawEvent"), &DpLogEvent::GetRawEvent)
.Prop(_SC("Severity"), &DpLogEvent::GetSeverity)
.Prop(_SC("Message"), &DpLogEvent::GetMessage)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("Ready"),
Class< DpReadyEvent, NoConstructor< DpReadyEvent > >(vm, SqDppReadyEvent::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppReadyEvent::Fn)
.Func(_SC("_tostring"), &DpReadyEvent::GetRawEvent)
// Member Properties
.Prop(_SC("RawEvent"), &DpReadyEvent::GetRawEvent)
.Prop(_SC("SessionID"), &DpReadyEvent::GetSessionID)
.Prop(_SC("ShardID"), &DpReadyEvent::GetShardID)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("GuildJoinRequestDelete"),
Class< DpGuildJoinRequestDeleteEvent, NoConstructor< DpGuildJoinRequestDeleteEvent > >(vm, SqDppGuildJoinRequestDeleteEvent::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppGuildJoinRequestDeleteEvent::Fn)
.Func(_SC("_tostring"), &DpGuildJoinRequestDeleteEvent::GetRawEvent)
// Member Properties
.Prop(_SC("RawEvent"), &DpGuildJoinRequestDeleteEvent::GetRawEvent)
.Prop(_SC("GuildID"), &DpGuildJoinRequestDeleteEvent::GetGuildID)
.Prop(_SC("UserID"), &DpGuildJoinRequestDeleteEvent::GetUserID)
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordEvent"), Enumeration(vm)
.Const(_SC("VoiceStateUpdate"), static_cast< SQInteger >(DpEventID::VoiceStateUpdate))
.Const(_SC("Log"), static_cast< SQInteger >(DpEventID::Log))
.Const(_SC("GuildJoinRequestDelete"), static_cast< SQInteger >(DpEventID::GuildJoinRequestDelete))
.Const(_SC("InteractionCreate"), static_cast< SQInteger >(DpEventID::InteractionCreate))
.Const(_SC("ButtonClick"), static_cast< SQInteger >(DpEventID::ButtonClick))
.Const(_SC("SelectClick"), static_cast< SQInteger >(DpEventID::SelectClick))
.Const(_SC("GuildDelete"), static_cast< SQInteger >(DpEventID::GuildDelete))
.Const(_SC("ChannelDelete"), static_cast< SQInteger >(DpEventID::ChannelDelete))
.Const(_SC("ChannelUpdate"), static_cast< SQInteger >(DpEventID::ChannelUpdate))
.Const(_SC("Ready"), static_cast< SQInteger >(DpEventID::Ready))
.Const(_SC("MessageDelete"), static_cast< SQInteger >(DpEventID::MessageDelete))
.Const(_SC("ApplicationCommandDelete"), static_cast< SQInteger >(DpEventID::ApplicationCommandDelete))
.Const(_SC("GuildMemberRemove"), static_cast< SQInteger >(DpEventID::GuildMemberRemove))
.Const(_SC("ApplicationCommandCreate"), static_cast< SQInteger >(DpEventID::ApplicationCommandCreate))
.Const(_SC("Resumed"), static_cast< SQInteger >(DpEventID::Resumed))
.Const(_SC("GuildRoleCreate"), static_cast< SQInteger >(DpEventID::GuildRoleCreate))
.Const(_SC("TypingStart"), static_cast< SQInteger >(DpEventID::TypingStart))
.Const(_SC("MessageReactionAdd"), static_cast< SQInteger >(DpEventID::MessageReactionAdd))
.Const(_SC("GuildMembersChunk"), static_cast< SQInteger >(DpEventID::GuildMembersChunk))
.Const(_SC("MessageReactionRemove"), static_cast< SQInteger >(DpEventID::MessageReactionRemove))
.Const(_SC("GuildCreate"), static_cast< SQInteger >(DpEventID::GuildCreate))
.Const(_SC("ChannelCreate"), static_cast< SQInteger >(DpEventID::ChannelCreate))
.Const(_SC("MessageReactionRemoveEmoji"), static_cast< SQInteger >(DpEventID::MessageReactionRemoveEmoji))
.Const(_SC("MessageDeleteBulk"), static_cast< SQInteger >(DpEventID::MessageDeleteBulk))
.Const(_SC("GuildRoleUpdate"), static_cast< SQInteger >(DpEventID::GuildRoleUpdate))
.Const(_SC("GuildRoleDelete"), static_cast< SQInteger >(DpEventID::GuildRoleDelete))
.Const(_SC("ChannelPinsUpdate"), static_cast< SQInteger >(DpEventID::ChannelPinsUpdate))
.Const(_SC("MessageReactionRemoveAll"), static_cast< SQInteger >(DpEventID::MessageReactionRemoveAll))
.Const(_SC("VoiceServerUpdate"), static_cast< SQInteger >(DpEventID::VoiceServerUpdate))
.Const(_SC("GuildEmojisUpdate"), static_cast< SQInteger >(DpEventID::GuildEmojisUpdate))
.Const(_SC("GuildStickersUpdate"), static_cast< SQInteger >(DpEventID::GuildStickersUpdate))
.Const(_SC("PresenceUpdate"), static_cast< SQInteger >(DpEventID::PresenceUpdate))
.Const(_SC("WebhooksUpdate"), static_cast< SQInteger >(DpEventID::WebhooksUpdate))
.Const(_SC("GuildMemberAdd"), static_cast< SQInteger >(DpEventID::GuildMemberAdd))
.Const(_SC("InviteDelete"), static_cast< SQInteger >(DpEventID::InviteDelete))
.Const(_SC("GuildUpdate"), static_cast< SQInteger >(DpEventID::GuildUpdate))
.Const(_SC("GuildIntegrationsUpdate"), static_cast< SQInteger >(DpEventID::GuildIntegrationsUpdate))
.Const(_SC("GuildMemberUpdate"), static_cast< SQInteger >(DpEventID::GuildMemberUpdate))
.Const(_SC("ApplicationCommandUpdate"), static_cast< SQInteger >(DpEventID::ApplicationCommandUpdate))
.Const(_SC("InviteCreate"), static_cast< SQInteger >(DpEventID::InviteCreate))
.Const(_SC("MessageUpdate"), static_cast< SQInteger >(DpEventID::MessageUpdate))
.Const(_SC("UserUpdate"), static_cast< SQInteger >(DpEventID::UserUpdate))
.Const(_SC("MessageCreate"), static_cast< SQInteger >(DpEventID::MessageCreate))
.Const(_SC("GuildBanAdd"), static_cast< SQInteger >(DpEventID::GuildBanAdd))
.Const(_SC("GuildBanRemove"), static_cast< SQInteger >(DpEventID::GuildBanRemove))
.Const(_SC("IntegrationCreate"), static_cast< SQInteger >(DpEventID::IntegrationCreate))
.Const(_SC("IntegrationUpdate"), static_cast< SQInteger >(DpEventID::IntegrationUpdate))
.Const(_SC("IntegrationDelete"), static_cast< SQInteger >(DpEventID::IntegrationDelete))
.Const(_SC("ThreadCreate"), static_cast< SQInteger >(DpEventID::ThreadCreate))
.Const(_SC("ThreadUpdate"), static_cast< SQInteger >(DpEventID::ThreadUpdate))
.Const(_SC("ThreadDelete"), static_cast< SQInteger >(DpEventID::ThreadDelete))
.Const(_SC("ThreadListSync"), static_cast< SQInteger >(DpEventID::ThreadListSync))
.Const(_SC("ThreadMemberUpdate"), static_cast< SQInteger >(DpEventID::ThreadMemberUpdate))
.Const(_SC("ThreadMembersUpdate"), static_cast< SQInteger >(DpEventID::ThreadMembersUpdate))
.Const(_SC("VoiceBufferSend"), static_cast< SQInteger >(DpEventID::VoiceBufferSend))
.Const(_SC("VoiceUserTalking"), static_cast< SQInteger >(DpEventID::VoiceUserTalking))
.Const(_SC("VoiceReady"), static_cast< SQInteger >(DpEventID::VoiceReady))
.Const(_SC("VoiceReceive"), static_cast< SQInteger >(DpEventID::VoiceReceive))
.Const(_SC("VoiceTrackMarker"), static_cast< SQInteger >(DpEventID::VoiceTrackMarker))
.Const(_SC("StageInstanceCreate"), static_cast< SQInteger >(DpEventID::StageInstanceCreate))
.Const(_SC("StageInstanceDelete"), static_cast< SQInteger >(DpEventID::StageInstanceDelete))
.Const(_SC("Max"), static_cast< SQInteger >(DpEventID::Max))
);
}
} // Namespace:: SqMod
-383
View File
@@ -1,383 +0,0 @@
#pragma once
// ------------------------------------------------------------------------------------------------
#include "Library/DPPTy.hpp"
// ------------------------------------------------------------------------------------------------
#include <chrono>
#include <functional>
// ------------------------------------------------------------------------------------------------
#include <dpp/dpp.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Unique ID for each event.
*/
struct DpEventID
{
/* --------------------------------------------------------------------------------------------
* ID enumeration.
*/
enum Type
{
VoiceStateUpdate=0,
Log,
GuildJoinRequestDelete,
InteractionCreate,
ButtonClick,
SelectClick,
GuildDelete,
ChannelDelete,
ChannelUpdate,
Ready,
MessageDelete,
ApplicationCommandDelete,
GuildMemberRemove,
ApplicationCommandCreate,
Resumed,
GuildRoleCreate,
TypingStart,
MessageReactionAdd,
GuildMembersChunk,
MessageReactionRemove,
GuildCreate,
ChannelCreate,
MessageReactionRemoveEmoji,
MessageDeleteBulk,
GuildRoleUpdate,
GuildRoleDelete,
ChannelPinsUpdate,
MessageReactionRemoveAll,
VoiceServerUpdate,
GuildEmojisUpdate,
GuildStickersUpdate,
PresenceUpdate,
WebhooksUpdate,
GuildMemberAdd,
InviteDelete,
GuildUpdate,
GuildIntegrationsUpdate,
GuildMemberUpdate,
ApplicationCommandUpdate,
InviteCreate,
MessageUpdate,
UserUpdate,
MessageCreate,
GuildBanAdd,
GuildBanRemove,
IntegrationCreate,
IntegrationUpdate,
IntegrationDelete,
ThreadCreate,
ThreadUpdate,
ThreadDelete,
ThreadListSync,
ThreadMemberUpdate,
ThreadMembersUpdate,
VoiceBufferSend,
VoiceUserTalking,
VoiceReady,
VoiceReceive,
VoiceTrackMarker,
StageInstanceCreate,
StageInstanceDelete,
Max
};
/* --------------------------------------------------------------------------------------------
* String identification.
*/
static const std::array< const char *, static_cast< size_t >(Max) > NAME;
};
/* ------------------------------------------------------------------------------------------------
* Base class of an event handler.
*/
struct DpEventBase
{
/* --------------------------------------------------------------------------------------------
* Raw event text.
*/
std::string mRaw{};
/* --------------------------------------------------------------------------------------------
* Shard the event came from.
*/
dpp::discord_client * mFrom{nullptr};
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
DpEventBase() noexcept = default;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpEventBase(const dpp::event_dispatch_t & d) noexcept
: mRaw(d.raw_event), mFrom(d.from)
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
DpEventBase(const DpEventBase &) noexcept = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor (disabled).
*/
DpEventBase(DpEventBase &&) noexcept = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
virtual ~DpEventBase() noexcept = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
DpEventBase & operator = (const DpEventBase &) noexcept = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator (disabled).
*/
DpEventBase & operator = (DpEventBase &&) noexcept = delete;
/* --------------------------------------------------------------------------------------------
* Cleanup after the event was processed.
*/
virtual void Cleanup()
{
mFrom = nullptr;
}
};
/* ------------------------------------------------------------------------------------------------
* Voice state update event.
*/
struct DpVoiceStateUpdateEvent : public DpEventBase
{
// --------------------------------------------------------------------------------------------
dpp::voicestate mState{};
// --------------------------------------------------------------------------------------------
LightObj mSqState{};
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpVoiceStateUpdateEvent(const dpp::voice_state_update_t & d) noexcept
: DpEventBase(d), mState(d.state), mSqState()
{
}
/* --------------------------------------------------------------------------------------------
* Validate the managed handle.
*/
void Validate() const { if (!mFrom) STHROWF("Invalid discord [Ready] event handle"); }
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and retrieve a reference to it.
*/
SQMOD_NODISCARD DpVoiceStateUpdateEvent & Valid() { Validate(); return *this; }
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and retrieve a const reference to it.
*/
SQMOD_NODISCARD const DpVoiceStateUpdateEvent & Valid() const { Validate(); return *this; }
/* --------------------------------------------------------------------------------------------
* Cleanup after the event was processed.
*/
void Cleanup() override
{
if (!mSqState.IsNull())
{
[[maybe_unused]] auto p = mSqState.CastI< DpVoiceState >()->mPtr.release();
// Release script resources
mSqState.Release();
}
// Allow the base to cleanup as well
DpEventBase::Cleanup();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw event.
*/
SQMOD_NODISCARD const std::string & GetRawEvent() const { return mRaw; }
/* --------------------------------------------------------------------------------------------
* Retrieve the voice state.
*/
SQMOD_NODISCARD LightObj & GetState()
{
if (Valid().mSqState.IsNull())
{
mSqState = LightObj{SqTypeIdentity< DpVoiceState >{}, SqVM(), &mState, false};
}
// Return the associated script object
return mSqState;
}
};
/* ------------------------------------------------------------------------------------------------
* Guild join request delete (user declined membership screening) event.
*/
struct DpGuildJoinRequestDeleteEvent : public DpEventBase
{
// --------------------------------------------------------------------------------------------
dpp::snowflake mGuildID{};
dpp::snowflake mUserID{};
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpGuildJoinRequestDeleteEvent(const dpp::guild_join_request_delete_t & d) noexcept
: DpEventBase(d), mGuildID(d.guild_id), mUserID(d.user_id)
{
}
/* --------------------------------------------------------------------------------------------
* Validate the managed handle.
*/
void Validate() const { if (!mFrom) STHROWF("Invalid discord [GuildJoinRequestDelete] event handle"); }
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and retrieve a reference to it.
*/
SQMOD_NODISCARD DpGuildJoinRequestDeleteEvent & Valid() { Validate(); return *this; }
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and retrieve a const reference to it.
*/
SQMOD_NODISCARD const DpGuildJoinRequestDeleteEvent & Valid() const { Validate(); return *this; }
/* --------------------------------------------------------------------------------------------
* Cleanup after the event was processed.
*/
void Cleanup() override
{
// Allow the base to cleanup as well
DpEventBase::Cleanup();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw event.
*/
SQMOD_NODISCARD const std::string & GetRawEvent() const { return Valid().mRaw; }
/* --------------------------------------------------------------------------------------------
* Retrieve the guild id.
*/
SQMOD_NODISCARD dpp::snowflake GetGuildID() const { return Valid().mGuildID; }
/* --------------------------------------------------------------------------------------------
* Retrieve the user id.
*/
SQMOD_NODISCARD dpp::snowflake GetUserID() const { return Valid().mUserID; }
};
/* ------------------------------------------------------------------------------------------------
* Log message event.
*/
struct DpLogEvent : public DpEventBase
{
// --------------------------------------------------------------------------------------------
SQInteger mSeverity{0};
std::string mMessage{};
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpLogEvent(const dpp::log_t & d) noexcept
: DpEventBase(d), mSeverity(d.severity), mMessage(d.message)
{
}
/* --------------------------------------------------------------------------------------------
* Cleanup after the event was processed.
*/
void Cleanup() override
{
// Allow the base to cleanup as well
DpEventBase::Cleanup();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw event.
*/
SQMOD_NODISCARD const std::string & GetRawEvent() const { return mRaw; }
/* --------------------------------------------------------------------------------------------
* Retrieve log severity.
*/
SQMOD_NODISCARD SQInteger GetSeverity() const { return mSeverity; }
/* --------------------------------------------------------------------------------------------
* Retrieve log message.
*/
SQMOD_NODISCARD const std::string & GetMessage() const { return mMessage; }
};
/* ------------------------------------------------------------------------------------------------
* Session ready event.
*/
struct DpReadyEvent : public DpEventBase
{
// --------------------------------------------------------------------------------------------
std::string mSessionID{};
uint32_t mShardID{};
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpReadyEvent(const dpp::ready_t & d) noexcept
: DpEventBase(d)
, mSessionID(d.session_id)
, mShardID(d.shard_id)
{
}
/* --------------------------------------------------------------------------------------------
* Validate the managed handle.
*/
void Validate() const { if (!mFrom) STHROWF("Invalid discord [Ready] event handle"); }
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and retrieve a reference to it.
*/
SQMOD_NODISCARD DpReadyEvent & Valid() { Validate(); return *this; }
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and retrieve a const reference to it.
*/
SQMOD_NODISCARD const DpReadyEvent & Valid() const { Validate(); return *this; }
/* --------------------------------------------------------------------------------------------
* Cleanup after the event was processed.
*/
void Cleanup() override
{
// Allow the base to cleanup as well
DpEventBase::Cleanup();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw event.
*/
SQMOD_NODISCARD const std::string & GetRawEvent() const { return Valid().mRaw; }
/* --------------------------------------------------------------------------------------------
* Retrieve the session id.
*/
SQMOD_NODISCARD const std::string & GetSessionID() const { return Valid().mSessionID; }
/* --------------------------------------------------------------------------------------------
* Retrieve the shard id.
*/
SQMOD_NODISCARD SQInteger GetShardID() const { return static_cast< SQInteger >(Valid().mShardID); }
};
} // Namespace:: SqMod
-257
View File
@@ -1,257 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Library/DPPTy.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
// ------------------------------------------------------------------------------------------------
#include <sqratConst.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMOD_DECL_TYPENAME(SqDppCachePolicy, _SC("SqDppCachePolicy"))
SQMOD_DECL_TYPENAME(SqDppUptime, _SC("SqDppUptime"))
SQMOD_DECL_TYPENAME(SqDppIconHash, _SC("SqDppIconHash"))
SQMOD_DECL_TYPENAME(SqDppActivity, _SC("SqDppActivity"))
SQMOD_DECL_TYPENAME(SqDppPresence, _SC("SqDppPresence"))
SQMOD_DECL_TYPENAME(SqDppVoiceState, _SC("SqDppVoiceState"))
SQMOD_DECL_TYPENAME(SqDppGuild, _SC("SqDppGuild"))
// ------------------------------------------------------------------------------------------------
void Register_DPPConst(HSQUIRRELVM vm, Table & ns);
// ------------------------------------------------------------------------------------------------
void Register_DPPTy(HSQUIRRELVM vm, Table & ns)
{
Register_DPPConst(vm, ns);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("Uptime"),
Class< dpp::utility::uptime >(vm, SqDppUptime::Str)
// Constructors
.Ctor()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppUptime::Fn)
.Func(_SC("_tostring"), &dpp::utility::uptime::to_string)
// Member Variables
.Var(_SC("Days"), &dpp::utility::uptime::days)
.Var(_SC("Hours"), &dpp::utility::uptime::hours)
.Var(_SC("Minutes"), &dpp::utility::uptime::mins)
.Var(_SC("Seconds"), &dpp::utility::uptime::secs)
// Member Methods
.Func(_SC("ToSeconds"), &dpp::utility::uptime::to_secs)
.Func(_SC("ToMilliseconds"), &dpp::utility::uptime::to_msecs)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("IconHash"),
Class< dpp::utility::iconhash >(vm, SqDppIconHash::Str)
// Constructors
.Ctor()
.Ctor< const std::string & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppIconHash::Fn)
.Func(_SC("_tostring"), &dpp::utility::iconhash::to_string)
// Member Variables
.Var(_SC("High"), &dpp::utility::iconhash::first)
.Var(_SC("Low"), &dpp::utility::iconhash::second)
// Member Methods
.Func(_SC("Set"), &dpp::utility::iconhash::set)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("CachePolicy"),
Class< DpCachePolicy >(vm, SqDppCachePolicy::Str)
// Constructors
.Ctor()
.Ctor< SQInteger >()
.Ctor< SQInteger, SQInteger >()
.Ctor< SQInteger, SQInteger, SQInteger >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppCachePolicy::Fn)
// Member Variables
.Var(_SC("UserPolicy"), &DpCachePolicy::mUserPolicy)
.Var(_SC("EmojiPolicy"), &DpCachePolicy::mEmojiPolicy)
.Var(_SC("RolePolicy"), &DpCachePolicy::mRolePolicy)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("Activity"),
Class< DpActivity >(vm, SqDppActivity::Str)
// Constructors
.Ctor()
.Ctor< SQInteger, StackStrF &, StackStrF &, StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppActivity::Fn)
// Member Properties
.Prop(_SC("Name"), &DpActivity::GetName, &DpActivity::SetName)
.Prop(_SC("State"), &DpActivity::GetState, &DpActivity::SetState)
.Prop(_SC("URL"), &DpActivity::GetURL, &DpActivity::SetURL)
.Prop(_SC("Type"), &DpActivity::GetType, &DpActivity::SetType)
.Prop(_SC("CreatedAt"), &DpActivity::GetCreatedAt, &DpActivity::SetCreatedAt)
.Prop(_SC("Start"), &DpActivity::GetStart, &DpActivity::SetStart)
.Prop(_SC("End"), &DpActivity::GetEnd, &DpActivity::SetEnd)
// Member Methods
.Func(_SC("SetName"), &DpActivity::ApplyName)
.Func(_SC("SetState"), &DpActivity::ApplyState)
.Func(_SC("SetURL"), &DpActivity::ApplyURL)
.Func(_SC("SetType"), &DpActivity::ApplyType)
.Func(_SC("SetCreatedAt"), &DpActivity::ApplyCreatedAt)
.Func(_SC("SetStart"), &DpActivity::ApplyStart)
.Func(_SC("SetEnd"), &DpActivity::ApplyEnd)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("Presence"),
Class< DpPresence >(vm, SqDppPresence::Str)
// Constructors
.Ctor()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppPresence::Fn)
// Member Properties
.Prop(_SC("UserID"), &DpPresence::GetUserID, &DpPresence::SetUserID)
.Prop(_SC("GuildID"), &DpPresence::GetGuildID, &DpPresence::SetGuildID)
.Prop(_SC("Flags"), &DpPresence::GetFlags, &DpPresence::SetFlags)
.Prop(_SC("ActivityCount"), &DpPresence::ActivityCount)
.Prop(_SC("DesktopStatus"), &DpPresence::GetDesktopStatus)
.Prop(_SC("WebStatus"), &DpPresence::GetWebStatus)
.Prop(_SC("MobileStatus"), &DpPresence::GetMobileStatus)
.Prop(_SC("Status"), &DpPresence::GetStatus)
// Member Methods
.Func(_SC("SetUserID"), &DpPresence::ApplyUserID)
.Func(_SC("SetGuildID"), &DpPresence::ApplyGuildID)
.Func(_SC("SetFlags"), &DpPresence::ApplyFlags)
.Func(_SC("AddActivity"), &DpPresence::AddActivity)
.Func(_SC("EachActivity"), &DpPresence::EachActivity)
.Func(_SC("ClearActivities"), &DpPresence::ClearActivities)
.Func(_SC("FilterActivities"), &DpPresence::FilterActivities)
.Func(_SC("BuildJSON"), &DpPresence::BuildJSON)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("VoiceState"),
Class< DpVoiceState, NoConstructor< DpVoiceState > >(vm, SqDppVoiceState::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppVoiceState::Fn)
.Func(_SC("_tojson"), &DpVoiceState::BuildJSON)
// Member Properties
.Prop(_SC("Valid"), &DpVoiceState::IsValid)
.Prop(_SC("GuildID"), &DpVoiceState::GetGuildID)
.Prop(_SC("ChannelID"), &DpVoiceState::GetChannelID)
.Prop(_SC("UserID"), &DpVoiceState::GetUserID)
.Prop(_SC("SessionID"), &DpVoiceState::GetSessionID)
.Prop(_SC("Flags"), &DpVoiceState::GetFlags, &DpVoiceState::SetFlags)
.Prop(_SC("JSON"), &DpVoiceState::BuildJSON)
.Prop(_SC("Deaf"), &DpVoiceState::IsDeaf)
.Prop(_SC("Mute"), &DpVoiceState::IsMute)
.Prop(_SC("SelfMute"), &DpVoiceState::IsSelfMute)
.Prop(_SC("SelfDeaf"), &DpVoiceState::IsSelfDeaf)
.Prop(_SC("SelfStream"), &DpVoiceState::SelfStream)
.Prop(_SC("SelfVideo"), &DpVoiceState::SelfVideo)
.Prop(_SC("Supressed"), &DpVoiceState::IsSupressed)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("Guild"),
Class< DpGuild, NoConstructor< DpGuild > >(vm, SqDppGuild::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqDppGuild::Fn)
// Member Properties
.Prop(_SC("Valid"), &DpGuild::IsValid)
);
}
// ------------------------------------------------------------------------------------------------
void Register_DPPConst(HSQUIRRELVM vm, Table & ns)
{
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordLogLevel"), Enumeration(vm)
.Const(_SC("Trace"), static_cast< SQInteger >(dpp::ll_trace))
.Const(_SC("Debug"), static_cast< SQInteger >(dpp::ll_debug))
.Const(_SC("Info"), static_cast< SQInteger >(dpp::ll_info))
.Const(_SC("Warning"), static_cast< SQInteger >(dpp::ll_warning))
.Const(_SC("Error"), static_cast< SQInteger >(dpp::ll_error))
.Const(_SC("Critical"), static_cast< SQInteger >(dpp::ll_critical))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordImageType"), Enumeration(vm)
.Const(_SC("PNG"), static_cast< SQInteger >(dpp::i_png))
.Const(_SC("JPG"), static_cast< SQInteger >(dpp::i_jpg))
.Const(_SC("GIF"), static_cast< SQInteger >(dpp::i_gif))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordCachePolicy"), Enumeration(vm)
.Const(_SC("Aggressive"), static_cast< SQInteger >(dpp::cp_aggressive))
.Const(_SC("Lazy"), static_cast< SQInteger >(dpp::cp_lazy))
.Const(_SC("None"), static_cast< SQInteger >(dpp::cp_none))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordClusterIntents"), Enumeration(vm)
.Const(_SC("Guilds"), static_cast< SQInteger >(dpp::i_guilds))
.Const(_SC("GuildMembers"), static_cast< SQInteger >(dpp::i_guild_members))
.Const(_SC("GuildBans"), static_cast< SQInteger >(dpp::i_guild_bans))
.Const(_SC("GuildEmojis"), static_cast< SQInteger >(dpp::i_guild_emojis))
.Const(_SC("GuildIntegrations"), static_cast< SQInteger >(dpp::i_guild_integrations))
.Const(_SC("GuildWebhooks"), static_cast< SQInteger >(dpp::i_guild_webhooks))
.Const(_SC("GuildInvites"), static_cast< SQInteger >(dpp::i_guild_invites))
.Const(_SC("GuildVoiceStates"), static_cast< SQInteger >(dpp::i_guild_voice_states))
.Const(_SC("GuildPresences"), static_cast< SQInteger >(dpp::i_guild_presences))
.Const(_SC("GuildMessages"), static_cast< SQInteger >(dpp::i_guild_messages))
.Const(_SC("GuildMessageReactions"), static_cast< SQInteger >(dpp::i_guild_message_reactions))
.Const(_SC("GuildMessageTyping"), static_cast< SQInteger >(dpp::i_guild_message_typing))
.Const(_SC("DirectMessages"), static_cast< SQInteger >(dpp::i_direct_messages))
.Const(_SC("DirectMessageReactions"), static_cast< SQInteger >(dpp::i_direct_message_reactions))
.Const(_SC("DirectMessageTyping"), static_cast< SQInteger >(dpp::i_direct_message_typing))
.Const(_SC("Default"), static_cast< SQInteger >(dpp::i_default_intents))
.Const(_SC("Privileged"), static_cast< SQInteger >(dpp::i_privileged_intents))
.Const(_SC("All"), static_cast< SQInteger >(dpp::i_all_intents))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordPresenceFlags"), Enumeration(vm)
.Const(_SC("DesktopOnline"), static_cast< SQInteger >(dpp::p_desktop_online))
.Const(_SC("DesktopDND"), static_cast< SQInteger >(dpp::p_desktop_dnd))
.Const(_SC("DesktopIdle"), static_cast< SQInteger >(dpp::p_desktop_idle))
.Const(_SC("WebWnline"), static_cast< SQInteger >(dpp::p_web_online))
.Const(_SC("WebDND"), static_cast< SQInteger >(dpp::p_web_dnd))
.Const(_SC("WebIdle"), static_cast< SQInteger >(dpp::p_web_idle))
.Const(_SC("MobileOnline"), static_cast< SQInteger >(dpp::p_mobile_online))
.Const(_SC("MobileDND"), static_cast< SQInteger >(dpp::p_mobile_dnd))
.Const(_SC("MobileIdle"), static_cast< SQInteger >(dpp::p_mobile_idle))
.Const(_SC("StatusOnline"), static_cast< SQInteger >(dpp::p_status_online))
.Const(_SC("StatusDND"), static_cast< SQInteger >(dpp::p_status_dnd))
.Const(_SC("StatusIdle"), static_cast< SQInteger >(dpp::p_status_idle))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordPresenceStatus"), Enumeration(vm)
.Const(_SC("Offline"), static_cast< SQInteger >(dpp::ps_offline))
.Const(_SC("Online"), static_cast< SQInteger >(dpp::ps_online))
.Const(_SC("DND"), static_cast< SQInteger >(dpp::ps_dnd))
.Const(_SC("Idle"), static_cast< SQInteger >(dpp::ps_idle))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordDesktopStatusBits"), Enumeration(vm)
.Const(_SC("ShiftDesktop"), static_cast< SQInteger >(PF_SHIFT_DESKTOP))
.Const(_SC("ShiftWeb"), static_cast< SQInteger >(PF_SHIFT_WEB))
.Const(_SC("ShiftMobile"), static_cast< SQInteger >(PF_SHIFT_MOBILE))
.Const(_SC("ShiftMain"), static_cast< SQInteger >(PF_SHIFT_MAIN))
.Const(_SC("StatusMask"), static_cast< SQInteger >(PF_STATUS_MASK))
.Const(_SC("ClearDesktop"), static_cast< SQInteger >(PF_CLEAR_DESKTOP))
.Const(_SC("ClearWeb"), static_cast< SQInteger >(PF_CLEAR_WEB))
.Const(_SC("ClearMobile"), static_cast< SQInteger >(PF_CLEAR_MOBILE))
.Const(_SC("ClearStatus"), static_cast< SQInteger >(PF_CLEAR_STATUS))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordActivityType"), Enumeration(vm)
.Const(_SC("Game"), static_cast< SQInteger >(dpp::at_game))
.Const(_SC("Streaming"), static_cast< SQInteger >(dpp::at_streaming))
.Const(_SC("Listening"), static_cast< SQInteger >(dpp::at_listening))
.Const(_SC("Custom"), static_cast< SQInteger >(dpp::at_custom))
.Const(_SC("Competing"), static_cast< SQInteger >(dpp::at_competing))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqDiscordActivityFlags"), Enumeration(vm)
.Const(_SC("Instance"), static_cast< SQInteger >(dpp::af_instance))
.Const(_SC("Join"), static_cast< SQInteger >(dpp::af_join))
.Const(_SC("Spectate"), static_cast< SQInteger >(dpp::af_spectate))
.Const(_SC("JoinRequest"), static_cast< SQInteger >(dpp::af_join_request))
.Const(_SC("Sync"), static_cast< SQInteger >(dpp::af_sync))
.Const(_SC("Play"), static_cast< SQInteger >(dpp::af_play))
);
}
} // Namespace:: SqMod
-702
View File
@@ -1,702 +0,0 @@
#pragma once
// ------------------------------------------------------------------------------------------------
#include "Core/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <dpp/dpp.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Represents the caching policy of the cluster.
*/
struct DpCachePolicy
{
SQInteger mUserPolicy{dpp::cp_aggressive};
SQInteger mEmojiPolicy{dpp::cp_aggressive};
SQInteger mRolePolicy{dpp::cp_aggressive};
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
DpCachePolicy() noexcept = default;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpCachePolicy(SQInteger user) noexcept
: mUserPolicy(user), mEmojiPolicy(dpp::cp_aggressive), mRolePolicy(dpp::cp_aggressive)
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpCachePolicy(SQInteger user, SQInteger emoji) noexcept
: mUserPolicy(user), mEmojiPolicy(emoji), mRolePolicy(dpp::cp_aggressive)
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpCachePolicy(SQInteger user, SQInteger emoji, SQInteger role) noexcept
: mUserPolicy(user), mEmojiPolicy(emoji), mRolePolicy(role)
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
DpCachePolicy(const DpCachePolicy &) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Convert to native cache policy type.
*/
SQMOD_NODISCARD dpp::cache_policy_t ToNative() const noexcept
{
return dpp::cache_policy_t{
static_cast< dpp::cache_policy_setting_t >(mUserPolicy),
static_cast< dpp::cache_policy_setting_t >(mEmojiPolicy),
static_cast< dpp::cache_policy_setting_t >(mRolePolicy)
};
}
};
/* ------------------------------------------------------------------------------------------------
* An activity is a representation of what a user is doing. It might be a game, or a website, or a movie. Whatever.
*/
struct DpActivity : public dpp::activity
{
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
DpActivity()
: dpp::activity()
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
DpActivity(SQInteger type, StackStrF & name, StackStrF & state, StackStrF & url)
: dpp::activity(static_cast< dpp::activity_type >(type), name.ToStr(), state.ToStr(), url.ToStr())
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
explicit DpActivity(const dpp::activity & o)
: dpp::activity(o)
{
}
/* --------------------------------------------------------------------------------------------
* Retrieve the name of the activity.
*/
SQMOD_NODISCARD const std::string & GetName() const noexcept
{
return dpp::activity::name;
}
/* --------------------------------------------------------------------------------------------
* Modify the name of the activity.
*/
void SetName(StackStrF & name)
{
dpp::activity::name = name.ToStr();
}
/* --------------------------------------------------------------------------------------------
* Modify the name of the activity.
*/
DpActivity & ApplyName(StackStrF & name)
{
SetName(name);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the state of the activity.
*/
SQMOD_NODISCARD const std::string & GetState() const noexcept
{
return dpp::activity::state;
}
/* --------------------------------------------------------------------------------------------
* Modify the state of the activity.
*/
void SetState(StackStrF & state)
{
dpp::activity::state = state.ToStr();
}
/* --------------------------------------------------------------------------------------------
* Modify the state of the activity.
*/
DpActivity & ApplyState(StackStrF & state)
{
SetState(state);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the url of the activity.
*/
SQMOD_NODISCARD const std::string & GetURL() const noexcept
{
return dpp::activity::url;
}
/* --------------------------------------------------------------------------------------------
* Modify the url of the activity.
*/
void SetURL(StackStrF & url)
{
dpp::activity::url = url.ToStr();
}
/* --------------------------------------------------------------------------------------------
* Modify the url of the activity.
*/
DpActivity & ApplyURL(StackStrF & url)
{
SetURL(url);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the type of the activity.
*/
SQMOD_NODISCARD SQInteger GetType() const noexcept
{
return static_cast< SQInteger >(dpp::activity::type);
}
/* --------------------------------------------------------------------------------------------
* Modify the type of the activity.
*/
void SetType(SQInteger s)
{
dpp::activity::type = static_cast< dpp::activity_type >(s);
}
/* --------------------------------------------------------------------------------------------
* Modify the type of the activity.
*/
DpActivity & ApplyType(SQInteger s)
{
SetType(s);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve when the activity was created.
*/
SQMOD_NODISCARD SQInteger GetCreatedAt() const noexcept
{
return static_cast< SQInteger >(std::chrono::duration_cast< std::chrono::seconds >(std::chrono::system_clock::from_time_t(dpp::activity::created_at).time_since_epoch()).count());
}
/* --------------------------------------------------------------------------------------------
* Modify when the activity was created.
*/
void SetCreatedAt(SQInteger s)
{
dpp::activity::created_at = std::chrono::system_clock::to_time_t(std::chrono::time_point< std::chrono::system_clock >{std::chrono::seconds{s}});
}
/* --------------------------------------------------------------------------------------------
* Modify when the activity was created.
*/
DpActivity & ApplyCreatedAt(SQInteger s)
{
SetCreatedAt(s);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve when the activity was started.
*/
SQMOD_NODISCARD SQInteger GetStart() const noexcept
{
return static_cast< SQInteger >(std::chrono::duration_cast< std::chrono::seconds >(std::chrono::system_clock::from_time_t(dpp::activity::start).time_since_epoch()).count());
}
/* --------------------------------------------------------------------------------------------
* Modify when the activity was started.
*/
void SetStart(SQInteger s)
{
dpp::activity::start = std::chrono::system_clock::to_time_t(std::chrono::time_point< std::chrono::system_clock >{std::chrono::seconds{s}});
}
/* --------------------------------------------------------------------------------------------
* Modify when the activity was started.
*/
DpActivity & ApplyStart(SQInteger s)
{
SetStart(s);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve when the activity was stopped.
*/
SQMOD_NODISCARD SQInteger GetEnd() const noexcept
{
return static_cast< SQInteger >(std::chrono::duration_cast< std::chrono::seconds >(std::chrono::system_clock::from_time_t(dpp::activity::end).time_since_epoch()).count());
}
/* --------------------------------------------------------------------------------------------
* Modify when the activity was stopped.
*/
void SetEnd(SQInteger s)
{
dpp::activity::end = std::chrono::system_clock::to_time_t(std::chrono::time_point< std::chrono::system_clock >{std::chrono::seconds{s}});
}
/* --------------------------------------------------------------------------------------------
* Modify when the activity was stopped.
*/
DpActivity & ApplyEnd(SQInteger s)
{
SetEnd(s);
return *this;
}
};
/* ------------------------------------------------------------------------------------------------
* Represents user presence, e.g. what game they are playing and if they are online.
*/
struct DpPresence : public dpp::presence
{
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
DpPresence()
: dpp::presence()
{
}
/* --------------------------------------------------------------------------------------------
* Retrieve the user that the presence applies to.
*/
SQMOD_NODISCARD dpp::snowflake GetUserID() const noexcept
{
return dpp::presence::user_id;
}
/* --------------------------------------------------------------------------------------------
* Modify the user that the presence applies to.
*/
void SetUserID(dpp::snowflake id)
{
dpp::presence::user_id = id;
}
/* --------------------------------------------------------------------------------------------
* Modify the user that the presence applies to.
*/
DpPresence & ApplyUserID(dpp::snowflake id)
{
SetUserID(id);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the guild that the presence applies to.
*/
SQMOD_NODISCARD dpp::snowflake GetGuildID() const noexcept
{
return dpp::presence::guild_id;
}
/* --------------------------------------------------------------------------------------------
* Modify the guild that the presence applies to.
*/
void SetGuildID(dpp::snowflake id)
{
dpp::presence::guild_id = id;
}
/* --------------------------------------------------------------------------------------------
* Modify the guild that the presence applies to.
*/
DpPresence & ApplyGuildID(dpp::snowflake id)
{
SetGuildID(id);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the presence bit-mask.
*/
SQMOD_NODISCARD SQInteger GetFlags() const noexcept
{
return static_cast< SQInteger >(dpp::presence::flags);
}
/* --------------------------------------------------------------------------------------------
* Modify the presence bit-mask.
*/
void SetFlags(SQInteger f)
{
dpp::presence::flags = static_cast< uint8_t >(f);
}
/* --------------------------------------------------------------------------------------------
* Modify the presence bit-mask.
*/
DpPresence & ApplyFlags(SQInteger f)
{
SetFlags(f);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of activities.
*/
SQMOD_NODISCARD SQInteger ActivityCount() const
{
return static_cast< SQInteger >(dpp::presence::activities.size());
}
/* --------------------------------------------------------------------------------------------
* Add a new activity.
*/
DpPresence & AddActivity(const DpActivity & a)
{
dpp::presence::activities.push_back(a);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Iterate all activities.
*/
DpPresence & EachActivity(Function & fn)
{
for (const auto & a : dpp::presence::activities)
{
fn.Execute(a);
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of activities.
*/
DpPresence & ClearActivities(const DpActivity & a)
{
dpp::presence::activities.clear();
return *this;
}
/* --------------------------------------------------------------------------------------------
* Filter activities.
*/
DpPresence & FilterActivities(Function & fn)
{
std::vector< dpp::activity > list;
list.reserve(dpp::presence::activities.size());
for (const auto & a : dpp::presence::activities)
{
auto ret = fn.Eval(a);
// (null || true) == keep & false == skip
if (!ret.IsNull() || !ret.template Cast< bool >())
{
list.push_back(a);
}
}
dpp::presence::activities.swap(list);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Build JSON string from this object.
*/
SQMOD_NODISCARD std::string BuildJSON() const
{
return dpp::presence::build_json();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the users status on desktop.
*/
SQMOD_NODISCARD SQInteger GetDesktopStatus() const noexcept
{
return static_cast< SQInteger >(dpp::presence::desktop_status());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the user's status on web.
*/
SQMOD_NODISCARD SQInteger GetWebStatus() const noexcept
{
return static_cast< SQInteger >(dpp::presence::web_status());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the user's status on mobile.
*/
SQMOD_NODISCARD SQInteger GetMobileStatus() const noexcept
{
return static_cast< SQInteger >(dpp::presence::mobile_status());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the user's status as shown to other users.
*/
SQMOD_NODISCARD SQInteger GetStatus() const noexcept
{
return static_cast< SQInteger >(dpp::presence::status());
}
};
/* ------------------------------------------------------------------------------------------------
* Represents the voice state of a user on a guild.
* These are stored in the DpGuild object, and accessible there, or via DpChannel::GetVoiceMembers.
*/
struct DpVoiceState
{
using Ptr = std::unique_ptr< dpp::voicestate >;
/* --------------------------------------------------------------------------------------------
* Referenced voice state instance.
*/
Ptr mPtr{nullptr};
/* --------------------------------------------------------------------------------------------
* Whether the referenced pointer is owned.
*/
bool mOwned{false};
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
DpVoiceState() noexcept = default;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpVoiceState(Ptr::pointer ptr, bool owned = false) noexcept
: mPtr(ptr), mOwned(owned)
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
DpVoiceState(const DpVoiceState & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
DpVoiceState(DpVoiceState && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~DpVoiceState() noexcept
{
// Do we own this to try delete it?
if (!mOwned && mPtr) [[maybe_unused]] auto p = mPtr.release();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
DpVoiceState & operator = (const DpVoiceState & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
DpVoiceState & operator = (DpVoiceState && o) noexcept
{
if (this != &o)
{
// Do we own this to try delete it?
if (!mOwned && mPtr) [[maybe_unused]] auto p = mPtr.release();
// Transfer members values
mPtr = std::move(o.mPtr);
mOwned = o.mOwned;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Validate the managed handle.
*/
void Validate() const { if (!mPtr) STHROWF("Invalid discord voice state handle"); }
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and retrieve a const reference to it.
*/
SQMOD_NODISCARD Ptr::element_type & Valid() const { Validate(); return *mPtr; }
/* --------------------------------------------------------------------------------------------
* Check whether a valid instance is managed.
*/
SQMOD_NODISCARD bool IsValid() const { return static_cast< bool >(mPtr); }
/* --------------------------------------------------------------------------------------------
* Retrieve the guild id this voice state is for (optional).
*/
SQMOD_NODISCARD dpp::snowflake GetGuildID() const { return Valid().guild_id; }
/* --------------------------------------------------------------------------------------------
* Retrieve the guild id this voice state is for (optional).
*/
SQMOD_NODISCARD dpp::snowflake GetChannelID() const { return Valid().channel_id; }
/* --------------------------------------------------------------------------------------------
* Retrieve the guild id this voice state is for (optional).
*/
SQMOD_NODISCARD dpp::snowflake GetUserID() const { return Valid().user_id; }
/* --------------------------------------------------------------------------------------------
* Retrieve the guild id this voice state is for (optional).
*/
SQMOD_NODISCARD const std::string & GetSessionID() const { return Valid().session_id; }
/* --------------------------------------------------------------------------------------------
* Retrieve the guild id this voice state is for (optional).
*/
SQMOD_NODISCARD SQInteger GetFlags() const { return Valid().flags; }
/* --------------------------------------------------------------------------------------------
* Retrieve the guild id this voice state is for (optional).
*/
void SetFlags(SQInteger flags) const { Valid().flags = flags; }
/* --------------------------------------------------------------------------------------------
* Retrieve the guild id this voice state is for (optional).
*/
SQMOD_NODISCARD std::string BuildJSON() const { return Valid().build_json(); }
/* --------------------------------------------------------------------------------------------
* Check if user is deafened.
*/
SQMOD_NODISCARD bool IsDeaf() const { return Valid().is_deaf(); }
/* --------------------------------------------------------------------------------------------
* Check if user is muted.
*/
SQMOD_NODISCARD bool IsMute() const { return Valid().is_mute(); }
/* --------------------------------------------------------------------------------------------
* Check if user muted themselves.
*/
SQMOD_NODISCARD bool IsSelfMute() const { return Valid().is_self_mute(); }
/* --------------------------------------------------------------------------------------------
* Check if user deafened themselves.
*/
SQMOD_NODISCARD bool IsSelfDeaf() const { return Valid().is_self_deaf(); }
/* --------------------------------------------------------------------------------------------
* Check if user is streamig.
*/
SQMOD_NODISCARD bool SelfStream() const { return Valid().self_stream(); }
/* --------------------------------------------------------------------------------------------
* Check if user is in video.
*/
SQMOD_NODISCARD bool SelfVideo() const { return Valid().self_video(); }
/* --------------------------------------------------------------------------------------------
* Check if user is surpressed.
*/
SQMOD_NODISCARD bool IsSupressed() const { return Valid().is_supressed(); }
};
/* ------------------------------------------------------------------------------------------------
* Represents a guild on Discord (AKA a server)
*/
struct DpGuild
{
using Ptr = std::unique_ptr< dpp::guild >;
/* --------------------------------------------------------------------------------------------
* Referenced voice state instance.
*/
Ptr mPtr{nullptr};
/* --------------------------------------------------------------------------------------------
* Whether the referenced pointer is owned.
*/
bool mOwned{false};
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
DpGuild() noexcept = default;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit DpGuild(Ptr::pointer ptr, bool owned = false) noexcept
: mPtr(ptr), mOwned(owned)
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
DpGuild(const DpGuild & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
DpGuild(DpGuild && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~DpGuild() noexcept
{
// Do we own this to try delete it?
if (!mOwned && mPtr) [[maybe_unused]] auto p = mPtr.release();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
DpGuild & operator = (const DpGuild & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
DpGuild & operator = (DpGuild && o) noexcept
{
if (this != &o)
{
// Do we own this to try delete it?
if (!mOwned && mPtr) [[maybe_unused]] auto p = mPtr.release();
// Transfer members values
mPtr = std::move(o.mPtr);
mOwned = o.mOwned;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Validate the managed handle.
*/
void Validate() const { if (!mPtr) STHROWF("Invalid discord guild handle"); }
/* --------------------------------------------------------------------------------------------
* Validate the managed handle and retrieve a const reference to it.
*/
SQMOD_NODISCARD Ptr::element_type & Valid() const { Validate(); return *mPtr; }
/* --------------------------------------------------------------------------------------------
* Check whether a valid instance is managed.
*/
SQMOD_NODISCARD bool IsValid() const { return static_cast< bool >(mPtr); }
};
} // Namespace:: SqMod
+56 -13
View File
@@ -11,6 +11,13 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include <Poco/Checksum.h> #include <Poco/Checksum.h>
#include <Poco/Base32Encoder.h>
#include <Poco/Base32Decoder.h>
#include <Poco/Base64Encoder.h>
#include <Poco/Base64Decoder.h>
// ------------------------------------------------------------------------------------------------
#include <sstream>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
@@ -30,7 +37,7 @@ SQInteger SqBuffer::WriteRawString(StackStrF & val) const
} }
// Calculate the string length // Calculate the string length
Buffer::SzType length = ConvTo< Buffer::SzType >::From(val.mLen); Buffer::SzType length = ConvTo< Buffer::SzType >::From(val.mLen);
// Write the the string contents // Write the string contents
m_Buffer->AppendS(val.mPtr, length); m_Buffer->AppendS(val.mPtr, length);
// Return the length of the written string // Return the length of the written string
return val.mLen; return val.mLen;
@@ -224,7 +231,7 @@ AABB SqBuffer::ReadAABB() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< AABB >(1); m_Buffer->Advance< AABB >(1);
// Return the requested information // Return the requested information
return AABB(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -237,7 +244,7 @@ Circle SqBuffer::ReadCircle() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Circle >(1); m_Buffer->Advance< Circle >(1);
// Return the requested information // Return the requested information
return Circle(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -250,7 +257,7 @@ Color3 SqBuffer::ReadColor3() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Color3 >(1); m_Buffer->Advance< Color3 >(1);
// Return the requested information // Return the requested information
return Color3(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -263,7 +270,7 @@ Color4 SqBuffer::ReadColor4() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Color4 >(1); m_Buffer->Advance< Color4 >(1);
// Return the requested information // Return the requested information
return Color4(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -276,7 +283,7 @@ Quaternion SqBuffer::ReadQuaternion() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Quaternion >(1); m_Buffer->Advance< Quaternion >(1);
// Return the requested information // Return the requested information
return Quaternion(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -289,7 +296,7 @@ Sphere SqBuffer::ReadSphere() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Sphere >(1); m_Buffer->Advance< Sphere >(1);
// Return the requested information // Return the requested information
return Sphere(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -302,7 +309,7 @@ Vector2 SqBuffer::ReadVector2() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Vector2 >(1); m_Buffer->Advance< Vector2 >(1);
// Return the requested information // Return the requested information
return Vector2(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -315,7 +322,7 @@ Vector2i SqBuffer::ReadVector2i() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Vector2i >(1); m_Buffer->Advance< Vector2i >(1);
// Return the requested information // Return the requested information
return Vector2i(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -328,7 +335,7 @@ Vector3 SqBuffer::ReadVector3() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Vector3 >(1); m_Buffer->Advance< Vector3 >(1);
// Return the requested information // Return the requested information
return Vector3(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -341,7 +348,7 @@ Vector4 SqBuffer::ReadVector4() const
// Advance the buffer cursor // Advance the buffer cursor
m_Buffer->Advance< Vector4 >(1); m_Buffer->Advance< Vector4 >(1);
// Return the requested information // Return the requested information
return Vector4(value); return {value};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -352,7 +359,7 @@ SQInteger SqBuffer::GetCRC32(SQInteger n) const
// Create the checksum computer // Create the checksum computer
Poco::Checksum c(Poco::Checksum::TYPE_CRC32); Poco::Checksum c(Poco::Checksum::TYPE_CRC32);
// Give it the data to process // Give it the data to process
c.update(&m_Buffer->Cursor< char >(), n >= 0 ? static_cast< uint32_t >(n) : m_Buffer->Remaining()); c.update(&m_Buffer->Cursor< char >(), ClampRemaining(n));
// return the result // return the result
return static_cast< SQInteger >(c.checksum()); return static_cast< SQInteger >(c.checksum());
} }
@@ -365,12 +372,46 @@ SQInteger SqBuffer::GetADLER32(SQInteger n) const
// Create the checksum computer // Create the checksum computer
Poco::Checksum c(Poco::Checksum::TYPE_ADLER32); Poco::Checksum c(Poco::Checksum::TYPE_ADLER32);
// Give it the data to process // Give it the data to process
c.update(&m_Buffer->Cursor< char >(), n >= 0 ? static_cast< uint32_t >(n) : m_Buffer->Remaining()); c.update(&m_Buffer->Cursor< char >(), ClampRemaining(n));
// return the result // return the result
return static_cast< SQInteger >(c.checksum()); return static_cast< SQInteger >(c.checksum());
} }
// ------------------------------------------------------------------------------------------------
LightObj SqBuffer::GetBase32(SQInteger n) const
{
// Validate the managed buffer reference
ValidateDeeper();
// Create a string receiver
std::ostringstream out;
// Create the encoder
Poco::Base32Encoder enc(out);
// Encode the string
enc.write(&m_Buffer->Cursor< char >(), ClampRemaining(n));
// Close the encoder
enc.close();
// Return the resulted string
return LightObj{out.str()};
}
// ------------------------------------------------------------------------------------------------
LightObj SqBuffer::GetBase64(SQInteger n) const
{
// Validate the managed buffer reference
ValidateDeeper();
// Create a string receiver
std::ostringstream out;
// Create the encoder
Poco::Base64Encoder enc(out);
// Encode the string
enc.write(&m_Buffer->Cursor< char >(), ClampRemaining(n));
// Close the encoder
enc.close();
// Return the resulted string
return LightObj{out.str()};
}
// ================================================================================================ // ================================================================================================
void Register_Buffer(HSQUIRRELVM vm) void Register_Buffer(HSQUIRRELVM vm)
{ {
@@ -457,6 +498,8 @@ void Register_Buffer(HSQUIRRELVM vm)
.Func(_SC("ReadVector4"), &SqBuffer::ReadVector4) .Func(_SC("ReadVector4"), &SqBuffer::ReadVector4)
.Func(_SC("CRC32"), &SqBuffer::GetCRC32) .Func(_SC("CRC32"), &SqBuffer::GetCRC32)
.Func(_SC("ADLER32"), &SqBuffer::GetADLER32) .Func(_SC("ADLER32"), &SqBuffer::GetADLER32)
.Func(_SC("Base32"), &SqBuffer::GetBase32)
.Func(_SC("Base64"), &SqBuffer::GetBase64)
); );
} }
+47 -7
View File
@@ -193,6 +193,24 @@ public:
return *m_Buffer; return *m_Buffer;
} }
/* --------------------------------------------------------------------------------------------
* Limit the specified amount at to the range of the cursor and the end of the buffer.
*/
SQMOD_NODISCARD SzType ClampRemaining(SQInteger n) const
{
// Do we even specify a buffer amount?
if (n >= 0)
{
// Is it within the range we currently have left?
if (static_cast< SzType >(n) <= m_Buffer->Remaining())
{
return static_cast< SzType >(n);
}
}
// Fall back to the actual remaining data
return m_Buffer->Remaining();
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve a certain element type at the specified position. * Retrieve a certain element type at the specified position.
*/ */
@@ -276,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;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -396,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();
@@ -420,6 +448,8 @@ public:
{ {
STHROWF("{}", e.what()); // Re-package STHROWF("{}", e.what()); // Re-package
} }
// Allow chaining
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -761,6 +791,16 @@ public:
* Compute the Adler-32 checksums on the data in the buffer. * Compute the Adler-32 checksums on the data in the buffer.
*/ */
SQMOD_NODISCARD SQInteger GetADLER32(SQInteger n) const; SQMOD_NODISCARD SQInteger GetADLER32(SQInteger n) const;
/* --------------------------------------------------------------------------------------------
* Encode the specified range of data as base32 and return it.
*/
SQMOD_NODISCARD LightObj GetBase32(SQInteger n) const;
/* --------------------------------------------------------------------------------------------
* Encode the specified range of data as base64 and return it.
*/
SQMOD_NODISCARD LightObj GetBase64(SQInteger n) const;
}; };
} // Namespace:: SqMod } // Namespace:: SqMod
+3 -3
View File
@@ -381,7 +381,7 @@ void Register_INI(HSQUIRRELVM vm)
.Func(_SC("Check"), &IniResult::Check) .Func(_SC("Check"), &IniResult::Check)
); );
inins.Bind(_SC("IniEntries"), inins.Bind(_SC("Entries"),
Class< IniEntries >(vm, EntriesTypename::Str) Class< IniEntries >(vm, EntriesTypename::Str)
// Constructors // Constructors
.Ctor() .Ctor()
@@ -409,7 +409,7 @@ void Register_INI(HSQUIRRELVM vm)
.Func(_SC("SortByLoadOrder"), &IniEntries::SortByLoadOrder) .Func(_SC("SortByLoadOrder"), &IniEntries::SortByLoadOrder)
); );
inins.Bind(_SC("IniDocument"), inins.Bind(_SC("Document"),
Class< IniDocument, NoCopy< IniDocument > >(vm, DocumentTypename::Str) Class< IniDocument, NoCopy< IniDocument > >(vm, DocumentTypename::Str)
// Constructors // Constructors
.Ctor() .Ctor()
@@ -464,7 +464,7 @@ void Register_INI(HSQUIRRELVM vm)
.Overload< bool (IniDocument::*)(const SQChar *, const SQChar *, const SQChar *, bool) >(_SC("DeleteValue"), &IniDocument::DeleteValue) .Overload< bool (IniDocument::*)(const SQChar *, const SQChar *, const SQChar *, bool) >(_SC("DeleteValue"), &IniDocument::DeleteValue)
); );
RootTable(vm).Bind(_SC("SqIni"), inins); RootTable(vm).Bind(_SC("SqINI"), inins);
ConstTable(vm).Enum(_SC("SqIniError"), Enumeration(vm) ConstTable(vm).Enum(_SC("SqIniError"), Enumeration(vm)
.Const(_SC("Ok"), int32_t(SI_OK)) .Const(_SC("Ok"), int32_t(SI_OK))
+592 -5
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
+271 -2
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
+423 -387
View File
File diff suppressed because it is too large Load Diff
+237 -179
View File
File diff suppressed because it is too large Load Diff
+14
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;
@@ -89,6 +91,9 @@ WebSocketClient & WebSocketClient::Connect()
{ {
STHROWF("Connection failed: {}", err_buf); STHROWF("Connection failed: {}", err_buf);
} }
// Reset memebrs
mClosing.store(false);
mClosed.store(false);
// Allow chaining // Allow chaining
return *this; return *this;
} }
@@ -113,6 +118,9 @@ WebSocketClient & WebSocketClient::ConnectExt()
{ {
STHROWF("Connection failed: {}", err_buf); STHROWF("Connection failed: {}", err_buf);
} }
// Reset memebrs
mClosing.store(false);
mClosed.store(false);
// Allow chaining // Allow chaining
return *this; return *this;
} }
@@ -129,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;
} }
@@ -167,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)
+40 -9
View File
@@ -154,6 +154,18 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
*/ */
std::atomic< bool > mClosing{false}; std::atomic< bool > mClosing{false};
/* --------------------------------------------------------------------------------------------
* Whether the closing callback was inoked (avoid recursive calls).
*/
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".
*/ */
@@ -179,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), 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
} }
@@ -189,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) , 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()
@@ -202,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) , 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()
@@ -215,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) , 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())
@@ -229,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) , 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())
@@ -289,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.
*/ */
@@ -648,7 +677,7 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Sends the contents of the given buffer through the socket as a single frame. * Sends the contents of the given buffer through the socket as a single frame.
*/ */
SQMOD_NODISCARD SQInteger SendOpCode(SqBuffer & buf, SQInteger opcode) SQMOD_NODISCARD SQInteger SendOpCode(SQInteger opcode)
{ {
return mg_websocket_client_write(Valid(), static_cast< int >(opcode), nullptr, 0); return mg_websocket_client_write(Valid(), static_cast< int >(opcode), nullptr, 0);
} }
@@ -706,9 +735,12 @@ struct WebSocketClient : public SqChainedInstances< WebSocketClient >
} }
} }
// Is the server closing the connection? // Is the server closing the connection?
if (closing && !mOnClose.IsNull()) if (closing && !mClosed.load() && !mOnClose.IsNull())
{ {
mOnClose.Execute(); // Let the user know // Let the user know
mOnClose.Execute();
// Prevent calling this callback again
mClosed.store(true);
} }
} }
@@ -756,5 +788,4 @@ protected:
} }
}; };
} // Namespace:: SqMod } // Namespace:: SqMod
+191
View File
@@ -0,0 +1,191 @@
// ------------------------------------------------------------------------------------------------
#include "Library/RegEx.hpp"
// ------------------------------------------------------------------------------------------------
#include <sqratConst.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMOD_DECL_TYPENAME(SqRxMatchTypename, _SC("SqRxMatch"))
SQMOD_DECL_TYPENAME(SqRxMatchesTypename, _SC("SqRxMatches"))
SQMOD_DECL_TYPENAME(SqRxInstanceTypename, _SC("SqRxInstance"))
// ------------------------------------------------------------------------------------------------
bool RxInstance::STUDY = true;
int RxInstance::OPTIONS = 0;
int RxInstance::STUDY_OPTIONS = 0;
// ================================================================================================
void Register_RegEx(HSQUIRRELVM vm)
{
RootTable(vm).Bind(SqRxMatchTypename::Str,
Class< RxMatch >(vm, SqRxMatchTypename::Str)
// Constructors
.Ctor()
.Ctor< SQInteger >()
.Ctor< SQInteger, SQInteger >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqRxMatchTypename::Fn)
// Properties
.Prop(_SC("Offset"), &RxMatch::GetOffset, &RxMatch::SetOffset)
.Prop(_SC("Length"), &RxMatch::GetLength, &RxMatch::SetLength)
.Prop(_SC("End"), &RxMatch::GetEnd)
// Member Methods
.Func(_SC("SubStr"), &RxMatch::SubStr)
);
RootTable(vm).Bind(SqRxMatchesTypename::Str,
Class< RxMatches >(vm, SqRxMatchesTypename::Str)
// Constructors
.Ctor()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqRxMatchesTypename::Fn)
// Properties
.Prop(_SC("Front"), &RxMatches::Front)
.Prop(_SC("Back"), &RxMatches::Back)
.Prop(_SC("Empty"), &RxMatches::Empty)
.Prop(_SC("Size"), &RxMatches::Size)
.Prop(_SC("Capacity"), &RxMatches::Capacity, &RxMatches::Reserve)
// Member Methods
.Func(_SC("Get"), &RxMatches::Get)
.Func(_SC("Reserve"), &RxMatches::Reserve)
.Func(_SC("Compact"), &RxMatches::Compact)
.Func(_SC("Clear"), &RxMatches::Clear)
.Func(_SC("Pop"), &RxMatches::Pop)
.Func(_SC("EraseAt"), &RxMatches::EraseAt)
.Func(_SC("EraseFrom"), &RxMatches::EraseFrom)
.Func(_SC("Each"), &RxMatches::Each)
.Func(_SC("EachRange"), &RxMatches::EachRange)
.Func(_SC("While"), &RxMatches::While)
.Func(_SC("WhileRange"), &RxMatches::WhileRange)
.Func(_SC("SubStr"), &RxMatches::SubStr)
);
RootTable(vm).Bind(_SC("SqRx"),
Class< RxInstance, NoCopy< RxInstance > >(vm, SqRxInstanceTypename::Str)
// Constructors
.Ctor()
.Ctor< StackStrF & >()
.Ctor< int, StackStrF & >()
.Ctor< int, bool, StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqRxInstanceTypename::Fn)
//.Func(_SC("_tostring"), &CPlayer::ToString)
// Static Values
.SetStaticValue(_SC("STUDY"), RxInstance::STUDY)
.SetStaticValue(_SC("OPTIONS"), RxInstance::OPTIONS)
.SetStaticValue(_SC("STUDY_OPTIONS"), RxInstance::STUDY_OPTIONS)
// Properties
.Prop(_SC("Valid"), &RxInstance::IsValid)
.Prop(_SC("Studied"), &RxInstance::IsStudied)
// Member Methods
.FmtFunc(_SC("CompileF"), &RxInstance::Compile1)
.FmtFunc(_SC("CompileExF"), &RxInstance::Compile2)
.FmtFunc(_SC("TryCompileF"), &RxInstance::TryCompile1)
.FmtFunc(_SC("TryCompileExF"), &RxInstance::TryCompile2)
.FmtFunc(_SC("MatchFirst"), &RxInstance::MatchFirst)
.FmtFunc(_SC("MatchFirstEx"), &RxInstance::MatchFirst_)
.FmtFunc(_SC("MatchFirstFrom"), &RxInstance::MatchFirstFrom)
.FmtFunc(_SC("MatchFirstFromEx"), &RxInstance::MatchFirstFrom_)
.FmtFunc(_SC("Match"), &RxInstance::Match)
.FmtFunc(_SC("MatchEx"), &RxInstance::Match_)
.FmtFunc(_SC("MatchFrom"), &RxInstance::MatchFrom)
.FmtFunc(_SC("MatchFromEx"), &RxInstance::MatchFrom_)
.FmtFunc(_SC("Matches"), &RxInstance::Matches)
.FmtFunc(_SC("MatchesEx"), &RxInstance::Matches_)
.FmtFunc(_SC("MatchesEx2"), &RxInstance::MatchesEx)
// Member Overloads
.Overload(_SC("Compile"), &RxInstance::Compile1)
.Overload(_SC("Compile"), &RxInstance::Compile2)
.Overload(_SC("TryCompile"), &RxInstance::TryCompile1)
.Overload(_SC("TryCompile"), &RxInstance::TryCompile2)
.Overload(_SC("Study"), &RxInstance::Study0)
.Overload(_SC("Study"), &RxInstance::Study1)
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqRxOption"), Enumeration(vm)
.Const(_SC("Caseless"), static_cast< SQInteger >(PCRE_CASELESS))
.Const(_SC("Multiline"), static_cast< SQInteger >(PCRE_MULTILINE))
.Const(_SC("Dotall"), static_cast< SQInteger >(PCRE_DOTALL))
.Const(_SC("Extended"), static_cast< SQInteger >(PCRE_EXTENDED))
.Const(_SC("Anchored"), static_cast< SQInteger >(PCRE_ANCHORED))
.Const(_SC("DollarEndOnly"), static_cast< SQInteger >(PCRE_DOLLAR_ENDONLY))
.Const(_SC("Extra"), static_cast< SQInteger >(PCRE_EXTRA))
.Const(_SC("NotBOL"), static_cast< SQInteger >(PCRE_NOTBOL))
.Const(_SC("NotEOL"), static_cast< SQInteger >(PCRE_NOTEOL))
.Const(_SC("UnGreedy"), static_cast< SQInteger >(PCRE_UNGREEDY))
.Const(_SC("NotEmpty"), static_cast< SQInteger >(PCRE_NOTEMPTY))
.Const(_SC("UTF8"), static_cast< SQInteger >(PCRE_UTF8))
.Const(_SC("UTF16"), static_cast< SQInteger >(PCRE_UTF16))
.Const(_SC("UTF32"), static_cast< SQInteger >(PCRE_UTF32))
.Const(_SC("NoAutoCapture"), static_cast< SQInteger >(PCRE_NO_AUTO_CAPTURE))
.Const(_SC("NoUTF8Check"), static_cast< SQInteger >(PCRE_NO_UTF8_CHECK))
.Const(_SC("NoUTF16Check"), static_cast< SQInteger >(PCRE_NO_UTF16_CHECK))
.Const(_SC("NoUTF32Check"), static_cast< SQInteger >(PCRE_NO_UTF32_CHECK))
.Const(_SC("AutoCallout"), static_cast< SQInteger >(PCRE_AUTO_CALLOUT))
.Const(_SC("PartialSoft"), static_cast< SQInteger >(PCRE_PARTIAL_SOFT))
.Const(_SC("Partial"), static_cast< SQInteger >(PCRE_PARTIAL))
.Const(_SC("NeverUTF"), static_cast< SQInteger >(PCRE_NEVER_UTF))
.Const(_SC("DfaShortest"), static_cast< SQInteger >(PCRE_DFA_SHORTEST))
.Const(_SC("NoAutoPossess"), static_cast< SQInteger >(PCRE_NO_AUTO_POSSESS))
.Const(_SC("DfaRestart"), static_cast< SQInteger >(PCRE_DFA_RESTART))
.Const(_SC("FirstLine"), static_cast< SQInteger >(PCRE_FIRSTLINE))
.Const(_SC("DupNames"), static_cast< SQInteger >(PCRE_DUPNAMES))
.Const(_SC("NewLineCR"), static_cast< SQInteger >(PCRE_NEWLINE_CR))
.Const(_SC("NewLineLF"), static_cast< SQInteger >(PCRE_NEWLINE_LF))
.Const(_SC("NewLineCRLF"), static_cast< SQInteger >(PCRE_NEWLINE_CRLF))
.Const(_SC("NewLineAny"), static_cast< SQInteger >(PCRE_NEWLINE_ANY))
.Const(_SC("NewLineAnyCRLF"), static_cast< SQInteger >(PCRE_NEWLINE_ANYCRLF))
.Const(_SC("BsrAnyCRLF"), static_cast< SQInteger >(PCRE_BSR_ANYCRLF))
.Const(_SC("BsrUnicode"), static_cast< SQInteger >(PCRE_BSR_UNICODE))
.Const(_SC("JavaScriptCompat"), static_cast< SQInteger >(PCRE_JAVASCRIPT_COMPAT))
.Const(_SC("NoStartOptimize"), static_cast< SQInteger >(PCRE_NO_START_OPTIMIZE))
.Const(_SC("NoStartOptimise"), static_cast< SQInteger >(PCRE_NO_START_OPTIMISE))
.Const(_SC("PartialHard"), static_cast< SQInteger >(PCRE_PARTIAL_HARD))
.Const(_SC("NotEmptyAtStart"), static_cast< SQInteger >(PCRE_NOTEMPTY_ATSTART))
.Const(_SC("UCP"), static_cast< SQInteger >(PCRE_UCP))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqRxError"), Enumeration(vm)
.Const(_SC("NoMatch"), static_cast< SQInteger >(PCRE_ERROR_NOMATCH))
.Const(_SC("Null"), static_cast< SQInteger >(PCRE_ERROR_NULL))
.Const(_SC("BadOption"), static_cast< SQInteger >(PCRE_ERROR_BADOPTION))
.Const(_SC("BadMagic"), static_cast< SQInteger >(PCRE_ERROR_BADMAGIC))
.Const(_SC("UnknownOpCode"), static_cast< SQInteger >(PCRE_ERROR_UNKNOWN_OPCODE))
.Const(_SC("UnknownNode"), static_cast< SQInteger >(PCRE_ERROR_UNKNOWN_NODE))
.Const(_SC("NoMemory"), static_cast< SQInteger >(PCRE_ERROR_NOMEMORY))
.Const(_SC("NoSubstring"), static_cast< SQInteger >(PCRE_ERROR_NOSUBSTRING))
.Const(_SC("MatchLimit"), static_cast< SQInteger >(PCRE_ERROR_MATCHLIMIT))
.Const(_SC("Callout"), static_cast< SQInteger >(PCRE_ERROR_CALLOUT))
.Const(_SC("BadUTF8"), static_cast< SQInteger >(PCRE_ERROR_BADUTF8))
.Const(_SC("BadUTF16"), static_cast< SQInteger >(PCRE_ERROR_BADUTF16))
.Const(_SC("BadUTF32"), static_cast< SQInteger >(PCRE_ERROR_BADUTF32))
.Const(_SC("BadUTF8Offset"), static_cast< SQInteger >(PCRE_ERROR_BADUTF8_OFFSET))
.Const(_SC("BadUTF16Offset"), static_cast< SQInteger >(PCRE_ERROR_BADUTF16_OFFSET))
.Const(_SC("Partial"), static_cast< SQInteger >(PCRE_ERROR_PARTIAL))
.Const(_SC("BadPartial"), static_cast< SQInteger >(PCRE_ERROR_BADPARTIAL))
.Const(_SC("Internal"), static_cast< SQInteger >(PCRE_ERROR_INTERNAL))
.Const(_SC("BadCount"), static_cast< SQInteger >(PCRE_ERROR_BADCOUNT))
.Const(_SC("DfaUitem"), static_cast< SQInteger >(PCRE_ERROR_DFA_UITEM))
.Const(_SC("DfaUcond"), static_cast< SQInteger >(PCRE_ERROR_DFA_UCOND))
.Const(_SC("DfaUmLimit"), static_cast< SQInteger >(PCRE_ERROR_DFA_UMLIMIT))
.Const(_SC("DfaWsSize"), static_cast< SQInteger >(PCRE_ERROR_DFA_WSSIZE))
.Const(_SC("DfaRecurse"), static_cast< SQInteger >(PCRE_ERROR_DFA_RECURSE))
.Const(_SC("RecursionLimit"), static_cast< SQInteger >(PCRE_ERROR_RECURSIONLIMIT))
.Const(_SC("NullWsLimit"), static_cast< SQInteger >(PCRE_ERROR_NULLWSLIMIT))
.Const(_SC("BadNewLine"), static_cast< SQInteger >(PCRE_ERROR_BADNEWLINE))
.Const(_SC("BadOffset"), static_cast< SQInteger >(PCRE_ERROR_BADOFFSET))
.Const(_SC("ShortUTF8"), static_cast< SQInteger >(PCRE_ERROR_SHORTUTF8))
.Const(_SC("ShortUTF16"), static_cast< SQInteger >(PCRE_ERROR_SHORTUTF16))
.Const(_SC("RecurseLoop"), static_cast< SQInteger >(PCRE_ERROR_RECURSELOOP))
.Const(_SC("JitStackLimit"), static_cast< SQInteger >(PCRE_ERROR_JIT_STACKLIMIT))
.Const(_SC("BadMode"), static_cast< SQInteger >(PCRE_ERROR_BADMODE))
.Const(_SC("BadEndianness"), static_cast< SQInteger >(PCRE_ERROR_BADENDIANNESS))
.Const(_SC("DfaBadRestart"), static_cast< SQInteger >(PCRE_ERROR_DFA_BADRESTART))
.Const(_SC("JitBadOption"), static_cast< SQInteger >(PCRE_ERROR_JIT_BADOPTION))
.Const(_SC("BadLength"), static_cast< SQInteger >(PCRE_ERROR_BADLENGTH))
.Const(_SC("Unset"), static_cast< SQInteger >(PCRE_ERROR_UNSET))
);
}
} // Namespace:: SqMod
+885
View File
@@ -0,0 +1,885 @@
#pragma once
// ------------------------------------------------------------------------------------------------
#include "Core/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#ifdef POCO_UNBUNDLED
#include <pcre.h>
#else
#include "pcre_config.h"
#include "pcre.h"
#endif
// ------------------------------------------------------------------------------------------------
#include <utility>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
*
*/
struct RxMatch
{
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger mOffset{0};
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger mLength{0};
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
RxMatch() noexcept = default;
/* --------------------------------------------------------------------------------------------
* Offset constructor.
*/
explicit RxMatch(SQInteger offset) noexcept
: mOffset{offset}
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
RxMatch(SQInteger offset, SQInteger length) noexcept
: mOffset{offset}, mLength{length}
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
RxMatch(const RxMatch & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
RxMatch(RxMatch && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
RxMatch & operator = (const RxMatch & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
RxMatch & operator = (RxMatch && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Retrieve offset.
*/
SQMOD_NODISCARD SQInteger GetOffset() const noexcept
{
return mOffset;
}
/* --------------------------------------------------------------------------------------------
* Modify offset.
*/
void SetOffset(SQInteger value) noexcept
{
mOffset = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve length.
*/
SQMOD_NODISCARD SQInteger GetLength() const noexcept
{
return mLength;
}
/* --------------------------------------------------------------------------------------------
* Modify length.
*/
void SetLength(SQInteger value) noexcept
{
mLength = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve match end.
*/
SQMOD_NODISCARD SQInteger GetEnd() const noexcept
{
return mOffset + mLength;
}
/* --------------------------------------------------------------------------------------------
* Extract a sub-string.
*/
[[nodiscard]] LightObj SubStr(StackStrF & str) const
{
if ((mOffset + mLength) > str.mLen)
{
STHROWF("Rx: Match is outside the range of the specified string.");
}
// Return the sub-string
return LightObj{str.mPtr + mOffset, mLength};
}
};
/* ------------------------------------------------------------------------------------------------
*
*/
struct RxMatches
{
using List = std::vector< RxMatch >;
/* --------------------------------------------------------------------------------------------
* Internal RegularExpression instance.
*/
List mList;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
RxMatches() = default;
/* --------------------------------------------------------------------------------------------
* Copy list constructor.
*/
explicit RxMatches(const List & l) // NOLINT(modernize-pass-by-value)
: mList{l}
{
}
/* --------------------------------------------------------------------------------------------
* Move list constructor.
*/
explicit RxMatches(List && m) noexcept
: mList{std::move(m)}
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
RxMatches(const RxMatches & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
RxMatches(RxMatches && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
RxMatches & operator = (const RxMatches & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
RxMatches & operator = (RxMatches && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Make sure an index is within range and return the container. Container must exist.
*/
List & ValidIdx(SQInteger i)
{
if (static_cast< size_t >(i) >= mList.size())
{
STHROWF("Invalid Regular Expression match list index({})", i);
}
return mList;
}
/* --------------------------------------------------------------------------------------------
* Make sure an index is within range and return the container. Container must exist.
*/
SQMOD_NODISCARD const List & ValidIdx(SQInteger i) const
{
if (static_cast< size_t >(i) >= mList.size())
{
STHROWF("Invalid Regular Expression match list index({})", i);
}
return mList;
}
/* --------------------------------------------------------------------------------------------
* Make sure a container instance is populated, then return it.
*/
SQMOD_NODISCARD List & ValidPop()
{
if (mList.empty())
{
STHROWF("Regular Expression match list container is empty");
}
return mList;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a value from the container.
*/
SQMOD_NODISCARD List::reference Get(SQInteger i)
{
return ValidIdx(i).at(ClampL< SQInteger, size_t >(i));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the first element in the container.
*/
SQMOD_NODISCARD List::reference Front()
{
return ValidPop().front();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last element in the container.
*/
SQMOD_NODISCARD List::reference Back()
{
return mList.back();
}
/* --------------------------------------------------------------------------------------------
* Check if the container has no elements.
*/
SQMOD_NODISCARD bool Empty() const
{
return mList.empty();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of elements in the container.
*/
SQMOD_NODISCARD SQInteger Size() const
{
return static_cast< SQInteger >(mList.size());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of elements that the container has currently allocated space for.
*/
SQMOD_NODISCARD SQInteger Capacity() const
{
return static_cast< SQInteger >(mList.capacity());
}
/* --------------------------------------------------------------------------------------------
* Increase the capacity of the container to a value that's greater or equal to the one specified.
*/
RxMatches & Reserve(SQInteger n)
{
mList.reserve(ClampL< SQInteger, size_t >(n));
return *this;
}
/* --------------------------------------------------------------------------------------------
* Request the removal of unused capacity.
*/
void Compact()
{
mList.shrink_to_fit();
}
/* --------------------------------------------------------------------------------------------
* Erase all elements from the container.
*/
void Clear()
{
mList.clear();
}
/* --------------------------------------------------------------------------------------------
* Pop the last element in the container.
*/
void Pop()
{
ValidPop().pop_back();
}
/* --------------------------------------------------------------------------------------------
* Erase the element at a certain position.
*/
void EraseAt(SQInteger i)
{
mList.erase(ValidIdx(i).begin() + static_cast< size_t >(i)); // NOLINT(cppcoreguidelines-narrowing-conversions)
}
/* --------------------------------------------------------------------------------------------
* Erase a certain amount of elements starting from a specific position.
*/
void EraseFrom(SQInteger i, SQInteger n)
{
mList.erase(ValidIdx(i).begin() + static_cast< size_t >(i), // NOLINT(cppcoreguidelines-narrowing-conversions)
ValidIdx(i + n).begin() + static_cast< size_t >(i + n)); // NOLINT(cppcoreguidelines-narrowing-conversions)
}
/* --------------------------------------------------------------------------------------------
* Iterate all values through a functor.
*/
void Each(Function & fn) const
{
for (const auto & e : mList)
{
fn.Execute(static_cast< SQInteger >(e.mOffset), static_cast< SQInteger >(e.mLength));
}
}
/* --------------------------------------------------------------------------------------------
* Iterate values in range through a functor.
*/
void EachRange(SQInteger p, SQInteger n, Function & fn) const
{
std::for_each(ValidIdx(p).begin() + static_cast< size_t >(p), // NOLINT(cppcoreguidelines-narrowing-conversions)
ValidIdx(p + n).begin() + static_cast< size_t >(p + n), // NOLINT(cppcoreguidelines-narrowing-conversions)
[&](List::const_reference & e) {
fn.Execute(static_cast< SQInteger >(e.mOffset), static_cast< SQInteger >(e.mLength));
});
}
/* --------------------------------------------------------------------------------------------
* Iterate all values through a functor until stopped (i.e. false is returned).
*/
void While(Function & fn) const
{
for (const auto & e : mList)
{
auto ret = fn.Eval(static_cast< SQInteger >(e.mOffset), static_cast< SQInteger >(e.mLength));
// (null || true) == continue & false == break
if (!ret.IsNull() || !ret.template Cast< bool >())
{
break;
}
}
}
/* --------------------------------------------------------------------------------------------
* Iterate values in range through a functor until stopped (i.e. false is returned).
*/
void WhileRange(SQInteger p, SQInteger n, Function & fn) const
{
auto itr = ValidIdx(p).begin() + static_cast< size_t >(p); // NOLINT(cppcoreguidelines-narrowing-conversions)
auto end = ValidIdx(p + n).begin() + static_cast< size_t >(p + n); // NOLINT(cppcoreguidelines-narrowing-conversions)
for (; itr != end; ++itr)
{
auto ret = fn.Eval(static_cast< SQInteger >(itr->mOffset), static_cast< SQInteger >(itr->mLength));
// (null || true) == continue & false == break
if (!ret.IsNull() || !ret.template Cast< bool >())
{
break;
}
}
}
/* --------------------------------------------------------------------------------------------
* Extract a sub-string.
*/
[[nodiscard]] LightObj SubStr(SQInteger i, StackStrF & str) const
{
const RxMatch & m = ValidIdx(i)[i];
// Check if match is within range
if ((m.mOffset + m.mLength) > str.mLen)
{
STHROWF("Rx: Match is outside the range of the specified string.");
}
// Return the sub-string
return LightObj{str.mPtr + m.mOffset, m.mLength};
}
};
/* ------------------------------------------------------------------------------------------------
*
*/
struct RxInstance
{
/* --------------------------------------------------------------------------------------------
* Whether to analyze and optimize the pattern by default for evey new instance (true).
*/
static bool STUDY;
/* --------------------------------------------------------------------------------------------
* Default options for every new instance (0).
*/
static int OPTIONS;
/* --------------------------------------------------------------------------------------------
* Default study options for every new instance (0).
*/
static int STUDY_OPTIONS;
/* --------------------------------------------------------------------------------------------
* Default offset vector size (must be multiple of 3).
*/
static constexpr int OVEC_SIZE = 63;
/* --------------------------------------------------------------------------------------------
* Internal vector type used for offsets buffer.
*/
using OVEC_t = std::vector< int >;
/* --------------------------------------------------------------------------------------------
* Internal RegularExpression instance.
*/
pcre * mPCRE{nullptr};
/* --------------------------------------------------------------------------------------------
* Internal RegularExpression instance.
*/
pcre_extra * mExtra{nullptr};
/* --------------------------------------------------------------------------------------------
* Internal buffer used for offsets.
*/
OVEC_t mOVEC{};
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
RxInstance() noexcept = default;
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
RxInstance(const RxInstance &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
RxInstance(RxInstance && o) noexcept
: mPCRE(o.mPCRE), mExtra(o.mExtra), mOVEC(std::move(o.mOVEC)) // Replicate it
{
o.mPCRE = nullptr; // Take ownership
o.mExtra = nullptr; // Take ownership
}
/* --------------------------------------------------------------------------------------------
* Basic constructor.
*/
explicit RxInstance(StackStrF & pattern)
: RxInstance(OPTIONS, STUDY, pattern)
{
}
/* --------------------------------------------------------------------------------------------
* Basic constructor. With specific options.
*/
explicit RxInstance(int options, StackStrF & pattern)
: RxInstance(options, STUDY, pattern)
{
}
/* --------------------------------------------------------------------------------------------
* Basic constructor. With specific options.
*/
explicit RxInstance(int options, bool study, StackStrF & pattern)
: mPCRE(Compile_(pattern.mPtr, options)), mExtra(nullptr)
{
if (study)
{
Study0();
}
}
/* --------------------------------------------------------------------------------------------
* Internal constructor.
*/
RxInstance(const char * pattern, int options, bool study)
: mPCRE(Compile_(pattern, options)), mExtra(nullptr)
{
if (study)
{
Study0();
}
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~RxInstance()
{
Destroy();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
RxInstance & operator = (const RxInstance &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
RxInstance & operator = (RxInstance && o) noexcept
{
// Prevent self assignment
if (this != &o)
{
// Release current instance, if any
Destroy();
// Replicate it
mPCRE = o.mPCRE;
mExtra = o.mExtra;
mOVEC = std::move(o.mOVEC);
// Take ownership
o.mPCRE = nullptr;
o.mExtra = nullptr;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Estimate the size necessary for the offsets vector buffer.
*/
void EstimateOVEC(bool force = false)
{
if (mOVEC.empty() || force)
{
int size = 0;
// Attempt to estimate the size of the offsets vector buffer
const int r = pcre_fullinfo(ValidPCRE(), mExtra, PCRE_INFO_CAPTURECOUNT, &size);
// Check for errors
if (r != 0)
{
STHROWF("Rx: Offsets vector buffer estimation failed ({})", r);
}
// Attempt to scale the vector (must be multiple of 3)
mOVEC.resize((size + 1) * 3);
}
}
/* --------------------------------------------------------------------------------------------
* Return a valid `pcre` instance pointer or throw an exception.
*/
SQMOD_NODISCARD pcre * ValidPCRE() const
{
// Do we manage a valid instance?
if (mPCRE == nullptr)
{
STHROWF("Uninitialized Regular Expression instance.");
}
// Return it
return mPCRE;
}
/* --------------------------------------------------------------------------------------------
* Return a valid `pcre_extra` instance pointer or throw an exception.
*/
SQMOD_NODISCARD pcre_extra * ValidExtra() const
{
// Do we manage a valid instance?
if (mExtra == nullptr)
{
STHROWF("Regular Expression was not studied and optimized.");
}
// Return it
return mExtra;
}
/* --------------------------------------------------------------------------------------------
* Compile the specified pattern.
*/
SQMOD_NODISCARD static pcre * Compile_(const char * pattern, int options = OPTIONS)
{
const char * error_msg = nullptr;
int error_code, error_offset = 0;
// Attempt to compile the specified pattern
pcre * ptr = pcre_compile2(pattern, options, &error_code, &error_msg, &error_offset, nullptr);
// Did the compilation failed?
if (ptr == nullptr)
{
STHROWF("Rx: {s} (code {}) (at offset {})", error_msg, error_code, error_offset);
}
// Return the `pcre` instance
return ptr;
}
/* --------------------------------------------------------------------------------------------
* Attempt to compile the specified pattern. Error information is returned instead of thrown.
*/
SQMOD_NODISCARD static std::pair< pcre *, Table > TryCompile_(const char * pattern, int options = OPTIONS)
{
const char * error_msg = nullptr;
int error_code, error_offset = 0;
// Attempt to compile the specified pattern
pcre * ptr = pcre_compile2(pattern, options, &error_code, &error_msg, &error_offset, nullptr);
// Did the compilation failed?
if (ptr == nullptr)
{
Table t;
t.SetValue("message", error_msg);
t.SetValue("code", error_code);
t.SetValue("offset", error_offset);
// Return the table with error information
return std::make_pair(ptr, std::move(t));
}
// Return the `pcre` instance with no error information
return std::make_pair(ptr, Table{});
}
/* --------------------------------------------------------------------------------------------
* Compile the specified pattern.
*/
RxInstance & Compile1(StackStrF & pattern)
{
return Compile2(OPTIONS, pattern);
}
/* --------------------------------------------------------------------------------------------
* Compile the specified pattern. With specific options.
*/
RxInstance & Compile2(int options, StackStrF & pattern)
{
// Release current instance, if any
Destroy();
// Attempt to compile
mPCRE = Compile_(pattern.mPtr, options);
// Allocate offsets vector buffer
EstimateOVEC();
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* Compile the specified pattern.
*/
Table TryCompile1(StackStrF & pattern)
{
return TryCompile2(OPTIONS, pattern);
}
/* --------------------------------------------------------------------------------------------
* Compile the specified pattern. With specific options.
*/
Table TryCompile2(int options, StackStrF & pattern)
{
// Release current instance, if any
Destroy();
// Attempt to compile
auto p = TryCompile_(pattern.mPtr, options);
// Were there any compilation errors?
if (p.first != nullptr)
{
mPCRE = p.first;
}
// Return compilation info
return p.second;
}
/* --------------------------------------------------------------------------------------------
* Analyze the managed pattern and optimized it.
*/
RxInstance & Study0()
{
return Study1(STUDY_OPTIONS);
}
/* --------------------------------------------------------------------------------------------
* Analyze the managed pattern and optimized it. With specific options.
*/
RxInstance & Study1(int options)
{
if (mExtra != nullptr)
{
STHROWF("Regular Expression was already analyzed and optimized");
}
const char * error = nullptr;
// Study and optimize the expression
mExtra = pcre_study(ValidPCRE(), options, &error);
// If there was an error studying the expression then throw it
if (mExtra == nullptr && error != nullptr)
{
STHROWF("Rx: {s}", error);
}
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* Release managed resources and revert to uninitialized instance.
*/
SQMOD_NODISCARD bool IsValid() const
{
return (mPCRE != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Release managed resources and revert to uninitialized instance.
*/
SQMOD_NODISCARD bool IsStudied() const
{
return (mExtra != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Release managed resources and revert to uninitialized instance.
*/
void Destroy()
{
// Do we manage any instance?
if (mPCRE != nullptr)
{
pcre_free(mPCRE);
mPCRE = nullptr;
}
// Is the expression optimized?
if (mExtra != nullptr)
{
pcre_free(mExtra);
mExtra = nullptr;
}
}
/* --------------------------------------------------------------------------------------------
* Matches the given subject string against the pattern.
* Returns the position of the first captured sub-string in m.
* If no part of the subject matches the pattern, m.mOffset is -1 and m.mLength is 0.
* Returns the number of matches. Throws a exception in case of an error.
*/
SQMOD_NODISCARD int MatchFirstFrom(SQInteger o, RxMatch & m, StackStrF & s)
{
return MatchFirstFrom_(OPTIONS, o, m, s);
}
SQMOD_NODISCARD int MatchFirstFrom_(int f, SQInteger o, RxMatch & m, StackStrF & s)
{
if (o > s.mLen)
{
STHROWF("Rx: Offset is out of range");
}
EstimateOVEC();
// Attempt to execute the expression on the specified subject
const int rc = pcre_exec(ValidPCRE(), mExtra, s.mPtr, static_cast< int >(s.mLen), static_cast< int >(o), f & 0xFFFF, mOVEC.data(), static_cast< int >(mOVEC.size()));
// Was there a match?
if (rc == PCRE_ERROR_NOMATCH)
{
m.mOffset = -1;
m.mLength = 0;
// No match found
return 0;
}
// Bad options/flags?
else if (rc == PCRE_ERROR_BADOPTION)
{
STHROWF("Rx: Bad option");
}
// Overflow?
else if (rc == 0)
{
STHROWF("Rx: too many captured sub-strings");
}
// Some other error?
else if (rc < 0)
{
STHROWF("Rx: error {}", rc);
}
// Store match
m.mOffset = mOVEC[0];
m.mLength = mOVEC[1] - mOVEC[0];
// Yield result back to script
return rc;
}
/* --------------------------------------------------------------------------------------------
* Matches the given subject string against the pattern.
* Returns the position of the first captured sub-string in m.
* If no part of the subject matches the pattern, m.mOffset is -1 and m.mLength is 0.
* Returns the number of matches. Throws a exception in case of an error.
*/
SQMOD_NODISCARD int MatchFirst(RxMatch & m, StackStrF & s)
{
return MatchFirstFrom_(OPTIONS, 0, m, s);
}
SQMOD_NODISCARD int MatchFirst_(int f, RxMatch & m, StackStrF & s)
{
return MatchFirstFrom_(f, 0, m, s);
}
/* --------------------------------------------------------------------------------------------
* Matches the given subject string against the pattern.
* The first entry in m contains the position of the captured sub-string.
* The following entries identify matching sub-patterns. See the PCRE documentation for a more detailed explanation.
* If no part of the subject matches the pattern, m is empty.
* Returns the number of matches. Throws an exception in case of an error.
*/
SQMOD_NODISCARD int MatchFrom(SQInteger o, RxMatches & m, StackStrF & s)
{
return MatchFrom_(OPTIONS, o, m, s);
}
SQMOD_NODISCARD int MatchFrom_(int f, SQInteger o, RxMatches & m, StackStrF & s)
{
if (o > s.mLen)
{
STHROWF("Rx: Offset is out of range");
}
EstimateOVEC();
// Clear previous matches, if any
m.mList.clear();
// Attempt to execute the expression on the specified subject
const int rc = pcre_exec(ValidPCRE(), mExtra, s.mPtr, static_cast< int >(s.mLen), static_cast< int >(o), f & 0xFFFF, mOVEC.data(), static_cast< int >(mOVEC.size()));
// Was there a match?
if (rc == PCRE_ERROR_NOMATCH)
{
return 0; // No match found
}
// Bad options/flags?
else if (rc == PCRE_ERROR_BADOPTION)
{
STHROWF("Rx: Bad option");
}
// Overflow?
else if (rc == 0)
{
STHROWF("Rx: too many captured sub-strings");
}
// Some other error?
else if (rc < 0)
{
STHROWF("Rx: error {}", rc);
}
// Reserve space in advance
m.mList.reserve(static_cast< size_t >(rc));
// Transfer matches to match-list
for (int i = 0; i < rc; ++i)
{
m.mList.emplace_back(mOVEC[i*2], mOVEC[i*2+1] - mOVEC[i*2]);
}
// Yield result back to script
return rc;
}
/* --------------------------------------------------------------------------------------------
* Matches the given subject string against the pattern.
* The first entry in m contains the position of the captured sub-string.
* The following entries identify matching sub-patterns. See the PCRE documentation for a more detailed explanation.
* If no part of the subject matches the pattern, m is empty.
* Returns the number of matches. Throws an exception in case of an error.
*/
SQMOD_NODISCARD int Match(RxMatches & m, StackStrF & s)
{
return MatchFrom_(OPTIONS, 0, m, s);
}
SQMOD_NODISCARD int Match_(int f, RxMatches & m, StackStrF & s)
{
return MatchFrom_(f, 0, m, s);
}
/* --------------------------------------------------------------------------------------------
* Returns true if and only if the subject matches the regular expression.
* Internally, this method sets the RE_ANCHORED and RE_NOTEMPTY options for matching,
* which means that the empty string will never match and the pattern is treated as if it starts with a ^.
*/
SQMOD_NODISCARD bool Matches(StackStrF & s)
{
return Matches_(PCRE_ANCHORED | PCRE_NOTEMPTY, s);
}
SQMOD_NODISCARD bool Matches_(SQInteger o, StackStrF & s)
{
return MatchesEx(PCRE_ANCHORED | PCRE_NOTEMPTY, 0, s);
}
SQMOD_NODISCARD bool MatchesEx(int f, SQInteger o, StackStrF & s)
{
RxMatch m;
const int rc = MatchFirstFrom_(f, o, m, s);
return (rc > 0) && (m.mOffset == o) && (m.mLength == (s.mLen - o));
}
};
} // Namespace:: SqMod
+160 -120
View File
@@ -362,6 +362,15 @@ static const EnumElement g_MainEnum[] = {
{_SC("WARNING_AUTOINDEX"), SQLITE_WARNING_AUTOINDEX} {_SC("WARNING_AUTOINDEX"), SQLITE_WARNING_AUTOINDEX}
}; };
// ------------------------------------------------------------------------------------------------
LightObj GetSQLiteFromSession(Poco::Data::SessionImpl * session)
{
// Create a reference counted connection handle instance
SQLiteConnRef ref(new SQLiteConnHnd(session));
// Transform it into a connection instance and yield it as a script object
return LightObj(SqTypeIdentity< SQLiteConnection >{}, SqVM(), ref);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static inline bool IsDigitsOnly(const SQChar * str) static inline bool IsDigitsOnly(const SQChar * str)
{ {
@@ -374,13 +383,13 @@ static inline bool IsDigitsOnly(const SQChar * str)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Object GetConnectionObj(const ConnRef & conn) Object GetConnectionObj(const SQLiteConnRef & conn)
{ {
return Object(new SQLiteConnection(conn)); return Object(new SQLiteConnection(conn));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Object GetStatementObj(const StmtRef & stmt) Object GetStatementObj(const SQLiteStmtRef & stmt)
{ {
return Object(new SQLiteStatement(stmt)); return Object(new SQLiteStatement(stmt));
} }
@@ -451,11 +460,15 @@ LightObj EscapeString(StackStrF & str)
} }
// Allocate a memory buffer // Allocate a memory buffer
std::vector< SQChar > b; std::vector< SQChar > b;
b.reserve(static_cast< size_t >(str.mLen)); // Allocate extra space to make sure there's room for a null terminator since we need it
// This is a f* up from SQLite devs not returning the number of written characters from snprintf
// So we can figure out if we actually had room for the null terminator or not
b.reserve(static_cast< size_t >(str.mLen * 2 + 1));
// Attempt to escape the specified string // Attempt to escape the specified string
sqlite3_snprintf(static_cast<int>(b.capacity()), b.data(), "%q", str.mPtr); sqlite3_snprintf(static_cast<int>(b.capacity()), b.data(), "%q", str.mPtr);
// Return the resulted string // Return the resulted string
return LightObj(b.data()); LightObj o(b.data(), -1);
return o;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -477,7 +490,8 @@ LightObj EscapeStringEx(SQChar spec, StackStrF & str)
fs[1] = spec; fs[1] = spec;
// Allocate a memory buffer // Allocate a memory buffer
std::vector< SQChar > b; std::vector< SQChar > b;
b.reserve(static_cast< size_t >(str.mLen)); // Allocate extra space to make sure there's room for a null terminator since we need it (see above)
b.reserve(static_cast< size_t >(str.mLen * 2 + 1));
// Attempt to escape the specified string // Attempt to escape the specified string
sqlite3_snprintf(static_cast<int>(b.capacity()), b.data(), fs, str.mPtr); sqlite3_snprintf(static_cast<int>(b.capacity()), b.data(), fs, str.mPtr);
// Return the resulted string // Return the resulted string
@@ -597,6 +611,7 @@ SQLiteConnHnd::SQLiteConnHnd()
, mFlags(0) , mFlags(0)
, mName() , mName()
, mVFS() , mVFS()
, mSession()
, mMemory(false) , mMemory(false)
, mTrace(false) , mTrace(false)
, mProfile(false) , mProfile(false)
@@ -604,6 +619,24 @@ SQLiteConnHnd::SQLiteConnHnd()
/* ... */ /* ... */
} }
// ------------------------------------------------------------------------------------------------
SQLiteConnHnd::SQLiteConnHnd(Poco::Data::SessionImpl * session)
: SQLiteConnHnd()
{
mSession.assign(session, true);
// Retrieve the internal handle property
mPtr = Poco::AnyCast< sqlite3 * >(mSession->getProperty("handle"));
}
// ------------------------------------------------------------------------------------------------
SQLiteConnHnd::SQLiteConnHnd(Poco::AutoPtr< Poco::Data::SessionImpl > && session)
: SQLiteConnHnd()
{
mSession = std::move(session);
// Retrieve the internal handle property
mPtr = Poco::AnyCast< sqlite3 * >(mSession->getProperty("handle"));
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQLiteConnHnd::~SQLiteConnHnd() SQLiteConnHnd::~SQLiteConnHnd()
{ {
@@ -614,10 +647,17 @@ SQLiteConnHnd::~SQLiteConnHnd()
Flush(static_cast<uint32_t>(mQueue.size()), NullObject(), NullFunction()); Flush(static_cast<uint32_t>(mQueue.size()), NullObject(), NullFunction());
// NOTE: Should we call sqlite3_interrupt(...) before closing? // NOTE: Should we call sqlite3_interrupt(...) before closing?
// Attempt to close the database // Attempt to close the database
if ((sqlite3_close(mPtr)) != SQLITE_OK) // If this connection is a pooled session then let it clean itself up
if (mSession.isNull() && (sqlite3_close(mPtr)) != SQLITE_OK)
{ {
LogErr("Unable to close SQLite connection [%s]", sqlite3_errmsg(mPtr)); LogErr("Unable to close SQLite connection [%s]", sqlite3_errmsg(mPtr));
} }
else
{
mSession.reset();
}
// Prevent further use of this connection
mPtr = nullptr;
} }
} }
@@ -625,7 +665,7 @@ SQLiteConnHnd::~SQLiteConnHnd()
void SQLiteConnHnd::Create(const SQChar * name, int32_t flags, const SQChar * vfs) void SQLiteConnHnd::Create(const SQChar * name, int32_t flags, const SQChar * vfs)
{ {
// Make sure a previous connection doesn't exist // Make sure a previous connection doesn't exist
if (mPtr) if (Access())
{ {
STHROWF("Unable to connect to database. Database already connected"); STHROWF("Unable to connect to database. Database already connected");
} }
@@ -658,7 +698,7 @@ void SQLiteConnHnd::Create(const SQChar * name, int32_t flags, const SQChar * vf
int32_t SQLiteConnHnd::Flush(uint32_t num, Object & env, Function & func) int32_t SQLiteConnHnd::Flush(uint32_t num, Object & env, Function & func)
{ {
// Do we even have a valid connection? // Do we even have a valid connection?
if (!mPtr) if (!Access())
{ {
return -1; // No connection! return -1; // No connection!
} }
@@ -746,10 +786,10 @@ int32_t SQLiteConnHnd::Flush(uint32_t num, Object & env, Function & func)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQLiteStmtHnd::SQLiteStmtHnd(ConnRef conn) SQLiteStmtHnd::SQLiteStmtHnd(SQLiteConnRef conn)
: mPtr(nullptr) : mPtr(nullptr)
, mStatus(SQLITE_OK) , mStatus(SQLITE_OK)
, mConn(std::move(conn)) , mConnection(std::move(conn))
, mQuery() , mQuery()
, mColumns(0) , mColumns(0)
, mParameters(0) , mParameters(0)
@@ -769,7 +809,7 @@ SQLiteStmtHnd::~SQLiteStmtHnd()
// Attempt to finalize the statement // Attempt to finalize the statement
if ((sqlite3_finalize(mPtr)) != SQLITE_OK) if ((sqlite3_finalize(mPtr)) != SQLITE_OK)
{ {
LogErr("Unable to finalize SQLite statement [%s]", mConn->ErrMsg()); LogErr("Unable to finalize SQLite statement [%s]", mConnection->ErrMsg());
} }
} }
} }
@@ -778,12 +818,12 @@ SQLiteStmtHnd::~SQLiteStmtHnd()
void SQLiteStmtHnd::Create(const SQChar * query, SQInteger length) void SQLiteStmtHnd::Create(const SQChar * query, SQInteger length)
{ {
// Make sure a previous statement doesn't exist // Make sure a previous statement doesn't exist
if (mPtr) if (Access())
{ {
STHROWF("Unable to prepare statement. Statement already prepared"); STHROWF("Unable to prepare statement. Statement already prepared");
} }
// Is the specified database connection is valid? // Is the specified database connection is valid?
else if (!mConn) else if (!mConnection)
{ {
STHROWF("Unable to prepare statement. Invalid connection handle"); STHROWF("Unable to prepare statement. Invalid connection handle");
} }
@@ -795,7 +835,7 @@ void SQLiteStmtHnd::Create(const SQChar * query, SQInteger length)
// Save the query string // Save the query string
mQuery.assign(query, static_cast< size_t >(length)); mQuery.assign(query, static_cast< size_t >(length));
// Attempt to prepare a statement with the specified query string // Attempt to prepare a statement with the specified query string
if ((mStatus = sqlite3_prepare_v2(mConn->mPtr, mQuery.c_str(), ConvTo< int32_t >::From(mQuery.size()), if ((mStatus = sqlite3_prepare_v2(mConnection->mPtr, mQuery.c_str(), ConvTo< int32_t >::From(mQuery.size()),
&mPtr, nullptr)) != SQLITE_OK) &mPtr, nullptr)) != SQLITE_OK)
{ {
// Clear the query string since it failed // Clear the query string since it failed
@@ -803,7 +843,7 @@ void SQLiteStmtHnd::Create(const SQChar * query, SQInteger length)
// Explicitly make sure the handle is null // Explicitly make sure the handle is null
mPtr = nullptr; mPtr = nullptr;
// Now it's safe to throw the error // Now it's safe to throw the error
STHROWF("Unable to prepare statement [{}]", mConn->ErrMsg()); STHROWF("Unable to prepare statement [{}]", mConnection->ErrMsg());
} }
else else
{ {
@@ -818,7 +858,7 @@ void SQLiteStmtHnd::Create(const SQChar * query, SQInteger length)
int32_t SQLiteStmtHnd::GetColumnIndex(const SQChar * name, SQInteger length) int32_t SQLiteStmtHnd::GetColumnIndex(const SQChar * name, SQInteger length)
{ {
// Validate the handle // Validate the handle
if (!mPtr) if (!Access())
{ {
STHROWF("Invalid SQLite statement"); STHROWF("Invalid SQLite statement");
} }
@@ -856,25 +896,25 @@ int32_t SQLiteStmtHnd::GetColumnIndex(const SQChar * name, SQInteger length)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const char * SQLiteStmtHnd::ErrStr() const const char * SQLiteStmtHnd::ErrStr() const
{ {
return mConn ? sqlite3_errstr(sqlite3_errcode(mConn->mPtr)) : _SC(""); return mConnection ? sqlite3_errstr(sqlite3_errcode(mConnection->Access())) : _SC("");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const char * SQLiteStmtHnd::ErrMsg() const const char * SQLiteStmtHnd::ErrMsg() const
{ {
return mConn ? sqlite3_errmsg(mConn->mPtr) : _SC(""); return mConnection ? sqlite3_errmsg(mConnection->Access()) : _SC("");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int32_t SQLiteStmtHnd::ErrNo() const int32_t SQLiteStmtHnd::ErrNo() const
{ {
return mConn ? sqlite3_errcode(mConn->mPtr) : SQLITE_NOMEM; return mConnection ? sqlite3_errcode(mConnection->Access()) : SQLITE_NOMEM;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int32_t SQLiteStmtHnd::ExErrNo() const int32_t SQLiteStmtHnd::ExErrNo() const
{ {
return mConn ? sqlite3_extended_errcode(mConn->mPtr) : SQLITE_NOMEM; return mConnection ? sqlite3_extended_errcode(mConnection->Access()) : SQLITE_NOMEM;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -916,7 +956,7 @@ void SQLiteConnection::ValidateCreated(const char * file, int32_t line) const
{ {
SqThrowF(SQMOD_RTFMT("Invalid SQLite connection reference =>[{}:{}]"), file, line); SqThrowF(SQMOD_RTFMT("Invalid SQLite connection reference =>[{}:{}]"), file, line);
} }
else if (m_Handle->mPtr == nullptr) else if (m_Handle->Access() == nullptr)
{ {
SqThrowF(SQMOD_RTFMT("Invalid SQLite connection =>[{}:{}]"), file, line); SqThrowF(SQMOD_RTFMT("Invalid SQLite connection =>[{}:{}]"), file, line);
} }
@@ -928,7 +968,7 @@ void SQLiteConnection::ValidateCreated() const
{ {
SqThrowF(fmt::runtime("Invalid SQLite connection reference")); SqThrowF(fmt::runtime("Invalid SQLite connection reference"));
} }
else if (m_Handle->mPtr == nullptr) else if (m_Handle->Access() == nullptr)
{ {
SqThrowF(fmt::runtime("Invalid SQLite connection")); SqThrowF(fmt::runtime("Invalid SQLite connection"));
} }
@@ -937,13 +977,13 @@ void SQLiteConnection::ValidateCreated() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & SQLiteConnection::GetValid(const char * file, int32_t line) const const SQLiteConnRef & SQLiteConnection::GetValid(const char * file, int32_t line) const
{ {
Validate(file, line); Validate(file, line);
return m_Handle; return m_Handle;
} }
#else #else
const ConnRef & SQLiteConnection::GetValid() const const SQLiteConnRef & SQLiteConnection::GetValid() const
{ {
Validate(); Validate();
return m_Handle; return m_Handle;
@@ -952,13 +992,13 @@ const ConnRef & SQLiteConnection::GetValid() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const ConnRef & SQLiteConnection::GetCreated(const char * file, int32_t line) const const SQLiteConnRef & SQLiteConnection::GetCreated(const char * file, int32_t line) const
{ {
ValidateCreated(file, line); ValidateCreated(file, line);
return m_Handle; return m_Handle;
} }
#else #else
const ConnRef & SQLiteConnection::GetCreated() const const SQLiteConnRef & SQLiteConnection::GetCreated() const
{ {
ValidateCreated(); ValidateCreated();
return m_Handle; return m_Handle;
@@ -971,7 +1011,7 @@ void SQLiteConnection::Open(StackStrF & name)
// Should we create a connection handle? // Should we create a connection handle?
if (!m_Handle) if (!m_Handle)
{ {
m_Handle = ConnRef(new SQLiteConnHnd()); m_Handle = SQLiteConnRef(new SQLiteConnHnd());
} }
// Make sure another database isn't opened // Make sure another database isn't opened
if (SQMOD_GET_VALID(*this)->mPtr != nullptr) if (SQMOD_GET_VALID(*this)->mPtr != nullptr)
@@ -991,7 +1031,7 @@ void SQLiteConnection::Open(StackStrF & name, int32_t flags)
// Should we create a connection handle? // Should we create a connection handle?
if (!m_Handle) if (!m_Handle)
{ {
m_Handle = ConnRef(new SQLiteConnHnd()); m_Handle = SQLiteConnRef(new SQLiteConnHnd());
} }
// Make sure another database isn't opened // Make sure another database isn't opened
if (SQMOD_GET_VALID(*this)->mPtr != nullptr) if (SQMOD_GET_VALID(*this)->mPtr != nullptr)
@@ -1008,7 +1048,7 @@ void SQLiteConnection::Open(StackStrF & name, int32_t flags, StackStrF & vfs)
// Should we create a connection handle? // Should we create a connection handle?
if (!m_Handle) if (!m_Handle)
{ {
m_Handle = ConnRef(new SQLiteConnHnd()); m_Handle = SQLiteConnRef(new SQLiteConnHnd());
} }
// Make sure another database isn't opened // Make sure another database isn't opened
if (SQMOD_GET_VALID(*this)->mPtr != nullptr) if (SQMOD_GET_VALID(*this)->mPtr != nullptr)
@@ -1024,14 +1064,14 @@ int32_t SQLiteConnection::Exec(StackStrF & str)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to execute the specified query // Attempt to execute the specified query
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, str.mPtr, nullptr, nullptr, nullptr); m_Handle->mStatus = sqlite3_exec(m_Handle->Access(), str.mPtr, nullptr, nullptr, nullptr);
// Validate the execution result // Validate the execution result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
STHROWF("Unable to execute query [{}]", m_Handle->ErrMsg()); STHROWF("Unable to execute query [{}]", m_Handle->ErrMsg());
} }
// Return rows affected by this query // Return rows affected by this query
return sqlite3_changes(m_Handle->mPtr); return sqlite3_changes(m_Handle->Access());
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1104,12 +1144,12 @@ void SQLiteConnection::SetTracing(bool SQ_UNUSED_ARG(toggle)) // NOLINT(readabil
// Do we have to disable it? // Do we have to disable it?
else if (m_Handle->mTrace) else if (m_Handle->mTrace)
{ {
sqlite3_trace(m_Handle->mPtr, nullptr, nullptr); sqlite3_trace(m_Handle->Access(), nullptr, nullptr);
} }
// Go ahead and enable tracing // Go ahead and enable tracing
else else
{ {
sqlite3_trace(m_Handle->mPtr, &SQLiteConnection::TraceOutput, nullptr); sqlite3_trace(m_Handle->Access(), &SQLiteConnection::TraceOutput, nullptr);
} }
#endif #endif
} }
@@ -1128,12 +1168,12 @@ void SQLiteConnection::SetProfiling(bool SQ_UNUSED_ARG(toggle)) // NOLINT(readab
// Do we have to disable it? // Do we have to disable it?
else if (m_Handle->mProfile) else if (m_Handle->mProfile)
{ {
sqlite3_profile(m_Handle->mPtr, nullptr, nullptr); sqlite3_profile(m_Handle->Access(), nullptr, nullptr);
} }
// Go ahead and enable profiling // Go ahead and enable profiling
else else
{ {
sqlite3_profile(m_Handle->mPtr, &SQLiteConnection::ProfileOutput, nullptr); sqlite3_profile(m_Handle->Access(), &SQLiteConnection::ProfileOutput, nullptr);
} }
#endif #endif
} }
@@ -1143,7 +1183,7 @@ void SQLiteConnection::SetBusyTimeout(int32_t millis)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Apply the requested timeout // Apply the requested timeout
if ((m_Handle->mStatus = sqlite3_busy_timeout(m_Handle->mPtr, millis)) != SQLITE_OK) if ((m_Handle->mStatus = sqlite3_busy_timeout(m_Handle->Access(), millis)) != SQLITE_OK)
{ {
STHROWF("Unable to set busy timeout [{}]", m_Handle->ErrMsg()); STHROWF("Unable to set busy timeout [{}]", m_Handle->ErrMsg());
} }
@@ -1264,7 +1304,7 @@ void SQLiteParameter::ValidateCreated(const char * file, int32_t line) const
{ {
SqThrowF(SQMOD_RTFMT("Invalid SQLite statement reference =>[{}:{}]"), file, line); SqThrowF(SQMOD_RTFMT("Invalid SQLite statement reference =>[{}:{}]"), file, line);
} }
else if (m_Handle->mPtr == nullptr) else if (m_Handle->Access() == nullptr)
{ {
SqThrowF(SQMOD_RTFMT("Invalid SQLite statement =>[{}:{}]"), file, line); SqThrowF(SQMOD_RTFMT("Invalid SQLite statement =>[{}:{}]"), file, line);
} }
@@ -1281,7 +1321,7 @@ void SQLiteParameter::ValidateCreated() const
{ {
SqThrowF(fmt::runtime("Invalid SQLite statement reference")); SqThrowF(fmt::runtime("Invalid SQLite statement reference"));
} }
else if (m_Handle->mPtr == nullptr) else if (m_Handle->Access() == nullptr)
{ {
SqThrowF(fmt::runtime("Invalid SQLite statement")); SqThrowF(fmt::runtime("Invalid SQLite statement"));
} }
@@ -1290,13 +1330,13 @@ void SQLiteParameter::ValidateCreated() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & SQLiteParameter::GetValid(const char * file, int32_t line) const const SQLiteStmtRef & SQLiteParameter::GetValid(const char * file, int32_t line) const
{ {
Validate(file, line); Validate(file, line);
return m_Handle; return m_Handle;
} }
#else #else
const StmtRef & SQLiteParameter::GetValid() const const SQLiteStmtRef & SQLiteParameter::GetValid() const
{ {
Validate(); Validate();
return m_Handle; return m_Handle;
@@ -1305,13 +1345,13 @@ const StmtRef & SQLiteParameter::GetValid() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & SQLiteParameter::GetCreated(const char * file, int32_t line) const const SQLiteStmtRef & SQLiteParameter::GetCreated(const char * file, int32_t line) const
{ {
ValidateCreated(file, line); ValidateCreated(file, line);
return m_Handle; return m_Handle;
} }
#else #else
const StmtRef & SQLiteParameter::GetCreated() const const SQLiteStmtRef & SQLiteParameter::GetCreated() const
{ {
ValidateCreated(); ValidateCreated();
return m_Handle; return m_Handle;
@@ -1372,7 +1412,7 @@ void SQLiteParameter::SetIndex(const Object & param)
STHROWF("Cannot use an empty parameter name"); STHROWF("Cannot use an empty parameter name");
} }
// Attempt to find a parameter with the specified name // Attempt to find a parameter with the specified name
idx = sqlite3_bind_parameter_index(SQMOD_GET_CREATED(*this)->mPtr, val.mPtr); idx = sqlite3_bind_parameter_index(SQMOD_GET_CREATED(*this)->Access(), val.mPtr);
} break; } break;
// Is this an integer value? (or at least can be easily converted to one) // Is this an integer value? (or at least can be easily converted to one)
case OT_INTEGER: case OT_INTEGER:
@@ -1404,7 +1444,7 @@ void SQLiteParameter::SetIndex(const Object & param)
// Attempt to find a parameter with the specified name // Attempt to find a parameter with the specified name
else else
{ {
idx = sqlite3_bind_parameter_index(SQMOD_GET_CREATED(*this)->mPtr, val.mPtr); idx = sqlite3_bind_parameter_index(SQMOD_GET_CREATED(*this)->Access(), val.mPtr);
} }
} break; } break;
// We don't recognize this kind of value! // We don't recognize this kind of value!
@@ -1427,7 +1467,7 @@ Object SQLiteParameter::GetStatement() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Object SQLiteParameter::GetConnection() const Object SQLiteParameter::GetConnection() const
{ {
return GetConnectionObj(SQMOD_GET_VALID(*this)->mConn); return GetConnectionObj(SQMOD_GET_VALID(*this)->mConnection);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1472,7 +1512,7 @@ void SQLiteParameter::SetBool(bool value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, value); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, value);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1485,7 +1525,7 @@ void SQLiteParameter::SetChar(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< SQChar >::From(value)); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, ConvTo< SQChar >::From(value));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1498,7 +1538,7 @@ void SQLiteParameter::SetInteger(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_integer(m_Handle->mPtr, m_Index, value); m_Handle->mStatus = sqlite3_bind_integer(m_Handle->Access(), m_Index, value);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1511,7 +1551,7 @@ void SQLiteParameter::SetInt8(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< int8_t >::From(value)); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, ConvTo< int8_t >::From(value));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1524,7 +1564,7 @@ void SQLiteParameter::SetUint8(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< uint8_t >::From(value)); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, ConvTo< uint8_t >::From(value));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1537,7 +1577,7 @@ void SQLiteParameter::SetInt16(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< int16_t >::From(value)); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, ConvTo< int16_t >::From(value));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1550,7 +1590,7 @@ void SQLiteParameter::SetUint16(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< uint16_t >::From(value)); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, ConvTo< uint16_t >::From(value));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1563,7 +1603,7 @@ void SQLiteParameter::SetInt32(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, ConvTo< int32_t >::From(value)); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, ConvTo< int32_t >::From(value));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1576,7 +1616,7 @@ void SQLiteParameter::SetUint32(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, static_cast< int32_t >(ConvTo< uint32_t >::From(value))); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, static_cast< int32_t >(ConvTo< uint32_t >::From(value)));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1589,7 +1629,7 @@ void SQLiteParameter::SetInt64(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int64(m_Handle->mPtr, m_Index, value); m_Handle->mStatus = sqlite3_bind_int64(m_Handle->Access(), m_Index, value);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1602,7 +1642,7 @@ void SQLiteParameter::SetUint64(SQInteger value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int64(m_Handle->mPtr, m_Index, value); m_Handle->mStatus = sqlite3_bind_int64(m_Handle->Access(), m_Index, value);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1615,7 +1655,7 @@ void SQLiteParameter::SetFloat(SQFloat value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_double(m_Handle->mPtr, m_Index, value); m_Handle->mStatus = sqlite3_bind_double(m_Handle->Access(), m_Index, value);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1628,7 +1668,7 @@ void SQLiteParameter::SetFloat32(SQFloat value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_double(m_Handle->mPtr, m_Index, ConvTo< float >::From(value)); m_Handle->mStatus = sqlite3_bind_double(m_Handle->Access(), m_Index, ConvTo< float >::From(value));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1641,7 +1681,7 @@ void SQLiteParameter::SetFloat64(SQFloat value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_double(m_Handle->mPtr, m_Index, value); m_Handle->mStatus = sqlite3_bind_double(m_Handle->Access(), m_Index, value);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1654,7 +1694,7 @@ void SQLiteParameter::SetString(StackStrF & value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, value.mPtr, static_cast<int>(value.mLen), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_text(m_Handle->Access(), m_Index, value.mPtr, static_cast<int>(value.mLen), SQLITE_TRANSIENT);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1667,7 +1707,7 @@ void SQLiteParameter::SetStringRaw(const SQChar * value, SQInteger length)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, value, static_cast<int>(length), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_text(m_Handle->Access(), m_Index, value, static_cast<int>(length), SQLITE_TRANSIENT);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1680,7 +1720,7 @@ void SQLiteParameter::SetZeroBlob(SQInteger size)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_zeroblob(m_Handle->mPtr, m_Index, ConvTo< int32_t >::From(size)); m_Handle->mStatus = sqlite3_bind_zeroblob(m_Handle->Access(), m_Index, ConvTo< int32_t >::From(size));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1712,7 +1752,7 @@ void SQLiteParameter::SetBlob(const Object & value)
len = sqstd_getblobsize(vm, -1); len = sqstd_getblobsize(vm, -1);
} }
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_blob(m_Handle->mPtr, m_Index, ptr, static_cast<int>(len), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_blob(m_Handle->Access(), m_Index, ptr, static_cast<int>(len), SQLITE_TRANSIENT);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1726,9 +1766,9 @@ void SQLiteParameter::SetData(const SqBuffer & value)
Buffer & buff = *value.GetRef(); Buffer & buff = *value.GetRef();
// Attempt to bind the specified value // Attempt to bind the specified value
#ifdef _SQ64 #ifdef _SQ64
m_Handle->mStatus = sqlite3_bind_blob64(m_Handle->mPtr, m_Index, buff.Data(), buff.Position(), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_blob64(m_Handle->Access(), m_Index, buff.Data(), buff.Position(), SQLITE_TRANSIENT);
#else #else
m_Handle->mStatus = sqlite3_bind_blob(m_Handle->mPtr, m_Index, buff.Data(), buff.Position(), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_blob(m_Handle->Access(), m_Index, buff.Data(), buff.Position(), SQLITE_TRANSIENT);
#endif #endif
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
@@ -1757,9 +1797,9 @@ void SQLiteParameter::SetDataEx(const SqBuffer & value, SQInteger offset, SQInte
} }
// Attempt to bind the specified value // Attempt to bind the specified value
#ifdef _SQ64 #ifdef _SQ64
m_Handle->mStatus = sqlite3_bind_blob64(m_Handle->mPtr, m_Index, (buff.Data() + offset), static_cast< sqlite3_uint64 >(offset + length), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_blob64(m_Handle->Access(), m_Index, (buff.Data() + offset), static_cast< sqlite3_uint64 >(offset + length), SQLITE_TRANSIENT);
#else #else
m_Handle->mStatus = sqlite3_bind_blob(m_Handle->mPtr, m_Index, (buff.Data() + offset), static_cast< int >(offset + length), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_blob(m_Handle->Access(), m_Index, (buff.Data() + offset), static_cast< int >(offset + length), SQLITE_TRANSIENT);
#endif #endif
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
@@ -1775,7 +1815,7 @@ void SQLiteParameter::SetDate(const Date & value)
// Attempt to generate the specified date string // Attempt to generate the specified date string
auto str = fmt::format("{} 00:00:00", value.ToString()); auto str = fmt::format("{} 00:00:00", value.ToString());
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, str.data(), static_cast< int >(str.size()), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_text(m_Handle->Access(), m_Index, str.data(), static_cast< int >(str.size()), SQLITE_TRANSIENT);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1798,7 +1838,7 @@ void SQLiteParameter::SetDateEx(SQInteger year, SQInteger month, SQInteger day)
// Attempt to generate the specified date string // Attempt to generate the specified date string
auto str = fmt::format("{}-{}-{} 00:00:00", y, m, d); auto str = fmt::format("{}-{}-{} 00:00:00", y, m, d);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, str.data(), static_cast< int >(str.size()), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_text(m_Handle->Access(), m_Index, str.data(), static_cast< int >(str.size()), SQLITE_TRANSIENT);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1811,7 +1851,7 @@ void SQLiteParameter::SetTime(const Time & value)
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, static_cast<int>(value.GetTimestamp().GetSecondsI())); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, static_cast<int>(value.GetTimestamp().GetSecondsI()));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1843,7 +1883,7 @@ void SQLiteParameter::SetTimeEx(SQInteger hour, SQInteger minute, SQInteger seco
STHROWF("Second value is out of range: {} >= 60", s); STHROWF("Second value is out of range: {} >= 60", s);
} }
// Calculate the number of seconds in the specified time and bind the resulted value // Calculate the number of seconds in the specified time and bind the resulted value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, (h * (60 * 60)) + (m * 60) + s); m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index, (h * (60 * 60)) + (m * 60) + s);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1891,7 +1931,7 @@ void SQLiteParameter::SetDatetimeEx(SQInteger year, SQInteger month, SQInteger d
// Attempt to generate the specified date string // Attempt to generate the specified date string
auto str = fmt::format(_SC("{:04}-{:02}-{:02} {:02}:{:02}:{:02}"), y, mo, d, h, mi, s); auto str = fmt::format(_SC("{:04}-{:02}-{:02} {:02}:{:02}:{:02}"), y, mo, d, h, mi, s);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_text(m_Handle->mPtr, m_Index, str.data(), static_cast< int >(str.size()), SQLITE_TRANSIENT); m_Handle->mStatus = sqlite3_bind_text(m_Handle->Access(), m_Index, str.data(), static_cast< int >(str.size()), SQLITE_TRANSIENT);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1904,7 +1944,7 @@ void SQLiteParameter::SetNow()
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_int(m_Handle->mPtr, m_Index, m_Handle->mStatus = sqlite3_bind_int(m_Handle->Access(), m_Index,
static_cast< int32_t >(std::time(nullptr))); static_cast< int32_t >(std::time(nullptr)));
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
@@ -1918,7 +1958,7 @@ void SQLiteParameter::SetNull()
{ {
SQMOD_VALIDATE_CREATED(*this); SQMOD_VALIDATE_CREATED(*this);
// Attempt to bind the specified value // Attempt to bind the specified value
m_Handle->mStatus = sqlite3_bind_null(m_Handle->mPtr, m_Index); m_Handle->mStatus = sqlite3_bind_null(m_Handle->Access(), m_Index);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -1970,7 +2010,7 @@ void SQLiteColumn::ValidateCreated(const char * file, int32_t line) const
{ {
SqThrowF(SQMOD_RTFMT("Invalid SQLite statement reference =>[{}:{}]"), file, line); SqThrowF(SQMOD_RTFMT("Invalid SQLite statement reference =>[{}:{}]"), file, line);
} }
else if (m_Handle->mPtr == nullptr) else if (m_Handle->Access() == nullptr)
{ {
SqThrowF(SQMOD_RTFMT("Invalid SQLite statement =>[{}:{}]"), file, line); SqThrowF(SQMOD_RTFMT("Invalid SQLite statement =>[{}:{}]"), file, line);
} }
@@ -1987,7 +2027,7 @@ void SQLiteColumn::ValidateCreated() const
{ {
SqThrowF(fmt::runtime("Invalid SQLite statement reference")); SqThrowF(fmt::runtime("Invalid SQLite statement reference"));
} }
else if (m_Handle->mPtr == nullptr) else if (m_Handle->Access() == nullptr)
{ {
SqThrowF(fmt::runtime("Invalid SQLite statement")); SqThrowF(fmt::runtime("Invalid SQLite statement"));
} }
@@ -1996,13 +2036,13 @@ void SQLiteColumn::ValidateCreated() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & SQLiteColumn::GetValid(const char * file, int32_t line) const const SQLiteStmtRef & SQLiteColumn::GetValid(const char * file, int32_t line) const
{ {
Validate(file, line); Validate(file, line);
return m_Handle; return m_Handle;
} }
#else #else
const StmtRef & SQLiteColumn::GetValid() const const SQLiteStmtRef & SQLiteColumn::GetValid() const
{ {
Validate(); Validate();
return m_Handle; return m_Handle;
@@ -2011,13 +2051,13 @@ const StmtRef & SQLiteColumn::GetValid() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & SQLiteColumn::GetCreated(const char * file, int32_t line) const const SQLiteStmtRef & SQLiteColumn::GetCreated(const char * file, int32_t line) const
{ {
ValidateCreated(file, line); ValidateCreated(file, line);
return m_Handle; return m_Handle;
} }
#else #else
const StmtRef & SQLiteColumn::GetCreated() const const SQLiteStmtRef & SQLiteColumn::GetCreated() const
{ {
ValidateCreated(); ValidateCreated();
return m_Handle; return m_Handle;
@@ -2156,7 +2196,7 @@ Object SQLiteColumn::GetStatement() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Object SQLiteColumn::GetConnection() const Object SQLiteColumn::GetConnection() const
{ {
return GetConnectionObj(SQMOD_GET_VALID(*this)->mConn); return GetConnectionObj(SQMOD_GET_VALID(*this)->mConnection);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -2202,7 +2242,7 @@ Object SQLiteColumn::GetValue() const
// Obtain the initial stack size // Obtain the initial stack size
const StackGuard sg; const StackGuard sg;
// Identify which type of value must be pushed on the stack // Identify which type of value must be pushed on the stack
switch (sqlite3_column_type(m_Handle->mPtr, m_Index)) switch (sqlite3_column_type(m_Handle->Access(), m_Index))
{ {
// Is this a null value? // Is this a null value?
case SQLITE_NULL: case SQLITE_NULL:
@@ -2212,28 +2252,28 @@ Object SQLiteColumn::GetValue() const
// Is this an integer? // Is this an integer?
case SQLITE_INTEGER: case SQLITE_INTEGER:
{ {
sq_pushinteger(SqVM(), sqlite3_column_integer(m_Handle->mPtr, m_Index)); sq_pushinteger(SqVM(), sqlite3_column_integer(m_Handle->Access(), m_Index));
} break; } break;
// Is this a floating point? // Is this a floating point?
case SQLITE_FLOAT: case SQLITE_FLOAT:
{ {
sq_pushfloat(SqVM(), sq_pushfloat(SqVM(),
ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index))); ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->Access(), m_Index)));
} break; } break;
// Is this a string? // Is this a string?
case SQLITE_TEXT: case SQLITE_TEXT:
{ {
sq_pushstring(SqVM(), sq_pushstring(SqVM(),
reinterpret_cast< const SQChar * >(sqlite3_column_text(m_Handle->mPtr, m_Index)), reinterpret_cast< const SQChar * >(sqlite3_column_text(m_Handle->Access(), m_Index)),
sqlite3_column_bytes(m_Handle->mPtr, m_Index)); sqlite3_column_bytes(m_Handle->Access(), m_Index));
} break; } break;
// Is this raw data? // Is this raw data?
case SQLITE_BLOB: case SQLITE_BLOB:
{ {
// Retrieve the size of the blob that must be allocated // Retrieve the size of the blob that must be allocated
const int32_t size = sqlite3_column_bytes(m_Handle->mPtr, m_Index); const int32_t size = sqlite3_column_bytes(m_Handle->Access(), m_Index);
// Retrieve the the actual blob data that must be returned // Retrieve the the actual blob data that must be returned
auto data = reinterpret_cast< const char * >(sqlite3_column_blob(m_Handle->mPtr, m_Index)); auto data = reinterpret_cast< const char * >(sqlite3_column_blob(m_Handle->Access(), m_Index));
// Attempt to create a buffer with the blob data on the stack // Attempt to create a buffer with the blob data on the stack
Var< const SqBuffer & >::push(SqVM(), SqBuffer(data, size, 0)); Var< const SqBuffer & >::push(SqVM(), SqBuffer(data, size, 0));
} break; } break;
@@ -2251,7 +2291,7 @@ Object SQLiteColumn::GetNumber() const
// Obtain the initial stack size // Obtain the initial stack size
const StackGuard sg; const StackGuard sg;
// Identify which type of value must be pushed on the stack // Identify which type of value must be pushed on the stack
switch (sqlite3_column_type(m_Handle->mPtr, m_Index)) switch (sqlite3_column_type(m_Handle->Access(), m_Index))
{ {
// Is this a null value? // Is this a null value?
case SQLITE_NULL: case SQLITE_NULL:
@@ -2261,18 +2301,18 @@ Object SQLiteColumn::GetNumber() const
// Is this an integer? // Is this an integer?
case SQLITE_INTEGER: case SQLITE_INTEGER:
{ {
sq_pushinteger(SqVM(), sqlite3_column_integer(m_Handle->mPtr, m_Index)); sq_pushinteger(SqVM(), sqlite3_column_integer(m_Handle->Access(), m_Index));
} break; } break;
// Is this a floating point? // Is this a floating point?
case SQLITE_FLOAT: case SQLITE_FLOAT:
{ {
sq_pushfloat(SqVM(), sq_pushfloat(SqVM(),
ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index))); ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->Access(), m_Index)));
} break; } break;
// Is this a string? // Is this a string?
case SQLITE_TEXT: case SQLITE_TEXT:
{ {
auto str = reinterpret_cast< const SQChar * >(sqlite3_column_text(m_Handle->mPtr, m_Index)); auto str = reinterpret_cast< const SQChar * >(sqlite3_column_text(m_Handle->Access(), m_Index));
// Is there even a string to parse? // Is there even a string to parse?
if (!str || *str == '\0') if (!str || *str == '\0')
{ {
@@ -2303,7 +2343,7 @@ SQInteger SQLiteColumn::GetInteger() const
{ {
SQMOD_VALIDATE_ROW(*this); SQMOD_VALIDATE_ROW(*this);
// Return the requested information // Return the requested information
return sqlite3_column_integer(m_Handle->mPtr, m_Index); return sqlite3_column_integer(m_Handle->Access(), m_Index);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -2311,7 +2351,7 @@ SQFloat SQLiteColumn::GetFloat() const
{ {
SQMOD_VALIDATE_ROW(*this); SQMOD_VALIDATE_ROW(*this);
// Return the requested information // Return the requested information
return ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->mPtr, m_Index)); return ConvTo< SQFloat >::From(sqlite3_column_double(m_Handle->Access(), m_Index));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -2319,7 +2359,7 @@ SQInteger SQLiteColumn::GetLong() const
{ {
SQMOD_VALIDATE_ROW(*this); SQMOD_VALIDATE_ROW(*this);
// Return the requested information // Return the requested information
return sqlite3_column_int64(m_Handle->mPtr, m_Index); return sqlite3_column_int64(m_Handle->Access(), m_Index);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -2329,8 +2369,8 @@ Object SQLiteColumn::GetString() const
// Obtain the initial stack size // Obtain the initial stack size
const StackGuard sg; const StackGuard sg;
// Push the column text on the stack // Push the column text on the stack
sq_pushstring(SqVM(), reinterpret_cast< const SQChar * >(sqlite3_column_text(m_Handle->mPtr, m_Index)), sq_pushstring(SqVM(), reinterpret_cast< const SQChar * >(sqlite3_column_text(m_Handle->Access(), m_Index)),
sqlite3_column_bytes(m_Handle->mPtr, m_Index)); sqlite3_column_bytes(m_Handle->Access(), m_Index));
// Get the object from the stack and return it // Get the object from the stack and return it
return Var< Object >(SqVM(), -1).value; return Var< Object >(SqVM(), -1).value;
} }
@@ -2340,7 +2380,7 @@ bool SQLiteColumn::GetBoolean() const
{ {
SQMOD_VALIDATE_ROW(*this); SQMOD_VALIDATE_ROW(*this);
// Return the requested information // Return the requested information
return sqlite3_column_int(m_Handle->mPtr, m_Index) > 0; return sqlite3_column_int(m_Handle->Access(), m_Index) > 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -2348,7 +2388,7 @@ SQChar SQLiteColumn::GetChar() const
{ {
SQMOD_VALIDATE_ROW(*this); SQMOD_VALIDATE_ROW(*this);
// Return the requested information // Return the requested information
return (SQChar)sqlite3_column_int(m_Handle->mPtr, m_Index); return (SQChar)sqlite3_column_int(m_Handle->Access(), m_Index);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -2358,9 +2398,9 @@ Object SQLiteColumn::GetBuffer() const
// Remember the current stack size // Remember the current stack size
const StackGuard sg; const StackGuard sg;
// Retrieve the size of the blob that must be allocated // Retrieve the size of the blob that must be allocated
const int32_t size = sqlite3_column_bytes(m_Handle->mPtr, m_Index); const int32_t size = sqlite3_column_bytes(m_Handle->Access(), m_Index);
// Retrieve the the actual blob data that must be returned // Retrieve the the actual blob data that must be returned
auto data = reinterpret_cast< const char * >(sqlite3_column_blob(m_Handle->mPtr, m_Index)); auto data = reinterpret_cast< const char * >(sqlite3_column_blob(m_Handle->Access(), m_Index));
// Attempt to create a buffer with the blob data on the stack // Attempt to create a buffer with the blob data on the stack
Var< const SqBuffer & >::push(SqVM(), SqBuffer(data, size, 0)); Var< const SqBuffer & >::push(SqVM(), SqBuffer(data, size, 0));
// Get the object from the stack and return it // Get the object from the stack and return it
@@ -2374,11 +2414,11 @@ Object SQLiteColumn::GetBlob() const
// Obtain the initial stack size // Obtain the initial stack size
const StackGuard sg; const StackGuard sg;
// Obtain the size of the data // Obtain the size of the data
const int32_t sz = sqlite3_column_bytes(m_Handle->mPtr, m_Index); const int32_t sz = sqlite3_column_bytes(m_Handle->Access(), m_Index);
// Allocate a blob of the same size // Allocate a blob of the same size
SQUserPointer p = sqstd_createblob(SqVM(), sz); SQUserPointer p = sqstd_createblob(SqVM(), sz);
// Obtain a pointer to the data // Obtain a pointer to the data
const void * b = sqlite3_column_blob(m_Handle->mPtr, m_Index); const void * b = sqlite3_column_blob(m_Handle->Access(), m_Index);
// Could the memory blob be allocated? // Could the memory blob be allocated?
if (!p) if (!p)
{ {
@@ -2428,7 +2468,7 @@ void SQLiteStatement::ValidateCreated(const char * file, int32_t line) const
{ {
SqThrowF(SQMOD_RTFMT("Invalid SQLite statement reference =>[{}:{}]"), file, line); SqThrowF(SQMOD_RTFMT("Invalid SQLite statement reference =>[{}:{}]"), file, line);
} }
else if (m_Handle->mPtr == nullptr) else if (m_Handle->Access() == nullptr)
{ {
SqThrowF(SQMOD_RTFMT("Invalid SQLite statement =>[{}:{}]"), file, line); SqThrowF(SQMOD_RTFMT("Invalid SQLite statement =>[{}:{}]"), file, line);
} }
@@ -2440,7 +2480,7 @@ void SQLiteStatement::ValidateCreated() const
{ {
SqThrowF(fmt::runtime("Invalid SQLite statement reference")); SqThrowF(fmt::runtime("Invalid SQLite statement reference"));
} }
else if (m_Handle->mPtr == nullptr) else if (m_Handle->Access() == nullptr)
{ {
SqThrowF(fmt::runtime("Invalid SQLite statement")); SqThrowF(fmt::runtime("Invalid SQLite statement"));
} }
@@ -2449,13 +2489,13 @@ void SQLiteStatement::ValidateCreated() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & SQLiteStatement::GetValid(const char * file, int32_t line) const const SQLiteStmtRef & SQLiteStatement::GetValid(const char * file, int32_t line) const
{ {
Validate(file, line); Validate(file, line);
return m_Handle; return m_Handle;
} }
#else #else
const StmtRef & SQLiteStatement::GetValid() const const SQLiteStmtRef & SQLiteStatement::GetValid() const
{ {
Validate(); Validate();
return m_Handle; return m_Handle;
@@ -2464,13 +2504,13 @@ const StmtRef & SQLiteStatement::GetValid() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const StmtRef & SQLiteStatement::GetCreated(const char * file, int32_t line) const const SQLiteStmtRef & SQLiteStatement::GetCreated(const char * file, int32_t line) const
{ {
ValidateCreated(file, line); ValidateCreated(file, line);
return m_Handle; return m_Handle;
} }
#else #else
const StmtRef & SQLiteStatement::GetCreated() const const SQLiteStmtRef & SQLiteStatement::GetCreated() const
{ {
ValidateCreated(); ValidateCreated();
return m_Handle; return m_Handle;
@@ -2556,7 +2596,7 @@ SQLiteStatement::SQLiteStatement(const SQLiteConnection & connection, StackStrF
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Object SQLiteStatement::GetConnection() const Object SQLiteStatement::GetConnection() const
{ {
return Object(new SQLiteConnection(SQMOD_GET_VALID(*this)->mConn)); return Object(new SQLiteConnection(SQMOD_GET_VALID(*this)->mConnection));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -2567,7 +2607,7 @@ SQLiteStatement & SQLiteStatement::Reset()
m_Handle->mGood = false; m_Handle->mGood = false;
m_Handle->mDone = false; m_Handle->mDone = false;
// Attempt to reset the statement to it's initial state // Attempt to reset the statement to it's initial state
m_Handle->mStatus = sqlite3_reset(m_Handle->mPtr); m_Handle->mStatus = sqlite3_reset(m_Handle->Access());
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -2585,7 +2625,7 @@ SQLiteStatement & SQLiteStatement::Clear()
m_Handle->mGood = false; m_Handle->mGood = false;
m_Handle->mDone = false; m_Handle->mDone = false;
// Attempt to clear the statement // Attempt to clear the statement
m_Handle->mStatus = sqlite3_clear_bindings(m_Handle->mPtr); m_Handle->mStatus = sqlite3_clear_bindings(m_Handle->Access());
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -2605,7 +2645,7 @@ int32_t SQLiteStatement::Exec()
STHROWF("Executed without resetting first"); STHROWF("Executed without resetting first");
} }
// Attempt to step the statement // Attempt to step the statement
m_Handle->mStatus = sqlite3_step(m_Handle->mPtr); m_Handle->mStatus = sqlite3_step(m_Handle->Access());
// Have we finished stepping? // Have we finished stepping?
if (m_Handle->mStatus == SQLITE_DONE) if (m_Handle->mStatus == SQLITE_DONE)
{ {
@@ -2613,7 +2653,7 @@ int32_t SQLiteStatement::Exec()
m_Handle->mGood = false; m_Handle->mGood = false;
m_Handle->mDone = true; m_Handle->mDone = true;
// Return the changes made by this statement // Return the changes made by this statement
return sqlite3_changes(m_Handle->mConn->mPtr); return sqlite3_changes(m_Handle->mConnection->mPtr);
} }
// Specify that we don't have any row and we haven't finished stepping // Specify that we don't have any row and we haven't finished stepping
m_Handle->mGood = false; m_Handle->mGood = false;
@@ -2646,7 +2686,7 @@ bool SQLiteStatement::Step()
STHROWF("Stepped without resetting first"); STHROWF("Stepped without resetting first");
} }
// Attempt to step the statement // Attempt to step the statement
m_Handle->mStatus = sqlite3_step(m_Handle->mPtr); m_Handle->mStatus = sqlite3_step(m_Handle->Access());
// Do we have a row available? // Do we have a row available?
if (m_Handle->mStatus == SQLITE_ROW) if (m_Handle->mStatus == SQLITE_ROW)
{ {
@@ -2796,7 +2836,7 @@ Table SQLiteStatement::GetTable(int32_t min, int32_t max) const
while (min <= max) while (min <= max)
{ {
// Attempt to obtain the column name // Attempt to obtain the column name
const SQChar * name = sqlite3_column_name(m_Handle->mPtr, min); const SQChar * name = sqlite3_column_name(m_Handle->Access(), min);
// Validate the obtained name // Validate the obtained name
if (!name) if (!name)
{ {
@@ -2819,7 +2859,7 @@ SQLiteTransaction::SQLiteTransaction(const SQLiteConnection & db)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQLiteTransaction::SQLiteTransaction(ConnRef db) SQLiteTransaction::SQLiteTransaction(SQLiteConnRef db)
: m_Handle(std::move(db)), m_Committed(false) : m_Handle(std::move(db)), m_Committed(false)
{ {
// Was the specified database connection valid? // Was the specified database connection valid?
@@ -2828,7 +2868,7 @@ SQLiteTransaction::SQLiteTransaction(ConnRef db)
STHROWF("Invalid connection handle"); STHROWF("Invalid connection handle");
} }
// Attempt to begin transaction // Attempt to begin transaction
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "BEGIN", nullptr, nullptr, nullptr); m_Handle->mStatus = sqlite3_exec(m_Handle->Access(), "BEGIN", nullptr, nullptr, nullptr);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -2845,7 +2885,7 @@ SQLiteTransaction::~SQLiteTransaction()
return; // We're done here! return; // We're done here!
} }
// Attempt to roll back changes because this failed to commit // Attempt to roll back changes because this failed to commit
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "ROLLBACK", nullptr, nullptr, nullptr); m_Handle->mStatus = sqlite3_exec(m_Handle->Access(), "ROLLBACK", nullptr, nullptr, nullptr);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
@@ -2868,7 +2908,7 @@ bool SQLiteTransaction::Commit()
STHROWF("Transaction was already committed"); STHROWF("Transaction was already committed");
} }
// Attempt to commit the change during this transaction // Attempt to commit the change during this transaction
m_Handle->mStatus = sqlite3_exec(m_Handle->mPtr, "COMMIT", nullptr, nullptr, nullptr); m_Handle->mStatus = sqlite3_exec(m_Handle->Access(), "COMMIT", nullptr, nullptr, nullptr);
// Validate the result // Validate the result
if (m_Handle->mStatus != SQLITE_OK) if (m_Handle->mStatus != SQLITE_OK)
{ {
+115 -50
View File
@@ -2,6 +2,7 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Core/Utility.hpp" #include "Core/Utility.hpp"
#include "Core/ThreadPool.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Library/IO/Buffer.hpp" #include "Library/IO/Buffer.hpp"
@@ -10,6 +11,10 @@
#include "Library/Chrono/Time.hpp" #include "Library/Chrono/Time.hpp"
#include "Library/Chrono/Timestamp.hpp" #include "Library/Chrono/Timestamp.hpp"
// ------------------------------------------------------------------------------------------------
#include "Poco/AutoPtr.h"
#include "Poco/Data/SessionImpl.h"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -78,18 +83,18 @@ struct SQLiteStmtHnd;
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Common typedefs. * Common typedefs.
*/ */
typedef SharedPtr< SQLiteConnHnd > ConnRef; typedef SharedPtr< SQLiteConnHnd > SQLiteConnRef;
typedef SharedPtr< SQLiteStmtHnd > StmtRef; typedef SharedPtr< SQLiteStmtHnd > SQLiteStmtRef;
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Obtain a script object from a connection handle. (meant to avoid having to include the header) * Obtain a script object from a connection handle. (meant to avoid having to include the header)
*/ */
Object GetConnectionObj(const ConnRef & conn); Object GetConnectionObj(const SQLiteConnRef & conn);
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Obtain a script object from a statement handle. (meant to avoid having to include the header) * Obtain a script object from a statement handle. (meant to avoid having to include the header)
*/ */
Object GetStatementObj(const StmtRef & stmt); Object GetStatementObj(const SQLiteStmtRef & stmt);
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Tests if a certain query string is empty. * Tests if a certain query string is empty.
@@ -178,6 +183,9 @@ public:
String mName; // The specified name to be used as the database file. String mName; // The specified name to be used as the database file.
String mVFS; // The specified virtual file system. String mVFS; // The specified virtual file system.
// --------------------------------------------------------------------------------------------
Poco::AutoPtr< Poco::Data::SessionImpl > mSession; // POCO session when this connection comes from a pool.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
bool mMemory; // Whether the database exists in memory and not disk. bool mMemory; // Whether the database exists in memory and not disk.
bool mTrace; // Whether tracing was activated on the database. bool mTrace; // Whether tracing was activated on the database.
@@ -188,6 +196,16 @@ public:
*/ */
SQLiteConnHnd(); SQLiteConnHnd();
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit SQLiteConnHnd(Poco::Data::SessionImpl * session);
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit SQLiteConnHnd(Poco::AutoPtr< Poco::Data::SessionImpl > && session);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled) * Copy constructor. (disabled)
*/ */
@@ -254,6 +272,20 @@ public:
{ {
return sqlite3_extended_errcode(mPtr); return sqlite3_extended_errcode(mPtr);
} }
/* --------------------------------------------------------------------------------------------
* Access the connection pointer.
*/
SQMOD_NODISCARD Pointer Access() const
{
if (!mSession.isNull()) {
// Only reason this is necessary is to dirty the connection handle access time-stamp
// So it won't be closed/collected when it comes from a connection/session-pool
[[maybe_unused]] auto _ = mSession->isConnected();
}
// We yield access to the pointer anyway
return mPtr;
}
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -286,7 +318,7 @@ public:
int32_t mStatus; // The last status code of this connection handle. int32_t mStatus; // The last status code of this connection handle.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
ConnRef mConn; // The handle to the associated database connection. SQLiteConnRef mConnection; // The handle to the associated database connection.
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
String mQuery; // The query string used to create this statement. String mQuery; // The query string used to create this statement.
@@ -303,7 +335,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Default constructor. * Default constructor.
*/ */
explicit SQLiteStmtHnd(ConnRef conn); explicit SQLiteStmtHnd(SQLiteConnRef conn);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled) * Copy constructor. (disabled)
@@ -375,6 +407,20 @@ public:
* Return the extended numeric result code for the most recent failed API call (if any). * Return the extended numeric result code for the most recent failed API call (if any).
*/ */
SQMOD_NODISCARD int32_t ExErrNo() const; SQMOD_NODISCARD int32_t ExErrNo() const;
/* --------------------------------------------------------------------------------------------
* Access the statement pointer.
*/
SQMOD_NODISCARD Pointer Access() const
{
if (bool(mConnection) && !(mConnection->mSession.isNull())) {
// Only reason this is necessary is to dirty the connection handle access time-stamp
// So it won't be closed/collected when it comes from a connection/session-pool
[[maybe_unused]] auto _ = mConnection->mSession->isConnected();
}
// We yield access to the pointer anyway
return mPtr;
}
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -385,7 +431,7 @@ class SQLiteConnection
private: private:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
ConnRef m_Handle; // Reference to the managed connection. SQLiteConnRef m_Handle; // Reference to the managed connection.
protected: protected:
@@ -421,18 +467,18 @@ protected:
* Validate the managed connection handle and throw an error if invalid. * Validate the managed connection handle and throw an error if invalid.
*/ */
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SQMOD_NODISCARD const ConnRef & GetValid(const char * file, int32_t line) const; SQMOD_NODISCARD const SQLiteConnRef & GetValid(const char * file, int32_t line) const;
#else #else
SQMOD_NODISCARD const ConnRef & GetValid() const; SQMOD_NODISCARD const SQLiteConnRef & GetValid() const;
#endif // _DEBUG #endif // _DEBUG
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Validate the managed connection handle and throw an error if invalid. * Validate the managed connection handle and throw an error if invalid.
*/ */
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SQMOD_NODISCARD const ConnRef & GetCreated(const char * file, int32_t line) const; SQMOD_NODISCARD const SQLiteConnRef & GetCreated(const char * file, int32_t line) const;
#else #else
SQMOD_NODISCARD const ConnRef & GetCreated() const; SQMOD_NODISCARD const SQLiteConnRef & GetCreated() const;
#endif // _DEBUG #endif // _DEBUG
public: public:
@@ -479,7 +525,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Direct handle constructor. * Direct handle constructor.
*/ */
explicit SQLiteConnection(ConnRef c) explicit SQLiteConnection(SQLiteConnRef c)
: m_Handle(std::move(c)) : m_Handle(std::move(c))
{ {
/* ... */ /* ... */
@@ -526,7 +572,7 @@ public:
*/ */
operator sqlite3 * () //NOLINT (intentionally implicit) operator sqlite3 * () //NOLINT (intentionally implicit)
{ {
return m_Handle ? m_Handle->mPtr : nullptr; return m_Handle ? m_Handle->Access() : nullptr;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -534,7 +580,7 @@ public:
*/ */
operator sqlite3 * () const //NOLINT (intentionally implicit) operator sqlite3 * () const //NOLINT (intentionally implicit)
{ {
return m_Handle ? m_Handle->mPtr : nullptr; return m_Handle ? m_Handle->Access() : nullptr;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -548,7 +594,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the associated connection handle. * Retrieve the associated connection handle.
*/ */
SQMOD_NODISCARD const ConnRef & GetHandle() const SQMOD_NODISCARD const SQLiteConnRef & GetHandle() const
{ {
return m_Handle; return m_Handle;
} }
@@ -566,7 +612,7 @@ public:
*/ */
SQMOD_NODISCARD bool IsConnected() const SQMOD_NODISCARD bool IsConnected() const
{ {
return m_Handle && (m_Handle->mPtr != nullptr); return m_Handle && (m_Handle->Access() != nullptr);
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -679,6 +725,16 @@ public:
*/ */
Object Query(StackStrF & str) const; Object Query(StackStrF & str) const;
/* --------------------------------------------------------------------------------------------
* Attempt to execute the specified query asynchronously.
*/
LightObj AsyncExec(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Attempt to create a statement from the specified query asynchronously.
*/
LightObj AsyncQuery(StackStrF & str) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* See if the database connection was opened in read-only mode. * See if the database connection was opened in read-only mode.
*/ */
@@ -857,8 +913,8 @@ class SQLiteParameter
private: private:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
int32_t m_Index{0}; // The index of the managed parameter. int32_t m_Index{0}; // The index of the managed parameter.
StmtRef m_Handle{}; // Reference to the managed statement. SQLiteStmtRef m_Handle{}; // Reference to the managed statement.
protected: protected:
@@ -884,18 +940,18 @@ protected:
* Validate the managed statement handle and throw an error if invalid. * Validate the managed statement handle and throw an error if invalid.
*/ */
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SQMOD_NODISCARD const StmtRef & GetValid(const char * file, int32_t line) const; SQMOD_NODISCARD const SQLiteStmtRef & GetValid(const char * file, int32_t line) const;
#else #else
SQMOD_NODISCARD const StmtRef & GetValid() const; SQMOD_NODISCARD const SQLiteStmtRef & GetValid() const;
#endif // _DEBUG #endif // _DEBUG
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid. * Validate the managed statement handle and throw an error if invalid.
*/ */
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SQMOD_NODISCARD const StmtRef & GetCreated(const char * file, int32_t line) const; SQMOD_NODISCARD const SQLiteStmtRef & GetCreated(const char * file, int32_t line) const;
#else #else
SQMOD_NODISCARD const StmtRef & GetCreated() const; SQMOD_NODISCARD const SQLiteStmtRef & GetCreated() const;
#endif // _DEBUG #endif // _DEBUG
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -943,7 +999,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* No parameter constructor. * No parameter constructor.
*/ */
explicit SQLiteParameter(StmtRef stmt) explicit SQLiteParameter(SQLiteStmtRef stmt)
: m_Index(0), m_Handle(std::move(stmt)) : m_Index(0), m_Handle(std::move(stmt))
{ {
/* ... */ /* ... */
@@ -952,7 +1008,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Index constructor. * Index constructor.
*/ */
SQLiteParameter(StmtRef stmt, int32_t idx) SQLiteParameter(SQLiteStmtRef stmt, int32_t idx)
: m_Index(idx), m_Handle(std::move(stmt)) : m_Index(idx), m_Handle(std::move(stmt))
{ {
SQMOD_VALIDATE_PARAM(*this, m_Index); SQMOD_VALIDATE_PARAM(*this, m_Index);
@@ -961,7 +1017,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Name constructor. * Name constructor.
*/ */
SQLiteParameter(const StmtRef & stmt, const SQChar * name) SQLiteParameter(const SQLiteStmtRef & stmt, const SQChar * name)
: m_Index(stmt ? sqlite3_bind_parameter_index(stmt->mPtr, name) : 0), m_Handle(stmt) : m_Index(stmt ? sqlite3_bind_parameter_index(stmt->mPtr, name) : 0), m_Handle(stmt)
{ {
SQMOD_VALIDATE_PARAM(*this, m_Index); SQMOD_VALIDATE_PARAM(*this, m_Index);
@@ -970,7 +1026,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Dynamic constructor. * Dynamic constructor.
*/ */
SQLiteParameter(StmtRef stmt, const Object & param) SQLiteParameter(SQLiteStmtRef stmt, const Object & param)
: m_Index(0), m_Handle(std::move(stmt)) : m_Index(0), m_Handle(std::move(stmt))
{ {
if (!m_Handle) if (!m_Handle)
@@ -1033,7 +1089,7 @@ public:
// Can we attempt to return the parameter name? // Can we attempt to return the parameter name?
if (m_Handle && m_Index) if (m_Handle && m_Index)
{ {
const SQChar * val = sqlite3_bind_parameter_name(m_Handle->mPtr, m_Index); const SQChar * val = sqlite3_bind_parameter_name(m_Handle->Access(), m_Index);
// Return the value if valid // Return the value if valid
return val ? val : String{}; return val ? val : String{};
} }
@@ -1252,7 +1308,7 @@ private:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
int32_t m_Index{-1}; // The index of the managed column. int32_t m_Index{-1}; // The index of the managed column.
StmtRef m_Handle{}; // The statement where the column exist. SQLiteStmtRef m_Handle{}; // The statement where the column exist.
protected: protected:
@@ -1278,18 +1334,18 @@ protected:
* Validate the managed statement handle and throw an error if invalid. * Validate the managed statement handle and throw an error if invalid.
*/ */
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SQMOD_NODISCARD const StmtRef & GetValid(const char * file, int32_t line) const; SQMOD_NODISCARD const SQLiteStmtRef & GetValid(const char * file, int32_t line) const;
#else #else
SQMOD_NODISCARD const StmtRef & GetValid() const; SQMOD_NODISCARD const SQLiteStmtRef & GetValid() const;
#endif // _DEBUG #endif // _DEBUG
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid. * Validate the managed statement handle and throw an error if invalid.
*/ */
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SQMOD_NODISCARD const StmtRef & GetCreated(const char * file, int32_t line) const; SQMOD_NODISCARD const SQLiteStmtRef & GetCreated(const char * file, int32_t line) const;
#else #else
SQMOD_NODISCARD const StmtRef & GetCreated() const; SQMOD_NODISCARD const SQLiteStmtRef & GetCreated() const;
#endif // _DEBUG #endif // _DEBUG
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1346,7 +1402,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* No column constructor. * No column constructor.
*/ */
explicit SQLiteColumn(StmtRef stmt) explicit SQLiteColumn(SQLiteStmtRef stmt)
: m_Index(-1), m_Handle(std::move(stmt)) : m_Index(-1), m_Handle(std::move(stmt))
{ {
/* ... */ /* ... */
@@ -1355,7 +1411,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Index constructor. * Index constructor.
*/ */
SQLiteColumn(StmtRef stmt, int32_t idx) SQLiteColumn(SQLiteStmtRef stmt, int32_t idx)
: m_Index(idx), m_Handle(std::move(stmt)) : m_Index(idx), m_Handle(std::move(stmt))
{ {
SQMOD_VALIDATE_COLUMN(*this, m_Index); SQMOD_VALIDATE_COLUMN(*this, m_Index);
@@ -1364,7 +1420,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Name constructor. * Name constructor.
*/ */
SQLiteColumn(const StmtRef & stmt, const SQChar * name) SQLiteColumn(const SQLiteStmtRef & stmt, const SQChar * name)
: m_Index(stmt ? stmt->GetColumnIndex(name) : -1), m_Handle(stmt) : m_Index(stmt ? stmt->GetColumnIndex(name) : -1), m_Handle(stmt)
{ {
SQMOD_VALIDATE_COLUMN(*this, m_Index); SQMOD_VALIDATE_COLUMN(*this, m_Index);
@@ -1373,7 +1429,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Dynamic constructor. * Dynamic constructor.
*/ */
SQLiteColumn(StmtRef stmt, const Object & column) SQLiteColumn(SQLiteStmtRef stmt, const Object & column)
: m_Index(-1), m_Handle(std::move(stmt)) : m_Index(-1), m_Handle(std::move(stmt))
{ {
if (!m_Handle) if (!m_Handle)
@@ -1436,7 +1492,7 @@ public:
// Can we attempt to return the parameter name? // Can we attempt to return the parameter name?
if (m_Handle && m_Index) if (m_Handle && m_Index)
{ {
const SQChar * val = sqlite3_column_name(m_Handle->mPtr, m_Index); const SQChar * val = sqlite3_column_name(m_Handle->Access(), m_Index);
// Return the value if valid // Return the value if valid
return val ? val : String{}; return val ? val : String{};
} }
@@ -1573,7 +1629,7 @@ class SQLiteStatement
private: private:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
StmtRef m_Handle; // Reference to the managed statement. SQLiteStmtRef m_Handle; // Reference to the managed statement.
protected: protected:
@@ -1599,18 +1655,18 @@ protected:
* Validate the managed statement handle and throw an error if invalid. * Validate the managed statement handle and throw an error if invalid.
*/ */
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SQMOD_NODISCARD const StmtRef & GetValid(const char * file, int32_t line) const; SQMOD_NODISCARD const SQLiteStmtRef & GetValid(const char * file, int32_t line) const;
#else #else
SQMOD_NODISCARD const StmtRef & GetValid() const; SQMOD_NODISCARD const SQLiteStmtRef & GetValid() const;
#endif // _DEBUG #endif // _DEBUG
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Validate the managed statement handle and throw an error if invalid. * Validate the managed statement handle and throw an error if invalid.
*/ */
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
SQMOD_NODISCARD const StmtRef & GetCreated(const char * file, int32_t line) const; SQMOD_NODISCARD const SQLiteStmtRef & GetCreated(const char * file, int32_t line) const;
#else #else
SQMOD_NODISCARD const StmtRef & GetCreated() const; SQMOD_NODISCARD const SQLiteStmtRef & GetCreated() const;
#endif // _DEBUG #endif // _DEBUG
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1654,12 +1710,21 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Construct a statement under the specified connection using the specified string. * Construct a statement under the specified connection using the specified string.
*/ */
SQLiteStatement(const ConnRef & connection, StackStrF & query) SQLiteStatement(const SQLiteConnRef & connection, StackStrF & query)
: m_Handle(new SQLiteStmtHnd(connection)) : m_Handle(new SQLiteStmtHnd(connection))
{ {
SQMOD_GET_VALID(*this)->Create(query.mPtr, query.mLen); SQMOD_GET_VALID(*this)->Create(query.mPtr, query.mLen);
} }
/* --------------------------------------------------------------------------------------------
* Construct a statement under the specified connection using the specified string.
*/
SQLiteStatement(const SQLiteConnRef & connection, const SQChar * query, SQInteger length)
: m_Handle(new SQLiteStmtHnd(connection))
{
SQMOD_GET_VALID(*this)->Create(query, length);
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Construct a statement under the specified connection using the specified string. * Construct a statement under the specified connection using the specified string.
*/ */
@@ -1668,7 +1733,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Direct handle constructor. * Direct handle constructor.
*/ */
explicit SQLiteStatement(StmtRef s) explicit SQLiteStatement(SQLiteStmtRef s)
: m_Handle(std::move(s)) : m_Handle(std::move(s))
{ {
/* ... */ /* ... */
@@ -1715,7 +1780,7 @@ public:
*/ */
operator sqlite3_stmt * () // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) operator sqlite3_stmt * () // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
{ {
return m_Handle ? m_Handle->mPtr : nullptr; return m_Handle ? m_Handle->Access() : nullptr;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1723,7 +1788,7 @@ public:
*/ */
operator sqlite3_stmt * () const // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) operator sqlite3_stmt * () const // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
{ {
return m_Handle ? m_Handle->mPtr : nullptr; return m_Handle ? m_Handle->Access() : nullptr;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1737,7 +1802,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the associated statement handle. * Retrieve the associated statement handle.
*/ */
SQMOD_NODISCARD const StmtRef & GetHandle() const SQMOD_NODISCARD const SQLiteStmtRef & GetHandle() const
{ {
return m_Handle; return m_Handle;
} }
@@ -1755,7 +1820,7 @@ public:
*/ */
SQMOD_NODISCARD bool IsPrepared() const SQMOD_NODISCARD bool IsPrepared() const
{ {
return m_Handle && (m_Handle->mPtr != nullptr); return m_Handle && (m_Handle->Access() != nullptr);
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -2436,7 +2501,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Construct using the direct connection handle. * Construct using the direct connection handle.
*/ */
explicit SQLiteTransaction(ConnRef db); explicit SQLiteTransaction(SQLiteConnRef db);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled) * Copy constructor. (disabled)
@@ -2495,7 +2560,7 @@ public:
private: private:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
ConnRef m_Handle{}; // The database connection handle where the transaction began. SQLiteConnRef m_Handle{}; // The database connection handle where the transaction began.
bool m_Committed{false}; // Whether changes were successfully committed to the database. bool m_Committed{false}; // Whether changes were successfully committed to the database.
}; };
+108 -6
View File
@@ -961,17 +961,17 @@ static SQInteger SqLevenshtein(StackStrF & a, StackStrF & b)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static SQInteger SqStrToI(SQInteger base, StackStrF & s) static SQInteger SqStringToInt(SQInteger base, StackStrF & s)
{ {
#ifdef _SQ64 #ifdef _SQ64
return std::stoll(s.mPtr, nullptr, ConvTo< int >::From((base))); return std::stoll(s.ToStr(), nullptr, ConvTo< int >::From((base)));
#else #else
return std::stoi(s.mPtr, nullptr, ConvTo< int >::From((base))); return std::stoi(s.ToStr(), nullptr, ConvTo< int >::From((base)));
#endif #endif
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static SQFloat SqStrToF(StackStrF & s) static SQFloat SqStringToFloat(StackStrF & s)
{ {
#ifdef SQUSEDOUBLE #ifdef SQUSEDOUBLE
return std::strtod(s.mPtr, nullptr); return std::strtod(s.mPtr, nullptr);
@@ -980,6 +980,102 @@ static SQFloat SqStrToF(StackStrF & s)
#endif #endif
} }
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static Table SqStringToL(SQInteger base, StackStrF & s)
{
SQChar * end = nullptr;
// Attempt to process the specified string
const auto r = std::strtol(s.mPtr, &end, ConvTo< int >::From((base)));
// Allocate a table for the result
Table t(SqVM(), 2);
// Insert the resulted value
t.SetValue(_SC("value"), r);
// Insert the end of the value
t.SetValue(_SC("end"), static_cast< intptr_t >(end - s.mPtr));
// Return the table containing the results
return t;
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static Table SqStringToLL(SQInteger base, StackStrF & s)
{
SQChar * end = nullptr;
// Attempt to process the specified string
const auto r = std::strtoll(s.mPtr, &end, ConvTo< int >::From((base)));
// Allocate a table for the result
Table t(SqVM(), 2);
// Insert the resulted value
t.SetValue(_SC("value"), r);
// Insert the end of the value
t.SetValue(_SC("end"), static_cast< intptr_t >(end - s.mPtr));
// Return the table containing the results
return t;
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static Table SqStringToUL(SQInteger base, StackStrF & s)
{
SQChar * end = nullptr;
// Attempt to process the specified string
const auto r = std::strtoul(s.mPtr, &end, ConvTo< int >::From((base)));
// Allocate a table for the result
Table t(SqVM(), 2);
// Insert the resulted value
t.SetValue(_SC("value"), r);
// Insert the end of the value
t.SetValue(_SC("end"), static_cast< intptr_t >(end - s.mPtr));
// Return the table containing the results
return t;
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static Table SqStringToULL(SQInteger base, StackStrF & s)
{
SQChar * end = nullptr;
// Attempt to process the specified string
const auto r = std::strtoull(s.mPtr, &end, ConvTo< int >::From((base)));
// Allocate a table for the result
Table t(SqVM(), 2);
// Insert the resulted value
t.SetValue(_SC("value"), r);
// Insert the end of the value
t.SetValue(_SC("end"), static_cast< intptr_t >(end - s.mPtr));
// Return the table containing the results
return t;
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static Table SqStringToF(StackStrF & s)
{
SQChar * end = nullptr;
// Attempt to process the specified string
const auto r = std::strtof(s.mPtr, &end);
// Allocate a table for the result
Table t(SqVM(), 2);
// Insert the resulted value
t.SetValue(_SC("value"), r);
// Insert the end of the value
t.SetValue(_SC("end"), static_cast< intptr_t >(end - s.mPtr));
// Return the table containing the results
return t;
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static Table SqStringToD(StackStrF & s)
{
SQChar * end = nullptr;
// Attempt to process the specified string
const auto r = std::strtod(s.mPtr, &end);
// Allocate a table for the result
Table t(SqVM(), 2);
// Insert the resulted value
t.SetValue(_SC("value"), r);
// Insert the end of the value
t.SetValue(_SC("end"), static_cast< intptr_t >(end - s.mPtr));
// Return the table containing the results
return t;
}
// ================================================================================================ // ================================================================================================
void Register_String(HSQUIRRELVM vm) void Register_String(HSQUIRRELVM vm)
{ {
@@ -1000,8 +1096,14 @@ void Register_String(HSQUIRRELVM vm)
.FmtFunc(_SC("Lowercase"), &SqToLowercase) .FmtFunc(_SC("Lowercase"), &SqToLowercase)
.FmtFunc(_SC("Uppercase"), &SqToUppercase) .FmtFunc(_SC("Uppercase"), &SqToUppercase)
.FmtFunc(_SC("JustAlnum"), &SqJustAlphaNum) .FmtFunc(_SC("JustAlnum"), &SqJustAlphaNum)
.FmtFunc(_SC("ToInt"), &SqStrToI) .FmtFunc(_SC("ToInt"), &SqStringToInt)
.FmtFunc(_SC("ToFloat"), &SqStrToF) .FmtFunc(_SC("ToFloat"), &SqStringToFloat)
.FmtFunc(_SC("ToL"), &SqStringToL)
.FmtFunc(_SC("ToLL"), &SqStringToLL)
.FmtFunc(_SC("ToUL"), &SqStringToUL)
.FmtFunc(_SC("ToULL"), &SqStringToULL)
.FmtFunc(_SC("ToF"), &SqStringToF)
.FmtFunc(_SC("ToD"), &SqStringToD)
.FmtFunc(_SC("Levenshtein"), &SqLevenshtein) .FmtFunc(_SC("Levenshtein"), &SqLevenshtein)
.FmtFunc(_SC("AreAllSpace"), &SqAllChars< std::isspace >) .FmtFunc(_SC("AreAllSpace"), &SqAllChars< std::isspace >)
.FmtFunc(_SC("AreAllPrint"), &SqAllChars< std::isprint >) .FmtFunc(_SC("AreAllPrint"), &SqAllChars< std::isprint >)
+1 -1
View File
@@ -594,7 +594,7 @@ public:
#if defined(UNICODE) || defined(_UNICODE) #if defined(UNICODE) || defined(_UNICODE)
return String(mHandle->extension, mHandle->extension + std::wcslen(mHandle->extension)); return String(mHandle->extension, mHandle->extension + std::wcslen(mHandle->extension));
#else #else
return String(mHandle->name); return String(mHandle->extension);
#endif #endif
} }
}; };
+135
View File
@@ -0,0 +1,135 @@
// ------------------------------------------------------------------------------------------------
#include "Library/UTF8.hpp"
#include "Core/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static SQInteger SqStrLenUTF8(StackStrF & str)
{
// Is the string empty or invalid?
if (str.mLen <= 0)
{
return str.mLen; // Return same value
}
// Perform the request and return the result
return static_cast< SQInteger >(utf8len(str.mPtr));
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static SQInteger SqStrNLenUTF8(SQInteger len, StackStrF & str)
{
// Is the string empty or invalid?
if (str.mLen <= 0)
{
return str.mLen; // Return same value
}
// Is the specified length within bounds?
else if (std::abs(len) > str.mLen)
{
STHROWF("Specified range {} is out of bounds {}", len, str.mLen);
}
// Should we compute the length backwards?
else if (len < 0)
{
len = str.mLen - std::abs(len); // Subtract from actual length
}
// Did we trim all of it?
else if (len == 0)
{
return 0; // Nothing to search for
}
// Perform the request and return the result
return static_cast< SQInteger >(utf8nlen(str.mPtr, static_cast< size_t >(len)));
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static SQInteger SqStrChrUTF8(SQInteger chr, StackStrF & str)
{
// Is the string empty or invalid?
if (str.mLen <= 0)
{
return -1; // Let the user know that we could not search for this
}
// Look for the specified character in the string
auto * p = reinterpret_cast< const SQChar * >(utf8chr(str.mPtr, static_cast< utf8_int32_t >(chr)));
// Return the distance in bytes where the character was found
return static_cast< SQInteger >(p - str.mPtr);
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static SQInteger SqCaseCmpUTF8(StackStrF & a, StackStrF & b)
{
// Is the left string invalid?
if (a.mLen < 0)
{
STHROWF("Invalid string on the left {}", a.mLen);
}
// Is the right string invalid?
else if (b.mLen < 0)
{
STHROWF("Invalid string on the right {}", b.mLen);
}
// Perform the request and return the result
return utf8casecmp(a.mPtr, b.mPtr);
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static SQInteger SqNCaseCmpUTF8(StackStrF & a, StackStrF & b)
{
// Is the left string invalid?
if (a.mLen < 0)
{
STHROWF("Invalid string on the left {}", a.mLen);
}
// Is the right string invalid?
else if (b.mLen < 0)
{
STHROWF("Invalid string on the right {}", b.mLen);
}
// See if we can decide this based on length differences
else if (a.mLen < b.mLen)
{
return -1;
}
else if (a.mLen > b.mLen)
{
return 1;
}
// Perform the request and return the result
return utf8ncasecmp(a.mPtr, b.mPtr, static_cast< size_t >(a.mLen));
}
// ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static SQInteger SqCaseStrUTF8(StackStrF & hs, StackStrF & nd)
{
// Is the haystack or needle string empty or invalid?
if (hs.mLen <= 0 || nd.mLen <= 0)
{
return -1; // Let the user know that we could not search for this
}
// Look for the specified needle string in the haystack string
auto * p = reinterpret_cast< const SQChar * >(utf8casestr(hs.mPtr, nd.mPtr));
// Return the distance in bytes where the string was found
return static_cast< SQInteger >(p - hs.mPtr);
}
// ================================================================================================
void Register_UTF8(HSQUIRRELVM vm)
{
Table ns(vm);
ns
.FmtFunc(_SC("StrLen"), &SqStrLenUTF8)
.FmtFunc(_SC("StrNLen"), &SqStrNLenUTF8)
.FmtFunc(_SC("StrChr"), &SqStrChrUTF8)
.FmtFunc(_SC("CaseCmp"), &SqCaseCmpUTF8)
.FmtFunc(_SC("NCaseCmp"), &SqNCaseCmpUTF8)
.FmtFunc(_SC("CaseStr"), &SqCaseStrUTF8)
;
RootTable(vm).Bind(_SC("SqUTF8"), ns);
}
} // Namespace:: SqMod
+14
View File
@@ -0,0 +1,14 @@
#pragma once
// ------------------------------------------------------------------------------------------------
#include "Core/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <utf8.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod
+17 -13
View File
@@ -138,9 +138,10 @@ SQInteger XmlAttribute::GetLong() const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XmlAttribute::SetLong(SQInteger value) XmlAttribute & XmlAttribute::SetLong(SQInteger value)
{ {
m_Attr = value; m_Attr = value;
return *this;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -150,9 +151,10 @@ SQInteger XmlAttribute::GetUlong() const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XmlAttribute::SetUlong(SQInteger value) XmlAttribute & XmlAttribute::SetUlong(SQInteger value)
{ {
m_Attr = static_cast< uint64_t >(value); m_Attr = static_cast< uint64_t >(value);
return *this;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -186,9 +188,10 @@ SQInteger XmlText::GetLong() const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XmlText::SetLong(SQInteger value) XmlText & XmlText::SetLong(SQInteger value)
{ {
m_Text = value; m_Text = value;
return *this;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -198,9 +201,10 @@ SQInteger XmlText::GetUlong() const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XmlText::SetUlong(SQInteger value) XmlText & XmlText::SetUlong(SQInteger value)
{ {
m_Text = static_cast< uint64_t >(value); m_Text = static_cast< uint64_t >(value);
return *this;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -259,8 +263,8 @@ void Register_XML(HSQUIRRELVM vm)
.Prop(_SC("Next"), &XmlAttribute::NextAttribute) .Prop(_SC("Next"), &XmlAttribute::NextAttribute)
.Prop(_SC("Prev"), &XmlAttribute::PrevAttribute) .Prop(_SC("Prev"), &XmlAttribute::PrevAttribute)
// Member Methods // Member Methods
.Func(_SC("SetName"), &XmlAttribute::ApplyName) .FmtFunc(_SC("SetName"), &XmlAttribute::SetName)
.Func(_SC("SetValue"), &XmlAttribute::ApplyValue) .FmtFunc(_SC("SetValue"), &XmlAttribute::ApplyValue)
.Func(_SC("AsString"), &XmlAttribute::AsString) .Func(_SC("AsString"), &XmlAttribute::AsString)
.Func(_SC("AsInt"), &XmlAttribute::AsInt) .Func(_SC("AsInt"), &XmlAttribute::AsInt)
.Func(_SC("AsUint"), &XmlAttribute::AsUint) .Func(_SC("AsUint"), &XmlAttribute::AsUint)
@@ -350,8 +354,8 @@ void Register_XML(HSQUIRRELVM vm)
.Overload(_SC("AppendBuffer"), &XmlNode::AppendBuffer1) .Overload(_SC("AppendBuffer"), &XmlNode::AppendBuffer1)
.Overload(_SC("AppendBuffer"), &XmlNode::AppendBuffer2) .Overload(_SC("AppendBuffer"), &XmlNode::AppendBuffer2)
.Overload(_SC("AppendBuffer"), &XmlNode::AppendBuffer3) .Overload(_SC("AppendBuffer"), &XmlNode::AppendBuffer3)
.Func(_SC("SetName"), &XmlNode::ApplyName) .FmtFunc(_SC("SetName"), &XmlNode::SetName)
.Func(_SC("SetValue"), &XmlNode::ApplyValue) .FmtFunc(_SC("SetValue"), &XmlNode::ApplyValue)
.Func(_SC("GetChild"), &XmlNode::Child) .Func(_SC("GetChild"), &XmlNode::Child)
.Func(_SC("GetAttr"), &XmlNode::GetAttribute) .Func(_SC("GetAttr"), &XmlNode::GetAttribute)
.Func(_SC("GetAttribute"), &XmlNode::GetAttribute) .Func(_SC("GetAttribute"), &XmlNode::GetAttribute)
@@ -368,8 +372,8 @@ void Register_XML(HSQUIRRELVM vm)
.Func(_SC("PrependAttrCopy"), &XmlNode::PrependAttrCopy) .Func(_SC("PrependAttrCopy"), &XmlNode::PrependAttrCopy)
.Func(_SC("InsertAttrCopyAfter"), &XmlNode::InsertAttrCopyAfter) .Func(_SC("InsertAttrCopyAfter"), &XmlNode::InsertAttrCopyAfter)
.Func(_SC("InsertAttrCopyBefore"), &XmlNode::InsertAttrCopyBefore) .Func(_SC("InsertAttrCopyBefore"), &XmlNode::InsertAttrCopyBefore)
.Func(_SC("AppendChild"), &XmlNode::AppendChild) .FmtFunc(_SC("AppendChild"), &XmlNode::AppendChild)
.Func(_SC("PrependChild"), &XmlNode::PrependChild) .FmtFunc(_SC("PrependChild"), &XmlNode::PrependChild)
.Func(_SC("AppendChildNode"), &XmlNode::AppendChildNode) .Func(_SC("AppendChildNode"), &XmlNode::AppendChildNode)
.Func(_SC("PrependChildNode"), &XmlNode::PrependChildNode) .Func(_SC("PrependChildNode"), &XmlNode::PrependChildNode)
.Func(_SC("AppendChildType"), &XmlNode::AppendChildType) .Func(_SC("AppendChildType"), &XmlNode::AppendChildType)
@@ -386,9 +390,9 @@ void Register_XML(HSQUIRRELVM vm)
.Func(_SC("PrependMove"), &XmlNode::PrependMove) .Func(_SC("PrependMove"), &XmlNode::PrependMove)
.Func(_SC("InsertMoveAfter"), &XmlNode::InsertMoveAfter) .Func(_SC("InsertMoveAfter"), &XmlNode::InsertMoveAfter)
.Func(_SC("InsertMoveBefore"), &XmlNode::InsertMoveBefore) .Func(_SC("InsertMoveBefore"), &XmlNode::InsertMoveBefore)
.Func(_SC("RemoveAttr"), &XmlNode::RemoveAttr) .FmtFunc(_SC("RemoveAttr"), &XmlNode::RemoveAttr)
.Func(_SC("RemoveAttrInst"), &XmlNode::RemoveAttrInst) .Func(_SC("RemoveAttrInst"), &XmlNode::RemoveAttrInst)
.Func(_SC("RemoveChild"), &XmlNode::RemoveChild) .FmtFunc(_SC("RemoveChild"), &XmlNode::RemoveChild)
.Func(_SC("RemoveChildInst"), &XmlNode::RemoveChildInst) .Func(_SC("RemoveChildInst"), &XmlNode::RemoveChildInst)
.Overload(_SC("FindChildByAttr"), &XmlNode::FindChildByAttr2) .Overload(_SC("FindChildByAttr"), &XmlNode::FindChildByAttr2)
.Overload(_SC("FindChildByAttr"), &XmlNode::FindChildByAttr3) .Overload(_SC("FindChildByAttr"), &XmlNode::FindChildByAttr3)
@@ -421,7 +425,7 @@ void Register_XML(HSQUIRRELVM vm)
.Overload(_SC("SaveFile"), &XmlDocument::SaveFile4) .Overload(_SC("SaveFile"), &XmlDocument::SaveFile4)
); );
RootTable(vm).Bind(_SC("SqXml"), xmlns); RootTable(vm).Bind(_SC("SqXML"), xmlns);
ConstTable(vm).Enum(_SC("SqXmlNodeType"), Enumeration(vm) ConstTable(vm).Enum(_SC("SqXmlNodeType"), Enumeration(vm)
.Const(_SC("Null"), static_cast< int32_t >(node_null)) .Const(_SC("Null"), static_cast< int32_t >(node_null))
+40 -40
View File
@@ -663,7 +663,7 @@ protected:
* Explicit constructor. * Explicit constructor.
*/ */
XmlNode(DocumentRef doc, const Type & node) XmlNode(DocumentRef doc, const Type & node)
: m_Doc(std::move(doc)), m_Node(node) : m_Node(node), m_Doc(std::move(doc))
{ {
/* ... */ /* ... */
} }
@@ -671,8 +671,8 @@ protected:
private: private:
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
DocumentRef m_Doc{}; // The main xml document instance.
Type m_Node{}; // The managed document node. Type m_Node{}; // The managed document node.
DocumentRef m_Doc{}; // The main xml document instance.
public: public:
@@ -777,20 +777,13 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify node name. * Modify node name.
*/ */
void SetName(StackStrF & name) XmlNode & SetName(StackStrF & name)
{ {
if (!m_Node.set_name(name.mPtr)) if (!m_Node.set_name(name.mPtr))
{ {
STHROWF("Unable to set XML node name"); STHROWF("Unable to set XML node name `{}`", name.ToStr());
} }
} return *this;
/* --------------------------------------------------------------------------------------------
* Modify the node name.
*/
bool ApplyName(StackStrF & name)
{
return m_Node.set_name(name.mPtr);
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -804,12 +797,13 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify node value. * Modify node value.
*/ */
void SetValue(StackStrF & name) XmlNode & SetValue(StackStrF & name)
{ {
if (!m_Node.set_value(name.mPtr)) if (!m_Node.set_value(name.mPtr))
{ {
STHROWF("Unable to set XML node value"); STHROWF("Unable to set XML node value");
} }
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1331,20 +1325,13 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve attribute name. * Retrieve attribute name.
*/ */
void SetName(StackStrF & name) XmlAttribute & SetName(StackStrF & name)
{ {
if (!m_Attr.set_name(name.mPtr)) if (!m_Attr.set_name(name.mPtr))
{ {
STHROWF("Unable to set XML attribute name"); STHROWF("Unable to set XML attribute name `{}`", name.ToStr());
} }
} return *this;
/* --------------------------------------------------------------------------------------------
* Modify the attribute name.
*/
bool ApplyName(StackStrF & name)
{
return m_Attr.set_name(name.mPtr);
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1358,12 +1345,13 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve attribute value. * Retrieve attribute value.
*/ */
void SetValue(StackStrF & name) XmlAttribute SetValue(StackStrF & name)
{ {
if (!m_Attr.set_value(name.mPtr)) if (!m_Attr.set_value(name.mPtr))
{ {
STHROWF("Unable to set XML attribute value"); STHROWF("Unable to set XML attribute value");
} }
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1501,9 +1489,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a string. * Modify the value as a string.
*/ */
void SetString(StackStrF & value) XmlAttribute & SetString(StackStrF & value)
{ {
m_Attr = value.mPtr; m_Attr = value.mPtr;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1517,9 +1506,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a integer. * Modify the value as a integer.
*/ */
void SetInt(int32_t value) XmlAttribute & SetInt(int32_t value)
{ {
m_Attr = value; m_Attr = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1533,9 +1523,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer. * Modify the value as a unsigned integer.
*/ */
void SetUint(uint32_t value) XmlAttribute & SetUint(uint32_t value)
{ {
m_Attr = value; m_Attr = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1549,9 +1540,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a floating point. * Modify the value as a floating point.
*/ */
void SetFloat(SQFloat value) XmlAttribute & SetFloat(SQFloat value)
{ {
m_Attr = value; m_Attr = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1565,9 +1557,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point. * Modify the value as a double floating point.
*/ */
void SetDouble(SQFloat value) XmlAttribute & SetDouble(SQFloat value)
{ {
m_Attr = value; m_Attr = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1578,7 +1571,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a long integer. * Modify the value as a long integer.
*/ */
void SetLong(SQInteger value); XmlAttribute & SetLong(SQInteger value);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer. * Retrieve the value as a unsigned long integer.
@@ -1588,7 +1581,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer. * Modify the value as a unsigned long integer.
*/ */
void SetUlong(SQInteger value); XmlAttribute & SetUlong(SQInteger value);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean. * Retrieve the value as a boolean.
@@ -1601,9 +1594,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a boolean. * Modify the value as a boolean.
*/ */
void SetBool(bool value) XmlAttribute & SetBool(bool value)
{ {
m_Attr = value; m_Attr = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1853,9 +1847,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a string. * Modify the value as a string.
*/ */
void SetString(StackStrF & value) XmlText & SetString(StackStrF & value)
{ {
m_Text = value.mPtr; m_Text = value.mPtr;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1869,9 +1864,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a integer. * Modify the value as a integer.
*/ */
void SetInt(int32_t value) XmlText & SetInt(int32_t value)
{ {
m_Text = value; m_Text = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1885,9 +1881,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer. * Modify the value as a unsigned integer.
*/ */
void SetUint(uint32_t value) XmlText & SetUint(uint32_t value)
{ {
m_Text = value; m_Text = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1901,9 +1898,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a floating point. * Modify the value as a floating point.
*/ */
void SetFloat(SQFloat value) XmlText & SetFloat(SQFloat value)
{ {
m_Text = value; m_Text = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1917,9 +1915,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point. * Modify the value as a double floating point.
*/ */
void SetDouble(SQFloat value) XmlText & SetDouble(SQFloat value)
{ {
m_Text = value; m_Text = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
@@ -1930,7 +1929,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a long integer. * Modify the value as a long integer.
*/ */
void SetLong(SQInteger value); XmlText & SetLong(SQInteger value);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer. * Retrieve the value as a unsigned long integer.
@@ -1940,7 +1939,7 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer. * Modify the value as a unsigned long integer.
*/ */
void SetUlong(SQInteger value); XmlText & SetUlong(SQInteger value);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean. * Retrieve the value as a boolean.
@@ -1953,9 +1952,10 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Modify the value as a boolean. * Modify the value as a boolean.
*/ */
void SetBool(bool value) XmlText & SetBool(bool value)
{ {
m_Text = value; m_Text = value;
return *this;
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
+15
View File
@@ -556,6 +556,21 @@ void Logger::ProcessMessage()
} }
} }
// ------------------------------------------------------------------------------------------------
void Logger::Send(uint8_t level, bool sub, const char * msg)
{
// Is this level even allowed?
if ((m_ConsoleLevels & level) || (m_LogFileLevels & level))
{
// Create a new message builder
MsgPtr message(new Message(level, sub));
// Generate the log message
message->Append(msg);
// Process the message in the buffer
PushMessage(message);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Logger::Send(uint8_t level, bool sub, const char * msg, size_t len) void Logger::Send(uint8_t level, bool sub, const char * msg, size_t len)
{ {
+5
View File
@@ -409,6 +409,11 @@ public:
*/ */
void BindCb(uint8_t level, Function & func); void BindCb(uint8_t level, Function & func);
/* --------------------------------------------------------------------------------------------
* Send a log message.
*/
void Send(uint8_t level, bool sub, const char * msg);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Send a log message. * Send a log message.
*/ */
+7 -7
View File
@@ -24,9 +24,6 @@ extern void ProcessRoutines();
extern void ProcessTasks(); extern void ProcessTasks();
extern void ProcessThreads(); extern void ProcessThreads();
extern void ProcessNet(); extern void ProcessNet();
#ifdef VCMP_ENABLE_DISCORD
extern void ProcessDPP();
#endif
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Will the scripts be reloaded at the end of the current event? * Will the scripts be reloaded at the end of the current event?
@@ -175,10 +172,6 @@ static void OnServerFrame(float elapsed_time)
ProcessThreads(); ProcessThreads();
// Process network // Process network
ProcessNet(); ProcessNet();
// Process DPP
#ifdef VCMP_ENABLE_DISCORD
ProcessDPP();
#endif
// Process log messages from other threads // Process log messages from other threads
Logger::Get().ProcessQueue(); Logger::Get().ProcessQueue();
// See if a reload was requested // See if a reload was requested
@@ -972,6 +965,11 @@ static void OnServerPerformanceReport(size_t /*entry_count*/, const char * * /*d
} // Namespace:: SqMod } // Namespace:: SqMod
/* ------------------------------------------------------------------------------------------------
* Automatically terminate the third-party allocator.
*/
static std::unique_ptr< SqMod::RPMallocInit > gsRPMallocInit;
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Plug-in initialization procedure. * Plug-in initialization procedure.
*/ */
@@ -996,6 +994,8 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallback
_Info->apiMinorVersion = PLUGIN_API_MINOR; _Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plug-in name // Assign the plug-in name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQMOD_HOST_NAME); std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQMOD_HOST_NAME);
// Initialize third-party allocator
gsRPMallocInit = std::make_unique< RPMallocInit >();
// Attempt to initialize the logger before anything else // Attempt to initialize the logger before anything else
Logger::Get().Initialize(nullptr); Logger::Get().Initialize(nullptr);
// Attempt to initialize the plug-in core // Attempt to initialize the plug-in core
+1 -1
View File
@@ -762,7 +762,7 @@ void SetSpawnCameraPositionEx(float x, float y, float z)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SetSpawnCameraLookAtEx(float x, float y, float z) void SetSpawnCameraLookAtEx(float x, float y, float z)
{ {
_Func->SetSpawnPlayerPosition(x, y, z); _Func->SetSpawnCameraLookAt(x, y, z);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
+138 -74
View File
@@ -52,6 +52,66 @@ SQMOD_DECL_TYPENAME(CPickupTn, _SC("CPickup"))
SQMOD_DECL_TYPENAME(CPlayerTn, _SC("CPlayer")) SQMOD_DECL_TYPENAME(CPlayerTn, _SC("CPlayer"))
SQMOD_DECL_TYPENAME(CVehicleTn, _SC("CVehicle")) SQMOD_DECL_TYPENAME(CVehicleTn, _SC("CVehicle"))
/* ------------------------------------------------------------------------------------------------
* Used to fetch the legacy entity instance even if a native one was specified.
*/
template < class LEGACY, class NATIVE > inline LEGACY & GetLgEnt(LightObj & o)
{
const auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag());
// Legacy entity type?
if (type == StaticClassTypeTag< LEGACY >::Get())
{
return *o.CastI< LEGACY >();
}
// Native entity type?
if (type == StaticClassTypeTag< NATIVE >::Get())
{
return *EntityInstSelect< NATIVE >::Get(o.CastI< NATIVE >()->GetID()).mLgInst;
}
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
}
/* ------------------------------------------------------------------------------------------------
* Used to fetch the legacy entity identifier even if a native one was specified.
*/
template < class LEGACY, class NATIVE > SQMOD_NODISCARD inline int32_t GetLgEntID(LightObj & o)
{
const auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag());
// Legacy entity type?
if (type == StaticClassTypeTag< LEGACY >::Get())
{
return o.CastI< LEGACY >()->mID;
}
// Native entity type?
if (type == StaticClassTypeTag< NATIVE >::Get())
{
return o.CastI< NATIVE >()->GetID();
}
STHROWF("Invalid entity type: {}", SqTypeName(SqVM(), o));
SQ_UNREACHABLE
}
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Entity type enumeration. * Entity type enumeration.
*/ */
@@ -250,10 +310,10 @@ void LgEntityQuaternion::Set()
case LgEntityType::Vehicle: case LgEntityType::Vehicle:
switch (mFlag) switch (mFlag)
{ {
case LgVehicleVectorFlag::Angle: case LgVehicleQuaternionFlag::Angle:
_Func->SetVehicleRotation(mID, x, y, z, w); _Func->SetVehicleRotation(mID, x, y, z, w);
break; break;
case LgVehicleVectorFlag::SpawnAngle: case LgVehicleQuaternionFlag::SpawnAngle:
_Func->SetVehicleSpawnRotation(mID, x, y, z, w); _Func->SetVehicleSpawnRotation(mID, x, y, z, w);
break; break;
default: break; default: break;
@@ -438,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;
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -506,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(); }
@@ -523,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;
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -587,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; }
@@ -595,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;
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@@ -663,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)); }
@@ -673,14 +733,14 @@ struct LgPlayer
void SetCanAttack(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionCanAttack, static_cast< uint8_t >(toggle)); } void SetCanAttack(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionCanAttack, static_cast< uint8_t >(toggle)); }
void SetWeaponSlot(int slot) const { Get().SetWeaponSlot(slot); } void SetWeaponSlot(int slot) const { Get().SetWeaponSlot(slot); }
void ShowMarkers(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionShowMarkers, static_cast< uint8_t >(toggle)); } void ShowMarkers(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionShowMarkers, static_cast< uint8_t >(toggle)); }
void SetSpectateTarget(LgPlayer & player) const { Get().SetSpectator(player.Get()); } void SetSpectateTarget(LightObj & player) const { player.IsNull() ? Get().SetSpectatorID(-1) : Get().SetSpectator(player.CastI< LgPlayer >()->Get()); }
void SetMarkerVisible(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, static_cast< uint8_t >(toggle)); } void SetMarkerVisible(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, static_cast< uint8_t >(toggle)); }
void SetCanUseColors(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionChatTagsEnabled, static_cast< uint8_t >(toggle)); } void SetCanUseColors(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionChatTagsEnabled, static_cast< uint8_t >(toggle)); }
void SetDrunkStatus(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects, static_cast< uint8_t >(toggle)); } void SetDrunkStatus(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects, static_cast< uint8_t >(toggle)); }
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(); }
@@ -692,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(); }
@@ -724,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; }
@@ -761,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); }
@@ -875,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(); }
@@ -899,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; }
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@@ -926,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); }
@@ -942,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; }
@@ -1233,11 +1293,11 @@ void Register_Official_Entity(HSQUIRRELVM vm)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void LgClientMessage(StackStrF & msg, LgPlayer & player, int r, int g, int b) static void LgClientMessage(StackStrF & msg, LightObj & player, int r, int g, int b)
{ _Func->SendClientMessage(player.GetIdentifier(), Color4(static_cast< uint8_t >(r), static_cast< uint8_t >(g), { _Func->SendClientMessage(GetLgEntID< LgPlayer, CPlayer >(player), Color4(static_cast< uint8_t >(r), static_cast< uint8_t >(g),
static_cast< uint8_t >(b), 255).GetRGBA(), "%s", msg.mPtr); } static_cast< uint8_t >(b), 255).GetRGBA(), "%s", msg.mPtr); }
static void LgClientMessageWithAlpha(StackStrF & msg, LgPlayer & player, int r, int g, int b, int a) static void LgClientMessageWithAlpha(StackStrF & msg, LightObj & player, int r, int g, int b, int a)
{ _Func->SendClientMessage(player.GetIdentifier(), Color4(static_cast< uint8_t >(r), static_cast< uint8_t >(g), { _Func->SendClientMessage(GetLgEntID< LgPlayer, CPlayer >(player), Color4(static_cast< uint8_t >(r), static_cast< uint8_t >(g),
static_cast< uint8_t >(b), static_cast< uint8_t >(a)).GetRGBA(), "%s", msg.mPtr); } static_cast< uint8_t >(b), static_cast< uint8_t >(a)).GetRGBA(), "%s", msg.mPtr); }
static void LgClientMessageToAll(StackStrF & msg, int r, int g, int b) { static void LgClientMessageToAll(StackStrF & msg, int r, int g, int b) {
const uint32_t c = Color4(static_cast< uint8_t >(r), static_cast< uint8_t >(g), const uint32_t c = Color4(static_cast< uint8_t >(r), static_cast< uint8_t >(g),
@@ -1249,10 +1309,10 @@ static void LgClientMessageToAllWithAlpha(StackStrF & msg, int r, int g, int b,
static_cast< uint8_t >(b), static_cast< uint8_t >(a)).GetRGBA(); static_cast< uint8_t >(b), static_cast< uint8_t >(a)).GetRGBA();
ForeachActivePlayer([&](auto & p) { _Func->SendClientMessage(p.mID, c, "%s", msg.mPtr); }); ForeachActivePlayer([&](auto & p) { _Func->SendClientMessage(p.mID, c, "%s", msg.mPtr); });
} }
static void LgGameMessage(StackStrF & msg, LgPlayer & player, int type) static void LgGameMessage(StackStrF & msg, LightObj & player, int type)
{ _Func->SendGameMessage(player.GetIdentifier(), type, msg.mPtr); } { _Func->SendGameMessage(GetLgEntID< LgPlayer, CPlayer >(player), type, msg.mPtr); }
static void LgGameMessageAlternate(StackStrF & msg, LgPlayer & player) static void LgGameMessageAlternate(StackStrF & msg, LightObj & player)
{ { _Func->SendGameMessage(player.GetIdentifier(), 1, msg.mPtr); } } { { _Func->SendGameMessage(GetLgEntID< LgPlayer, CPlayer >(player), 1, msg.mPtr); } }
static void LgGameMessageToAll(StackStrF & msg, int type) static void LgGameMessageToAll(StackStrF & msg, int type)
{ _Func->SendGameMessage(-1, type, msg.mPtr); } { _Func->SendGameMessage(-1, type, msg.mPtr); }
static void LgGameMessageToAllAlternate(StackStrF & msg) static void LgGameMessageToAllAlternate(StackStrF & msg)
@@ -1394,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; }
@@ -1409,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;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -1467,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)); }
@@ -1545,9 +1605,9 @@ SQMOD_NODISCARD SQInteger LgGetObjectCount() {
} }
return count; return count;
} }
SQMOD_NODISCARD SQInteger LgGetPlayers() { return ForeachConnectedPlayerCount([](int32_t) { return true; }); } SQMOD_NODISCARD SQInteger LgGetPlayers() { return ForeachPlayerSlotCount([](int32_t idx) -> bool { return _Func->IsPlayerConnected(idx) != 0; }); }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void LgSetVehiclesForcedRespawnHeight(SQFloat height) { _Func->SetVehiclesForcedRespawnHeight(height); } static void LgSetVehiclesForcedRespawnHeight(SQFloat height) { _Func->SetVehiclesForcedRespawnHeight(static_cast< float >(height)); }
SQMOD_NODISCARD static SQFloat LgGetVehiclesForcedRespawnHeight() { return _Func->GetVehiclesForcedRespawnHeight(); } SQMOD_NODISCARD static SQFloat LgGetVehiclesForcedRespawnHeight() { return _Func->GetVehiclesForcedRespawnHeight(); }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SQMOD_NODISCARD static SQInteger LgFindPlayer(HSQUIRRELVM vm) { SQMOD_NODISCARD static SQInteger LgFindPlayer(HSQUIRRELVM vm) {
@@ -1569,7 +1629,7 @@ SQMOD_NODISCARD static SQInteger LgFindPlayer(HSQUIRRELVM vm) {
char name_buf[SQMOD_NAMELENGTH]; char name_buf[SQMOD_NAMELENGTH];
const int32_t id = ForeachConnectedPlayerUntil([&](int32_t id) -> bool { const int32_t id = ForeachConnectedPlayerUntil([&](int32_t id) -> bool {
_Func->GetPlayerName(id, name_buf, 64); _Func->GetPlayerName(id, name_buf, 64);
std::transform(name_buf, name_buf + strlen(name_buf), name_buf, [](unsigned char c){ return std::tolower(c); }); std::transform(name_buf, name_buf + strlen(name_buf), name_buf, [](unsigned char c) { return std::tolower(c); });
return name.compare(name_buf) == 0; // NOLINT(readability-string-compare) return name.compare(name_buf) == 0; // NOLINT(readability-string-compare)
}); });
if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) Var< LightObj >::push(vm, Core::Get().GetPlayer(id).mLgObj); if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) Var< LightObj >::push(vm, Core::Get().GetPlayer(id).mLgObj);
@@ -1634,10 +1694,11 @@ SQMOD_NODISCARD static SQInteger LgInPolyProcStack(HSQUIRRELVM vm) {
points.reserve(static_cast<unsigned long long int>((top - 1) / 2)); points.reserve(static_cast<unsigned long long int>((top - 1) / 2));
for (SQInteger idx = 4; idx < top;) { for (SQInteger idx = 4; idx < top;) {
points.emplace_back(); points.emplace_back();
points.back().x = PopStackFloat(vm, idx++); points.back().x = SQMOD_DOUBLE_OR(static_cast< Vector2::Value >(PopStackFloat(vm, idx++)), PopStackFloat(vm, idx++));
points.back().y = PopStackFloat(vm, idx++); points.back().y = SQMOD_DOUBLE_OR(static_cast< Vector2::Value >(PopStackFloat(vm, idx++)), PopStackFloat(vm, idx++));
} }
sq_pushbool(vm, static_cast< SQBool >(LgInternal_InPoly(x, y, points.size(), points.data()))); sq_pushbool(vm, static_cast< SQBool >(LgInternal_InPoly(SQMOD_DOUBLE_OR(static_cast< float >(x), x),
SQMOD_DOUBLE_OR(static_cast< float >(y), y), points.size(), points.data())));
return 1; return 1;
} }
SQMOD_NODISCARD static SQInteger LgInPolyProcString(HSQUIRRELVM vm) { SQMOD_NODISCARD static SQInteger LgInPolyProcString(HSQUIRRELVM vm) {
@@ -1654,7 +1715,8 @@ SQMOD_NODISCARD static SQInteger LgInPolyProcString(HSQUIRRELVM vm) {
ss >> points.back().y >> c; ss >> points.back().y >> c;
else break; else break;
} }
sq_pushbool(vm, static_cast< SQBool >(LgInternal_InPoly(x, y, points.size(), points.data()))); sq_pushbool(vm, static_cast< SQBool >(LgInternal_InPoly(SQMOD_DOUBLE_OR(static_cast< float >(x), x),
SQMOD_DOUBLE_OR(static_cast< float >(y), y), points.size(), points.data())));
return 1; return 1;
} }
SQMOD_NODISCARD static SQInteger LgInPolyProcArray(HSQUIRRELVM vm) { SQMOD_NODISCARD static SQInteger LgInPolyProcArray(HSQUIRRELVM vm) {
@@ -1665,13 +1727,14 @@ SQMOD_NODISCARD static SQInteger LgInPolyProcArray(HSQUIRRELVM vm) {
arr.Foreach([&](HSQUIRRELVM vm, SQInteger i) -> SQRESULT { arr.Foreach([&](HSQUIRRELVM vm, SQInteger i) -> SQRESULT {
if ((i & 1) == 0) { if ((i & 1) == 0) {
points.emplace_back(); points.emplace_back();
points.back().x = PopStackFloat(vm, -1); points.back().x = SQMOD_DOUBLE_OR(static_cast< Vector2::Value >(PopStackFloat(vm, -1)), PopStackFloat(vm, -1));
} else { } else {
points.back().y = PopStackFloat(vm, -1); points.back().y = SQMOD_DOUBLE_OR(static_cast< Vector2::Value >(PopStackFloat(vm, -1)), PopStackFloat(vm, -1));
} }
return SQ_OK; return SQ_OK;
}); });
sq_pushbool(vm, static_cast< SQBool >(LgInternal_InPoly(x, y, points.size(), points.data()))); sq_pushbool(vm, static_cast< SQBool >(LgInternal_InPoly(SQMOD_DOUBLE_OR(static_cast< float >(x), x),
SQMOD_DOUBLE_OR(static_cast< float >(y), y), points.size(), points.data())));
return 1; return 1;
} }
SQMOD_NODISCARD static SQInteger LgInPoly(HSQUIRRELVM vm) { SQMOD_NODISCARD static SQInteger LgInPoly(HSQUIRRELVM vm) {
@@ -1752,10 +1815,10 @@ void Register_Official_Functions(HSQUIRRELVM vm)
.Func(_SC("SetMaxHeight"), LgSetMaxHeight) .Func(_SC("SetMaxHeight"), LgSetMaxHeight)
.Func(_SC("SetFallTimer"), LgSetFallTimer) .Func(_SC("SetFallTimer"), LgSetFallTimer)
.Func(_SC("GetServerName"), LgGetServerName) .SquirrelFunc(_SC("GetServerName"), LgGetServerName)
.Func(_SC("GetMaxPlayers"), LgGetMaxPlayers) .Func(_SC("GetMaxPlayers"), LgGetMaxPlayers)
.Func(_SC("GetPassword"), LgGetServerPassword) .SquirrelFunc(_SC("GetPassword"), LgGetServerPassword)
.Func(_SC("GetGameModeName"), LgGetGameModeText) .SquirrelFunc(_SC("GetGameModeName"), LgGetGameModeText)
.Func(_SC("GetTimeRate"), LgGetTimeRate) .Func(_SC("GetTimeRate"), LgGetTimeRate)
.Func(_SC("GetHour"), LgGetHour) .Func(_SC("GetHour"), LgGetHour)
.Func(_SC("GetMinute"), LgGetMinute) .Func(_SC("GetMinute"), LgGetMinute)
@@ -1943,6 +2006,7 @@ void Register_Official_Functions(HSQUIRRELVM vm)
.Func(_SC("SetVehiclesForcedRespawnHeight"), LgSetVehiclesForcedRespawnHeight) .Func(_SC("SetVehiclesForcedRespawnHeight"), LgSetVehiclesForcedRespawnHeight)
.SquirrelFunc(_SC("FindPlayer"), LgFindPlayer) .SquirrelFunc(_SC("FindPlayer"), LgFindPlayer)
.SquirrelFunc(_SC("FindPlayerCompat"), LgFindPlayer)
.SquirrelFunc(_SC("InPoly"), LgInPoly) .SquirrelFunc(_SC("InPoly"), LgInPoly)
.SquirrelFunc(_SC("SetAmmuWeapon"), LgSetAmmuWeapon) .SquirrelFunc(_SC("SetAmmuWeapon"), LgSetAmmuWeapon)
@@ -2258,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);
+2 -2
View File
@@ -113,8 +113,8 @@ int32_t GetSkinID(StackStrF & name)
{ {
// Clone the string into an editable version // Clone the string into an editable version
String str(name.mPtr, static_cast< size_t >(name.mLen)); String str(name.mPtr, static_cast< size_t >(name.mLen));
// Strip non alphanumeric characters from the name // Strip non-alphanumeric characters from the name
str.erase(std::remove_if(str.begin(), str.end(), std::not1(std::ptr_fun(::isalnum))), str.end()); str.erase(std::remove_if(str.begin(), str.end(), [](char c) -> bool { return std::isalnum(c) == 0; }), str.end());
// Convert the string to lowercase // Convert the string to lowercase
std::transform(str.begin(), str.end(), str.begin(), ::tolower); std::transform(str.begin(), str.end(), str.begin(), ::tolower);
// See if we still have a valid name after the cleanup // See if we still have a valid name after the cleanup
+2 -2
View File
@@ -122,8 +122,8 @@ int32_t GetAutomobileID(StackStrF & name)
{ {
// Clone the string into an editable version // Clone the string into an editable version
String str(name.mPtr, static_cast< size_t >(name.mLen)); String str(name.mPtr, static_cast< size_t >(name.mLen));
// Strip non alphanumeric characters from the name // Strip non-alphanumeric characters from the name
str.erase(std::remove_if(str.begin(), str.end(), std::not1(std::ptr_fun(::isalnum))), str.end()); str.erase(std::remove_if(str.begin(), str.end(), [](char c) -> bool { return std::isalnum(c) == 0; }), str.end());
// Convert the string to lowercase // Convert the string to lowercase
std::transform(str.begin(), str.end(), str.begin(), ::tolower); std::transform(str.begin(), str.end(), str.begin(), ::tolower);
// See if we still have a valid name after the cleanup // See if we still have a valid name after the cleanup
+4 -3
View File
@@ -162,8 +162,8 @@ int32_t GetWeaponID(StackStrF & name)
{ {
// Clone the string into an editable version // Clone the string into an editable version
String str(name.mPtr, static_cast< size_t >(name.mLen)); String str(name.mPtr, static_cast< size_t >(name.mLen));
// Strip non alphanumeric characters from the name // Strip non-alphanumeric characters from the name
str.erase(std::remove_if(str.begin(), str.end(), std::not1(std::ptr_fun(::isalnum))), str.end()); str.erase(std::remove_if(str.begin(), str.end(), [](char c) -> bool { return std::isalnum(c) == 0; }), str.end());
// Convert the string to lowercase // Convert the string to lowercase
std::transform(str.begin(), str.end(), str.begin(), ::tolower); std::transform(str.begin(), str.end(), str.begin(), ::tolower);
// See if we still have a valid name after the cleanup // See if we still have a valid name after the cleanup
@@ -324,6 +324,7 @@ int32_t GetWeaponID(StackStrF & name)
// [S]PAS-12 Shotgun // [S]PAS-12 Shotgun
// [S]tubby Shotgun // [S]tubby Shotgun
// [S]uicide // [S]uicide
// Pump action [S]hotgun
case 's': case 's':
// [Sc]rewdriver // [Sc]rewdriver
if (b == 'c') return SQMOD_WEAPON_SCREWDRIVER; if (b == 'c') return SQMOD_WEAPON_SCREWDRIVER;
@@ -337,7 +338,7 @@ int32_t GetWeaponID(StackStrF & name)
else if (b == 't') return SQMOD_WEAPON_STUBBY; else if (b == 't') return SQMOD_WEAPON_STUBBY;
// [Su]icide // [Su]icide
else if (b == 'u') return SQMOD_WEAPON_SUICIDE; else if (b == 'u') return SQMOD_WEAPON_SUICIDE;
// Pump action [Sh]otgun // Pump action [Sh]otgun
else if (b == 'h') return SQMOD_WEAPON_SHOTGUN; else if (b == 'h') return SQMOD_WEAPON_SHOTGUN;
// Default to unknwon // Default to unknwon
else return SQMOD_UNKNOWN; else return SQMOD_UNKNOWN;
+586 -3
View File
@@ -1,5 +1,9 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "PocoLib/Data.hpp" #include "PocoLib/Data.hpp"
#include "Core/ThreadPool.hpp"
#include "Library/SQLite.hpp"
#include "Library/MySQL.hpp"
#include "Poco/Data/SessionImpl.h"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include <sqratConst.h> #include <sqratConst.h>
@@ -33,6 +37,7 @@ SQMOD_DECL_TYPENAME(SqPcDataStatement, _SC("SqDataStatement"))
SQMOD_DECL_TYPENAME(SqPcDataRecordSet, _SC("SqDataRecordSet")) SQMOD_DECL_TYPENAME(SqPcDataRecordSet, _SC("SqDataRecordSet"))
SQMOD_DECL_TYPENAME(SqPcDataTransaction, _SC("SqDataTransaction")) SQMOD_DECL_TYPENAME(SqPcDataTransaction, _SC("SqDataTransaction"))
SQMOD_DECL_TYPENAME(SqPcDataSessionPool, _SC("SqDataSessionPool")) SQMOD_DECL_TYPENAME(SqPcDataSessionPool, _SC("SqDataSessionPool"))
SQMOD_DECL_TYPENAME(SqPcSqDataAsyncBuilder, _SC("SqSqDataAsyncBuilder"))
SQMOD_DECL_TYPENAME(SqPcDataStatementResult, _SC("SqDataStatementResult")) SQMOD_DECL_TYPENAME(SqPcDataStatementResult, _SC("SqDataStatementResult"))
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -66,7 +71,7 @@ static LightObj SQLiteEscapeString(StackStrF & str)
// Allocate a memory buffer // Allocate a memory buffer
Buffer b(static_cast< Buffer::SzType >(str.mLen * 2 + 1)); Buffer b(static_cast< Buffer::SzType >(str.mLen * 2 + 1));
// Attempt to escape the specified string // Attempt to escape the specified string
sqlite3_snprintf(b.Capacity(), b.Get< char >(), "%q", str.mPtr); sqlite3_snprintf(static_cast< int >(b.Capacity()), b.Get< char >(), "%q", str.mPtr);
// Return the resulted string // Return the resulted string
return LightObj(b.Get< SQChar >(), -1); return LightObj(b.Get< SQChar >(), -1);
} }
@@ -90,7 +95,7 @@ static LightObj SQLiteEscapeStringEx(SQChar spec, StackStrF & str)
// Allocate a memory buffer // Allocate a memory buffer
Buffer b(static_cast< Buffer::SzType >(str.mLen * 2 + 1)); Buffer b(static_cast< Buffer::SzType >(str.mLen * 2 + 1));
// Attempt to escape the specified string // Attempt to escape the specified string
sqlite3_snprintf(b.Capacity(), b.Get< char >(), fs, str.mPtr); sqlite3_snprintf(static_cast< int >(b.Capacity()), b.Get< char >(), fs, str.mPtr);
// Return the resulted string // Return the resulted string
return LightObj(b.Get< SQChar >(), -1); return LightObj(b.Get< SQChar >(), -1);
} }
@@ -196,7 +201,7 @@ SqDataStatement SqDataSession::GetStatement(StackStrF & data)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SqDataRecordSet SqDataSession::GetRecordSet(StackStrF & data) SqDataRecordSet SqDataSession::GetRecordSet(StackStrF & data)
{ {
return SqDataRecordSet(*this, data); return {*this, data};
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@@ -470,6 +475,566 @@ SqDataStatement & SqDataStatement::Into_(LightObj & obj, LightObj & def)
return *this; return *this;
} }
// ------------------------------------------------------------------------------------------------
extern LightObj GetSQLiteFromSession(Poco::Data::SessionImpl * session);
extern LightObj GetMySQLFromSession(Poco::Data::SessionImpl * session);
// ------------------------------------------------------------------------------------------------
LightObj SqDataSessionPool::GetSq()
{
auto session = get();
auto * session_impl = session.impl();
auto & connector = session_impl->connectorName();
// Is this a SQLite session?
if (connector == "sqlite")
{
return GetSQLiteFromSession(session_impl);
}
// Is this a MySQL session?
else if (connector == "mysql")
{
return GetMySQLFromSession(session_impl);
}
STHROWF("Unknown connector type {}", connector);
SQ_UNREACHABLE
}
// ------------------------------------------------------------------------------------------------
LightObj SqDataSessionPool::AsyncExec(StackStrF & sql)
{
return LightObj{SqTypeIdentity< SqDataAsyncBuilder >{}, SqVM(), get().impl(), sql, true, false, false};
}
// ------------------------------------------------------------------------------------------------
LightObj SqDataSessionPool::AsyncQuery(StackStrF & sql)
{
return LightObj{SqTypeIdentity< SqDataAsyncBuilder >{}, SqVM(), get().impl(), sql, false, true, false};
}
// ------------------------------------------------------------------------------------------------
LightObj SqDataSessionPool::IncAsyncQuery(StackStrF & sql)
{
return LightObj{SqTypeIdentity< SqDataAsyncBuilder >{}, SqVM(), get().impl(), sql, false, true, true};
}
// ------------------------------------------------------------------------------------------------
LightObj SqDataSessionPool::ExecAsyncQuery(StackStrF & sql)
{
return LightObj{SqTypeIdentity< SqDataAsyncBuilder >{}, SqVM(), get().impl(), sql, true, true, false};
}
/* ------------------------------------------------------------------------------------------------
* Asynchronous SQLite query execution implementation.
*/
struct SQLiteAsyncExec : public ThreadPoolItem
{
using SessionRef = Poco::AutoPtr< Poco::Data::SessionImpl >;
// --------------------------------------------------------------------------------------------
SQLiteConnRef mConnection{}; // Internal connection handle.
// --------------------------------------------------------------------------------------------
Function mResolved{}; // Callback to invoke when the task was completed.
Function mRejected{}; // Callback to invoke when the task was aborted.
// --------------------------------------------------------------------------------------------
int32_t mResult{SQLITE_OK}; // Execution result code.
int32_t mChanges{0}; // Rows affected by this query.
// --------------------------------------------------------------------------------------------
const SQChar * mQueryStr{nullptr}; // The query string that will be executed.
LightObj mQueryObj{}; // Strong reference to the query string object.
// --------------------------------------------------------------------------------------------
LightObj mCtx{}; // User specified context object, if any.
// --------------------------------------------------------------------------------------------
String mError{}; // Error message, if any.
/* --------------------------------------------------------------------------------------------
* Base constructor. Members are supposed to be validated and filled by the builder/proxy.
*/
SQLiteAsyncExec() = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~SQLiteAsyncExec() override = default;
/* --------------------------------------------------------------------------------------------
* Provide a name to what type of task this is. Mainly for debugging purposes.
*/
SQMOD_NODISCARD const char * TypeName() noexcept override { return "sqlite async execute"; }
/* --------------------------------------------------------------------------------------------
* Provide unique information that may help identify the task. Mainly for debugging purposes.
*/
SQMOD_NODISCARD const char * IdentifiableInfo() noexcept override { return mQueryStr; }
/* --------------------------------------------------------------------------------------------
* Invoked in worker thread by the thread pool after obtaining the task from the queue.
* Must return true to indicate that the task can be performed. False indicates failure.
*/
SQMOD_NODISCARD bool OnPrepare() override
{
// Coincidentally, this also dirties the handle time-stamp so, it doesn't get collected
return mConnection->mSession->isConnected();
}
/* --------------------------------------------------------------------------------------------
* Called in worker by the thread pool to performed by the associated tasks.
* Will be called continuously while the returned value is true. While false means it finished.
*/
SQMOD_NODISCARD bool OnProcess() override
{
char * err_msg = nullptr;
// Attempt to execute the specified query
mResult = sqlite3_exec(mConnection->Access(), mQueryStr, nullptr, nullptr, &err_msg);
// Store changes count
if (mResult == SQLITE_OK)
{
mChanges = sqlite3_changes(mConnection->Access());
}
// Check for error message
if (err_msg != nullptr)
{
mError.assign(err_msg);
sqlite3_free(err_msg);
}
// Don't retry
return false;
};
/* --------------------------------------------------------------------------------------------
* 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 the boolean parameter is try then the thread-pool is in the process of shutting down.
*/
SQMOD_NODISCARD bool OnCompleted(bool SQ_UNUSED_ARG(stop)) override
{
if (mResult == SQLITE_OK)
{
if (!mResolved.IsNull())
{
LightObj c{SqTypeIdentity< SQLiteConnection >{}, SqVM(), mConnection};
mResolved.Execute(c, mCtx, mChanges, mQueryObj);
}
}
else if (!mRejected.IsNull())
{
LightObj c{SqTypeIdentity< SQLiteConnection >{}, SqVM(), mConnection};
mRejected.Execute(c, mCtx, mResult, mError, mQueryObj);
}
// Finished
return false;
}
/* --------------------------------------------------------------------------------------------
* Called in worker by the thread pool to let the task know that it will be aborted.
* Most likely due to a shutdown of the thread pool.
*/
void OnAborted(bool SQ_UNUSED_ARG(retry)) override
{
// We don't really have to do anything for now
}
};
/* ------------------------------------------------------------------------------------------------
* Asynchronous SQLite statement implementation.
*/
struct SQLiteAsyncStmtBase : public ThreadPoolItem
{
using SessionRef = Poco::AutoPtr< Poco::Data::SessionImpl >;
// --------------------------------------------------------------------------------------------
SQLiteConnRef mConnection{}; // Internal connection handle.
SQLiteStmtRef mStatement{}; // Internal statement handle.
// --------------------------------------------------------------------------------------------
Function mResolved{}; // Callback to invoke when the task was completed.
Function mRejected{}; // Callback to invoke when the task was aborted.
Function mPrepared{}; // Callback to invoke when the task must be prepared.
// --------------------------------------------------------------------------------------------
SQLiteStatement * mStatementPtr{nullptr}; // Pointer to the script statement instance.
LightObj mStatementObj{}; // Strong reference to the statement instance object.
// --------------------------------------------------------------------------------------------
const SQChar * mQueryStr{nullptr}; // The query string that will be executed.
LightObj mQueryObj{}; // Strong reference to the query string object.
// --------------------------------------------------------------------------------------------
LightObj mCtx{}; // User specified context object, if any.
// --------------------------------------------------------------------------------------------
int32_t mChanges{0}; // Rows affected by this query.
bool mPrepped{false}; // Whether the statement was prepared.
bool mRow{false}; // Whether we still have rows to process.
/* --------------------------------------------------------------------------------------------
* Base constructor. Members are supposed to be validated and filled by the builder/proxy.
*/
SQLiteAsyncStmtBase() = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~SQLiteAsyncStmtBase() override = default;
/* --------------------------------------------------------------------------------------------
* Provide unique information that may help identify the task. Mainly for debugging purposes.
*/
SQMOD_NODISCARD const char * IdentifiableInfo() noexcept override { return mQueryStr; }
/* --------------------------------------------------------------------------------------------
* Invoked in worker thread by the thread pool after obtaining the task from the queue.
* Must return true to indicate that the task can be performed. False indicates failure.
*/
SQMOD_NODISCARD bool OnPrepare() override
{
// Coincidentally, this also dirties the handle time-stamp so, it doesn't get collected
if (mConnection->mSession->isConnected())
{
if (mStatement->mPtr == nullptr)
{
mStatement->Create(mQueryStr, static_cast< SQInteger >(strlen(mQueryStr)));
// Statement was not prepared/filled with information (yet)
mPrepped = mPrepared.IsNull();
}
// Prepared
return true;
}
// Can't prepare
return false;
}
/* --------------------------------------------------------------------------------------------
* Called in worker by the thread pool to let the task know that it will be aborted.
* Most likely due to a shutdown of the thread pool.
*/
void OnAborted(bool SQ_UNUSED_ARG(retry)) override
{
// We don't really have to do anything for now
}
};
/* ------------------------------------------------------------------------------------------------
* Asynchronous SQLite statement execution implementation.
*/
struct SQLiteAsyncStmtExec : public SQLiteAsyncStmtBase
{
/* --------------------------------------------------------------------------------------------
* Provide a name to what type of task this is. Mainly for debugging purposes.
*/
SQMOD_NODISCARD const char * TypeName() noexcept override { return "sqlite async query exec"; }
/* --------------------------------------------------------------------------------------------
* Called in worker by the thread pool to performed by the associated tasks.
* Will be called continuously while the returned value is true. While false means it finished.
*/
SQMOD_NODISCARD bool OnProcess() override
{
// Was the statement prepared?
if (mPrepped)
{
mChanges = mStatementPtr->Exec();
}
// Don't retry
return false;
};
/* --------------------------------------------------------------------------------------------
* 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 the boolean parameter is try then the thread-pool is in the process of shutting down.
*/
SQMOD_NODISCARD bool OnCompleted(bool SQ_UNUSED_ARG(stop)) override
{
if (mPrepped && mStatement->mDone)
{
if (!mResolved.IsNull())
{
LightObj o = mResolved.Eval(mStatementObj, mCtx, mChanges);
// Should we abort the whole thing?
if (!o.IsNull() && o.Cast< bool >() == false)
{
return false; // Allow to abort itself
}
}
// No longer prepared
mPrepped = false;
}
// Allow to prepare itself, either on initial call or again after execution
if (!mPrepped && (mStatement->mStatus == SQLITE_OK || mStatement->mStatus == SQLITE_DONE))
{
mPrepped = true;
// Is there a prepping callback?
if (!mPrepared.IsNull())
{
// Should we reset?
if (mStatement->mStatus == SQLITE_DONE)
{
mStatementPtr->Reset();
}
LightObj o = mPrepared.Eval(mStatementObj, mCtx);
// Should we abort the whole thing?
if (!o.IsNull())
{
return o.Cast< bool >(); // Allow to abort itself
}
else
{
return true; // Re-queue the task by default
}
}
}
else if (!mRejected.IsNull() && (mStatement->mStatus != SQLITE_OK && mStatement->mStatus != SQLITE_DONE))
{
mRejected.Execute(mStatementObj, mCtx, mQueryObj);
}
// Finished
return false;
}
};
/* ------------------------------------------------------------------------------------------------
* Asynchronous SQLite statement stepping implementation.
*/
struct SQLiteAsyncStmtStep : public SQLiteAsyncStmtBase
{
/* --------------------------------------------------------------------------------------------
* Provide a name to what type of task this is. Mainly for debugging purposes.
*/
SQMOD_NODISCARD const char * TypeName() noexcept override { return "sqlite async query step"; }
/* --------------------------------------------------------------------------------------------
* Called in worker by the thread pool to performed by the associated tasks.
* Will be called continuously while the returned value is true. While false means it finished.
*/
SQMOD_NODISCARD bool OnProcess() override
{
// Was the statement prepared?
if (mPrepped)
{
mRow = mStatementPtr->Step();
}
// Don't retry
return false;
};
/* --------------------------------------------------------------------------------------------
* 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 the boolean parameter is try then the thread-pool is in the process of shutting down.
*/
SQMOD_NODISCARD bool OnCompleted(bool SQ_UNUSED_ARG(stop)) override
{
// This is only done once, before performing any step
if (!mPrepped)
{
mPrepped = true;
// Is there a prepping callback?
if (!mPrepared.IsNull())
{
LightObj o = mPrepared.Eval(mStatementObj, mCtx);
// Should we abort the whole thing?
if (!o.IsNull())
{
return o.Cast< bool >(); // Allow to abort itself
}
else
{
return true; // Re-queue the task by default
}
}
}
if (mStatement->mGood || mStatement->mDone)
{
if (!mResolved.IsNull())
{
// You are expected to step the statement manually until the end
mResolved.Execute(mStatementObj, mCtx);
}
}
else if (!mRejected.IsNull())
{
mRejected.Execute(mStatementObj, mCtx, mQueryObj);
}
// Finished
return false;
}
};
/* ------------------------------------------------------------------------------------------------
* Asynchronous SQLite incremental statement stepping implementation.
*/
struct SQLiteAsyncStmtIncStep : public SQLiteAsyncStmtBase
{
/* --------------------------------------------------------------------------------------------
* Provide a name to what type of task this is. Mainly for debugging purposes.
*/
SQMOD_NODISCARD const char * TypeName() noexcept override { return "sqlite incremental async query step"; }
/* --------------------------------------------------------------------------------------------
* Called in worker by the thread pool to performed by the associated tasks.
* Will be called continuously while the returned value is true. While false means it finished.
*/
SQMOD_NODISCARD bool OnProcess() override
{
// Was the statement prepared?
if (mPrepped)
{
mRow = mStatementPtr->Step();
}
// Don't retry
return false;
};
/* --------------------------------------------------------------------------------------------
* 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 the boolean parameter is try then the thread-pool is in the process of shutting down.
*/
SQMOD_NODISCARD bool OnCompleted(bool SQ_UNUSED_ARG(stop)) override
{
// This is only done once, before performing any step
if (!mPrepped)
{
mPrepped = true;
// Is there a prepping callback?
if (!mPrepared.IsNull())
{
LightObj o = mPrepared.Eval(mStatementObj, mCtx);
// Should we abort the whole thing?
if (!o.IsNull())
{
return o.Cast< bool >(); // Allow to abort itself
}
else
{
return true; // Re-queue the task by default
}
}
}
if (mStatement->mGood && !mStatement->mDone)
{
if (!mResolved.IsNull())
{
// Should all steps be completed here?
if (stop)
{
do {
LightObj o = mResolved.Eval(mStatementObj, mCtx);
// Should we abort the whole thing?
if (!o.IsNull() && !o.Cast< bool >())
{
return false;
}
// Don't let exceptions be stupid
mRow = false;
// Force process whole statement
if (mStatement->mGood) OnProcess();
} while (mRow);
}
else
{
LightObj o = mResolved.Eval(mStatementObj, mCtx);
// Should we abort the whole thing?
if (!o.IsNull() && !o.Cast< bool >())
{
return false;
}
}
}
}
else if (!mRejected.IsNull() && (mStatement->mStatus != SQLITE_OK && mStatement->mStatus != SQLITE_DONE))
{
mRejected.Execute(mStatementObj, mCtx, mQueryObj);
}
// Re-queue if we still have rows to process
return mRow;
}
};
// ------------------------------------------------------------------------------------------------
SqDataAsyncBuilder::SqDataAsyncBuilder(Poco::Data::SessionImpl * session, StackStrF & sql, bool exec, bool stmt, bool inc) noexcept
: mSession(session, true)
, mResolved(), mRejected()
, mQueryStr(sql.mPtr), mQueryObj(sql.mObj)
, mExec(exec), mStmt(stmt), mInc(inc)
{
}
// ------------------------------------------------------------------------------------------------
void SqDataAsyncBuilder::Submit_(LightObj & ctx)
{
if (mSession.isNull())
{
STHROWF("Asynchronous query builder instance is invalid.");
}
auto & connector = mSession->connectorName();
// Is this a SQLite session?
if (connector == "sqlite")
{
// Retrieve the internal handle property
auto * connection = Poco::AnyCast< sqlite3 * >(mSession->getProperty("handle"));
// Is this a statement?
if (mStmt)
{
SQLiteAsyncStmtBase * item = nullptr;
// Is this just for executing?
if (mExec)
{
item = static_cast< SQLiteAsyncStmtBase * >(new SQLiteAsyncStmtExec());
}
// Is this incremental?
else if (mInc)
{
item = static_cast< SQLiteAsyncStmtBase * >(new SQLiteAsyncStmtIncStep());
}
else
{
item = static_cast< SQLiteAsyncStmtBase * >(new SQLiteAsyncStmtStep());
}
// Take ownership before any exception can be thrown
std::unique_ptr< ThreadPoolItem > task{static_cast< ThreadPoolItem * >(item)};
// Populate task information
item->mConnection = SQLiteConnRef{new SQLiteConnHnd(std::move(mSession))};
item->mStatement = SQLiteStmtRef{new SQLiteStmtHnd(item->mConnection)};
item->mResolved = std::move(mResolved);
item->mRejected = std::move(mRejected);
item->mPrepared = std::move(mPrepared);
item->mStatementObj = LightObj{SqTypeIdentity< SQLiteStatement >{}, SqVM(), item->mStatement};
item->mStatementPtr = item->mStatementObj.CastI< SQLiteStatement >();
item->mQueryStr = mQueryStr;
item->mQueryObj = std::move(mQueryObj);
item->mCtx = std::move(ctx);
// Submit the task
ThreadPool::Get().Enqueue(std::move(task));
}
else
{
auto * item = new SQLiteAsyncExec();
// Take ownership before any exception can be thrown
std::unique_ptr< ThreadPoolItem > task{static_cast< ThreadPoolItem * >(item)};
// Populate task information
item->mConnection = SQLiteConnRef{new SQLiteConnHnd(std::move(mSession))};
item->mResolved = std::move(mResolved);
item->mRejected = std::move(mRejected);
item->mQueryStr = mQueryStr;
item->mQueryObj = std::move(mQueryObj);
item->mCtx = std::move(ctx);
// Submit the task
ThreadPool::Get().Enqueue(std::move(task));
}
}
// Is this a MySQL session?
else if (connector == "mysql")
{
if (mStmt)
{
//...
}
else
{
//...
}
}
else
{
STHROWF("Unknown connector type {}", connector);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
LightObj SqDataSessionPool::GetProperty(StackStrF & name) LightObj SqDataSessionPool::GetProperty(StackStrF & name)
{ {
@@ -746,6 +1311,19 @@ void Register_POCO_Data(HSQUIRRELVM vm, Table &)
.Overload(_SC("Value"), &SqDataRecordSet::GetValueOr) .Overload(_SC("Value"), &SqDataRecordSet::GetValueOr)
); );
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
ns.Bind(_SC("AsyncBuilder"),
Class< SqDataAsyncBuilder, NoConstructor< SqDataAsyncBuilder > >(vm, SqPcSqDataAsyncBuilder::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqPcSqDataAsyncBuilder::Fn)
// Member Methods
.CbFunc(_SC("Resolved"), &SqDataAsyncBuilder::OnResolved)
.CbFunc(_SC("Rejected"), &SqDataAsyncBuilder::OnRejected)
.CbFunc(_SC("Prepared"), &SqDataAsyncBuilder::OnPrepared)
// Overloaded methods
.Overload(_SC("Submit"), &SqDataAsyncBuilder::Submit)
.Overload(_SC("Submit"), &SqDataAsyncBuilder::Submit_)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("SessionPool"), ns.Bind(_SC("SessionPool"),
Class< SqDataSessionPool, NoCopy< SqDataSessionPool > >(vm, SqPcDataSessionPool::Str) Class< SqDataSessionPool, NoCopy< SqDataSessionPool > >(vm, SqPcDataSessionPool::Str)
// Constructors // Constructors
@@ -764,6 +1342,11 @@ void Register_POCO_Data(HSQUIRRELVM vm, Table &)
.Prop(_SC("IsActive"), &SqDataSessionPool::IsActive) .Prop(_SC("IsActive"), &SqDataSessionPool::IsActive)
// Member Methods // Member Methods
.Func(_SC("Get"), &SqDataSessionPool::Get) .Func(_SC("Get"), &SqDataSessionPool::Get)
.Func(_SC("GetSq"), &SqDataSessionPool::GetSq)
.FmtFunc(_SC("AsyncExec"), &SqDataSessionPool::AsyncExec)
.FmtFunc(_SC("AsyncQuery"), &SqDataSessionPool::AsyncQuery)
.FmtFunc(_SC("IncAsyncQuery"), &SqDataSessionPool::IncAsyncQuery)
.FmtFunc(_SC("ExecAsyncQuery"), &SqDataSessionPool::ExecAsyncQuery)
.FmtFunc(_SC("GetWithProperty"), &SqDataSessionPool::GetWithProperty) .FmtFunc(_SC("GetWithProperty"), &SqDataSessionPool::GetWithProperty)
.FmtFunc(_SC("GetWithFeature"), &SqDataSessionPool::GetWithFeature) .FmtFunc(_SC("GetWithFeature"), &SqDataSessionPool::GetWithFeature)
.FmtFunc(_SC("SetFeature"), &SqDataSessionPool::SetFeature) .FmtFunc(_SC("SetFeature"), &SqDataSessionPool::SetFeature)
+115 -2
View File
@@ -1707,7 +1707,7 @@ protected:
} }
SQ_UNREACHABLE SQ_UNREACHABLE
// Unreachable // Unreachable
return LightObj(); return {};
} }
}; };
@@ -1746,7 +1746,7 @@ struct SqDataSessionPool : public SessionPool
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Destroys the SessionPool. * Destroys the SessionPool.
*/ */
~SqDataSessionPool() = default; ~SqDataSessionPool() override = default;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Assignment operator (disabled). * Assignment operator (disabled).
@@ -1766,6 +1766,31 @@ struct SqDataSessionPool : public SessionPool
return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get()); return LightObj(SqTypeIdentity< SqDataSession >{}, SqVM(), get());
} }
/* --------------------------------------------------------------------------------------------
* Retrieve a Session wrapped in a native/legacy implementation.
*/
LightObj GetSq();
/* --------------------------------------------------------------------------------------------
* Create an asynchronous query execution builder.
*/
LightObj AsyncExec(StackStrF & sql);
/* --------------------------------------------------------------------------------------------
* Create an asynchronous query execution builder.
*/
LightObj AsyncQuery(StackStrF & sql);
/* --------------------------------------------------------------------------------------------
* Create an asynchronous query execution builder.
*/
LightObj IncAsyncQuery(StackStrF & sql);
/* --------------------------------------------------------------------------------------------
* Create an asynchronous query execution builder.
*/
LightObj ExecAsyncQuery(StackStrF & sql);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Retrieve a Session with requested property set. * Retrieve a Session with requested property set.
*/ */
@@ -2070,4 +2095,92 @@ struct SqDataTransaction : public Transaction
} }
}; };
/* ------------------------------------------------------------------------------------------------
* Common session action implementation.
*/
struct SqDataAsyncBuilder
{
using SessionRef = Poco::AutoPtr< Poco::Data::SessionImpl >;
// --------------------------------------------------------------------------------------------
SessionRef mSession{}; // The connection that will be used by the task.
// --------------------------------------------------------------------------------------------
Function mResolved{}; // Callback to invoke when the task was completed.
Function mRejected{}; // Callback to invoke when the task was aborted.
Function mPrepared{}; // Callback to invoke when the task was must be prepared.
// --------------------------------------------------------------------------------------------
const SQChar * mQueryStr{nullptr}; // The query string that will be executed.
LightObj mQueryObj{}; // Strong reference to the query string object.
// --------------------------------------------------------------------------------------------
bool mExec{false}; // Whether this is a query execution.
bool mStmt{false}; // Whether this is a query statement.
bool mInc{false}; // Whether this is an incremental query statement.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
SqDataAsyncBuilder(Poco::Data::SessionImpl * session, StackStrF & sql, bool exec, bool stmt, bool inc) noexcept;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
SqDataAsyncBuilder(const SqDataAsyncBuilder & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
SqDataAsyncBuilder(SqDataAsyncBuilder && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~SqDataAsyncBuilder() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
SqDataAsyncBuilder & operator = (const SqDataAsyncBuilder & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
SqDataAsyncBuilder & operator = (SqDataAsyncBuilder && o) = default;
/* --------------------------------------------------------------------------------------------
* Create the task with the supplied information and submit it to the worker pool.
*/
void Submit() { Submit_(NullLightObj()); }
/* --------------------------------------------------------------------------------------------
* Create the task with the supplied information and submit it to the worker pool.
*/
void Submit_(LightObj & ctx);
/* --------------------------------------------------------------------------------------------
* Set the callback to be executed if the query was resolved.
*/
SqDataAsyncBuilder & OnResolved(Function & cb)
{
mResolved = std::move(cb);
return *this; // Allow chaining
}
/* --------------------------------------------------------------------------------------------
* Set the callback to be executed if the query was rejected/failed.
*/
SqDataAsyncBuilder & OnRejected(Function & cb)
{
mRejected = std::move(cb);
return *this; // Allow chaining
}
/* --------------------------------------------------------------------------------------------
* Set the callback to be executed in order to compose the query/statement.
*/
SqDataAsyncBuilder & OnPrepared(Function & cb)
{
mPrepared = std::move(cb);
return *this; // Allow chaining
}
};
} // Namespace:: SqMod } // Namespace:: SqMod
-112
View File
@@ -1,112 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "PocoLib/RegEx.hpp"
// ------------------------------------------------------------------------------------------------
#include <sqratConst.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMOD_DECL_TYPENAME(SqRegEx, _SC("SqRegEx"))
SQMOD_DECL_TYPENAME(SqRegExMatch, _SC("SqRegExMatch"))
SQMOD_DECL_TYPENAME(SqRegExMatches, _SC("SqRegExMatches"))
// ------------------------------------------------------------------------------------------------
// ================================================================================================
void Register_POCO_RegEx(HSQUIRRELVM vm, Table & ns)
{
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("RegExMatch"),
Class< PcRegExMatch >(vm, SqRegExMatch::Str)
// Constructors
.Ctor()
.Ctor< SQInteger >()
.Ctor< SQInteger, SQInteger >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqRegExMatch::Fn)
// Properties
.Prop(_SC("Offset"), &PcRegExMatch::GetOffset, &PcRegExMatch::SetOffset)
.Prop(_SC("Length"), &PcRegExMatch::GetLength, &PcRegExMatch::SetLength)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("RegExMatches"),
Class< PcRegExMatches >(vm, SqRegExMatches::Str)
// Constructors
.Ctor()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqRegExMatches::Fn)
// Properties
.Prop(_SC("Front"), &PcRegExMatches::Front)
.Prop(_SC("Back"), &PcRegExMatches::Back)
.Prop(_SC("Empty"), &PcRegExMatches::Empty)
.Prop(_SC("Size"), &PcRegExMatches::Size)
.Prop(_SC("Capacity"), &PcRegExMatches::Capacity, &PcRegExMatches::Reserve)
// Member Methods
.Func(_SC("Get"), &PcRegExMatches::Get)
.Func(_SC("Reserve"), &PcRegExMatches::Reserve)
.Func(_SC("Compact"), &PcRegExMatches::Compact)
.Func(_SC("Clear"), &PcRegExMatches::Clear)
.Func(_SC("Pop"), &PcRegExMatches::Pop)
.Func(_SC("EraseAt"), &PcRegExMatches::EraseAt)
.Func(_SC("EraseFrom"), &PcRegExMatches::EraseFrom)
.Func(_SC("Each"), &PcRegExMatches::Each)
.Func(_SC("EachRange"), &PcRegExMatches::EachRange)
.Func(_SC("While"), &PcRegExMatches::While)
.Func(_SC("WhileRange"), &PcRegExMatches::WhileRange)
);
// --------------------------------------------------------------------------------------------
ns.Bind(_SC("RegEx"),
Class< PcRegEx, NoCopy< PcRegEx > >(vm, SqRegEx::Str)
// Constructors
.Ctor< StackStrF & >()
.Ctor< int, StackStrF & >()
.Ctor< int, bool, StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqRegEx::Fn)
// Member Methods
//.Func(_SC("Assign"), &PcRegEx::assign)
// Overloaded Member Methods
.Overload(_SC("MatchFirst"), &PcRegEx::MatchFirst)
.Overload(_SC("MatchFirst"), &PcRegEx::MatchFirst_)
.Overload(_SC("MatchFirstFrom"), &PcRegEx::MatchFirstFrom)
.Overload(_SC("MatchFirstFrom"), &PcRegEx::MatchFirstFrom_)
.Overload(_SC("Match"), &PcRegEx::Match)
.Overload(_SC("Match"), &PcRegEx::Match_)
.Overload(_SC("MatchFrom"), &PcRegEx::MatchFrom)
.Overload(_SC("MatchFrom"), &PcRegEx::MatchFrom_)
.Overload(_SC("Matches"), &PcRegEx::Matches)
.Overload(_SC("Matches"), &PcRegEx::Matches_)
.Overload(_SC("Matches"), &PcRegEx::MatchesEx)
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqRegExOption"), Enumeration(vm)
.Const(_SC("Caseless"), static_cast< SQInteger >(Poco::RegularExpression::RE_CASELESS))
.Const(_SC("MultiLine"), static_cast< SQInteger >(Poco::RegularExpression::RE_MULTILINE))
.Const(_SC("DotAll"), static_cast< SQInteger >(Poco::RegularExpression::RE_DOTALL))
.Const(_SC("Extended"), static_cast< SQInteger >(Poco::RegularExpression::RE_EXTENDED))
.Const(_SC("Anchored"), static_cast< SQInteger >(Poco::RegularExpression::RE_ANCHORED))
.Const(_SC("DollarEndOnly"), static_cast< SQInteger >(Poco::RegularExpression::RE_DOLLAR_ENDONLY))
.Const(_SC("Extra"), static_cast< SQInteger >(Poco::RegularExpression::RE_EXTRA))
.Const(_SC("NotBOL"), static_cast< SQInteger >(Poco::RegularExpression::RE_NOTBOL))
.Const(_SC("NotEOL"), static_cast< SQInteger >(Poco::RegularExpression::RE_NOTEOL))
.Const(_SC("Ungreedy"), static_cast< SQInteger >(Poco::RegularExpression::RE_UNGREEDY))
.Const(_SC("NotEmpty"), static_cast< SQInteger >(Poco::RegularExpression::RE_NOTEMPTY))
.Const(_SC("UTF8"), static_cast< SQInteger >(Poco::RegularExpression::RE_UTF8))
.Const(_SC("NoAutoCapture"), static_cast< SQInteger >(Poco::RegularExpression::RE_NO_AUTO_CAPTURE))
.Const(_SC("NoUTF8Check"), static_cast< SQInteger >(Poco::RegularExpression::RE_NO_UTF8_CHECK))
.Const(_SC("FirstLine"), static_cast< SQInteger >(Poco::RegularExpression::RE_FIRSTLINE))
.Const(_SC("DupNames"), static_cast< SQInteger >(Poco::RegularExpression::RE_DUPNAMES))
.Const(_SC("NewLineCR"), static_cast< SQInteger >(Poco::RegularExpression::RE_NEWLINE_CR))
.Const(_SC("NewLineLF"), static_cast< SQInteger >(Poco::RegularExpression::RE_NEWLINE_LF))
.Const(_SC("NewLineCRLF"), static_cast< SQInteger >(Poco::RegularExpression::RE_NEWLINE_CRLF))
.Const(_SC("NewLineAny"), static_cast< SQInteger >(Poco::RegularExpression::RE_NEWLINE_ANY))
.Const(_SC("NewLineAnyCRLF"), static_cast< SQInteger >(Poco::RegularExpression::RE_NEWLINE_ANYCRLF))
.Const(_SC("Global"), static_cast< SQInteger >(Poco::RegularExpression::RE_GLOBAL))
.Const(_SC("NoVars"), static_cast< SQInteger >(Poco::RegularExpression::RE_NO_VARS))
);
}
} // Namespace:: SqMod
-481
View File
@@ -1,481 +0,0 @@
#pragma once
// ------------------------------------------------------------------------------------------------
#include "Core/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <algorithm>
// ------------------------------------------------------------------------------------------------
#include <Poco/RegularExpression.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
*
*/
struct PcRegExMatch : public Poco::RegularExpression::Match
{
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
PcRegExMatch() noexcept
: Poco::RegularExpression::Match{}
{
}
/* --------------------------------------------------------------------------------------------
* Offset constructor.
*/
explicit PcRegExMatch(SQInteger offset) noexcept
: Poco::RegularExpression::Match{static_cast< std::string::size_type >(offset), 0}
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
PcRegExMatch(SQInteger offset, SQInteger length) noexcept
: Poco::RegularExpression::Match{
static_cast< std::string::size_type >(offset),
static_cast< std::string::size_type >(length)
}
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
PcRegExMatch(const PcRegExMatch & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
PcRegExMatch(PcRegExMatch && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
PcRegExMatch & operator = (const PcRegExMatch & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
PcRegExMatch & operator = (PcRegExMatch && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Retrieve offset.
*/
SQMOD_NODISCARD SQInteger GetOffset() const noexcept
{
return static_cast< SQInteger >(Poco::RegularExpression::Match::offset);
}
/* --------------------------------------------------------------------------------------------
* Modify offset.
*/
void SetOffset(SQInteger value) noexcept
{
Poco::RegularExpression::Match::offset = static_cast< std::string::size_type >(value);
}
/* --------------------------------------------------------------------------------------------
* Retrieve length.
*/
SQMOD_NODISCARD SQInteger GetLength() const noexcept
{
return static_cast< SQInteger >(Poco::RegularExpression::Match::length);
}
/* --------------------------------------------------------------------------------------------
* Modify length.
*/
void SetLength(SQInteger value) noexcept
{
Poco::RegularExpression::Match::length = static_cast< std::string::size_type >(value);
}
};
/* ------------------------------------------------------------------------------------------------
*
*/
struct PcRegExMatches
{
using List = Poco::RegularExpression::MatchVec;
/* --------------------------------------------------------------------------------------------
* Internal RegularExpression instance.
*/
List m_List;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
PcRegExMatches() = default;
/* --------------------------------------------------------------------------------------------
* Copy list constructor.
*/
explicit PcRegExMatches(const List & l) // NOLINT(modernize-pass-by-value)
: m_List{l}
{
}
/* --------------------------------------------------------------------------------------------
* Move list constructor.
*/
explicit PcRegExMatches(List && m) noexcept
: m_List{std::move(m)}
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
PcRegExMatches(const PcRegExMatches & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
PcRegExMatches(PcRegExMatches && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
PcRegExMatches & operator = (const PcRegExMatches & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
PcRegExMatches & operator = (PcRegExMatches && o) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Make sure an index is within range and return the container. Container must exist.
*/
List & ValidIdx(SQInteger i)
{
if (static_cast< size_t >(i) >= m_List.size())
{
STHROWF("Invalid RegEx match list index({})", i);
}
return m_List;
}
/* --------------------------------------------------------------------------------------------
* Make sure an index is within range and return the container. Container must exist.
*/
SQMOD_NODISCARD const List & ValidIdx(SQInteger i) const
{
if (static_cast< size_t >(i) >= m_List.size())
{
STHROWF("Invalid RegEx match list index({})", i);
}
return m_List;
}
/* --------------------------------------------------------------------------------------------
* Make sure a container instance is populated, then return it.
*/
SQMOD_NODISCARD List & ValidPop()
{
if (m_List.empty())
{
STHROWF("RegEx match list container is empty");
}
return m_List;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a value from the container.
*/
SQMOD_NODISCARD List::reference Get(SQInteger i)
{
return ValidIdx(i).at(ClampL< SQInteger, size_t >(i));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the first element in the container.
*/
SQMOD_NODISCARD List::reference Front()
{
return ValidPop().front();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last element in the container.
*/
SQMOD_NODISCARD List::reference Back()
{
return m_List.back();
}
/* --------------------------------------------------------------------------------------------
* Check if the container has no elements.
*/
SQMOD_NODISCARD bool Empty() const
{
return m_List.empty();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of elements in the container.
*/
SQMOD_NODISCARD SQInteger Size() const
{
return static_cast< SQInteger >(m_List.size());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of elements that the container has currently allocated space for.
*/
SQMOD_NODISCARD SQInteger Capacity() const
{
return static_cast< SQInteger >(m_List.capacity());
}
/* --------------------------------------------------------------------------------------------
* Increase the capacity of the container to a value that's greater or equal to the one specified.
*/
PcRegExMatches & Reserve(SQInteger n)
{
m_List.reserve(ClampL< SQInteger, size_t >(n));
return *this;
}
/* --------------------------------------------------------------------------------------------
* Request the removal of unused capacity.
*/
void Compact()
{
m_List.shrink_to_fit();
}
/* --------------------------------------------------------------------------------------------
* Erase all elements from the container.
*/
void Clear()
{
m_List.clear();
}
/* --------------------------------------------------------------------------------------------
* Pop the last element in the container.
*/
void Pop()
{
ValidPop().pop_back();
}
/* --------------------------------------------------------------------------------------------
* Erase the element at a certain position.
*/
void EraseAt(SQInteger i)
{
m_List.erase(ValidIdx(i).begin() + static_cast< size_t >(i));
}
/* --------------------------------------------------------------------------------------------
* Erase a certain amount of elements starting from a specific position.
*/
void EraseFrom(SQInteger i, SQInteger n)
{
m_List.erase(ValidIdx(i).begin() + static_cast< size_t >(i),
ValidIdx(i + n).begin() + static_cast< size_t >(i + n));
}
/* --------------------------------------------------------------------------------------------
* Iterate all values through a functor.
*/
void Each(Function & fn) const
{
for (const auto & e : m_List)
{
fn.Execute(static_cast< SQInteger >(e.offset), static_cast< SQInteger >(e.length));
}
}
/* --------------------------------------------------------------------------------------------
* Iterate values in range through a functor.
*/
void EachRange(SQInteger p, SQInteger n, Function & fn) const
{
std::for_each(ValidIdx(p).begin() + static_cast< size_t >(p),
ValidIdx(p + n).begin() + static_cast< size_t >(p + n),
[&](List::const_reference & e) {
fn.Execute(static_cast< SQInteger >(e.offset), static_cast< SQInteger >(e.length));
});
}
/* --------------------------------------------------------------------------------------------
* Iterate all values through a functor until stopped (i.e false is returned).
*/
void While(Function & fn) const
{
for (const auto & e : m_List)
{
auto ret = fn.Eval(static_cast< SQInteger >(e.offset), static_cast< SQInteger >(e.length));
// (null || true) == continue & false == break
if (!ret.IsNull() || !ret.template Cast< bool >())
{
break;
}
}
}
/* --------------------------------------------------------------------------------------------
* Iterate values in range through a functor until stopped (i.e false is returned).
*/
void WhileRange(SQInteger p, SQInteger n, Function & fn) const
{
auto itr = ValidIdx(p).begin() + static_cast< size_t >(p);
auto end = ValidIdx(p + n).begin() + static_cast< size_t >(p + n);
for (; itr != end; ++itr)
{
auto ret = fn.Eval(static_cast< SQInteger >(itr->offset), static_cast< SQInteger >(itr->length));
// (null || true) == continue & false == break
if (!ret.IsNull() || !ret.template Cast< bool >())
{
break;
}
}
}
};
/* ------------------------------------------------------------------------------------------------
* A class for working with regular expressions.
* Implemented using PCRE, the Perl Compatible Regular Expressions library. (see http://www.pcre.org)
*/
struct PcRegEx
{
/* --------------------------------------------------------------------------------------------
* Internal RegularExpression instance.
*/
Poco::RegularExpression m_Rx;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
explicit PcRegEx(StackStrF & str)
: m_Rx(str.ToStr())
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
PcRegEx(int options, StackStrF & str)
: m_Rx(str.ToStr(), options)
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
PcRegEx(int options, bool study, StackStrF & str)
: m_Rx(str.ToStr(), options, study)
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
PcRegEx(const PcRegEx & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
PcRegEx(PcRegEx && o) = delete;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
PcRegEx & operator = (const PcRegEx & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
PcRegEx & operator = (PcRegEx && o) = delete;
/* --------------------------------------------------------------------------------------------
* Matches the given subject string against the pattern.
* Returns the position of the first captured sub-string in m.
* If no part of the subject matches the pattern, m.offset is std::string::npos and m.length is 0.
* Returns the number of matches. Throws a exception in case of an error.
*/
SQMOD_NODISCARD int MatchFirst(PcRegExMatch & m, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), m);
}
SQMOD_NODISCARD int MatchFirst_(int f, PcRegExMatch & m, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), m, f);
}
/* --------------------------------------------------------------------------------------------
* Matches the given subject string against the pattern.
* Returns the position of the first captured sub-string in m.
* If no part of the subject matches the pattern, m.offset is std::string::npos and m.length is 0.
* Returns the number of matches. Throws a exception in case of an error.
*/
SQMOD_NODISCARD int MatchFirstFrom(SQInteger o, PcRegExMatch & m, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), static_cast< std::string::size_type >(o), m);
}
SQMOD_NODISCARD int MatchFirstFrom_(int f, SQInteger o, PcRegExMatch & m, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), static_cast< std::string::size_type >(o), m, f);
}
/* --------------------------------------------------------------------------------------------
* Matches the given subject string against the pattern.
* The first entry in m contains the position of the captured sub-string.
* The following entries identify matching subpatterns. See the PCRE documentation for a more detailed explanation.
* If no part of the subject matches the pattern, m is empty.
* Returns the number of matches. Throws a exception in case of an error.
*/
SQMOD_NODISCARD int Match(PcRegExMatches & m, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), 0, m.m_List);
}
SQMOD_NODISCARD int Match_(int f, PcRegExMatches & m, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), 0, m.m_List, f);
}
/* --------------------------------------------------------------------------------------------
* Matches the given subject string against the pattern.
* The first entry in m contains the position of the captured sub-string.
* The following entries identify matching subpatterns. See the PCRE documentation for a more detailed explanation.
* If no part of the subject matches the pattern, m is empty.
* Returns the number of matches. Throws a exception in case of an error.
*/
SQMOD_NODISCARD int MatchFrom(SQInteger o, PcRegExMatches & m, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), static_cast< std::string::size_type >(o), m.m_List);
}
SQMOD_NODISCARD int MatchFrom_(int f, SQInteger o, PcRegExMatches & m, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), static_cast< std::string::size_type >(o), m.m_List, f);
}
/* --------------------------------------------------------------------------------------------
* Returns true if and only if the subject matches the regular expression.
* Internally, this method sets the RE_ANCHORED and RE_NOTEMPTY options for matching,
* which means that the empty string will never match and the pattern is treated as if it starts with a ^.
*/
SQMOD_NODISCARD bool Matches(StackStrF & s) const
{
return m_Rx.match(s.ToStr());
}
SQMOD_NODISCARD bool Matches_(SQInteger o, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), static_cast< std::string::size_type >(o));
}
SQMOD_NODISCARD bool MatchesEx(int f, SQInteger o, StackStrF & s) const
{
return m_Rx.match(s.ToStr(), static_cast< std::string::size_type >(o), f);
}
};
} // Namespace:: SqMod
-2
View File
@@ -8,7 +8,6 @@ namespace SqMod {
extern void Register_POCO_Crypto(HSQUIRRELVM vm, Table & ns); extern void Register_POCO_Crypto(HSQUIRRELVM vm, Table & ns);
extern void Register_POCO_Data(HSQUIRRELVM vm, Table & ns); extern void Register_POCO_Data(HSQUIRRELVM vm, Table & ns);
extern void Register_POCO_Net(HSQUIRRELVM vm, Table & ns); extern void Register_POCO_Net(HSQUIRRELVM vm, Table & ns);
extern void Register_POCO_RegEx(HSQUIRRELVM vm, Table & ns);
extern void Register_POCO_Time(HSQUIRRELVM vm, Table & ns); extern void Register_POCO_Time(HSQUIRRELVM vm, Table & ns);
extern void Register_POCO_Util(HSQUIRRELVM vm, Table & ns); extern void Register_POCO_Util(HSQUIRRELVM vm, Table & ns);
@@ -20,7 +19,6 @@ void Register_POCO(HSQUIRRELVM vm)
Register_POCO_Crypto(vm, ns); Register_POCO_Crypto(vm, ns);
Register_POCO_Data(vm, ns); Register_POCO_Data(vm, ns);
Register_POCO_Net(vm, ns); Register_POCO_Net(vm, ns);
Register_POCO_RegEx(vm, ns);
Register_POCO_Time(vm, ns); Register_POCO_Time(vm, ns);
Register_POCO_Util(vm, ns); Register_POCO_Util(vm, ns);
+4 -6
View File
@@ -39,14 +39,13 @@ extern void Register_JSON(HSQUIRRELVM vm);
extern void Register_MMDB(HSQUIRRELVM vm); extern void Register_MMDB(HSQUIRRELVM vm);
extern void Register_Net(HSQUIRRELVM vm); extern void Register_Net(HSQUIRRELVM vm);
extern void Register_Numeric(HSQUIRRELVM vm); extern void Register_Numeric(HSQUIRRELVM vm);
extern void Register_RegEx(HSQUIRRELVM vm);
extern void Register_String(HSQUIRRELVM vm); extern void Register_String(HSQUIRRELVM vm);
extern void Register_System(HSQUIRRELVM vm); extern void Register_System(HSQUIRRELVM vm);
extern void Register_UTF8(HSQUIRRELVM vm);
extern void Register_Utils(HSQUIRRELVM vm); extern void Register_Utils(HSQUIRRELVM vm);
extern void Register_XML(HSQUIRRELVM vm); extern void Register_XML(HSQUIRRELVM vm);
extern void Register_ZMQ(HSQUIRRELVM vm); extern void Register_ZMQ(HSQUIRRELVM vm);
#ifdef VCMP_ENABLE_DISCORD
extern void Register_DPP(HSQUIRRELVM vm);
#endif
#ifdef SQMOD_POCO_HAS_SQLITE #ifdef SQMOD_POCO_HAS_SQLITE
extern void Register_SQLite(HSQUIRRELVM vm); extern void Register_SQLite(HSQUIRRELVM vm);
#endif #endif
@@ -108,14 +107,13 @@ bool RegisterAPI(HSQUIRRELVM vm)
Register_MMDB(vm); Register_MMDB(vm);
Register_Net(vm); Register_Net(vm);
Register_Numeric(vm); Register_Numeric(vm);
Register_RegEx(vm);
Register_String(vm); Register_String(vm);
Register_System(vm); Register_System(vm);
Register_UTF8(vm);
Register_Utils(vm); Register_Utils(vm);
Register_XML(vm); Register_XML(vm);
Register_ZMQ(vm); Register_ZMQ(vm);
#ifdef VCMP_ENABLE_DISCORD
Register_DPP(vm);
#endif
#ifdef SQMOD_POCO_HAS_SQLITE #ifdef SQMOD_POCO_HAS_SQLITE
Register_SQLite(vm); Register_SQLite(vm);
#endif #endif
+1 -1
View File
@@ -75,7 +75,7 @@
#define SQMOD_NAME "Squirrel Module" #define SQMOD_NAME "Squirrel Module"
#define SQMOD_AUTHOR "Sandu Liviu Catalin (S.L.C)" #define SQMOD_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQMOD_COPYRIGHT "Copyright (C) 2021 Sandu Liviu Catalin" #define SQMOD_COPYRIGHT "Copyright (C) 2022 Sandu Liviu Catalin"
#define SQMOD_HOST_NAME "SqModHost" #define SQMOD_HOST_NAME "SqModHost"
#define SQMOD_VERSION 001 #define SQMOD_VERSION 001
#define SQMOD_VERSION_STR "0.0.1" #define SQMOD_VERSION_STR "0.0.1"
+24
View File
@@ -612,6 +612,30 @@ public:
//sq_pop(vm,1); // pop array //sq_pop(vm,1); // pop array
return *this; return *this;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Appends values to the end of the Array
///
/// \param vec Vector to be appended to the array
///
/// \tparam T Type of value (usually doesnt need to be defined explicitly)
///
/// \return The Array itself so the call can be chained
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
ArrayBase& AppendFromVector(const std::vector< T > & vec) {
HSQUIRRELVM vm = SqVM();
const StackGuard sg(vm);
sq_pushobject(vm, GetObj());
for (const auto & v : vec)
{
Var< const T & >::push(vm, v);
sq_arrayappend(vm, -2);
}
//sq_pop(vm,1); // pop array
return *this;
}
}; };
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+75
View File
@@ -29,6 +29,7 @@
#include <squirrelex.h> #include <squirrelex.h>
#include <cstring>
#include <typeinfo> #include <typeinfo>
#include "sqratObject.h" #include "sqratObject.h"
@@ -661,6 +662,80 @@ public:
return *this; return *this;
} }
protected:
// Used internally to proxy calls to wrapped squirrel methods.
template < class T = C, SQInteger(T::*Mptr)(HSQUIRRELVM) > static SQInteger SquirrelMethodProxy(HSQUIRRELVM vm) noexcept
{
try {
return ((::Sqrat::Var<T*>(vm, 1).value)->*Mptr)(vm);
} catch (const Poco::Exception& e) {
return sq_throwerror(vm, e.displayText().c_str());
} catch (const std::exception& e) {
return sq_throwerror(vm, e.what());
} catch (...) {
return sq_throwerror(vm, _SC("unknown exception occured"));
}
}
// Used internally to proxy calls to wrapped squirrel methods.
template < class T = C, SQInteger(T::*Mptr)(HSQUIRRELVM) const > static SQInteger SquirrelMethodProxy(HSQUIRRELVM vm) noexcept
{
try {
return ((::Sqrat::Var<T*>(vm, 1).value)->*Mptr)(vm);
} catch (const Poco::Exception& e) {
return sq_throwerror(vm, e.displayText().c_str());
} catch (const std::exception& e) {
return sq_throwerror(vm, e.what());
} catch (...) {
return sq_throwerror(vm, _SC("unknown exception occured"));
}
}
public:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Binds a class method that is treated as a squirrel function but invoked on the instance itself
///
/// \param name Name of the function as it will appear in Squirrel
/// \param func Function to bind
///
/// \return The Class itself so the call can be chained
///
/// \remarks
/// Inside of the function, the class instance the function was called with will be at index 1 on the
/// stack and all arguments will be after that index in the order they were given to the function.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template < class T = C, SQInteger(T::*Mptr)(HSQUIRRELVM) > Class& SquirrelMethod(const SQChar* name) {
return SquirrelFunc(name, &SquirrelMethodProxy< T, Mptr >);
}
template < class T = C, SQInteger(T::*Mptr)(HSQUIRRELVM) const > Class& SquirrelMethod(const SQChar* name) {
return SquirrelFunc(name, &SquirrelMethodProxy< T, Mptr >);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Binds a class method that is treated as a squirrel function but invoked on the instance itself
///
/// \param name Name of the function as it will appear in Squirrel
/// \param func Function to bind
/// \param pnum Number of parameters the function expects.
/// \param mask Types of parameters the function expects.
///
/// \return The Class itself so the call can be chained
///
/// \remarks
/// Inside of the function, the class instance the function was called with will be at index 1 on the
/// stack and all arguments will be after that index in the order they were given to the function.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template < class T = C, SQInteger(T::*Mptr)(HSQUIRRELVM) > Class& SquirrelMethod(const SQChar* name, SQInteger pnum, const SQChar * mask) {
return SquirrelFunc(name, &SquirrelMethodProxy< T, Mptr >, pnum, mask);
}
template < class T = C, SQInteger(T::*Mptr)(HSQUIRRELVM) const > Class& SquirrelMethod(const SQChar* name, SQInteger pnum, const SQChar * mask) {
return SquirrelFunc(name, &SquirrelMethodProxy< T, Mptr >, pnum, mask);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Gets a Function from a name in the Class /// Gets a Function from a name in the Class
/// ///
+25 -16
View File
@@ -88,6 +88,15 @@ struct LightObj {
sq_addref(SqVM(), &mObj); sq_addref(SqVM(), &mObj);
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Constructs a LightObj from a string object
///
/// \param o Squirrel object
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
explicit LightObj(const string & s) : LightObj(s.c_str(), static_cast< SQInteger >(s.size())) {
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Constructs a LightObj from a Squirrel object at a certain index on the stack /// Constructs a LightObj from a Squirrel object at a certain index on the stack
/// ///
@@ -186,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();
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -237,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();
} }
+6 -6
View File
@@ -157,7 +157,7 @@ template <class C,class R> struct SqMember {
} catch (const std::exception& e) { } catch (const std::exception& e) {
return sq_throwerror(vm, e.what()); return sq_throwerror(vm, e.what());
} catch (...) { } catch (...) {
return sq_throwerror(vm, _SC("unknown exception occured")); return sq_throwerror(vm, _SC("unknown exception occurred"));
} }
SQ_UNREACHABLE SQ_UNREACHABLE
}; };
@@ -178,7 +178,7 @@ template <class C,class R> struct SqMember {
} catch (const std::exception& e) { } catch (const std::exception& e) {
return sq_throwerror(vm, e.what()); return sq_throwerror(vm, e.what());
} catch (...) { } catch (...) {
return sq_throwerror(vm, _SC("unknown exception occured")); return sq_throwerror(vm, _SC("unknown exception occurred"));
} }
SQ_UNREACHABLE SQ_UNREACHABLE
}; };
@@ -206,7 +206,7 @@ template <class C, class R> struct SqMember<C,R&> {
} catch (const std::exception& e) { } catch (const std::exception& e) {
return sq_throwerror(vm, e.what()); return sq_throwerror(vm, e.what());
} catch (...) { } catch (...) {
return sq_throwerror(vm, _SC("unknown exception occured")); return sq_throwerror(vm, _SC("unknown exception occurred"));
} }
SQ_UNREACHABLE SQ_UNREACHABLE
}; };
@@ -227,7 +227,7 @@ template <class C, class R> struct SqMember<C,R&> {
} catch (const std::exception& e) { } catch (const std::exception& e) {
return sq_throwerror(vm, e.what()); return sq_throwerror(vm, e.what());
} catch (...) { } catch (...) {
return sq_throwerror(vm, _SC("unknown exception occured")); return sq_throwerror(vm, _SC("unknown exception occurred"));
} }
SQ_UNREACHABLE SQ_UNREACHABLE
}; };
@@ -256,7 +256,7 @@ template <class C> struct SqMember<C, void> {
} catch (const std::exception& e) { } catch (const std::exception& e) {
return sq_throwerror(vm, e.what()); return sq_throwerror(vm, e.what());
} catch (...) { } catch (...) {
return sq_throwerror(vm, _SC("unknown exception occured")); return sq_throwerror(vm, _SC("unknown exception occurred"));
} }
SQ_UNREACHABLE SQ_UNREACHABLE
}; };
@@ -277,7 +277,7 @@ template <class C> struct SqMember<C, void> {
} catch (const std::exception& e) { } catch (const std::exception& e) {
return sq_throwerror(vm, e.what()); return sq_throwerror(vm, e.what());
} catch (...) { } catch (...) {
return sq_throwerror(vm, _SC("unknown exception occured")); return sq_throwerror(vm, _SC("unknown exception occurred"));
} }
SQ_UNREACHABLE SQ_UNREACHABLE
}; };
+125
View File
@@ -31,6 +31,9 @@
#include <cstring> #include <cstring>
#include <map>
#include <unordered_map>
#include "sqratAllocator.h" #include "sqratAllocator.h"
#include "sqratTypes.h" #include "sqratTypes.h"
#include "sqratOverloadMethods.h" #include "sqratOverloadMethods.h"
@@ -669,6 +672,128 @@ public:
return res; return res;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Inserts associative container values into the managed object.
///
/// \param map Associative container to be inserted to the table
///
/// \tparam K Type of key (usually doesnt need to be defined explicitly)
///
/// \tparam V Type of value (usually doesnt need to be defined explicitly)
///
/// \return Result value returned by squirrel.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class K, class V>
SQRESULT InsertFromMap(const std::unordered_map< K, V > & map, bool staticVar = false) {
HSQUIRRELVM vm = SqVM();
const StackGuard sg(vm);
sq_pushobject(vm, GetObj());
for (const auto & p : map)
{
Var< const K & >::push(vm, p.first);
Var< const V & >::push(vm, p.second);
const auto r = sq_newslot(vm, -3, staticVar);
if (SQ_FAILED(r)) return r;
}
//sq_pop(vm, 1); // pop object
return SQ_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Inserts associative container values into the managed object.
///
/// \param map Associative container to be inserted to the table
///
/// \tparam K Type of key (usually doesnt need to be defined explicitly)
///
/// \tparam V Type of value (usually doesnt need to be defined explicitly)
///
/// \return Result value returned by squirrel.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class K, class V>
SQRESULT InsertFromMap(const std::map< K, V > & map, bool staticVar = false) {
HSQUIRRELVM vm = SqVM();
const StackGuard sg(vm);
sq_pushobject(vm, GetObj());
for (const auto & p : map)
{
Var< const K & >::push(vm, p.first);
Var< const V & >::push(vm, p.second);
const auto r = sq_newslot(vm, -3, staticVar);
if (SQ_FAILED(r)) return r;
}
//sq_pop(vm, 1); // pop object
return SQ_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Inserts associative container values into the managed object.
///
/// \param map Associative container to be inserted to the table
///
/// \param func Functor that is continuously called to push values on the stack
///
/// \tparam K Type of key (usually doesnt need to be defined explicitly)
///
/// \tparam V Type of value (usually doesnt need to be defined explicitly)
///
/// \tparam F Type of functor (usually doesnt need to be defined explicitly)
///
/// \return Result value returned by squirrel.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class K, class V, class F>
SQRESULT InsertFromMapWith(const std::unordered_map< K, V > & map, F func, bool staticVar = false) {
HSQUIRRELVM vm = SqVM();
const StackGuard sg(vm);
sq_pushobject(vm, GetObj());
SQRESULT r = SQ_OK;
for (const auto & p : map)
{
r = func(vm, p.first, p.second);
if (SQ_FAILED(r)) break;
r = sq_newslot(vm, -3, staticVar);
if (SQ_FAILED(r)) return r;
}
//sq_pop(vm, 1); // pop object
return r;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Inserts associative container values into the managed object.
///
/// \param map Associative container to be inserted to the table
///
/// \param func Functor that is continuously called to push values on the stack
///
/// \tparam K Type of key (usually doesnt need to be defined explicitly)
///
/// \tparam V Type of value (usually doesnt need to be defined explicitly)
///
/// \tparam F Type of functor (usually doesnt need to be defined explicitly)
///
/// \return Result value returned by squirrel.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class K, class V, class F>
SQRESULT InsertFromMapWith(const std::map< K, V > & map, F func, bool staticVar = false) {
HSQUIRRELVM vm = SqVM();
const StackGuard sg(vm);
sq_pushobject(vm, GetObj());
SQRESULT r = SQ_OK;
for (const auto & p : map)
{
r = func(vm, p.first, p.second);
if (SQ_FAILED(r)) break;
r = sq_newslot(vm, -3, staticVar);
if (SQ_FAILED(r)) return r;
}
//sq_pop(vm, 1); // pop object
return r;
}
protected: protected:
/// @cond DEV /// @cond DEV
+36 -36
View File
@@ -181,7 +181,7 @@ private:
template <class T2, bool b> template <class T2, bool b>
struct pushAsInt { struct pushAsInt {
void push(HSQUIRRELVM vm, const T2& /*value*/) { inline void push(HSQUIRRELVM vm, const T2& /*value*/) noexcept {
assert(false); // fails because called before a Sqrat::Class for T exists and T is not convertible to SQInteger assert(false); // fails because called before a Sqrat::Class for T exists and T is not convertible to SQInteger
sq_pushnull(vm); sq_pushnull(vm);
} }
@@ -189,8 +189,8 @@ private:
template <class T2> template <class T2>
struct pushAsInt<T2, true> { struct pushAsInt<T2, true> {
void push(HSQUIRRELVM vm, const T2& value) { inline void push(HSQUIRRELVM vm, const T2& val) noexcept {
sq_pushinteger(vm, static_cast<SQInteger>(value)); sq_pushinteger(vm, static_cast<SQInteger>(val));
} }
}; };
}; };
@@ -237,7 +237,7 @@ private:
template <class T2, bool b> template <class T2, bool b>
struct pushAsInt { struct pushAsInt {
void push(HSQUIRRELVM vm, const T2& /*value*/) { inline void push(HSQUIRRELVM vm, const T2& /*value*/) noexcept {
assert(false); // fails because called before a Sqrat::Class for T exists and T is not convertible to SQInteger assert(false); // fails because called before a Sqrat::Class for T exists and T is not convertible to SQInteger
sq_pushnull(vm); sq_pushnull(vm);
} }
@@ -245,8 +245,8 @@ private:
template <class T2> template <class T2>
struct pushAsInt<T2, true> { struct pushAsInt<T2, true> {
void push(HSQUIRRELVM vm, const T2& value) { inline void push(HSQUIRRELVM vm, const T2& val) noexcept {
sq_pushinteger(vm, static_cast<SQInteger>(value)); sq_pushinteger(vm, static_cast<SQInteger>(val));
} }
}; };
}; };
@@ -483,7 +483,7 @@ struct Var<SharedPtr<T> > {
Var(HSQUIRRELVM vm, SQInteger idx) { \ Var(HSQUIRRELVM vm, SQInteger idx) { \
value = popAsInt<type, true>(vm, idx).value; \ value = popAsInt<type, true>(vm, idx).value; \
} \ } \
static void push(HSQUIRRELVM vm, const type& value) { \ inline static void push(HSQUIRRELVM vm, const type& value) noexcept { \
sq_pushinteger(vm, static_cast<SQInteger>(value)); \ sq_pushinteger(vm, static_cast<SQInteger>(value)); \
} \ } \
};\ };\
@@ -494,7 +494,7 @@ struct Var<SharedPtr<T> > {
Var(HSQUIRRELVM vm, SQInteger idx) { \ Var(HSQUIRRELVM vm, SQInteger idx) { \
value = popAsInt<type, true>(vm, idx).value; \ value = popAsInt<type, true>(vm, idx).value; \
} \ } \
static void push(HSQUIRRELVM vm, const type& value) { \ inline static void push(HSQUIRRELVM vm, const type& value) noexcept { \
sq_pushinteger(vm, static_cast<SQInteger>(value)); \ sq_pushinteger(vm, static_cast<SQInteger>(value)); \
} \ } \
}; };
@@ -525,7 +525,7 @@ SCRAT_INTEGER(signed __int64)
Var(HSQUIRRELVM vm, SQInteger idx) { \ Var(HSQUIRRELVM vm, SQInteger idx) { \
value = popAsFloat<type>(vm, idx).value; \ value = popAsFloat<type>(vm, idx).value; \
} \ } \
static void push(HSQUIRRELVM vm, const type& value) { \ inline static void push(HSQUIRRELVM vm, const type& value) noexcept { \
sq_pushfloat(vm, static_cast<SQFloat>(value)); \ sq_pushfloat(vm, static_cast<SQFloat>(value)); \
} \ } \
}; \ }; \
@@ -536,7 +536,7 @@ SCRAT_INTEGER(signed __int64)
Var(HSQUIRRELVM vm, SQInteger idx) { \ Var(HSQUIRRELVM vm, SQInteger idx) { \
value = popAsFloat<type>(vm, idx).value; \ value = popAsFloat<type>(vm, idx).value; \
} \ } \
static void push(HSQUIRRELVM vm, const type& value) { \ inline static void push(HSQUIRRELVM vm, const type& value) noexcept { \
sq_pushfloat(vm, static_cast<SQFloat>(value)); \ sq_pushfloat(vm, static_cast<SQFloat>(value)); \
} \ } \
}; };
@@ -572,7 +572,7 @@ struct Var<bool> {
/// \param value Value to push on to the VM's stack /// \param value Value to push on to the VM's stack
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const bool& value) { inline static void push(HSQUIRRELVM vm, const bool& value) noexcept {
sq_pushbool(vm, static_cast<SQBool>(value)); sq_pushbool(vm, static_cast<SQBool>(value));
} }
}; };
@@ -605,7 +605,7 @@ struct Var<const bool&> {
/// \param value Value to push on to the VM's stack /// \param value Value to push on to the VM's stack
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const bool& value) { inline static void push(HSQUIRRELVM vm, const bool& value) noexcept {
sq_pushbool(vm, static_cast<SQBool>(value)); sq_pushbool(vm, static_cast<SQBool>(value));
} }
}; };
@@ -615,7 +615,7 @@ struct Var<const bool&> {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
struct Var<std::nullptr_t> { struct Var<std::nullptr_t> {
std::nullptr_t value; ///< The actual value of get operations std::nullptr_t value{}; ///< The actual value of get operations
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Attempts to get the value off the stack at idx as a nullptr_t /// Attempts to get the value off the stack at idx as a nullptr_t
@@ -632,7 +632,7 @@ struct Var<std::nullptr_t> {
/// \param vm Target VM /// \param vm Target VM
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm) { inline static void push(HSQUIRRELVM vm) noexcept {
sq_pushnull(vm); sq_pushnull(vm);
} }
@@ -643,7 +643,7 @@ struct Var<std::nullptr_t> {
/// \param value Value to push on to the VM's stack /// \param value Value to push on to the VM's stack
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, std::nullptr_t SQ_UNUSED_ARG(value)) { inline static void push(HSQUIRRELVM vm, std::nullptr_t SQ_UNUSED_ARG(value)) noexcept {
sq_pushnull(vm); sq_pushnull(vm);
} }
}; };
@@ -655,13 +655,13 @@ template<>
struct Var<SQChar*> { struct Var<SQChar*> {
private: private:
HSQOBJECT obj; /* hold a reference to the object holding value during the Var struct lifetime*/ HSQOBJECT obj{}; /* hold a reference to the object holding value during the Var struct lifetime*/
HSQUIRRELVM v; HSQUIRRELVM v{nullptr};
public: public:
SQChar* value; ///< The actual value of get operations SQChar* value{nullptr}; ///< The actual value of get operations
SQInteger size; ///< The size of the obtained string SQInteger size{0}; ///< The size of the obtained string
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Attempts to get the value off the stack at idx as a character array /// Attempts to get the value off the stack at idx as a character array
@@ -698,7 +698,7 @@ public:
/// \param len Length of the string (defaults to finding the length by searching for a terminating null-character) /// \param len Length of the string (defaults to finding the length by searching for a terminating null-character)
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const SQChar* value, SQInteger len = -1) { inline static void push(HSQUIRRELVM vm, const SQChar* value, SQInteger len = -1) noexcept {
sq_pushstring(vm, value, len); sq_pushstring(vm, value, len);
} }
}; };
@@ -710,13 +710,13 @@ template<>
struct Var<const SQChar*> { struct Var<const SQChar*> {
private: private:
HSQOBJECT obj; /* hold a reference to the object holding value during the Var struct lifetime*/ HSQOBJECT obj{}; /* hold a reference to the object holding value during the Var struct lifetime*/
HSQUIRRELVM v; HSQUIRRELVM v{nullptr};
public: public:
const SQChar* value; ///< The actual value of get operations const SQChar* value{nullptr}; ///< The actual value of get operations
SQInteger size; ///< The size of the obtained string SQInteger size{0}; ///< The size of the obtained string
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Attempts to get the value off the stack at idx as a character array /// Attempts to get the value off the stack at idx as a character array
@@ -753,7 +753,7 @@ public:
/// \param len Length of the string (defaults to finding the length by searching for a terminating null-character) /// \param len Length of the string (defaults to finding the length by searching for a terminating null-character)
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const SQChar* value, SQInteger len = -1) { inline static void push(HSQUIRRELVM vm, const SQChar* value, SQInteger len = -1) noexcept {
sq_pushstring(vm, value, len); sq_pushstring(vm, value, len);
} }
}; };
@@ -789,8 +789,8 @@ struct Var<string> {
/// \param value Value to push on to the VM's stack /// \param value Value to push on to the VM's stack
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const string& value) { inline static void push(HSQUIRRELVM vm, const string& value) noexcept {
sq_pushstring(vm, value.c_str(), value.size()); sq_pushstring(vm, value.c_str(), static_cast< SQInteger >(value.size()));
} }
}; };
@@ -825,8 +825,8 @@ struct Var<const string&> {
/// \param value Value to push on to the VM's stack /// \param value Value to push on to the VM's stack
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const string& value) { inline static void push(HSQUIRRELVM vm, const string& value) noexcept {
sq_pushstring(vm, value.c_str(), value.size()); sq_pushstring(vm, value.c_str(), static_cast< SQInteger >(value.size()));
} }
}; };
@@ -863,7 +863,7 @@ struct Var<std::wstring> {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const std::wstring& value) { static void push(HSQUIRRELVM vm, const std::wstring& value) {
std::string s(value.begin(), value.end()); std::string s(value.begin(), value.end());
sq_pushstring(vm, s.c_str(), s.size()); sq_pushstring(vm, s.c_str(), static_cast< SQInteger >(s.size()));
} }
}; };
@@ -900,7 +900,7 @@ struct Var<const std::wstring&> {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const std::wstring& value) { static void push(HSQUIRRELVM vm, const std::wstring& value) {
std::string s(value.begin(), value.end()); std::string s(value.begin(), value.end());
sq_pushstring(vm, s.c_str(), s.size()); sq_pushstring(vm, s.c_str(), static_cast< SQInteger >(s.size()));
} }
}; };
@@ -1173,7 +1173,7 @@ struct Var<StackStrF> {
/// \param value Value to push on to the VM's stack /// \param value Value to push on to the VM's stack
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const StackStrF& value) { static void push(HSQUIRRELVM vm, const StackStrF& value) noexcept {
if (sq_isstring(value.mObj)) { if (sq_isstring(value.mObj)) {
sq_pushobject(vm, value.mObj); sq_pushobject(vm, value.mObj);
} else { } else {
@@ -1284,7 +1284,7 @@ inline void PushVars(HSQUIRRELVM /*vm*/) { }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T> template<class T>
inline void PushVars(HSQUIRRELVM vm, T value) { inline void PushVars(HSQUIRRELVM vm, T value) {
PushVar(vm, value); PushVar(vm, std::forward< T >(value));
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1292,15 +1292,15 @@ inline void PushVars(HSQUIRRELVM vm, T value) {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T, class... Ts> template<class T, class... Ts>
inline void PushVars(HSQUIRRELVM vm, T value, Ts &&... tail) { inline void PushVars(HSQUIRRELVM vm, T value, Ts &&... tail) {
PushVar(vm, value); PushVar(vm, std::forward< T >(value));
PushVars(vm, std::forward<Ts>(tail)...); PushVars(vm, std::forward< Ts >(tail)...);
} }
/// @cond DEV /// @cond DEV
template<class T, bool b> template<class T, bool b>
struct PushVarR_helper { struct PushVarR_helper {
inline static void push(HSQUIRRELVM vm, T value) { inline static void push(HSQUIRRELVM vm, T value) {
PushVar<T>(vm, value); PushVar<T>(vm, std::forward< T >(value));
} }
}; };
template<class T> template<class T>
+166 -42
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
+19 -4
View File
@@ -1,13 +1,23 @@
add_subdirectory(ConcurrentQueue) add_subdirectory(ConcurrentQueue)
add_subdirectory(Fmt) add_subdirectory(Fmt)
add_subdirectory(xxHash) add_subdirectory(xxHash)
add_subdirectory(RPMalloc)
add_subdirectory(Squirrel) add_subdirectory(Squirrel)
add_subdirectory(SimpleIni) add_subdirectory(SimpleIni)
add_subdirectory(TinyDir) add_subdirectory(TinyDir)
add_subdirectory(SAJSON) add_subdirectory(SAJSON)
add_subdirectory(CPR) add_subdirectory(CPR)
add_subdirectory(UTF8)
add_subdirectory(PUGIXML) add_subdirectory(PUGIXML)
add_subdirectory(CivetWeb) add_subdirectory(CivetWeb)
if (ENABLE_BUILTIN_MYSQL_C)
set(WITH_MSI OFF CACHE INTERNAL "" FORCE)
set(WITH_UNIT_TESTS OFF CACHE INTERNAL "" FORCE)
set(WITH_EXTERNAL_ZLIB ON CACHE INTERNAL "" FORCE)
set(WITH_CURL ON CACHE INTERNAL "" FORCE)
set(WITH_SSL ON CACHE INTERNAL "" FORCE)
add_subdirectory(MDBC)
endif()
set(BUILD_TESTING OFF CACHE INTERNAL "" FORCE) set(BUILD_TESTING OFF CACHE INTERNAL "" FORCE)
set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "" FORCE) set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "" FORCE)
add_subdirectory(MaxmindDB) add_subdirectory(MaxmindDB)
@@ -36,6 +46,15 @@ set(ENABLE_TESTS OFF CACHE INTERNAL "" FORCE)
set(ENABLE_ACTIVERECORD OFF CACHE INTERNAL "" FORCE) set(ENABLE_ACTIVERECORD OFF CACHE INTERNAL "" FORCE)
set(ENABLE_ACTIVERECORD_COMPILER OFF CACHE INTERNAL "" FORCE) set(ENABLE_ACTIVERECORD_COMPILER OFF CACHE INTERNAL "" FORCE)
set(POCO_UNBUNDLED OFF CACHE INTERNAL "" FORCE) set(POCO_UNBUNDLED OFF CACHE INTERNAL "" FORCE)
# Manualy enable some options if available
find_package(MySQL)
if(MYSQL_FOUND)
set(ENABLE_DATA_MYSQL ON CACHE INTERNAL "" FORCE)
endif()
find_package(PostgreSQL)
if(PostgreSQL_FOUND)
set(ENABLE_DATA_POSTGRESQL ON CACHE INTERNAL "" FORCE)
endif()
add_subdirectory(POCO) add_subdirectory(POCO)
# Windows gets stupid sometimes # Windows gets stupid sometimes
if (WIN32 AND MINGW) if (WIN32 AND MINGW)
@@ -52,7 +71,3 @@ if (WIN32 OR MINGW)
set(ZMQ_HAVE_IPC OFF CACHE INTERNAL "" FORCE) set(ZMQ_HAVE_IPC OFF CACHE INTERNAL "" FORCE)
endif() endif()
add_subdirectory(ZMQ) add_subdirectory(ZMQ)
# Should we include DPP?
if (ENABLE_DISCORD)
add_subdirectory(DPP)
endif()
-174
View File
@@ -1,174 +0,0 @@
# Create the DPP library
add_library(DPP STATIC
include/dpp/nlohmann/json.hpp
include/dpp/nlohmann/json_fwd.hpp
include/dpp/auditlog.h
include/dpp/ban.h
include/dpp/cache.h
include/dpp/channel.h
include/dpp/cluster.h
include/dpp/commandhandler.h
include/dpp/discord.h
include/dpp/discordclient.h
include/dpp/discordevents.h
include/dpp/discordvoiceclient.h
include/dpp/dispatcher.h
include/dpp/dpp.h
include/dpp/dtemplate.h
include/dpp/emoji.h
include/dpp/event.h
include/dpp/export.h
include/dpp/guild.h
include/dpp/httplib.h
include/dpp/integration.h
include/dpp/intents.h
include/dpp/invite.h
include/dpp/json_fwd.hpp
include/dpp/message.h
include/dpp/presence.h
include/dpp/prune.h
include/dpp/queues.h
include/dpp/role.h
include/dpp/slashcommand.h
include/dpp/sslclient.h
include/dpp/stringops.h
include/dpp/user.h
include/dpp/version.h
include/dpp/voiceregion.h
include/dpp/voicestate.h
include/dpp/webhook.h
include/dpp/wsclient.h
src/dpp/ban.cpp
src/dpp/cache.cpp
src/dpp/channel.cpp
src/dpp/cluster.cpp
src/dpp/commandhandler.cpp
src/dpp/discordclient.cpp
src/dpp/discordevents.cpp
src/dpp/discordvoiceclient.cpp
src/dpp/dispatcher.cpp
src/dpp/dtemplate.cpp
src/dpp/emoji.cpp
src/dpp/guild.cpp
src/dpp/httplib.cpp
src/dpp/integration.cpp
src/dpp/invite.cpp
src/dpp/managed.cpp
src/dpp/message.cpp
src/dpp/presence.cpp
src/dpp/prune.cpp
src/dpp/queues.cpp
src/dpp/role.cpp
src/dpp/slashcommand.cpp
src/dpp/sslclient.cpp
src/dpp/user.cpp
src/dpp/utility.cpp
src/dpp/voiceregion.cpp
src/dpp/voicestate.cpp
src/dpp/webhook.cpp
src/dpp/wsclient.cpp
src/dpp/auditlog.cpp
src/dpp/events/application_command_update.cpp
src/dpp/events/channel_create.cpp
src/dpp/events/channel_delete.cpp
src/dpp/events/channel_pins_update.cpp
src/dpp/events/channel_update.cpp
src/dpp/events/guild_ban_add.cpp
src/dpp/events/guild_ban_remove.cpp
src/dpp/events/guild_create.cpp
src/dpp/events/guild_delete.cpp
src/dpp/events/guild_emojis_update.cpp
src/dpp/events/guild_integrations_update.cpp
src/dpp/events/guild_join_request_delete.cpp
src/dpp/events/guild_member_add.cpp
src/dpp/events/guild_member_remove.cpp
src/dpp/events/guild_member_update.cpp
src/dpp/events/guild_members_chunk.cpp
src/dpp/events/guild_role_create.cpp
src/dpp/events/guild_role_delete.cpp
src/dpp/events/guild_role_update.cpp
src/dpp/events/guild_stickers_update.cpp
src/dpp/events/guild_update.cpp
src/dpp/events/integration_create.cpp
src/dpp/events/integration_delete.cpp
src/dpp/events/integration_update.cpp
src/dpp/events/interaction_create.cpp
src/dpp/events/invite_create.cpp
src/dpp/events/invite_delete.cpp
src/dpp/events/logger.cpp
src/dpp/events/message_create.cpp
src/dpp/events/message_delete.cpp
src/dpp/events/message_delete_bulk.cpp
src/dpp/events/message_reaction_add.cpp
src/dpp/events/message_reaction_remove.cpp
src/dpp/events/message_reaction_remove_all.cpp
src/dpp/events/message_reaction_remove_emoji.cpp
src/dpp/events/message_update.cpp
src/dpp/events/presence_update.cpp
src/dpp/events/ready.cpp
src/dpp/events/resumed.cpp
src/dpp/events/stage_instance_create.cpp
src/dpp/events/stage_instance_delete.cpp
src/dpp/events/thread_create.cpp
src/dpp/events/thread_delete.cpp
src/dpp/events/thread_list_sync.cpp
src/dpp/events/thread_member_update.cpp
src/dpp/events/thread_members_update.cpp
src/dpp/events/thread_update.cpp
src/dpp/events/typing_start.cpp
src/dpp/events/user_update.cpp
src/dpp/events/voice_server_update.cpp
src/dpp/events/voice_state_update.cpp
src/dpp/events/webhooks_update.cpp
src/dpp/events/application_command_create.cpp
src/dpp/events/application_command_delete.cpp
)
# Configure include folders
target_include_directories(DPP PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src)
target_include_directories(DPP PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/dpp)
target_include_directories(DPP PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
# Link to built-in third-party libraries
target_link_libraries(DPP PUBLIC fmt::fmt)
# Project defines
target_compile_definitions(DPP PUBLIC DPP_BUILD=1)
# Platform defines
if(WIN32)
target_compile_definitions(DPP PRIVATE _WIN32_WINNT=0x0601 OPENSSL_SYS_WIN32=1 _WINSOCK_DEPRECATED_NO_WARNINGS=1 WIN32_LEAN_AND_MEAN=1 _CRT_SECURE_NO_WARNINGS=1 _CRT_NONSTDC_NO_DEPRECATE=1)
if (MINGW)
target_compile_definitions(DPP PUBLIC WIN32=1)
endif()
target_link_libraries(DPP PRIVATE Crypt32)
endif()
# Third-party library preferences
set(THREADS_PREFER_PTHREAD_FLAG ON)
# Find required third-party libraries
find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)
find_package(OpenSSL REQUIRED)
# Link to required third-party libraries
target_link_libraries(DPP PUBLIC Threads::Threads ZLIB::ZLIB OpenSSL::Crypto OpenSSL::SSL)
# Include the custom module folder
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake/")
# Enable voice support in discord library
if (ENABLE_DISCORD_VOICE)
# Look for sodium and opus libraries
include("cmake/FindSodium.cmake")
include("cmake/FindOpus.cmake")
# Was the opus library found?
if(DEFINED OPUS_FOUND)
message(STATUS "Opus library was found")
# Link to opus library
target_include_directories(DPP PUBLIC ${OPUS_INCLUDE_DIRS})
target_link_libraries(DPP PUBLIC ${OPUS_LIBRARIES})
# Was the sodium library found?
if(DEFINED sodium_VERSION_STRING)
message(STATUS "Sodium library was found")
message(STATUS "DPP voice support enabled")
# Let the code know about this
target_compile_definitions(DPP PRIVATE HAVE_VOICE=1)
# Link to sodium library
target_include_directories(DPP PUBLIC ${sodium_INCLUDE_DIR})
target_link_libraries(DPP PUBLIC ${sodium_LIBRARY_RELEASE})
endif()
endif()
endif()
-201
View File
@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Some files were not shown because too many files have changed in this diff Show More