1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-21 17:47:13 +02:00

Various minor changes and fixes that were not pushed to the repository. Just random stuff.

This commit is contained in:
Sandu Liviu Catalin
2019-01-29 18:44:55 +02:00
parent c516c53bd3
commit 0f0b795ca9
10 changed files with 314 additions and 154 deletions

View File

@ -52,7 +52,7 @@ template <class C,class R> struct SqMemberProxy {
M* methodPtr;
sq_getuserdata(vm, -1, reinterpret_cast<SQUserPointer*>(&methodPtr), nullptr);
M method = *methodPtr;
R ret = (inst->*method)(a...);
R ret = (inst->*method)(std::forward< A >(a)...);
PushVar(vm, ret);
});
return 1;
@ -64,7 +64,7 @@ template <class C,class R> struct SqMemberProxy {
M* methodPtr;
sq_getuserdata(vm, -1, reinterpret_cast<SQUserPointer*>(&methodPtr), nullptr);
M method = *methodPtr;
R ret = (inst->*method)(a...);
R ret = (inst->*method)(std::forward< A >(a)...);
PushVar(vm, ret);
});
return 1;
@ -83,7 +83,7 @@ template <class C, class R> struct SqMemberProxy<C,R&> {
M* methodPtr;
sq_getuserdata(vm, -1, reinterpret_cast<SQUserPointer*>(&methodPtr), nullptr);
M method = *methodPtr;
R& ret = (inst->*method)(a...);
R& ret = (inst->*method)(std::forward< A >(a)...);
PushVarR(vm, ret);
});
return 1;
@ -95,7 +95,7 @@ template <class C, class R> struct SqMemberProxy<C,R&> {
M* methodPtr;
sq_getuserdata(vm, -1, reinterpret_cast<SQUserPointer*>(&methodPtr), nullptr);
M method = *methodPtr;
R& ret = (inst->*method)(a...);
R& ret = (inst->*method)(std::forward< A >(a)...);
PushVarR(vm, ret);
});
return 1;
@ -114,7 +114,7 @@ template <class C> struct SqMemberProxy<C, void> {
M* methodPtr;
sq_getuserdata(vm, -1, reinterpret_cast<SQUserPointer*>(&methodPtr), nullptr);
M method = *methodPtr;
(inst->*method)(a...);
(inst->*method)(std::forward< A >(a)...);
});
return 0;
}
@ -125,7 +125,7 @@ template <class C> struct SqMemberProxy<C, void> {
M* methodPtr;
sq_getuserdata(vm, -1, reinterpret_cast<SQUserPointer*>(&methodPtr), nullptr);
M method = *methodPtr;
(inst->*method)(a...);
(inst->*method)(std::forward< A >(a)...);
});
return 0;
}

View File

@ -682,6 +682,32 @@ struct Var<Object&> : Var<Object> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Obje
template<>
struct Var<const Object&> : Var<Object> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Object>(vm, idx) {}};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Create a script object from the specified value on the default VM.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template < typename T > Object MakeObject(const T & v)
{
// Remember the current stack size
const StackGuard sg;
// Transform the specified value into a script object
PushVar< T >(DefaultVM::Get(), v);
// Get the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Create a script object from the specified value on the specified VM.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template < typename T > Object MakeObject(HSQUIRRELVM vm, const T & v)
{
// Remember the current stack size
const StackGuard sg;
// Transform the specified value into a script object
PushVar< T >(vm, v);
// Get the object from the stack and return it
return Var< Object >(vm, -1).value;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// A lightweight wrapper arround the Squirrel objects that implements RAII and still remains a POD type.
///
@ -799,6 +825,20 @@ struct LightObj {
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 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 = DefaultVM::Get()) : LightObj(guard.Get(), v) {
guard.Release();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Destructor
///
@ -927,6 +967,45 @@ struct LightObj {
sq_pop(vm,1); // pop table
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Casts the object to a certain C++ type
///
/// \tparam T Type to cast to
///
/// \return A copy of the value of the Object with the given type
///
/// \remarks
/// This function MUST have its Error handled if it occurred.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <class T>
T Cast() const {
HSQUIRRELVM vm = DefaultVM::Get();
sq_pushobject(vm, mObj);
Var<T> v(vm, -1);
sq_pop(vm, 1);
return v.value;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Casts the object to a certain C++ type instance
///
/// \tparam T Type to cast to
///
/// \return A pointer to the value of the Object with the given type
///
/// \remarks
/// This function MUST have its Error handled if it occurred.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <class T>
T * CastI() const {
HSQUIRRELVM vm = DefaultVM::Get();
sq_pushobject(vm, mObj);
Var<T *> v(vm, -1);
sq_pop(vm, 1);
return v.value;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -974,6 +1053,84 @@ struct Var<LightObj&> : Var<LightObj> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<
template<>
struct Var<const LightObj&> : Var<LightObj> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<LightObj>(vm, idx) {}};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Create a script object from the specified value on the default VM.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template < typename T > LightObj MakeLightObj(const T & v)
{
// Remember the current stack size
const StackGuard sg;
// Transform the specified value into a script object
PushVar< T >(DefaultVM::Get(), v);
// Get the object from the stack and return it
return Var< LightObj >(DefaultVM::Get(), -1).value;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Create a script object from the specified value on the specified VM.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template < typename T > LightObj MakeLightObj(HSQUIRRELVM vm, const T & v)
{
// Remember the current stack size
const StackGuard sg;
// Transform the specified value into a script object
PushVar< T >(vm, v);
// Get the object from the stack and return it
return Var< LightObj >(vm, -1).value;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Used to get and push pure script objects to and from the stack as references (HSQOBJECT is always a reference)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<>
struct Var<HSQOBJECT> {
HSQOBJECT value; ///< The actual value of get operations
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Attempts to get the value off the stack at idx as an HSQOBJECT
///
/// \param vm Target VM
/// \param idx Index trying to be read
///
/// \remarks
/// This function MUST have its Error handled if it occurred.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Var(HSQUIRRELVM vm, SQInteger idx) {
if (SQ_FAILED(sq_getstackobj(vm, idx, &value))) {
sq_resetobject(&value);
} else {
sq_addref(vm, &value);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Called by Sqrat::PushVar to put an HSQOBJECT on the stack
///
/// \param vm Target VM
/// \param value Value to push on to the VM's stack
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void push(HSQUIRRELVM vm, const HSQOBJECT& value) {
sq_pushobject(vm, value);
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Used to get and push pure script objects to and from the stack as references (HSQOBJECT is always a reference)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<>
struct Var<HSQOBJECT&> : Var<HSQOBJECT> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<HSQOBJECT>(vm, idx) {}};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Used to get and push pure script objects to and from the stack as references (HSQOBJECT is always a reference)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<>
struct Var<const HSQOBJECT&> : Var<HSQOBJECT> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<HSQOBJECT>(vm, idx) {}};
}
#endif

View File

@ -1554,6 +1554,68 @@ inline SQInteger IndexAbs(SQInteger top, SQInteger idx)
return (idx <= -1) ? (top + idx + 1) : idx;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Hashing utilities.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef const uint8_t * FnvHashData;
static constexpr uint32_t FnvHashSeed32 = 2166136261u;
static constexpr uint32_t FnvHashPrime32 = 16777619u;
// Hash a single byte.
inline uint32_t Fnv1a32(uint8_t byte, uint32_t hash = FnvHashSeed32)
{
return (byte ^ hash) * FnvHashPrime32;
}
// Hash an array of bytes. 32-bit variant.
inline uint32_t FnvHash32(FnvHashData data, size_t size, uint32_t hash = FnvHashSeed32)
{
assert(data);
while (size--)
{
hash = Fnv1a32(*(data++), hash);
}
return hash;
}
static constexpr uint64_t FnvHashSeed64 = 14695981039346656037llu;
static constexpr uint64_t FnvHashPrime64 = 1099511628211llu;
// Hash a single byte.
inline uint64_t Fnv1a64(uint8_t byte, uint64_t hash = FnvHashSeed64)
{
return (byte ^ hash) * FnvHashPrime64;
}
// Hash an array of bytes. 64-bit variant.
inline uint64_t FnvHash64(FnvHashData data, size_t size, uint64_t hash = FnvHashSeed64)
{
assert(data);
while (size--)
{
hash = Fnv1a64(*(data++), hash);
}
return hash;
}
#ifdef _SQ64
static constexpr size_t FnvHashSeed = FnvHashSeed64;
static constexpr size_t FnvHashPrime = FnvHashPrime64;
#else
static constexpr size_t FnvHashSeed = FnvHashSeed32;
static constexpr size_t FnvHashPrime = FnvHashPrime32;
#endif // _SQ64
// Hash a single byte.
inline size_t Fnv1a(uint8_t byte, size_t hash = FnvHashSeed)
{
return (byte ^ hash) * FnvHashPrime;
}
// Hash an array of bytes.
inline size_t FnvHash(const uint8_t * data, size_t size, size_t hash = FnvHashSeed) {
assert(data);
while (size--)
{
hash = Fnv1a(*(data++), hash);
}
return hash;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Helper structure for retrieving a value from the stack as a string or a formatted string.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1648,9 +1710,35 @@ struct StackStrF
StackStrF & operator = (const StackStrF & o) = delete;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Move assignment operator. (disabled)
/// Move assignment operator.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StackStrF & operator = (StackStrF && o) = delete;
StackStrF & operator = (StackStrF && o)
{
if (this != &o)
{
// Release
if (!sq_isnull(mObj))
{
sq_release(mVM ? mVM : DefaultVM::Get(), &mObj);
sq_resetobject(&mObj);
}
// Replicate
mPtr = o.mPtr;
mLen = o.mLen;
mRes = o.mRes;
mObj = o.mObj;
mVM = o.mVM;
mIdx = o.mIdx;
// Own
o.mPtr = _SC("");
o.mLen = 0;
o.mRes = SQ_OK;
o.mVM = nullptr;
o.mIdx = -1;
sq_resetobject(&o.mObj);
}
return *this;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Release any object references.
@ -1771,6 +1859,35 @@ struct StackStrF
}
return mRes;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Compute the hash of the managed string using the FNV-1a algorithm.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
size_t ToHash() const
{
return mLen ? FnvHash(reinterpret_cast< FnvHashData >(mPtr), static_cast< size_t >(mLen) * sizeof(SQChar)) : FnvHashSeed;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Compute the string hash and cache it into the mRes member.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CacheHash()
{
mRes = static_cast< SQInteger >(ToHash());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Retrieve the cached string hash.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
size_t GetHash() const
{
return static_cast< size_t >(mRes);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Compute the hash of the managed string, cashe it then retrieve it.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
size_t HashIt()
{
CacheHash();
return GetHash();
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1818,7 +1935,7 @@ public:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Default constructor.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DeleteGuard(T * ptr)
explicit DeleteGuard(T * ptr)
: m_Ptr(ptr)
{
/* ... */
@ -1830,9 +1947,13 @@ public:
DeleteGuard(const DeleteGuard & o) = delete;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Move constructor. (disabled)
/// Move constructor.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DeleteGuard(DeleteGuard && o) = delete;
DeleteGuard(DeleteGuard && o)
: m_Ptr(o.m_Ptr)
{
o.m_Ptr = nullptr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Destructor.
@ -1878,6 +1999,16 @@ public:
{
m_Ptr = nullptr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Retrieve and release the managed instance.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
T * Grab()
{
T * ptr = m_Ptr;
m_Ptr = nullptr;
return ptr;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////