mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Compare commits
8 Commits
aa3952fd45
...
804a5abb29
Author | SHA1 | Date | |
---|---|---|---|
|
804a5abb29 | ||
|
68551e4466 | ||
|
4618577ae4 | ||
|
2f428962c8 | ||
|
34a78dc166 | ||
|
49df7b75ee | ||
|
0d927f5d72 | ||
|
44243aadd2 |
@ -1049,4 +1049,37 @@ template < class F > SQMOD_NODISCARD inline int32_t ForeachConnectedPlayerUntil(
|
||||
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
|
||||
|
@ -103,7 +103,7 @@ void ThreadPool::Terminate(bool SQ_UNUSED_ARG(shutdown))
|
||||
// Is the item valid?
|
||||
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.reset();
|
||||
@ -126,7 +126,11 @@ void ThreadPool::Process()
|
||||
if (item)
|
||||
{
|
||||
try {
|
||||
item->OnCompleted(); // Allow the item to finish itself
|
||||
// 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());
|
||||
}
|
||||
|
@ -79,8 +79,10 @@ struct ThreadPoolItem
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
|
@ -468,6 +468,16 @@ void CCheckpoint::SetColorA(int32_t a) const
|
||||
// Perform the requested operation
|
||||
_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,
|
||||
@ -517,6 +527,9 @@ void Register_CCheckpoint(HSQUIRRELVM vm)
|
||||
.Prop(_SC("Tag"), &CCheckpoint::GetTag, &CCheckpoint::SetTag)
|
||||
.Prop(_SC("Data"), &CCheckpoint::GetData, &CCheckpoint::SetData)
|
||||
.Prop(_SC("Active"), &CCheckpoint::IsActive)
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
.Prop(_SC("Legacy"), &CCheckpoint::GetLegacyObject)
|
||||
#endif
|
||||
// Core Methods
|
||||
.FmtFunc(_SC("SetTag"), &CCheckpoint::ApplyTag)
|
||||
.Func(_SC("CustomEvent"), &CCheckpoint::CustomEvent)
|
||||
|
@ -320,6 +320,12 @@ public:
|
||||
* Modify the alpha transparency of the managed checkpoint entity.
|
||||
*/
|
||||
void SetColorA(int32_t a) const;
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve legacy object instance for this entity.
|
||||
*/
|
||||
LightObj & GetLegacyObject() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -833,6 +833,16 @@ void CObject::RotateByEulerZ(float z) const
|
||||
// Perform the requested operation
|
||||
_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,
|
||||
@ -883,6 +893,9 @@ void Register_CObject(HSQUIRRELVM vm)
|
||||
.Prop(_SC("Tag"), &CObject::GetTag, &CObject::SetTag)
|
||||
.Prop(_SC("Data"), &CObject::GetData, &CObject::SetData)
|
||||
.Prop(_SC("Active"), &CObject::IsActive)
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
.Prop(_SC("Legacy"), &CObject::GetLegacyObject)
|
||||
#endif
|
||||
// Core Methods
|
||||
.FmtFunc(_SC("SetTag"), &CObject::ApplyTag)
|
||||
.Func(_SC("CustomEvent"), &CObject::CustomEvent)
|
||||
|
@ -499,6 +499,12 @@ public:
|
||||
* Modify the rotation on the z axis of the managed object entity.
|
||||
*/
|
||||
void RotateByEulerZ(float z) const;
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve legacy object instance for this entity.
|
||||
*/
|
||||
LightObj & GetLegacyObject() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -449,6 +449,16 @@ void CPickup::SetPositionZ(float z) const
|
||||
// Perform the requested operation
|
||||
_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,
|
||||
@ -496,6 +506,9 @@ void Register_CPickup(HSQUIRRELVM vm)
|
||||
.Prop(_SC("Tag"), &CPickup::GetTag, &CPickup::SetTag)
|
||||
.Prop(_SC("Data"), &CPickup::GetData, &CPickup::SetData)
|
||||
.Prop(_SC("Active"), &CPickup::IsActive)
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
.Prop(_SC("Legacy"), &CPickup::GetLegacyObject)
|
||||
#endif
|
||||
// Core Methods
|
||||
.FmtFunc(_SC("SetTag"), &CPickup::ApplyTag)
|
||||
.Func(_SC("CustomEvent"), &CPickup::CustomEvent)
|
||||
|
@ -298,6 +298,12 @@ public:
|
||||
* Modify the position on the z axis of the managed pickup entity.
|
||||
*/
|
||||
void SetPositionZ(float z) const;
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve legacy object instance for this entity.
|
||||
*/
|
||||
LightObj & GetLegacyObject() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -2593,7 +2593,16 @@ SQInteger CPlayer::AnnounceEx(HSQUIRRELVM vm)
|
||||
// This function does not return a value
|
||||
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)
|
||||
{
|
||||
@ -2793,6 +2802,9 @@ void Register_CPlayer(HSQUIRRELVM vm)
|
||||
.Prop(_SC("Tag"), &CPlayer::GetTag, &CPlayer::SetTag)
|
||||
.Prop(_SC("Data"), &CPlayer::GetData, &CPlayer::SetData)
|
||||
.Prop(_SC("Active"), &CPlayer::IsActive)
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
.Prop(_SC("Legacy"), &CPlayer::GetLegacyObject)
|
||||
#endif
|
||||
// Core Methods
|
||||
.FmtFunc(_SC("SetTag"), &CPlayer::ApplyTag)
|
||||
.Func(_SC("CustomEvent"), &CPlayer::CustomEvent)
|
||||
|
@ -1101,6 +1101,12 @@ public:
|
||||
* Send a formatted announcement message to the managed player entity.
|
||||
*/
|
||||
static SQInteger AnnounceEx(HSQUIRRELVM vm);
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve legacy object instance for this entity.
|
||||
*/
|
||||
LightObj & GetLegacyObject() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -2015,6 +2015,16 @@ void CVehicle::SetRelativeTurnSpeedZ(float z) const
|
||||
// Perform the requested operation
|
||||
_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,
|
||||
@ -2061,6 +2071,9 @@ void Register_CVehicle(HSQUIRRELVM vm)
|
||||
.Prop(_SC("ID"), &CVehicle::GetID)
|
||||
.Prop(_SC("Tag"), &CVehicle::GetTag, &CVehicle::SetTag)
|
||||
.Prop(_SC("Data"), &CVehicle::GetData, &CVehicle::SetData)
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
.Prop(_SC("Legacy"), &CVehicle::GetLegacyObject)
|
||||
#endif
|
||||
.Prop(_SC("Active"), &CVehicle::IsActive)
|
||||
// Core Methods
|
||||
.FmtFunc(_SC("SetTag"), &CVehicle::ApplyTag)
|
||||
|
@ -942,6 +942,12 @@ public:
|
||||
* Modify the relative turn velocity on the z axis of the managed vehicle entity.
|
||||
*/
|
||||
void SetRelativeTurnSpeedZ(float z) const;
|
||||
#ifdef VCMP_ENABLE_OFFICIAL
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve legacy object instance for this entity.
|
||||
*/
|
||||
LightObj & GetLegacyObject() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -47,9 +47,11 @@ struct CpBaseAction : public ThreadPoolItem
|
||||
~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?
|
||||
if (!mCallback.IsNull())
|
||||
@ -58,6 +60,8 @@ struct CpBaseAction : public ThreadPoolItem
|
||||
}
|
||||
// Unlock the session
|
||||
mInstance->mPending = nullptr;
|
||||
// Don't re-queue
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
|
@ -606,6 +606,15 @@ MySQLConnHnd::MySQLConnHnd(Poco::Data::SessionImpl * session)
|
||||
mPtr = Poco::AnyCast< MYSQL * >(session->getProperty("handle"));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
MySQLConnHnd::MySQLConnHnd(Poco::AutoPtr< Poco::Data::SessionImpl > && session)
|
||||
: MySQLConnHnd()
|
||||
{
|
||||
mSession = std::move(session);
|
||||
// Retrieve the internal handle property
|
||||
mPtr = Poco::AnyCast< MYSQL * >(session->getProperty("handle"));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
MySQLConnHnd::~MySQLConnHnd()
|
||||
{
|
||||
|
@ -268,6 +268,11 @@ public:
|
||||
*/
|
||||
explicit MySQLConnHnd(Poco::Data::SessionImpl * session);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Explicit constructor.
|
||||
*/
|
||||
explicit MySQLConnHnd(Poco::AutoPtr< Poco::Data::SessionImpl > && session);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
|
@ -625,16 +625,16 @@ SQLiteConnHnd::SQLiteConnHnd(Poco::Data::SessionImpl * session)
|
||||
{
|
||||
mSession.assign(session, true);
|
||||
// Retrieve the internal handle property
|
||||
mPtr = Poco::AnyCast< sqlite3 * >(session->getProperty("handle"));
|
||||
mPtr = Poco::AnyCast< sqlite3 * >(mSession->getProperty("handle"));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQLiteConnHnd::SQLiteConnHnd(Poco::AutoPtr< Poco::Data::SessionImpl > && session)
|
||||
: SQLiteConnHnd()
|
||||
{
|
||||
mSession == std::forward< Poco::AutoPtr< Poco::Data::SessionImpl > >(session);
|
||||
mSession = std::move(session);
|
||||
// Retrieve the internal handle property
|
||||
mPtr = Poco::AnyCast< sqlite3 * >(session->getProperty("handle"));
|
||||
mPtr = Poco::AnyCast< sqlite3 * >(mSession->getProperty("handle"));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -1716,6 +1716,15 @@ public:
|
||||
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.
|
||||
*/
|
||||
@ -1724,7 +1733,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Direct handle constructor.
|
||||
*/
|
||||
explicit SQLiteStatement(SQLiteStmtRef s)
|
||||
explicit SQLiteStatement(SQLiteStmtRef s)
|
||||
: m_Handle(std::move(s))
|
||||
{
|
||||
/* ... */
|
||||
|
@ -52,6 +52,46 @@ SQMOD_DECL_TYPENAME(CPickupTn, _SC("CPickup"))
|
||||
SQMOD_DECL_TYPENAME(CPlayerTn, _SC("CPlayer"))
|
||||
SQMOD_DECL_TYPENAME(CVehicleTn, _SC("CVehicle"))
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Used to fetch the legacy entity instance even if a native one was specified.
|
||||
*/
|
||||
template < class T, class U > inline T & GetLgEnt(LightObj & o)
|
||||
{
|
||||
auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag());
|
||||
// Legacy entity type?
|
||||
if (type == StaticClassTypeTag< T >::Get())
|
||||
{
|
||||
return *o.CastI< T >();
|
||||
}
|
||||
// Native entity type?
|
||||
if (type == StaticClassTypeTag< U >::Get())
|
||||
{
|
||||
return *EntityInstSelect< U >(o.CastI< U >()->GetID()).mLgInst;
|
||||
}
|
||||
STHROWF("Invalid entity type");
|
||||
SQ_UNREACHABLE
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Used to fetch the legacy entity identifier even if a native one was specified.
|
||||
*/
|
||||
template < class T, class U > SQMOD_NODISCARD inline int32_t GetLgEntID(LightObj & o)
|
||||
{
|
||||
auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag());
|
||||
// Legacy entity type?
|
||||
if (type == StaticClassTypeTag< T >::Get())
|
||||
{
|
||||
return o.CastI< T >()->mID;
|
||||
}
|
||||
// Native entity type?
|
||||
if (type == StaticClassTypeTag< U >::Get())
|
||||
{
|
||||
return o.CastI< U >()->GetID();
|
||||
}
|
||||
STHROWF("Invalid entity type");
|
||||
SQ_UNREACHABLE
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Entity type enumeration.
|
||||
*/
|
||||
@ -1233,11 +1273,11 @@ void Register_Official_Entity(HSQUIRRELVM vm)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LgClientMessage(StackStrF & msg, LgPlayer & player, int r, int g, int b)
|
||||
{ _Func->SendClientMessage(player.GetIdentifier(), Color4(static_cast< uint8_t >(r), static_cast< uint8_t >(g),
|
||||
static void LgClientMessage(StackStrF & msg, LightObj & player, int r, int g, int b)
|
||||
{ _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 void LgClientMessageWithAlpha(StackStrF & msg, LgPlayer & player, int r, int g, int b, int a)
|
||||
{ _Func->SendClientMessage(player.GetIdentifier(), Color4(static_cast< uint8_t >(r), static_cast< uint8_t >(g),
|
||||
static void LgClientMessageWithAlpha(StackStrF & msg, LightObj & player, int r, int g, int b, int a)
|
||||
{ _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 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),
|
||||
@ -1249,10 +1289,10 @@ static void LgClientMessageToAllWithAlpha(StackStrF & msg, int r, int g, int b,
|
||||
static_cast< uint8_t >(b), static_cast< uint8_t >(a)).GetRGBA();
|
||||
ForeachActivePlayer([&](auto & p) { _Func->SendClientMessage(p.mID, c, "%s", msg.mPtr); });
|
||||
}
|
||||
static void LgGameMessage(StackStrF & msg, LgPlayer & player, int type)
|
||||
{ _Func->SendGameMessage(player.GetIdentifier(), type, msg.mPtr); }
|
||||
static void LgGameMessageAlternate(StackStrF & msg, LgPlayer & player)
|
||||
{ { _Func->SendGameMessage(player.GetIdentifier(), 1, msg.mPtr); } }
|
||||
static void LgGameMessage(StackStrF & msg, LightObj & player, int type)
|
||||
{ _Func->SendGameMessage(GetLgEntID< LgPlayer, CPlayer >(player), type, msg.mPtr); }
|
||||
static void LgGameMessageAlternate(StackStrF & msg, LightObj & player)
|
||||
{ { _Func->SendGameMessage(GetLgEntID< LgPlayer, CPlayer >(player), 1, msg.mPtr); } }
|
||||
static void LgGameMessageToAll(StackStrF & msg, int type)
|
||||
{ _Func->SendGameMessage(-1, type, msg.mPtr); }
|
||||
static void LgGameMessageToAllAlternate(StackStrF & msg)
|
||||
@ -1946,6 +1986,7 @@ void Register_Official_Functions(HSQUIRRELVM vm)
|
||||
.Func(_SC("SetVehiclesForcedRespawnHeight"), LgSetVehiclesForcedRespawnHeight)
|
||||
|
||||
.SquirrelFunc(_SC("FindPlayer"), LgFindPlayer)
|
||||
.SquirrelFunc(_SC("FindPlayerCompat"), LgFindPlayer)
|
||||
.SquirrelFunc(_SC("InPoly"), LgInPoly)
|
||||
|
||||
.SquirrelFunc(_SC("SetAmmuWeapon"), LgSetAmmuWeapon)
|
||||
|
@ -114,7 +114,7 @@ int32_t GetSkinID(StackStrF & name)
|
||||
// Clone the string into an editable version
|
||||
String str(name.mPtr, static_cast< size_t >(name.mLen));
|
||||
// Strip non-alphanumeric characters from the name
|
||||
str.erase(std::remove_if(str.begin(), str.end(), std::function<int(int)>(::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
|
||||
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
|
||||
// See if we still have a valid name after the cleanup
|
||||
|
@ -123,7 +123,7 @@ int32_t GetAutomobileID(StackStrF & name)
|
||||
// Clone the string into an editable version
|
||||
String str(name.mPtr, static_cast< size_t >(name.mLen));
|
||||
// Strip non-alphanumeric characters from the name
|
||||
str.erase(std::remove_if(str.begin(), str.end(), std::function<int(int)>(::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
|
||||
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
|
||||
// See if we still have a valid name after the cleanup
|
||||
|
@ -163,7 +163,7 @@ int32_t GetWeaponID(StackStrF & name)
|
||||
// Clone the string into an editable version
|
||||
String str(name.mPtr, static_cast< size_t >(name.mLen));
|
||||
// Strip non-alphanumeric characters from the name
|
||||
str.erase(std::remove_if(str.begin(), str.end(), std::function<int(int)>(::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
|
||||
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
|
||||
// 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]tubby Shotgun
|
||||
// [S]uicide
|
||||
// Pump action [S]hotgun
|
||||
case 's':
|
||||
// [Sc]rewdriver
|
||||
if (b == 'c') return SQMOD_WEAPON_SCREWDRIVER;
|
||||
@ -337,7 +338,7 @@ int32_t GetWeaponID(StackStrF & name)
|
||||
else if (b == 't') return SQMOD_WEAPON_STUBBY;
|
||||
// [Su]icide
|
||||
else if (b == 'u') return SQMOD_WEAPON_SUICIDE;
|
||||
// Pump action [Sh]otgun
|
||||
// Pump action [Sh]otgun
|
||||
else if (b == 'h') return SQMOD_WEAPON_SHOTGUN;
|
||||
// Default to unknwon
|
||||
else return SQMOD_UNKNOWN;
|
||||
|
@ -71,7 +71,7 @@ static LightObj SQLiteEscapeString(StackStrF & str)
|
||||
// Allocate a memory buffer
|
||||
Buffer b(static_cast< Buffer::SzType >(str.mLen * 2 + 1));
|
||||
// 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 LightObj(b.Get< SQChar >(), -1);
|
||||
}
|
||||
@ -95,7 +95,7 @@ static LightObj SQLiteEscapeStringEx(SQChar spec, StackStrF & str)
|
||||
// Allocate a memory buffer
|
||||
Buffer b(static_cast< Buffer::SzType >(str.mLen * 2 + 1));
|
||||
// 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 LightObj(b.Get< SQChar >(), -1);
|
||||
}
|
||||
@ -201,7 +201,7 @@ SqDataStatement SqDataSession::GetStatement(StackStrF & data)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SqDataRecordSet SqDataSession::GetRecordSet(StackStrF & data)
|
||||
{
|
||||
return SqDataRecordSet(*this, data);
|
||||
return {*this, data};
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -502,24 +502,35 @@ LightObj SqDataSessionPool::GetSq()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LightObj SqDataSessionPool::AsyncExec(StackStrF & sql)
|
||||
{
|
||||
return LightObj{SqTypeIdentity< SqDataAsyncBuilder >{}, SqVM(), get().impl(), sql, false};
|
||||
return LightObj{SqTypeIdentity< SqDataAsyncBuilder >{}, SqVM(), get().impl(), sql, true, false, false};
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LightObj SqDataSessionPool::AsyncQuery(StackStrF & sql)
|
||||
{
|
||||
return LightObj{SqTypeIdentity< SqDataAsyncBuilder >{}, SqVM(), get().impl(), sql, true};
|
||||
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};
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Common session action implementation.
|
||||
* Asynchronous SQLite query execution implementation.
|
||||
*/
|
||||
struct SQLiteAsyncExec : public ThreadPoolItem
|
||||
{
|
||||
using SessionRef = Poco::AutoPtr< Poco::Data::SessionImpl >;
|
||||
// --------------------------------------------------------------------------------------------
|
||||
SessionRef mSession{}; // The connection that will be used by this task.
|
||||
sqlite3 * mConnection{nullptr}; // Raw connection handle.
|
||||
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.
|
||||
@ -530,6 +541,8 @@ struct SQLiteAsyncExec : public ThreadPoolItem
|
||||
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.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -558,8 +571,8 @@ struct SQLiteAsyncExec : public ThreadPoolItem
|
||||
*/
|
||||
SQMOD_NODISCARD bool OnPrepare() override
|
||||
{
|
||||
// Coincidentally, this also dirties the handle time-stamp so it doesn't get collected
|
||||
return mSession->isConnected();
|
||||
// Coincidentally, this also dirties the handle time-stamp so, it doesn't get collected
|
||||
return mConnection->mSession->isConnected();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -570,11 +583,11 @@ struct SQLiteAsyncExec : public ThreadPoolItem
|
||||
{
|
||||
char * err_msg = nullptr;
|
||||
// Attempt to execute the specified query
|
||||
mResult = sqlite3_exec(mConnection, mQueryStr, nullptr, nullptr, &err_msg);
|
||||
mResult = sqlite3_exec(mConnection->Access(), mQueryStr, nullptr, nullptr, &err_msg);
|
||||
// Store changes count
|
||||
if (mResult == SQLITE_OK)
|
||||
{
|
||||
mChanges = sqlite3_changes(mConnection);
|
||||
mChanges = sqlite3_changes(mConnection->Access());
|
||||
}
|
||||
// Check for error message
|
||||
if (err_msg != nullptr)
|
||||
@ -588,25 +601,26 @@ struct SQLiteAsyncExec : public ThreadPoolItem
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
*/
|
||||
void OnCompleted() override
|
||||
SQMOD_NODISCARD bool OnCompleted(bool SQ_UNUSED_ARG(stop)) override
|
||||
{
|
||||
if (mResult == SQLITE_OK)
|
||||
{
|
||||
if (!mResolved.IsNull())
|
||||
{
|
||||
SQLiteConnRef conn_ref{new SQLiteConnHnd(std::move(mSession))};
|
||||
LightObj connection{SqTypeIdentity< SQLiteConnection >{}, SqVM(), conn_ref};
|
||||
mResolved.Execute(connection, mChanges, mQueryObj);
|
||||
LightObj c{SqTypeIdentity< SQLiteConnection >{}, SqVM(), mConnection};
|
||||
mResolved.Execute(c, mCtx, mChanges, mQueryObj);
|
||||
}
|
||||
}
|
||||
else if (!mRejected.IsNull())
|
||||
{
|
||||
SQLiteConnRef conn_ref{new SQLiteConnHnd(std::move(mSession))};
|
||||
LightObj connection{SqTypeIdentity< SQLiteConnection >{}, SqVM(), conn_ref};
|
||||
mRejected.Execute(connection, mResult, mError, mQueryObj);
|
||||
|
||||
LightObj c{SqTypeIdentity< SQLiteConnection >{}, SqVM(), mConnection};
|
||||
mRejected.Execute(c, mCtx, mResult, mError, mQueryObj);
|
||||
}
|
||||
// Finished
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -619,17 +633,329 @@ struct SQLiteAsyncExec : public ThreadPoolItem
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* 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 stmt) noexcept
|
||||
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)
|
||||
, mStmt(stmt)
|
||||
, mExec(exec), mStmt(stmt), mInc(inc)
|
||||
{
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqDataAsyncBuilder::Submit()
|
||||
void SqDataAsyncBuilder::Submit_(LightObj & ctx)
|
||||
{
|
||||
if (mSession.isNull())
|
||||
{
|
||||
@ -644,7 +970,36 @@ void SqDataAsyncBuilder::Submit()
|
||||
// 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
|
||||
{
|
||||
@ -652,12 +1007,12 @@ void SqDataAsyncBuilder::Submit()
|
||||
// Take ownership before any exception can be thrown
|
||||
std::unique_ptr< ThreadPoolItem > task{static_cast< ThreadPoolItem * >(item)};
|
||||
// Populate task information
|
||||
item->mConnection = connection;
|
||||
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->mSession = std::move(mSession);
|
||||
item->mCtx = std::move(ctx);
|
||||
// Submit the task
|
||||
ThreadPool::Get().Enqueue(std::move(task));
|
||||
}
|
||||
@ -961,9 +1316,12 @@ void Register_POCO_Data(HSQUIRRELVM vm, Table &)
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &SqPcSqDataAsyncBuilder::Fn)
|
||||
// Member Methods
|
||||
.Func(_SC("Submit"), &SqDataAsyncBuilder::Submit)
|
||||
.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"),
|
||||
@ -985,8 +1343,10 @@ void Register_POCO_Data(HSQUIRRELVM vm, Table &)
|
||||
// Member Methods
|
||||
.Func(_SC("Get"), &SqDataSessionPool::Get)
|
||||
.Func(_SC("GetSq"), &SqDataSessionPool::GetSq)
|
||||
.Func(_SC("AsyncExec"), &SqDataSessionPool::AsyncExec)
|
||||
.Func(_SC("AsyncQuery"), &SqDataSessionPool::AsyncQuery)
|
||||
.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("GetWithFeature"), &SqDataSessionPool::GetWithFeature)
|
||||
.FmtFunc(_SC("SetFeature"), &SqDataSessionPool::SetFeature)
|
||||
|
@ -1772,15 +1772,25 @@ struct SqDataSessionPool : public SessionPool
|
||||
LightObj GetSq();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create an asynchronus query execution builder.
|
||||
* Create an asynchronous query execution builder.
|
||||
*/
|
||||
LightObj AsyncExec(StackStrF & sql);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create an asynchronus query execution builder.
|
||||
* 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.
|
||||
*/
|
||||
@ -2096,16 +2106,19 @@ struct SqDataAsyncBuilder
|
||||
// --------------------------------------------------------------------------------------------
|
||||
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 mStmt{false}; // Whether this is a query statement or a simple query execution.
|
||||
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 stmt) noexcept;
|
||||
SqDataAsyncBuilder(Poco::Data::SessionImpl * session, StackStrF & sql, bool exec, bool stmt, bool inc) noexcept;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
@ -2135,7 +2148,12 @@ struct SqDataAsyncBuilder
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create the task with the suplied information and submit it to the worker pool.
|
||||
*/
|
||||
void Submit();
|
||||
void Submit() { Submit_(NullLightObj()); }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create the task with the suplied information and submit it to the worker pool.
|
||||
*/
|
||||
void Submit_(LightObj & ctx);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the callback to be executed if the query was resolved.
|
||||
@ -2154,6 +2172,15 @@ struct SqDataAsyncBuilder
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user