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

Rename source to module.

This commit is contained in:
Sandu Liviu Catalin
2020-03-21 23:02:27 +02:00
parent a5c87bae5e
commit c0fd374404
237 changed files with 0 additions and 272718 deletions

923
module/Base/AABB.cpp Normal file
View File

@ -0,0 +1,923 @@
// ------------------------------------------------------------------------------------------------
#include "Base/AABB.hpp"
#include "Base/Sphere.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("AABB"))
// ------------------------------------------------------------------------------------------------
const AABB AABB::NIL = AABB(0, 0);
const AABB AABB::MIN = AABB(-1, -1, -1, 1, 1, 1);
const AABB AABB::MAX = AABB(HUGE_VALF, -HUGE_VALF);
// ------------------------------------------------------------------------------------------------
SQChar AABB::Delim = ',';
// ------------------------------------------------------------------------------------------------
AABB::AABB()
: min(HUGE_VALF), max(-HUGE_VALF)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
AABB::AABB(Value mins, Value maxs)
: min(mins), max(maxs)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
AABB::AABB(Value xv, Value yv, Value zv)
: min(xv, yv, zv)
, max(xv, yv, zv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
AABB::AABB(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax)
: min(xmin, ymin, zmin), max(xmax, ymax, zmax)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
AABB::AABB(const Vector3 & vmin, const Vector3 & vmax)
: min(vmin), max(vmax)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator = (const Vector3 & v)
{
DefineVector3(v);
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator += (const AABB & b)
{
min += b.min;
max += b.max;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator -= (const AABB & b)
{
min -= b.min;
max -= b.max;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator *= (const AABB & b)
{
min *= b.min;
max *= b.max;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator /= (const AABB & b)
{
min /= b.min;
max /= b.max;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator %= (const AABB & b)
{
min %= b.min;
max %= b.max;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator += (Value s)
{
min += s;
max += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator -= (Value s)
{
min -= s;
max -= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator *= (Value s)
{
min *= s;
max *= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator /= (Value s)
{
min /= s;
max /= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator %= (Value s)
{
min %= s;
max %= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator ++ ()
{
++min;
++max;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB & AABB::operator -- ()
{
--min;
--max;
return *this;
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator ++ (int)
{
AABB state(*this);
++min;
++max;
return state;
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator -- (int)
{
AABB state(*this);
--min;
--max;
return state;
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator + (const AABB & b) const
{
return AABB(min + b.min, max + b.max);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator - (const AABB & b) const
{
return AABB(min - b.min, max - b.max);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator * (const AABB & b) const
{
return AABB(min * b.min, max * b.max);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator / (const AABB & b) const
{
return AABB(min / b.min, max / b.max);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator % (const AABB & b) const
{
return AABB(min % b.min, max % b.max);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator + (Value s) const
{
return AABB(min + s, max + s);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator - (Value s) const
{
return AABB(min - s, max - s);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator * (Value s) const
{
return AABB(min * s, max * s);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator / (Value s) const
{
return AABB(min / s, max / s);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator % (Value s) const
{
return AABB(min % s, max % s);
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator + () const
{
return AABB(min.Abs(), max.Abs());
}
// ------------------------------------------------------------------------------------------------
AABB AABB::operator - () const
{
return AABB(-min, -max);
}
// ------------------------------------------------------------------------------------------------
bool AABB::operator == (const AABB & b) const
{
return (min == b.min) && (max == b.max);
}
// ------------------------------------------------------------------------------------------------
bool AABB::operator != (const AABB & b) const
{
return (min != b.min) || (max != b.max);
}
// ------------------------------------------------------------------------------------------------
bool AABB::operator < (const AABB & b) const
{
return (min < b.min) && (max < b.max);
}
// ------------------------------------------------------------------------------------------------
bool AABB::operator > (const AABB & b) const
{
return (min > b.min) && (max > b.max);
}
// ------------------------------------------------------------------------------------------------
bool AABB::operator <= (const AABB & b) const
{
return (min <= b.min) && (max <= b.max);
}
// ------------------------------------------------------------------------------------------------
bool AABB::operator >= (const AABB & b) const
{
return (min >= b.min) && (max >= b.max);
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::Cmp(const AABB & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr AABB::ToString() const
{
return ToStrF("%f,%f,%f,%f,%f,%f", min.x, min.y, min.z, max.x, max.y, max.z);
}
// ------------------------------------------------------------------------------------------------
void AABB::SetStr(SQChar delim, StackStrF & values)
{
DefineAABB(AABB::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void AABB::Clear()
{
min.SetVector3Ex(HUGE_VALF, HUGE_VALF, HUGE_VALF);
max.SetVector3Ex(-HUGE_VALF, -HUGE_VALF, -HUGE_VALF);
}
// ------------------------------------------------------------------------------------------------
void AABB::DefineScalar(Value mins, Value maxs)
{
min.SetVector3Ex(mins, mins, mins);
max.SetVector3Ex(maxs, maxs, maxs);
}
// ------------------------------------------------------------------------------------------------
void AABB::DefineVector3(const Vector3 & point)
{
min = max = point;
}
// ------------------------------------------------------------------------------------------------
void AABB::DefineVector3Ex(Value x, Value y, Value z)
{
min.SetVector3Ex(x, y, z);
max.SetVector3Ex(x, y, z);
}
// ------------------------------------------------------------------------------------------------
void AABB::DefineAllVector3(const Vector3 & nmin, const Vector3 & nmax)
{
min = nmin;
max = nmax;
}
// ------------------------------------------------------------------------------------------------
void AABB::DefineAllVector3Ex(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax)
{
min.SetVector3Ex(xmin, ymin, zmin);
max.SetVector3Ex(xmax, ymax, zmax);
}
// ------------------------------------------------------------------------------------------------
void AABB::DefineAABB(const AABB & box)
{
min = box.min;
max = box.max;
}
// ------------------------------------------------------------------------------------------------
void AABB::DefineSphere(const Sphere & sphere)
{
min = sphere.pos + Vector3(-sphere.rad);
max = sphere.pos + Vector3(sphere.rad);
}
// ------------------------------------------------------------------------------------------------
void AABB::DefineSphereEx(Value x, Value y, Value z, Value r)
{
DefineSphere(Sphere(x, y, z, r));
}
// ------------------------------------------------------------------------------------------------
void AABB::MergeVector3(const Vector3 & point)
{
MergeVector3Ex(point.x, point.y, point.z);
}
// ------------------------------------------------------------------------------------------------
void AABB::MergeVector3Ex(Value x, Value y, Value z)
{
if (x < min.x)
{
min.x = x;
}
if (y < min.y)
{
min.y = y;
}
if (z < min.z)
{
min.z = z;
}
if (x > max.x)
{
max.x = x;
}
if (y > max.y)
{
max.y = y;
}
if (z > max.z)
{
max.z = z;
}
}
// ------------------------------------------------------------------------------------------------
void AABB::MergeAABB(const AABB & box)
{
if (box.min.x < min.x)
{
min.x = box.min.x;
}
if (box.min.y < min.y)
{
min.y = box.min.y;
}
if (box.min.z < min.z)
{
min.z = box.min.z;
}
if (box.max.x > max.x)
{
max.x = box.max.x;
}
if (box.max.y > max.y)
{
max.y = box.max.y;
}
if (box.max.z > max.z)
{
max.z = box.max.z;
}
}
// ------------------------------------------------------------------------------------------------
void AABB::MergeAABBEx(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax)
{
if (xmin < min.x)
{
min.x = xmin;
}
if (ymin < min.y)
{
min.y = ymin;
}
if (zmin < min.z)
{
min.z = zmin;
}
if (xmax > max.x)
{
max.x = xmax;
}
if (ymax > max.y)
{
max.y = ymax;
}
if (zmax > max.z)
{
max.z = zmax;
}
}
// ------------------------------------------------------------------------------------------------
void AABB::MergeSphere(const Sphere & sphere)
{
MergeVector3(sphere.pos + Vector3(sphere.rad));
MergeVector3(sphere.pos + Vector3(-sphere.rad));
}
// ------------------------------------------------------------------------------------------------
void AABB::MergeSphereEx(Value x, Value y, Value z, Value r)
{
MergeSphere(Sphere(x, y, z, r));
}
// ------------------------------------------------------------------------------------------------
bool AABB::Empty() const
{
return (min == max);
}
// ------------------------------------------------------------------------------------------------
bool AABB::Defined() const
{
return min.x != HUGE_VALF;
}
// ------------------------------------------------------------------------------------------------
Vector3 AABB::Center() const
{
return (max + min) * 0.5f;
}
// ------------------------------------------------------------------------------------------------
Vector3 AABB::Size() const
{
return max - min;
}
// ------------------------------------------------------------------------------------------------
Vector3 AABB::HalfSize() const
{
return (max - min) * 0.5f;
}
// ------------------------------------------------------------------------------------------------
AABB::Value AABB::Radius() const
{
return Size().GetLength() / Value(2);
}
// ------------------------------------------------------------------------------------------------
AABB::Value AABB::Volume() const
{
const Vector3 v = Size();
return static_cast< Value >(v.x * v.y * v.z);
}
// ------------------------------------------------------------------------------------------------
AABB::Value AABB::Area() const
{
const Vector3 v = Size();
return static_cast< Value >(Value(2) * (v.x * v.y + v.x * v.z + v.y * v.z));
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsVector3Inside(const Vector3 & point) const
{
return (point.x < min.x || point.x > max.x ||
point.y < min.y || point.y > max.y ||
point.z < min.z || point.z > max.z) ? SQMODI_OUTSIDE : SQMODI_INSIDE;
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsVector3InsideEx(Value x, Value y, Value z) const
{
return (x < min.x || x > max.x ||
y < min.y || y > max.y ||
z < min.z || z > max.z) ? SQMODI_OUTSIDE : SQMODI_INSIDE;
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsAABBInside(const AABB & box) const
{
if (box.max.x < min.x || box.min.x > max.x ||
box.max.y < min.y || box.min.y > max.y ||
box.max.z < min.z || box.min.z > max.z)
{
return SQMODI_OUTSIDE;
}
else if (box.min.x < min.x || box.max.x > max.x ||
box.min.y < min.y || box.max.y > max.y ||
box.min.z < min.z || box.max.z > max.z)
{
return SQMODI_INTERSECTS;
}
else
{
return SQMODI_INSIDE;
}
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsAABBInsideEx(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax) const
{
if (xmax < min.x || xmin > max.x ||
ymax < min.y || ymin > max.y ||
zmax < min.z || zmin > max.z)
{
return SQMODI_OUTSIDE;
}
else if (xmin < min.x || xmax > max.x ||
ymin < min.y || ymax > max.y ||
zmin < min.z || zmax > max.z)
{
return SQMODI_INTERSECTS;
}
else
{
return SQMODI_INSIDE;
}
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsAABBInsideFast(const AABB & box) const
{
if (box.max.x < min.x || box.min.x > max.x ||
box.max.y < min.y || box.min.y > max.y ||
box.max.z < min.z || box.min.z > max.z)
{
return SQMODI_OUTSIDE;
}
else
{
return SQMODI_INSIDE;
}
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsAABBInsideFastEx(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax) const
{
if (xmax < min.x || xmin > max.x ||
ymax < min.y || ymin > max.y ||
zmax < min.z || zmin > max.z)
{
return SQMODI_OUTSIDE;
}
else
{
return SQMODI_INSIDE;
}
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsSphereInside(const Sphere & sphere) const
{
Value dist_squared = 0, temp;
const Vector3 & center = sphere.pos;
if (center.x < min.x)
{
temp = center.x - min.x;
dist_squared += temp * temp;
}
else if (center.x > max.x)
{
temp = center.x - max.x;
dist_squared += temp * temp;
}
if (center.y < min.y)
{
temp = center.y - min.y;
dist_squared += temp * temp;
}
else if (center.y > max.y)
{
temp = center.y - max.y;
dist_squared += temp * temp;
}
if (center.z < min.z)
{
temp = center.z - min.z;
dist_squared += temp * temp;
}
else if (center.z > max.z)
{
temp = center.z - max.z;
dist_squared += temp * temp;
}
const Value radius = sphere.rad;
if (dist_squared >= radius * radius)
{
return SQMODI_OUTSIDE;
}
else if (center.x - radius < min.x || center.x + radius > max.x || center.y - radius < min.y ||
center.y + radius > max.y || center.z - radius < min.z || center.z + radius > max.z)
{
return SQMODI_INTERSECTS;
}
else
{
return SQMODI_INSIDE;
}
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsSphereInsideEx(Value x, Value y, Value z, Value r) const
{
return IsSphereInside(Sphere(x, y, z, r));
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsSphereInsideFast(const Sphere & sphere) const
{
Value dist_squared = 0, temp;
const Vector3& center = sphere.pos;
if (center.x < min.x)
{
temp = center.x - min.x;
dist_squared += temp * temp;
}
else if (center.x > max.x)
{
temp = center.x - max.x;
dist_squared += temp * temp;
}
if (center.y < min.y)
{
temp = center.y - min.y;
dist_squared += temp * temp;
}
else if (center.y > max.y)
{
temp = center.y - max.y;
dist_squared += temp * temp;
}
if (center.z < min.z)
{
temp = center.z - min.z;
dist_squared += temp * temp;
}
else if (center.z > max.z)
{
temp = center.z - max.z;
dist_squared += temp * temp;
}
const Value radius = sphere.rad;
if (dist_squared >= radius * radius)
{
return SQMODI_OUTSIDE;
}
else
{
return SQMODI_INSIDE;
}
}
// ------------------------------------------------------------------------------------------------
Int32 AABB::IsSphereInsideFastEx(Value x, Value y, Value z, Value r) const
{
return IsSphereInsideFast(Sphere(x, y, z, r));
}
// ------------------------------------------------------------------------------------------------
const AABB & AABB::Get(StackStrF & str)
{
return AABB::GetEx(AABB::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const AABB & AABB::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %f , %f , %f , %f , %f , %f ");
static AABB box;
// Clear previous values, if any
box.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return box; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
fs[9] = delim;
fs[14] = delim;
fs[19] = delim;
fs[24] = delim;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, fs, &box.min.x, &box.min.y, &box.min.z, &box.max.x, &box.max.y, &box.max.z);
// Return the resulted value
return box;
}
// ------------------------------------------------------------------------------------------------
const AABB & GetAABB()
{
static AABB box;
box.Clear();
return box;
}
// ------------------------------------------------------------------------------------------------
const AABB & GetAABB(Float32 mins, Float32 maxs)
{
static AABB box;
box.DefineScalar(mins, maxs);
return box;
}
// ------------------------------------------------------------------------------------------------
const AABB & GetAABB(Float32 xv, Float32 yv, Float32 zv)
{
static AABB box;
box.DefineVector3Ex(xv, yv, zv);
return box;
}
// ------------------------------------------------------------------------------------------------
const AABB & GetAABB(Float32 xmin, Float32 ymin, Float32 zmin, Float32 xmax, Float32 ymax, Float32 zmax)
{
static AABB box;
box.DefineAllVector3Ex(xmin, ymin, zmin, xmax, ymax, zmax);
return box;
}
// ------------------------------------------------------------------------------------------------
const AABB & GetAABB(const Vector3 & vmin, const Vector3 & vmax)
{
static AABB box;
box.DefineAllVector3(vmin, vmax);
return box;
}
// ------------------------------------------------------------------------------------------------
const AABB & GetAABB(const AABB & o)
{
static AABB box;
box.DefineAABB(o);
return box;
}
// ================================================================================================
void Register_AABB(HSQUIRRELVM vm)
{
typedef AABB::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< AABB >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< const AABB & >()
.Ctor< Val, Val, Val >()
.Ctor< Val, Val, Val, Val, Val, Val >()
.Ctor< const Vector3 &, const Vector3 & >()
// Member Variables
.Var(_SC("min"), &AABB::min)
.Var(_SC("max"), &AABB::max)
.Var(_SC("Min"), &AABB::min)
.Var(_SC("Max"), &AABB::max)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &AABB::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< AABB >, SQFloat, SQInteger, bool, std::nullptr_t, AABB >)
.Func< AABB (AABB::*)(void) const >(_SC("_unm"), &AABB::operator -)
// Properties
.Prop(_SC("Empty"), &AABB::Empty)
.Prop(_SC("Defined"), &AABB::Defined)
.Prop(_SC("Center"), &AABB::Center)
.Prop(_SC("Size"), &AABB::Size)
.Prop(_SC("Extent"), &AABB::Size)
.Prop(_SC("HalfSize"), &AABB::HalfSize)
.Prop(_SC("HalfExtent"), &AABB::HalfSize)
.Prop(_SC("Radius"), &AABB::Radius)
.Prop(_SC("Volume"), &AABB::Volume)
.Prop(_SC("Area"), &AABB::Area)
// Member Methods
.FmtFunc(_SC("SetStr"), &AABB::SetStr)
.Func(_SC("Clear"), &AABB::Clear)
.Func(_SC("DefineScalar"), &AABB::DefineScalar)
.Func(_SC("DefineVector3"), &AABB::DefineVector3)
.Func(_SC("DefineVector3Ex"), &AABB::DefineVector3Ex)
.Func(_SC("DefineAllVector3"), &AABB::DefineAllVector3)
.Func(_SC("DefineAllVector3Ex"), &AABB::DefineAllVector3Ex)
.Func(_SC("DefineAABB"), &AABB::DefineAABB)
.Func(_SC("DefineSphere"), &AABB::DefineSphere)
.Func(_SC("DefineSphereEx"), &AABB::DefineSphereEx)
.Func(_SC("MergeVector3"), &AABB::MergeVector3)
.Func(_SC("MergeVector3Ex"), &AABB::MergeVector3Ex)
.Func(_SC("MergeAABB"), &AABB::MergeAABB)
.Func(_SC("MergeAABBEx"), &AABB::MergeAABBEx)
.Func(_SC("MergeSphere"), &AABB::MergeSphere)
.Func(_SC("MergeSphereEx"), &AABB::MergeSphereEx)
.Func(_SC("IsVector3Inside"), &AABB::IsVector3Inside)
.Func(_SC("IsVector3InsideEx"), &AABB::IsVector3InsideEx)
.Func(_SC("IsAABBInside"), &AABB::IsAABBInside)
.Func(_SC("IsAABBInsideEx"), &AABB::IsAABBInsideEx)
.Func(_SC("IsAABBInsideFast"), &AABB::IsAABBInsideFast)
.Func(_SC("IsAABBInsideFastEx"), &AABB::IsAABBInsideFastEx)
.Func(_SC("IsSphereInside"), &AABB::IsSphereInside)
.Func(_SC("IsSphereInsideEx"), &AABB::IsSphereInsideEx)
.Func(_SC("IsSphereInsideFast"), &AABB::IsSphereInsideFast)
.Func(_SC("IsSphereInsideFastEx"), &AABB::IsSphereInsideFastEx)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< AABB >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< AABB >)
.StaticFmtFunc(_SC("FromStr"), &AABB::Get)
.StaticFmtFunc(_SC("FromStrEx"), &AABB::GetEx)
// Operator Exposure
.Func< AABB & (AABB::*)(const AABB &) >(_SC("opAddAssign"), &AABB::operator +=)
.Func< AABB & (AABB::*)(const AABB &) >(_SC("opSubAssign"), &AABB::operator -=)
.Func< AABB & (AABB::*)(const AABB &) >(_SC("opMulAssign"), &AABB::operator *=)
.Func< AABB & (AABB::*)(const AABB &) >(_SC("opDivAssign"), &AABB::operator /=)
.Func< AABB & (AABB::*)(const AABB &) >(_SC("opModAssign"), &AABB::operator %=)
.Func< AABB & (AABB::*)(AABB::Value) >(_SC("opAddAssignS"), &AABB::operator +=)
.Func< AABB & (AABB::*)(AABB::Value) >(_SC("opSubAssignS"), &AABB::operator -=)
.Func< AABB & (AABB::*)(AABB::Value) >(_SC("opMulAssignS"), &AABB::operator *=)
.Func< AABB & (AABB::*)(AABB::Value) >(_SC("opDivAssignS"), &AABB::operator /=)
.Func< AABB & (AABB::*)(AABB::Value) >(_SC("opModAssignS"), &AABB::operator %=)
.Func< AABB & (AABB::*)(void) >(_SC("opPreInc"), &AABB::operator ++)
.Func< AABB & (AABB::*)(void) >(_SC("opPreDec"), &AABB::operator --)
.Func< AABB (AABB::*)(int) >(_SC("opPostInc"), &AABB::operator ++)
.Func< AABB (AABB::*)(int) >(_SC("opPostDec"), &AABB::operator --)
.Func< AABB (AABB::*)(const AABB &) const >(_SC("opAdd"), &AABB::operator +)
.Func< AABB (AABB::*)(const AABB &) const >(_SC("opSub"), &AABB::operator -)
.Func< AABB (AABB::*)(const AABB &) const >(_SC("opMul"), &AABB::operator *)
.Func< AABB (AABB::*)(const AABB &) const >(_SC("opDiv"), &AABB::operator /)
.Func< AABB (AABB::*)(const AABB &) const >(_SC("opMod"), &AABB::operator %)
.Func< AABB (AABB::*)(AABB::Value) const >(_SC("opAddS"), &AABB::operator +)
.Func< AABB (AABB::*)(AABB::Value) const >(_SC("opSubS"), &AABB::operator -)
.Func< AABB (AABB::*)(AABB::Value) const >(_SC("opMulS"), &AABB::operator *)
.Func< AABB (AABB::*)(AABB::Value) const >(_SC("opDivS"), &AABB::operator /)
.Func< AABB (AABB::*)(AABB::Value) const >(_SC("opModS"), &AABB::operator %)
.Func< AABB (AABB::*)(void) const >(_SC("opUnPlus"), &AABB::operator +)
.Func< AABB (AABB::*)(void) const >(_SC("opUnMinus"), &AABB::operator -)
.Func< bool (AABB::*)(const AABB &) const >(_SC("opEqual"), &AABB::operator ==)
.Func< bool (AABB::*)(const AABB &) const >(_SC("opNotEqual"), &AABB::operator !=)
.Func< bool (AABB::*)(const AABB &) const >(_SC("opLessThan"), &AABB::operator <)
.Func< bool (AABB::*)(const AABB &) const >(_SC("opGreaterThan"), &AABB::operator >)
.Func< bool (AABB::*)(const AABB &) const >(_SC("opLessEqual"), &AABB::operator <=)
.Func< bool (AABB::*)(const AABB &) const >(_SC("opGreaterEqual"), &AABB::operator >=)
);
}
} // Namespace:: SqMod

483
module/Base/AABB.hpp Normal file
View File

@ -0,0 +1,483 @@
#ifndef _BASE_AABB_HPP_
#define _BASE_AABB_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Vector3.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent an axis aligned bounding box in three-dimensional space.
*/
struct AABB
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef float Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const AABB NIL;
static const AABB MIN;
static const AABB MAX;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The minimum and maximum components of this type.
*/
Vector3 min, max;
/* --------------------------------------------------------------------------------------------
* Construct with zero size.
*/
AABB();
/* --------------------------------------------------------------------------------------------
* Construct a an equally sized and perfectly shaped box from scalar values.
*/
explicit AABB(Value mins, Value maxs);
/* --------------------------------------------------------------------------------------------
* Construct a an equally sized but imperfectly shaped box from individual components of a
* three-dimensional point.
*/
AABB(Value xv, Value yv, Value zv);
/* --------------------------------------------------------------------------------------------
* Construct a an unequally sized and imperfectly shaped box from individual components of two
* three-dimensional points.
*/
AABB(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax);
/* --------------------------------------------------------------------------------------------
* Construct a an unequally sized and imperfectly shaped box from two three-dimensional
* vectors representing two three-dimensional points.
*/
AABB(const Vector3 & vmin, const Vector3 & vmax);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
AABB(const AABB & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
AABB(AABB && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~AABB() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
AABB & operator = (const AABB & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
AABB & operator = (AABB && o) = default;
/* --------------------------------------------------------------------------------------------
* Three-dimensional vector assignment operator.
*/
AABB & operator = (const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
AABB & operator += (const AABB & b);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
AABB & operator -= (const AABB & b);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
AABB & operator *= (const AABB & b);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
AABB & operator /= (const AABB & b);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
AABB & operator %= (const AABB & b);
/* --------------------------------------------------------------------------------------------
* Scalar value addition assignment operator.
*/
AABB & operator += (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction assignment operator.
*/
AABB & operator -= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication assignment operator.
*/
AABB & operator *= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value division assignment operator.
*/
AABB & operator /= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value modulo assignment operator.
*/
AABB & operator %= (Value s);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
AABB & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
AABB & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
AABB operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
AABB operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
AABB operator + (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
AABB operator - (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
AABB operator * (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
AABB operator / (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
AABB operator % (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Scalar value addition operator.
*/
AABB operator + (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction operator.
*/
AABB operator - (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication operator.
*/
AABB operator * (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value division operator.
*/
AABB operator / (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value modulo operator.
*/
AABB operator % (Value s) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
AABB operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
AABB operator - () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const AABB & b) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(AABB(s, s, s, s, s, s));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
const Value v = static_cast< Value >(s);
return Cmp(AABB(v, v, v, v, v, v));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
const Value v = static_cast< Value >(s);
return Cmp(AABB(v, v, v, v, v, v));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
const Value v = static_cast< Value >(0);
return Cmp(AABB(v, v, v, v, v, v));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & values);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear();
/* --------------------------------------------------------------------------------------------
* Define from minimum and maximum floats (all dimensions same).
*/
void DefineScalar(Value mins, Value maxs);
/* --------------------------------------------------------------------------------------------
* Define from a point.
*/
void DefineVector3(const Vector3 & point);
/* --------------------------------------------------------------------------------------------
* Define from a point.
*/
void DefineVector3Ex(Value x, Value y, Value z);
/* --------------------------------------------------------------------------------------------
* Define from minimum and maximum vectors.
*/
void DefineAllVector3(const Vector3 & nmin, const Vector3 & nmax);
/* --------------------------------------------------------------------------------------------
* Define from minimum and maximum vectors.
*/
void DefineAllVector3Ex(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax);
/* --------------------------------------------------------------------------------------------
* Define from another bounding box.
*/
void DefineAABB(const AABB & box);
/* --------------------------------------------------------------------------------------------
* Define from a sphere.
*/
void DefineSphere(const Sphere & sphere);
/* --------------------------------------------------------------------------------------------
* Define from a sphere.
*/
void DefineSphereEx(Value x, Value y, Value z, Value r);
/* --------------------------------------------------------------------------------------------
* Merge a point into this bounding box.
*/
void MergeVector3(const Vector3 & point);
/* --------------------------------------------------------------------------------------------
* Merge a point into this bounding box.
*/
void MergeVector3Ex(Value x, Value y, Value z);
/* --------------------------------------------------------------------------------------------
* Merge another bounding box into this bounding box.
*/
void MergeAABB(const AABB & box);
/* --------------------------------------------------------------------------------------------
* Merge another bounding box into this bounding box.
*/
void MergeAABBEx(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax);
/* --------------------------------------------------------------------------------------------
* Merge a sphere into this bounding box.
*/
void MergeSphere(const Sphere & sphere);
/* --------------------------------------------------------------------------------------------
* Merge a sphere into this bounding box.
*/
void MergeSphereEx(Value x, Value y, Value z, Value r);
/* --------------------------------------------------------------------------------------------
* Check if the box is empty. This means that there is no space between the min and max edge.
*/
bool Empty() const;
/* --------------------------------------------------------------------------------------------
* Return true if this bounding box is defined via a previous call to Define() or Merge().
*/
bool Defined() const;
/* --------------------------------------------------------------------------------------------
* Return center.
*/
Vector3 Center() const;
/* --------------------------------------------------------------------------------------------
* Get size/extent of the box (maximal distance of two points in the box).
*/
Vector3 Size() const;
/* --------------------------------------------------------------------------------------------
* Return half-size.
*/
Vector3 HalfSize() const;
/* --------------------------------------------------------------------------------------------
* Get radius of the bounding sphere.
*/
Value Radius() const;
/* --------------------------------------------------------------------------------------------
* Get the volume enclosed by the box in cubed units.
*/
Value Volume() const;
/* --------------------------------------------------------------------------------------------
* Get the surface area of the box in squared units.
*/
Value Area() const;
/* --------------------------------------------------------------------------------------------
* Test if a point is inside.
*/
Int32 IsVector3Inside(const Vector3 & point) const;
/* --------------------------------------------------------------------------------------------
* Test if a point is inside.
*/
Int32 IsVector3InsideEx(Value x, Value y, Value z) const;
/* --------------------------------------------------------------------------------------------
* Test if another bounding box is inside, outside or intersects.
*/
Int32 IsAABBInside(const AABB & box) const;
/* --------------------------------------------------------------------------------------------
* Test if another bounding box is inside, outside or intersects.
*/
Int32 IsAABBInsideEx(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax) const;
/* --------------------------------------------------------------------------------------------
* Test if another bounding box is (partially) inside or outside.
*/
Int32 IsAABBInsideFast(const AABB & box) const;
/* --------------------------------------------------------------------------------------------
* Test if another bounding box is (partially) inside or outside.
*/
Int32 IsAABBInsideFastEx(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax) const;
/* --------------------------------------------------------------------------------------------
* Test if a sphere is inside, outside or intersects.
*/
Int32 IsSphereInside(const Sphere & sphere) const;
/* --------------------------------------------------------------------------------------------
* Test if a sphere is inside, outside or intersects.
*/
Int32 IsSphereInsideEx(Value x, Value y, Value z, Value r) const;
/* --------------------------------------------------------------------------------------------
* Test if a sphere is (partially) inside or outside.
*/
Int32 IsSphereInsideFast(const Sphere & sphere) const;
/* --------------------------------------------------------------------------------------------
* Test if a sphere is (partially) inside or outside.
*/
Int32 IsSphereInsideFastEx(Value x, Value y, Value z, Value r) const;
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the AABB type from a string.
*/
static const AABB & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the AABB type from a string.
*/
static const AABB & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_AABB_HPP_

612
module/Base/Buffer.cpp Normal file
View File

@ -0,0 +1,612 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Buffer.hpp"
#include "sqrat/sqratUtil.h"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
#include <cstring>
#include <exception>
#include <stdexcept>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Compute the next power of two for the specified number.
*/
inline unsigned int NextPow2(unsigned int num)
{
--num;
num |= num >> 1;
num |= num >> 2;
num |= num >> 4;
num |= num >> 8;
num |= num >> 16;
return ++num;
}
/* ------------------------------------------------------------------------------------------------
* Throw an memory exception.
*/
void ThrowMemExcept(const char * msg, ...)
{
// Exception messages should be concise
SQChar buffer[256];
// Variable arguments structure
va_list args;
// Get the specified arguments
va_start(args, msg);
// Run the specified format
int ret = std::vsnprintf(buffer, sizeof(buffer), msg, args);
// Check for formatting errors
if (ret < 0)
{
throw Sqrat::Exception(_SC("Unknown memory error"));
}
// Throw the actual exception
throw Sqrat::Exception(buffer);
}
/* ------------------------------------------------------------------------------------------------
* Allocate a memory buffer and return it.
*/
static Buffer::Pointer AllocMem(Buffer::SzType size)
{
// Attempt to allocate memory directly
Buffer::Pointer ptr = reinterpret_cast< Buffer::Pointer >(std::malloc(size));
// Validate the allocated memory
if (!ptr)
{
ThrowMemExcept("Unable to allocate (%u) bytes of memory", size);
}
// Return the allocated memory
return ptr;
}
/* ------------------------------------------------------------------------------------------------
* ...
*/
class MemCat
{
// --------------------------------------------------------------------------------------------
friend class Memory;
friend class Buffer;
public:
// --------------------------------------------------------------------------------------------
typedef Buffer::Value Value; // The type of value used to represent a byte.
// --------------------------------------------------------------------------------------------
typedef Buffer::Reference Reference; // A reference to the stored value type.
typedef Buffer::ConstRef ConstRef; // A const reference to the stored value type.
// --------------------------------------------------------------------------------------------
typedef Buffer::Pointer Pointer; // A pointer to the stored value type.
typedef Buffer::ConstPtr ConstPtr; // A const pointer to the stored value type.
// --------------------------------------------------------------------------------------------
typedef Buffer::SzType SzType; // The type used to represent size in general.
private:
/* --------------------------------------------------------------------------------------------
* Structure used to store a memory chunk in the linked list.
*/
struct Node
{
// ----------------------------------------------------------------------------------------
SzType mCap; // The size of the memory chunk.
Pointer mPtr; // Pointer to the memory chunk.
Node* mNext; // The next node in the list.
/* ----------------------------------------------------------------------------------------
* Base constructor.
*/
Node(Node * next)
: mCap(0)
, mPtr(nullptr)
, mNext(next)
{
/* ... */
}
};
// --------------------------------------------------------------------------------------------
static Node * s_Nodes; /* List of unused node instances. */
// --------------------------------------------------------------------------------------------
Node* m_Head; /* The head memory node. */
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
MemCat()
: m_Head(nullptr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~MemCat()
{
for (Node * node = m_Head, * next = nullptr; node; node = next)
{
// Free the memory (if any)
if (node->mPtr)
{
std::free(node->mPtr);
}
// Save the next node
next = node->mNext;
// Release the node instance
delete node;
}
// Explicitly set the head node to null
m_Head = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Clear all memory buffers from the pool.
*/
void Clear()
{
for (Node * node = m_Head, * next = nullptr; node; node = next)
{
// Free the memory (if any)
if (node->mPtr)
{
free(node->mPtr);
}
// Save the next node
next = node->mNext;
// Release the node instance
Push(node);
}
// Explicitly set the head node to null
m_Head = nullptr;
}
/* --------------------------------------------------------------------------------------------
* Grab a memory buffer from the pool.
*/
void Grab(Pointer & ptr, SzType & size)
{
// NOTE: Function assumes (size > 0)
// Find a buffer large enough to satisfy the requested size
for (Node * node = m_Head, * prev = nullptr; node; prev = node, node = node->mNext)
{
// Is this buffer large enough?
if (node->mCap >= size)
{
// Was there a previous node?
if (prev)
{
prev->mNext = node->mNext;
}
// Probably this was the head
else
{
m_Head = node->mNext;
}
// Assign the memory
ptr = node->mPtr;
// Assign the size
size = node->mCap;
// Release the node instance
Push(node);
// Exit the function
return;
}
}
// Round up the size to a power of two number
size = (size & (size - 1)) ? NextPow2(size) : size;
// Allocate the memory directly
ptr = AllocMem(size);
// See if the memory could be allocated
// (shouldn't reach this point if allocation failed)
if (!ptr)
{
// Revert the size
size = 0;
// Throw the exception
ThrowMemExcept("Unable to allocate (%u) bytes of memory", size);
}
}
/* --------------------------------------------------------------------------------------------
* Return a memory buffer to the pool.
*/
void Drop(Pointer & ptr, SzType & size)
{
if (!ptr)
{
ThrowMemExcept("Cannot store invalid memory buffer");
}
// Request a node instance
Node * node = Pull();
// Assign the specified memory
node->mPtr = ptr;
// Assign the specified size
node->mCap = size;
// Demote the current head node
node->mNext = m_Head;
// Promote as the head node
m_Head = node;
}
/* --------------------------------------------------------------------------------------------
* Allocate a group of nodes and pool them for later use.
*/
static void Make()
{
for (SzType n = 16; n; --n)
{
// Create a new node instance
s_Nodes = new Node(s_Nodes);
// Validate the head node
if (!s_Nodes)
{
ThrowMemExcept("Unable to allocate memory nodes");
}
}
}
/* --------------------------------------------------------------------------------------------
* Retrieve an unused node from the free list.
*/
static Node * Pull()
{
// Are there any nodes available?
if (!s_Nodes)
{
Make(); // Make some!
}
// Grab the head node
Node * node = s_Nodes;
// Promote the next node as the head
s_Nodes = node->mNext;
// Return the node
return node;
}
/* --------------------------------------------------------------------------------------------
* Return a node to the free list.
*/
static void Push(Node * node)
{
// See if the node is even valid
if (!node)
{
ThrowMemExcept("Attempting to push invalid node");
}
// Demote the current head node
node->mNext = s_Nodes;
// Promote as the head node
s_Nodes = node;
}
};
// ------------------------------------------------------------------------------------------------
MemCat::Node * MemCat::s_Nodes = nullptr;
/* ------------------------------------------------------------------------------------------------
* Lightweight memory allocator to reduce the overhead of small allocations.
*/
class Memory
{
// --------------------------------------------------------------------------------------------
friend class Buffer; // Allow the buffer type to access the memory categories.
friend class MemRef; // Allow the memory manager reference to create new instances.
private:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Memory()
: m_Small()
, m_Medium()
, m_Large()
{
// Allocate several nodes for when memory starts pooling
MemCat::Make();
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Memory()
{
for (MemCat::Node * node = MemCat::s_Nodes, * next = nullptr; node; node = next)
{
// Save the next node
next = node->mNext;
// Release the node instance
delete node;
}
// Explicitly set the head node to null
MemCat::s_Nodes = nullptr;
}
private:
// --------------------------------------------------------------------------------------------
MemCat m_Small; // Small memory allocations of <= 1024 bytes.
MemCat m_Medium; // Medium memory allocations of <= 4096 bytes.
MemCat m_Large; // Large memory allocations of <= 4096 bytes.
};
// ------------------------------------------------------------------------------------------------
MemRef MemRef::s_Mem;
// ------------------------------------------------------------------------------------------------
void MemRef::Grab()
{
if (m_Ptr)
{
++(*m_Ref);
}
}
// ------------------------------------------------------------------------------------------------
void MemRef::Drop()
{
if (m_Ptr && --(*m_Ref) == 0)
{
delete m_Ptr;
delete m_Ref;
m_Ptr = nullptr;
m_Ref = nullptr;
}
}
// ------------------------------------------------------------------------------------------------
const MemRef & MemRef::Get()
{
if (!s_Mem.m_Ptr)
{
s_Mem.m_Ptr = new Memory();
s_Mem.m_Ref = new Counter(1);
}
return s_Mem;
}
// ------------------------------------------------------------------------------------------------
Buffer::Buffer(const Buffer & o)
: m_Ptr(nullptr)
, m_Cap(o.m_Cap)
, m_Cur(o.m_Cur)
, m_Mem(o.m_Mem)
{
if (m_Cap)
{
Request(o.m_Cap);
std::memcpy(m_Ptr, o.m_Ptr, o.m_Cap);
}
}
// ------------------------------------------------------------------------------------------------
Buffer::~Buffer()
{
// Do we have a buffer?
if (m_Ptr)
{
Release(); // Release it!
}
}
// ------------------------------------------------------------------------------------------------
Buffer & Buffer::operator = (const Buffer & o)
{
if (m_Ptr != o.m_Ptr)
{
// Can we work in the current buffer?
if (m_Cap && o.m_Cap <= m_Cap)
{
// It's safe to copy the data
std::memcpy(m_Ptr, o.m_Ptr, o.m_Cap);
}
// Do we even have data to copy?
else if (!o.m_Cap)
{
// Do we have a buffer?
if (m_Ptr)
{
Release(); // Release it!
}
}
else
{
// Do we have a buffer?
if (m_Ptr)
{
Release(); // Release it!
}
// Request a larger buffer
Request(o.m_Cap);
// Now it's safe to copy the data
std::memcpy(m_Ptr, o.m_Ptr, o.m_Cap);
}
// Also copy the edit cursor
m_Cur = o.m_Cur;
}
return *this;
}
// ------------------------------------------------------------------------------------------------
void Buffer::Grow(SzType n)
{
// Backup the current memory
Buffer bkp(m_Ptr, m_Cap, m_Cur, m_Mem);
// Acquire a bigger buffer
Request(bkp.m_Cap + n);
// Copy the data from the old buffer
std::memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap);
// Copy the previous edit cursor
m_Cur = bkp.m_Cur;
}
// ------------------------------------------------------------------------------------------------
void Buffer::Request(SzType n)
{
// NOTE: Function assumes (n > 0)
// Is there a memory manager available?
if (!m_Mem)
{
// Round up the size to a power of two number
n = (n & (n - 1)) ? NextPow2(n) : n;
// Allocate the memory directly
m_Ptr = AllocMem(n);
}
// Find out in which category does this buffer reside
else if (n <= 1024)
{
m_Mem->m_Small.Grab(m_Ptr, n);
}
else if (n <= 4096)
{
m_Mem->m_Medium.Grab(m_Ptr, n);
}
else
{
m_Mem->m_Large.Grab(m_Ptr, n);
}
// If no errors occurred then we can set the size
m_Cap = n;
}
// ------------------------------------------------------------------------------------------------
void Buffer::Release()
{
// TODO: Implement a limit on how much memory can actually be pooled.
// Is there a memory manager available?
if (!m_Mem)
{
std::free(m_Ptr); // Deallocate the memory directly
}
// Find out to which category does this buffer belong
else if (m_Cap <= 1024)
{
m_Mem->m_Small.Drop(m_Ptr, m_Cap);
}
else if (m_Cap <= 4096)
{
m_Mem->m_Medium.Drop(m_Ptr, m_Cap);
}
else
{
m_Mem->m_Large.Drop(m_Ptr, m_Cap);
}
// Explicitly reset the buffer
m_Ptr = nullptr;
m_Cap = 0;
m_Cur = 0;
}
// ------------------------------------------------------------------------------------------------
Buffer::SzType Buffer::Write(SzType pos, ConstPtr data, SzType size)
{
// Do we have what to write?
if (!data || !size)
{
return 0;
}
// See if the buffer size must be adjusted
else if ((pos + size) >= m_Cap)
{
// Acquire a larger buffer
Grow((pos + size) - m_Cap + 32);
}
// Copy the data into the internal buffer
std::memcpy(m_Ptr + pos, data, size);
// Return the amount of data written to the buffer
return size;
}
// ------------------------------------------------------------------------------------------------
Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, ...)
{
// Initialize the variable argument list
va_list args;
va_start(args, fmt);
// Call the function that takes the variable argument list
const SzType ret = WriteF(pos, fmt, args);
// Finalize the variable argument list
va_end(args);
// Return the result
return ret;
}
// ------------------------------------------------------------------------------------------------
Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, va_list args)
{
// Is the specified position within range?
if (pos >= m_Cap)
{
// Acquire a larger buffer
Grow(pos - m_Cap + 32);
}
// Backup the variable argument list
va_list args_cpy;
va_copy(args_cpy, args);
// Attempt to write to the current buffer
// (if empty, it should tell us the necessary size)
int ret = std::vsnprintf(m_Ptr + pos, m_Cap, fmt, args);
// Do we need a bigger buffer?
if ((pos + ret) >= m_Cap)
{
// Acquire a larger buffer
Grow((pos + ret) - m_Cap + 32);
// Retry writing the requested information
ret = std::vsnprintf(m_Ptr + pos, m_Cap, fmt, args_cpy);
}
// Return the value 0 if data could not be written
if (ret < 0)
{
return 0;
}
// Return the number of written characters
return static_cast< SzType >(ret);
}
// ------------------------------------------------------------------------------------------------
Buffer::SzType Buffer::WriteS(SzType pos, ConstPtr str)
{
// Is there any string to write?
if (str && *str != '\0')
{
// Forward this to the regular write function
return Write(pos, str, std::strlen(str));
}
// Nothing to write
return 0;
}
// ------------------------------------------------------------------------------------------------
void Buffer::AppendF(const char * fmt, ...)
{
// Initialize the variable argument list
va_list args;
va_start(args, fmt);
// Forward this to the regular write function
m_Cur += WriteF(m_Cur, fmt, args);
// Finalize the variable argument list
va_end(args);
}
// ------------------------------------------------------------------------------------------------
void Buffer::AppendS(const char * str)
{
// Is there any string to write?
if (str)
{
m_Cur += Write(m_Cur, str, std::strlen(str));
}
}
} // Namespace:: SqMod

1026
module/Base/Buffer.hpp Normal file

File diff suppressed because it is too large Load Diff

635
module/Base/Circle.cpp Normal file
View File

@ -0,0 +1,635 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Circle.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Circle"))
// ------------------------------------------------------------------------------------------------
const Circle Circle::NIL = Circle();
const Circle Circle::MIN = Circle(0.0);
const Circle Circle::MAX = Circle(std::numeric_limits< Circle::Value >::max());
// ------------------------------------------------------------------------------------------------
SQChar Circle::Delim = ',';
// ------------------------------------------------------------------------------------------------
Circle::Circle()
: pos(0.0, 0.0), rad(0.0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Circle::Circle(Value rv)
: pos(0.0, 0.0), rad(rv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Circle::Circle(const Vector2 & pv, Value rv)
: pos(pv), rad(rv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Circle::Circle(Value xv, Value yv, Value rv)
: pos(xv, yv), rad(rv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator = (Value r)
{
rad = r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator = (const Vector2 & p)
{
pos = p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator += (const Circle & c)
{
pos += c.pos;
rad += c.rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator -= (const Circle & c)
{
pos -= c.pos;
rad -= c.rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator *= (const Circle & c)
{
pos *= c.pos;
rad *= c.rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator /= (const Circle & c)
{
pos /= c.pos;
rad /= c.rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator %= (const Circle & c)
{
pos %= c.pos;
rad = std::fmod(rad, c.rad);
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator += (Value r)
{
rad += r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator -= (Value r)
{
rad -= r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator *= (Value r)
{
rad *= r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator /= (Value r)
{
rad /= r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator %= (Value r)
{
rad = std::fmod(rad, r);
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator += (const Vector2 & p)
{
pos += p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator -= (const Vector2 & p)
{
pos -= p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator *= (const Vector2 & p)
{
pos *= p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator /= (const Vector2 & p)
{
pos /= p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator %= (const Vector2 & p)
{
pos %= p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator ++ ()
{
++pos;
++rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle & Circle::operator -- ()
{
--pos;
--rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator ++ (int)
{
Circle state(*this);
++pos;
++rad;
return state;
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator -- (int)
{
Circle state(*this);
--pos;
--rad;
return state;
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator + (const Circle & c) const
{
return Circle(pos + c.pos, rad + c.rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator - (const Circle & c) const
{
return Circle(pos - c.pos, rad - c.rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator * (const Circle & c) const
{
return Circle(pos * c.pos, rad * c.rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator / (const Circle & c) const
{
return Circle(pos / c.pos, rad / c.rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator % (const Circle & c) const
{
return Circle(pos % c.pos, std::fmod(rad, c.rad));
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator + (Value r) const
{
return Circle(rad + r);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator - (Value r) const
{
return Circle(rad - r);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator * (Value r) const
{
return Circle(rad * r);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator / (Value r) const
{
return Circle(rad / r);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator % (Value r) const
{
return Circle(std::fmod(rad, r));
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator + (const Vector2 & p) const
{
return Circle(pos + p, rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator - (const Vector2 & p) const
{
return Circle(pos - p, rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator * (const Vector2 & p) const
{
return Circle(pos * p, rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator / (const Vector2 & p) const
{
return Circle(pos / p, rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator % (const Vector2 & p) const
{
return Circle(pos % p, rad);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator + () const
{
return Circle(pos.Abs(), std::fabs(rad));
}
// ------------------------------------------------------------------------------------------------
Circle Circle::operator - () const
{
return Circle(-pos, -rad);
}
// ------------------------------------------------------------------------------------------------
bool Circle::operator == (const Circle & c) const
{
return EpsEq(rad, c.rad) && (pos == c.pos);
}
// ------------------------------------------------------------------------------------------------
bool Circle::operator != (const Circle & c) const
{
return !EpsEq(rad, c.rad) || (pos != c.pos);
}
// ------------------------------------------------------------------------------------------------
bool Circle::operator < (const Circle & c) const
{
return EpsLt(rad, c.rad) && (pos < c.pos);
}
// ------------------------------------------------------------------------------------------------
bool Circle::operator > (const Circle & c) const
{
return EpsGt(rad, c.rad) && (pos > c.pos);
}
// ------------------------------------------------------------------------------------------------
bool Circle::operator <= (const Circle & c) const
{
return EpsLtEq(rad, c.rad) && (pos <= c.pos);
}
// ------------------------------------------------------------------------------------------------
bool Circle::operator >= (const Circle & c) const
{
return EpsGtEq(rad, c.rad) && (pos >= c.pos);
}
// ------------------------------------------------------------------------------------------------
Int32 Circle::Cmp(const Circle & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Circle::ToString() const
{
return ToStrF("%f,%f,%f", pos.x, pos.y, rad);
}
// ------------------------------------------------------------------------------------------------
void Circle::SetRadius(Value nr)
{
rad = nr;
}
// ------------------------------------------------------------------------------------------------
void Circle::SetCircle(const Circle & nc)
{
pos = nc.pos;
rad = nc.rad;
}
// ------------------------------------------------------------------------------------------------
void Circle::SetCircleEx(Value nx, Value ny, Value nr)
{
pos.SetVector2Ex(nx, ny);
rad = nr;
}
// ------------------------------------------------------------------------------------------------
void Circle::SetValues(const Vector2 & np, Value nr)
{
pos = np;
rad = nr;
}
// ------------------------------------------------------------------------------------------------
void Circle::SetPosition(const Vector2 & np)
{
pos = np;
}
// ------------------------------------------------------------------------------------------------
void Circle::SetPositionEx(Value nx, Value ny)
{
pos.SetVector2Ex(nx, ny);
}
// ------------------------------------------------------------------------------------------------
void Circle::SetStr(SQChar delim, StackStrF & values)
{
SetCircle(Circle::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Circle::Generate()
{
pos.Generate();
rad = GetRandomFloat32();
}
// ------------------------------------------------------------------------------------------------
void Circle::Generate(Value min, Value max, bool r)
{
if (EpsLt(max, min))
{
STHROWF("max value is lower than min value");
}
else if (r)
{
rad = GetRandomFloat32(min, max);
}
else
{
pos.Generate(min, max);
}
}
// ------------------------------------------------------------------------------------------------
void Circle::Generate(Value xmin, Value xmax, Value ymin, Value ymax)
{
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin))
{
STHROWF("max value is lower than min value");
}
pos.Generate(xmin, xmax, ymin, ymax);
}
// ------------------------------------------------------------------------------------------------
void Circle::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value rmin, Value rmax)
{
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(rmax, rmin))
{
STHROWF("max value is lower than min value");
}
pos.Generate(xmin, xmax, ymin, ymax);
rad = GetRandomFloat32(rmin, rmax);
}
// ------------------------------------------------------------------------------------------------
Circle Circle::Abs() const
{
return Circle(pos.Abs(), std::fabs(rad));
}
// ------------------------------------------------------------------------------------------------
const Circle & Circle::Get(StackStrF & str)
{
return Circle::GetEx(Circle::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Circle & Circle::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %f , %f , %f ");
static Circle circle;
// Clear previous values, if any
circle.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return circle; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
fs[9] = delim;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, fs, &circle.pos.x, &circle.pos.y, &circle.rad);
// Return the resulted value
return circle;
}
// ------------------------------------------------------------------------------------------------
const Circle & GetCircle()
{
static Circle circle;
circle.Clear();
return circle;
}
// ------------------------------------------------------------------------------------------------
const Circle & GetCircle(Float32 rv)
{
static Circle circle;
circle.SetRadius(rv);
return circle;
}
// ------------------------------------------------------------------------------------------------
const Circle & GetCircle(const Vector2 & pv, Float32 rv)
{
static Circle circle;
circle.SetValues(pv, rv);
return circle;
}
// ------------------------------------------------------------------------------------------------
const Circle & GetCircle(Float32 xv, Float32 yv, Float32 rv)
{
static Circle circle;
circle.SetCircleEx(xv, yv, rv);
return circle;
}
// ------------------------------------------------------------------------------------------------
const Circle & GetCircle(const Circle & o)
{
static Circle circle;
circle.SetCircle(o);
return circle;
}
// ================================================================================================
void Register_Circle(HSQUIRRELVM vm)
{
typedef Circle::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Circle >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< const Vector2 &, Val >()
.Ctor< Val, Val, Val >()
// Member Variables
.Var(_SC("pos"), &Circle::pos)
.Var(_SC("rad"), &Circle::rad)
.Var(_SC("Pos"), &Circle::pos)
.Var(_SC("Rad"), &Circle::rad)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Circle::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Circle >, SQFloat, SQInteger, bool, std::nullptr_t, Circle >)
.Func< Circle (Circle::*)(void) const >(_SC("_unm"), &Circle::operator -)
// Properties
.Prop(_SC("Abs"), &Circle::Abs)
// Member Methods
.Func(_SC("SetRadius"), &Circle::SetRadius)
.Func(_SC("SetCircle"), &Circle::SetCircle)
.Func(_SC("SetCircleEx"), &Circle::SetCircleEx)
.Func(_SC("SetValues"), &Circle::SetValues)
.Func(_SC("SetPos"), &Circle::SetPosition)
.Func(_SC("SetPosition"), &Circle::SetPosition)
.Func(_SC("SetPosEx"), &Circle::SetPositionEx)
.Func(_SC("SetPositionEx"), &Circle::SetPositionEx)
.FmtFunc(_SC("SetStr"), &Circle::SetStr)
.Func(_SC("Clear"), &Circle::Clear)
// Member Overloads
.Overload< void (Circle::*)(void) >(_SC("Generate"), &Circle::Generate)
.Overload< void (Circle::*)(Val, Val, bool) >(_SC("Generate"), &Circle::Generate)
.Overload< void (Circle::*)(Val, Val, Val, Val) >(_SC("Generate"), &Circle::Generate)
.Overload< void (Circle::*)(Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Circle::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Circle >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Circle >)
.StaticFmtFunc(_SC("FromStr"), &Circle::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Circle::GetEx)
// Operator Exposure
.Func< Circle & (Circle::*)(const Circle &) >(_SC("opAddAssign"), &Circle::operator +=)
.Func< Circle & (Circle::*)(const Circle &) >(_SC("opSubAssign"), &Circle::operator -=)
.Func< Circle & (Circle::*)(const Circle &) >(_SC("opMulAssign"), &Circle::operator *=)
.Func< Circle & (Circle::*)(const Circle &) >(_SC("opDivAssign"), &Circle::operator /=)
.Func< Circle & (Circle::*)(const Circle &) >(_SC("opModAssign"), &Circle::operator %=)
.Func< Circle & (Circle::*)(Circle::Value) >(_SC("opAddAssignR"), &Circle::operator +=)
.Func< Circle & (Circle::*)(Circle::Value) >(_SC("opSubAssignR"), &Circle::operator -=)
.Func< Circle & (Circle::*)(Circle::Value) >(_SC("opMulAssignR"), &Circle::operator *=)
.Func< Circle & (Circle::*)(Circle::Value) >(_SC("opDivAssignR"), &Circle::operator /=)
.Func< Circle & (Circle::*)(Circle::Value) >(_SC("opModAssignR"), &Circle::operator %=)
.Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opAddAssignP"), &Circle::operator +=)
.Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opSubAssignP"), &Circle::operator -=)
.Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opMulAssignP"), &Circle::operator *=)
.Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opDivAssignP"), &Circle::operator /=)
.Func< Circle & (Circle::*)(const Vector2 &) >(_SC("opModAssignP"), &Circle::operator %=)
.Func< Circle & (Circle::*)(void) >(_SC("opPreInc"), &Circle::operator ++)
.Func< Circle & (Circle::*)(void) >(_SC("opPreDec"), &Circle::operator --)
.Func< Circle (Circle::*)(int) >(_SC("opPostInc"), &Circle::operator ++)
.Func< Circle (Circle::*)(int) >(_SC("opPostDec"), &Circle::operator --)
.Func< Circle (Circle::*)(const Circle &) const >(_SC("opAdd"), &Circle::operator +)
.Func< Circle (Circle::*)(const Circle &) const >(_SC("opSub"), &Circle::operator -)
.Func< Circle (Circle::*)(const Circle &) const >(_SC("opMul"), &Circle::operator *)
.Func< Circle (Circle::*)(const Circle &) const >(_SC("opDiv"), &Circle::operator /)
.Func< Circle (Circle::*)(const Circle &) const >(_SC("opMod"), &Circle::operator %)
.Func< Circle (Circle::*)(Circle::Value) const >(_SC("opAddR"), &Circle::operator +)
.Func< Circle (Circle::*)(Circle::Value) const >(_SC("opSubR"), &Circle::operator -)
.Func< Circle (Circle::*)(Circle::Value) const >(_SC("opMulR"), &Circle::operator *)
.Func< Circle (Circle::*)(Circle::Value) const >(_SC("opDivR"), &Circle::operator /)
.Func< Circle (Circle::*)(Circle::Value) const >(_SC("opModR"), &Circle::operator %)
.Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opAddP"), &Circle::operator +)
.Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opSubP"), &Circle::operator -)
.Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opMulP"), &Circle::operator *)
.Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opDivP"), &Circle::operator /)
.Func< Circle (Circle::*)(const Vector2 &) const >(_SC("opModP"), &Circle::operator %)
.Func< Circle (Circle::*)(void) const >(_SC("opUnPlus"), &Circle::operator +)
.Func< Circle (Circle::*)(void) const >(_SC("opUnMinus"), &Circle::operator -)
.Func< bool (Circle::*)(const Circle &) const >(_SC("opEqual"), &Circle::operator ==)
.Func< bool (Circle::*)(const Circle &) const >(_SC("opNotEqual"), &Circle::operator !=)
.Func< bool (Circle::*)(const Circle &) const >(_SC("opLessThan"), &Circle::operator <)
.Func< bool (Circle::*)(const Circle &) const >(_SC("opGreaterThan"), &Circle::operator >)
.Func< bool (Circle::*)(const Circle &) const >(_SC("opLessEqual"), &Circle::operator <=)
.Func< bool (Circle::*)(const Circle &) const >(_SC("opGreaterEqual"), &Circle::operator >=)
);
}
} // Namespace:: SqMod

428
module/Base/Circle.hpp Normal file
View File

@ -0,0 +1,428 @@
#ifndef _BASE_CIRCLE_HPP_
#define _BASE_CIRCLE_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
#include "Base/Vector2.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent a two-dimensional circle.
*/
struct Circle
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef float Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Circle NIL;
static const Circle MIN;
static const Circle MAX;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The position and radius components of this type.
*/
Vector2 pos;
Value rad;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Circle();
/* --------------------------------------------------------------------------------------------
* Construct a circle at position 0,0 using the specified radius.
*/
explicit Circle(Value rv);
/* --------------------------------------------------------------------------------------------
* Construct a circle at the specified position using the specified radius.
*/
Circle(const Vector2 & pv, Value rv);
/* --------------------------------------------------------------------------------------------
* Construct a circle at the specified position using the specified radius.
*/
Circle(Value xv, Value yv, Value rv);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Circle(const Circle & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Circle(Circle && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Circle() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Circle & operator = (const Circle & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Circle & operator = (Circle && o) = default;
/* --------------------------------------------------------------------------------------------
* Radius assignment operator.
*/
Circle & operator = (Value r);
/* --------------------------------------------------------------------------------------------
* Position assignment operator.
*/
Circle & operator = (const Vector2 & p);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Circle & operator += (const Circle & c);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Circle & operator -= (const Circle & c);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Circle & operator *= (const Circle & c);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Circle & operator /= (const Circle & c);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Circle & operator %= (const Circle & c);
/* --------------------------------------------------------------------------------------------
* Radius addition assignment operator.
*/
Circle & operator += (Value r);
/* --------------------------------------------------------------------------------------------
* Radius subtraction assignment operator.
*/
Circle & operator -= (Value r);
/* --------------------------------------------------------------------------------------------
* Radius multiplication assignment operator.
*/
Circle & operator *= (Value r);
/* --------------------------------------------------------------------------------------------
* Radius division assignment operator.
*/
Circle & operator /= (Value r);
/* --------------------------------------------------------------------------------------------
* Radius modulo assignment operator.
*/
Circle & operator %= (Value r);
/* --------------------------------------------------------------------------------------------
* Position addition assignment operator.
*/
Circle & operator += (const Vector2 & p);
/* --------------------------------------------------------------------------------------------
* Position subtraction assignment operator.
*/
Circle & operator -= (const Vector2 & p);
/* --------------------------------------------------------------------------------------------
* Position multiplication assignment operator.
*/
Circle & operator *= (const Vector2 & p);
/* --------------------------------------------------------------------------------------------
* Position division assignment operator.
*/
Circle & operator /= (const Vector2 & p);
/* --------------------------------------------------------------------------------------------
* Position modulo assignment operator.
*/
Circle & operator %= (const Vector2 & p);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Circle & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Circle & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Circle operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Circle operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Circle operator + (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Circle operator - (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Circle operator * (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Circle operator / (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Circle operator % (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Radius addition operator.
*/
Circle operator + (Value r) const;
/* --------------------------------------------------------------------------------------------
* Radius subtraction operator.
*/
Circle operator - (Value r) const;
/* --------------------------------------------------------------------------------------------
* Radius multiplication operator.
*/
Circle operator * (Value r) const;
/* --------------------------------------------------------------------------------------------
* Radius division operator.
*/
Circle operator / (Value r) const;
/* --------------------------------------------------------------------------------------------
* Radius modulo operator.
*/
Circle operator % (Value r) const;
/* --------------------------------------------------------------------------------------------
* Position addition operator.
*/
Circle operator + (const Vector2 & p) const;
/* --------------------------------------------------------------------------------------------
* Position subtraction operator.
*/
Circle operator - (const Vector2 & p) const;
/* --------------------------------------------------------------------------------------------
* Position multiplication operator.
*/
Circle operator * (const Vector2 & p) const;
/* --------------------------------------------------------------------------------------------
* Position division operator.
*/
Circle operator / (const Vector2 & p) const;
/* --------------------------------------------------------------------------------------------
* Position modulo operator.
*/
Circle operator % (const Vector2 & p) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Circle operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Circle operator - () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Circle & c) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Circle(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Circle(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Circle(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(Circle(static_cast< Value >(0)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set the specified radius.
*/
void SetRadius(Value nr);
/* --------------------------------------------------------------------------------------------
* Copy the circle from another instance of this type.
*/
void SetCircle(const Circle & nc);
/* --------------------------------------------------------------------------------------------
* Set the specified position and radius.
*/
void SetCircleEx(Value nx, Value ny, Value nr);
/* --------------------------------------------------------------------------------------------
* Set the specified position and radius.
*/
void SetValues(const Vector2 & np, Value nr);
/* --------------------------------------------------------------------------------------------
* Set the specified position.
*/
void SetPosition(const Vector2 & np);
/* --------------------------------------------------------------------------------------------
* Set the specified position.
*/
void SetPositionEx(Value nx, Value ny);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & values);
/* --------------------------------------------------------------------------------------------
* Generate a randomly sized and positioned circle.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate a randomly sized or positioned circle within the specified bounds.
*/
void Generate(Value min, Value max, bool r);
/* --------------------------------------------------------------------------------------------
* Generate a randomly positioned circle within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax);
/* --------------------------------------------------------------------------------------------
* Generate a randomly sized and positioned circle within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value rmin, Value rmax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
pos.Clear();
rad = 0.0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a new instance of this type with absolute component values.
*/
Circle Abs() const;
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Circle type from a string.
*/
static const Circle & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Circle type from a string.
*/
static const Circle & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_CIRCLE_HPP_

814
module/Base/Color3.cpp Normal file
View File

@ -0,0 +1,814 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Color3.hpp"
#include "Base/Color4.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Color3"))
// ------------------------------------------------------------------------------------------------
const Color3 Color3::NIL = Color3();
const Color3 Color3::MIN = Color3(std::numeric_limits< Color3::Value >::min());
const Color3 Color3::MAX = Color3(std::numeric_limits< Color3::Value >::max());
// ------------------------------------------------------------------------------------------------
SQChar Color3::Delim = ',';
// ------------------------------------------------------------------------------------------------
Color3::Color3()
: r(0), g(0), b(0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Color3::Color3(Value sv)
: r(sv), g(sv), b(sv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Color3::Color3(Value rv, Value gv, Value bv)
: r(rv), g(gv), b(bv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Color3::Color3(Value rv, Value gv, Value bv, Value /*av*/)
: r(rv), g(gv), b(bv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator = (Value s)
{
r = s;
g = s;
b = s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator = (const Color4 & c)
{
r = c.r;
g = c.g;
b = c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator += (const Color3 & c)
{
r += c.r;
g += c.g;
b += c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator -= (const Color3 & c)
{
r -= c.r;
g -= c.g;
b -= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator *= (const Color3 & c)
{
r *= c.r;
g *= c.g;
b *= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator /= (const Color3 & c)
{
r /= c.r;
g /= c.g;
b /= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator %= (const Color3 & c)
{
r %= c.r;
g %= c.g;
b %= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator &= (const Color3 & c)
{
r &= c.r;
g &= c.g;
b &= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator |= (const Color3 & c)
{
r |= c.r;
g |= c.g;
b |= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator ^= (const Color3 & c)
{
r ^= c.r;
g ^= c.g;
b ^= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator <<= (const Color3 & c)
{
r <<= c.r;
g <<= c.g;
b <<= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator >>= (const Color3 & c)
{
r >>= c.r;
g >>= c.g;
b >>= c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator += (Value s)
{
r += s;
g += s;
b += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator -= (Value s)
{
r -= s;
g -= s;
b -= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator *= (Value s)
{
r *= s;
g *= s;
b *= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator /= (Value s)
{
r /= s;
g /= s;
b /= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator %= (Value s)
{
r %= s;
g %= s;
b %= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator &= (Value s)
{
r &= s;
g &= s;
b &= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator |= (Value s)
{
r |= s;
g |= s;
b |= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator ^= (Value s)
{
r ^= s;
g ^= s;
b ^= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator <<= (Value s)
{
r <<= s;
g <<= s;
b <<= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator >>= (Value s)
{
r >>= s;
g >>= s;
b >>= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator ++ ()
{
++r;
++g;
++b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 & Color3::operator -- ()
{
--r;
--g;
--b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator ++ (int)
{
Color3 state(*this);
++r;
++g;
++b;
return state;
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator -- (int)
{
Color3 state(*this);
--r;
--g;
--b;
return state;
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator + (const Color3 & c) const
{
return Color3(r + c.r, g + c.g, b + c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator - (const Color3 & c) const
{
return Color3(r - c.r, g - c.g, b - c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator * (const Color3 & c) const
{
return Color3(r * c.r, g * c.g, b * c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator / (const Color3 & c) const
{
return Color3(r / c.r, g / c.g, b / c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator % (const Color3 & c) const
{
return Color3(r % c.r, g % c.g, b % c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator & (const Color3 & c) const
{
return Color3(r & c.r, g & c.g, b & c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator | (const Color3 & c) const
{
return Color3(r | c.r, g | c.g, b | c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator ^ (const Color3 & c) const
{
return Color3(r ^ c.r, g ^ c.g, b ^ c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator << (const Color3 & c) const
{
return Color3(r << c.r, g << c.g, b << c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator >> (const Color3 & c) const
{
return Color3(r >> c.r, g >> c.g, b >> c.b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator + (Value s) const
{
return Color3(r + s, g + s, b + s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator - (Value s) const
{
return Color3(r - s, g - s, b - s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator * (Value s) const
{
return Color3(r * s, g * s, b * s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator / (Value s) const
{
return Color3(r / s, g / s, b / s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator % (Value s) const
{
return Color3(r % s, g % s, b % s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator & (Value s) const
{
return Color3(r & s, g & s, b & s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator | (Value s) const
{
return Color3(r | s, g | s, b | s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator ^ (Value s) const
{
return Color3(r ^ s, g ^ s, b ^ s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator << (Value s) const
{
return Color3(r << s, g << s, b << s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator >> (Value s) const
{
return Color3(r >> s, g >> s, b >> s);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator + () const
{
return Color3(r, g, b);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator - () const
{
return Color3(0, 0, 0);
}
// ------------------------------------------------------------------------------------------------
Color3 Color3::operator ~ () const
{
return Color3(~r, ~g, ~b);
}
// ------------------------------------------------------------------------------------------------
bool Color3::operator == (const Color3 & c) const
{
return (r == c.r) && (g == c.g) && (b == c.b);
}
// ------------------------------------------------------------------------------------------------
bool Color3::operator != (const Color3 & c) const
{
return (r != c.r) || (g != c.g) || (b != c.b);
}
// ------------------------------------------------------------------------------------------------
bool Color3::operator < (const Color3 & c) const
{
return (r < c.r) && (g < c.g) && (b < c.b);
}
// ------------------------------------------------------------------------------------------------
bool Color3::operator > (const Color3 & c) const
{
return (r > c.r) && (g > c.g) && (b > c.b);
}
// ------------------------------------------------------------------------------------------------
bool Color3::operator <= (const Color3 & c) const
{
return (r <= c.r) && (g <= c.g) && (b <= c.b);
}
// ------------------------------------------------------------------------------------------------
bool Color3::operator >= (const Color3 & c) const
{
return (r >= c.r) && (g >= c.g) && (b >= c.b);
}
// ------------------------------------------------------------------------------------------------
Color3::operator Color4 () const
{
return Color4(r, g, b);
}
// ------------------------------------------------------------------------------------------------
Int32 Color3::Cmp(const Color3 & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Color3::ToString() const
{
return ToStrF("%u,%u,%u", r, g, b);
}
// ------------------------------------------------------------------------------------------------
void Color3::SetScalar(Value ns)
{
r = ns;
g = ns;
b = ns;
}
// ------------------------------------------------------------------------------------------------
void Color3::SetColor3(const Color3 & c)
{
r = c.r;
g = c.g;
b = c.b;
}
// ------------------------------------------------------------------------------------------------
void Color3::SetColor3Ex(Value nr, Value ng, Value nb)
{
r = nr;
g = ng;
b = nb;
}
// ------------------------------------------------------------------------------------------------
void Color3::SetColor4(const Color4 & c)
{
r = c.r;
g = c.g;
b = c.b;
}
// ------------------------------------------------------------------------------------------------
void Color3::SetColor4Ex(Value nr, Value ng, Value nb, Value /*na*/)
{
r = nr;
g = ng;
b = nb;
}
// ------------------------------------------------------------------------------------------------
void Color3::SetStr(SQChar delim, StackStrF & values)
{
SetColor3(Color3::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Color3::SetName(StackStrF & name)
{
SetColor3(GetColor(name));
}
// ------------------------------------------------------------------------------------------------
Uint32 Color3::GetRGB() const
{
return Uint32(r << 16 | g << 8 | b);
}
// ------------------------------------------------------------------------------------------------
void Color3::SetRGB(Uint32 p)
{
r = static_cast< Value >((p >> 16) & 0xFF);
g = static_cast< Value >((p >> 8) & 0xFF);
b = static_cast< Value >((p) & 0xFF);
}
// ------------------------------------------------------------------------------------------------
Uint32 Color3::GetRGBA() const
{
return Uint32(r << 24 | g << 16 | b << 8 | 0x00);
}
// ------------------------------------------------------------------------------------------------
void Color3::SetRGBA(Uint32 p)
{
r = static_cast< Value >((p >> 24) & 0xFF);
g = static_cast< Value >((p >> 16) & 0xFF);
b = static_cast< Value >((p >> 8) & 0xFF);
}
// ------------------------------------------------------------------------------------------------
Uint32 Color3::GetARGB() const
{
return Uint32(0x00 << 24 | r << 16 | g << 8 | b);
}
// ------------------------------------------------------------------------------------------------
void Color3::SetARGB(Uint32 p)
{
r = static_cast< Value >((p >> 16) & 0xFF);
g = static_cast< Value >((p >> 8) & 0xFF);
b = static_cast< Value >((p) & 0xFF);
}
// ------------------------------------------------------------------------------------------------
void Color3::Generate()
{
r = GetRandomUint8();
g = GetRandomUint8();
b = GetRandomUint8();
}
// ------------------------------------------------------------------------------------------------
void Color3::Generate(Value min, Value max)
{
if (max < min)
{
STHROWF("max value is lower than min value");
}
r = GetRandomUint8(min, max);
g = GetRandomUint8(min, max);
b = GetRandomUint8(min, max);
}
// ------------------------------------------------------------------------------------------------
void Color3::Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax)
{
if (rmax < rmin || gmax < gmin || bmax < bmin)
{
STHROWF("max value is lower than min value");
}
r = GetRandomUint8(rmin, rmax);
g = GetRandomUint8(gmin, gmax);
b = GetRandomUint8(bmin, bmax);
}
// ------------------------------------------------------------------------------------------------
void Color3::Random()
{
SetColor3(GetRandomColor());
}
// ------------------------------------------------------------------------------------------------
void Color3::Inverse()
{
r = static_cast< Value >(~r);
g = static_cast< Value >(~g);
b = static_cast< Value >(~b);
}
// ------------------------------------------------------------------------------------------------
const Color3 & Color3::Get(StackStrF & str)
{
return Color3::GetEx(Color3::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Color3 & Color3::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %u , %u , %u ");
static Color3 col;
// The minimum and maximum values supported by the Color3 type
static const Uint32 min = std::numeric_limits< Color3::Value >::min();
static const Uint32 max = std::numeric_limits< Color3::Value >::max();
// Clear previous values, if any
col.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return col; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
fs[9] = delim;
// The sscanf function requires at least 32 bit integers
Uint32 r = 0, g = 0, b = 0;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, fs, &r, &g, &b);
// Cast the extracted integers to the value used by the Color3 type
col.r = static_cast< Color3::Value >(Clamp(r, min, max));
col.g = static_cast< Color3::Value >(Clamp(g, min, max));
col.b = static_cast< Color3::Value >(Clamp(b, min, max));
// Return the resulted value
return col;
}
// ------------------------------------------------------------------------------------------------
const Color3 & GetColor3()
{
static Color3 col;
col.Clear();
return col;
}
// ------------------------------------------------------------------------------------------------
const Color3 & GetColor3(Uint8 sv)
{
static Color3 col;
col.SetScalar(sv);
return col;
}
// ------------------------------------------------------------------------------------------------
const Color3 & GetColor3(Uint8 rv, Uint8 gv, Uint8 bv)
{
static Color3 col;
col.SetColor3Ex(rv, gv, bv);
return col;
}
// ------------------------------------------------------------------------------------------------
const Color3 & GetColor3(const Color3 & o)
{
static Color3 col;
col.SetColor3(o);
return col;
}
// ================================================================================================
void Register_Color3(HSQUIRRELVM vm)
{
typedef Color3::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Color3 >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< Val, Val, Val >()
.Ctor< Val, Val, Val, Val >()
// Member Variables
.Var(_SC("r"), &Color3::r)
.Var(_SC("g"), &Color3::g)
.Var(_SC("b"), &Color3::b)
.Var(_SC("R"), &Color3::r)
.Var(_SC("G"), &Color3::g)
.Var(_SC("B"), &Color3::b)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Color3::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Color3 >, SQFloat, SQInteger, bool, std::nullptr_t, Color3 >)
.Func< Color3 (Color3::*)(void) const >(_SC("_unm"), &Color3::operator -)
// Properties
.Prop(_SC("RGB"), &Color3::GetRGB, &Color3::SetRGB)
.Prop(_SC("RGBA"), &Color3::GetRGBA, &Color3::SetRGBA)
.Prop(_SC("ARGB"), &Color3::GetARGB, &Color3::SetARGB)
// Member Methods
.Func(_SC("SetScalar"), &Color3::SetScalar)
.Func(_SC("SetColor3"), &Color3::SetColor3)
.Func(_SC("SetColor3Ex"), &Color3::SetColor3Ex)
.Func(_SC("SetColor4"), &Color3::SetColor4)
.Func(_SC("SetColor4Ex"), &Color3::SetColor4Ex)
.FmtFunc(_SC("SetStr"), &Color3::SetStr)
.FmtFunc(_SC("SetName"), &Color3::SetName)
.Func(_SC("Clear"), &Color3::Clear)
.Func(_SC("Random"), &Color3::Random)
.Func(_SC("Inverse"), &Color3::Inverse)
// Member Overloads
.Overload< void (Color3::*)(void) >(_SC("Generate"), &Color3::Generate)
.Overload< void (Color3::*)(Val, Val) >(_SC("Generate"), &Color3::Generate)
.Overload< void (Color3::*)(Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Color3::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Color3 >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Color3 >)
.StaticFmtFunc(_SC("FromStr"), &Color3::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Color3::GetEx)
// Operator Exposure
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opAddAssign"), &Color3::operator +=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opSubAssign"), &Color3::operator -=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opMulAssign"), &Color3::operator *=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opDivAssign"), &Color3::operator /=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opModAssign"), &Color3::operator %=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opAndAssign"), &Color3::operator &=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opOrAssign"), &Color3::operator |=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opXorAssign"), &Color3::operator ^=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opShlAssign"), &Color3::operator <<=)
.Func< Color3 & (Color3::*)(const Color3 &) >(_SC("opShrAssign"), &Color3::operator >>=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opAddAssignS"), &Color3::operator +=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opSubAssignS"), &Color3::operator -=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opMulAssignS"), &Color3::operator *=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opDivAssignS"), &Color3::operator /=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opModAssignS"), &Color3::operator %=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opAndAssignS"), &Color3::operator &=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opOrAssignS"), &Color3::operator |=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opXorAssignS"), &Color3::operator ^=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opShlAssignS"), &Color3::operator <<=)
.Func< Color3 & (Color3::*)(Color3::Value) >(_SC("opShrAssignS"), &Color3::operator >>=)
.Func< Color3 & (Color3::*)(void) >(_SC("opPreInc"), &Color3::operator ++)
.Func< Color3 & (Color3::*)(void) >(_SC("opPreDec"), &Color3::operator --)
.Func< Color3 (Color3::*)(int) >(_SC("opPostInc"), &Color3::operator ++)
.Func< Color3 (Color3::*)(int) >(_SC("opPostDec"), &Color3::operator --)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opAdd"), &Color3::operator +)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opSub"), &Color3::operator -)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opMul"), &Color3::operator *)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opDiv"), &Color3::operator /)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opMod"), &Color3::operator %)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opAnd"), &Color3::operator &)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opOr"), &Color3::operator |)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opShl"), &Color3::operator ^)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opShl"), &Color3::operator <<)
.Func< Color3 (Color3::*)(const Color3 &) const >(_SC("opShr"), &Color3::operator >>)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opAddS"), &Color3::operator +)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opSubS"), &Color3::operator -)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opMulS"), &Color3::operator *)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opDivS"), &Color3::operator /)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opModS"), &Color3::operator %)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opAndS"), &Color3::operator &)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opOrS"), &Color3::operator |)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opShlS"), &Color3::operator ^)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opShlS"), &Color3::operator <<)
.Func< Color3 (Color3::*)(Color3::Value) const >(_SC("opShrS"), &Color3::operator >>)
.Func< Color3 (Color3::*)(void) const >(_SC("opUnPlus"), &Color3::operator +)
.Func< Color3 (Color3::*)(void) const >(_SC("opUnMinus"), &Color3::operator -)
.Func< Color3 (Color3::*)(void) const >(_SC("opCom"), &Color3::operator ~)
.Func< bool (Color3::*)(const Color3 &) const >(_SC("opEqual"), &Color3::operator ==)
.Func< bool (Color3::*)(const Color3 &) const >(_SC("opNotEqual"), &Color3::operator !=)
.Func< bool (Color3::*)(const Color3 &) const >(_SC("opLessThan"), &Color3::operator <)
.Func< bool (Color3::*)(const Color3 &) const >(_SC("opGreaterThan"), &Color3::operator >)
.Func< bool (Color3::*)(const Color3 &) const >(_SC("opLessEqual"), &Color3::operator <=)
.Func< bool (Color3::*)(const Color3 &) const >(_SC("opGreaterEqual"), &Color3::operator >=)
);
}
} // Namespace:: SqMod

515
module/Base/Color3.hpp Normal file
View File

@ -0,0 +1,515 @@
#ifndef _BASE_COLOR3_HPP_
#define _BASE_COLOR3_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent an opaque RGB color.
*/
struct Color3
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef unsigned char Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Color3 NIL;
static const Color3 MIN;
static const Color3 MAX;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The red, green and blue components of this type.
*/
Value r, g, b;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Color3();
/* --------------------------------------------------------------------------------------------
* Construct a color with all components with the same specified color.
*/
explicit Color3(Value sv);
/* --------------------------------------------------------------------------------------------
* Construct with individually specified red, green and blue colors.
*/
Color3(Value rv, Value gv, Value bv);
/* --------------------------------------------------------------------------------------------
* Construct with individually specified red, green, blue and alpha colors.
*/
Color3(Value rv, Value gv, Value bv, Value av);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Color3(const Color3 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Color3(Color3 && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Color3() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Color3 & operator = (const Color3 & o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Color3 & operator = (Color3 && o) = default;
/* --------------------------------------------------------------------------------------------
* Scalar value assignment operator.
*/
Color3 & operator = (Value s);
/* --------------------------------------------------------------------------------------------
* Transparent color assignment operator.
*/
Color3 & operator = (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Color3 & operator += (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Color3 & operator -= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Color3 & operator *= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Color3 & operator /= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Color3 & operator %= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise AND assignment operator.
*/
Color3 & operator &= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise OR assignment operator.
*/
Color3 & operator |= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise XOR assignment operator.
*/
Color3 & operator ^= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise left shift assignment operator.
*/
Color3 & operator <<= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise right shift assignment operator.
*/
Color3 & operator >>= (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Scalar value addition assignment operator.
*/
Color3 & operator += (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction assignment operator.
*/
Color3 & operator -= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication assignment operator.
*/
Color3 & operator *= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value division assignment operator.
*/
Color3 & operator /= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value modulo assignment operator.
*/
Color3 & operator %= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise AND assignment operator.
*/
Color3 & operator &= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise OR assignment operator.
*/
Color3 & operator |= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise XOR assignment operator.
*/
Color3 & operator ^= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise left shift assignment operator.
*/
Color3 & operator <<= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise right shift assignment operator.
*/
Color3 & operator >>= (Value s);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Color3 & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Color3 & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Color3 operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Color3 operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Color3 operator + (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Color3 operator - (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Color3 operator * (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Color3 operator / (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Color3 operator % (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise AND operator.
*/
Color3 operator & (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise OR operator.
*/
Color3 operator | (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise XOR operator.
*/
Color3 operator ^ (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise shift left operator.
*/
Color3 operator << (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise shift right operator.
*/
Color3 operator >> (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Scalar value addition operator.
*/
Color3 operator + (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction operator.
*/
Color3 operator - (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication operator.
*/
Color3 operator * (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value division operator.
*/
Color3 operator / (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value modulo operator.
*/
Color3 operator % (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise AND operator.
*/
Color3 operator & (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise OR operator.
*/
Color3 operator | (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise XOR operator.
*/
Color3 operator ^ (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise shift left operator.
*/
Color3 operator << (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise shift right operator.
*/
Color3 operator >> (Value s) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Color3 operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Color3 operator - () const;
/* --------------------------------------------------------------------------------------------
* Bitwise NOT operator.
*/
Color3 operator ~ () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Implicit conversion to transparent color.
*/
operator Color4 () const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Color3 & c) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Color3(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Color3(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Color3(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(Color3(static_cast< Value >(0)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value.
*/
void SetScalar(Value ns);
/* --------------------------------------------------------------------------------------------
* Copy the values from another instance of this type.
*/
void SetColor3(const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetColor3Ex(Value nr, Value ng, Value nb);
/* --------------------------------------------------------------------------------------------
* Copy the values from an opaque color.
*/
void SetColor4(const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetColor4Ex(Value nr, Value ng, Value nb, Value na);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Set the values from the identified color.
*/
void SetName(StackStrF & name);
/* --------------------------------------------------------------------------------------------
* Get the component values packed inside an integer value.
*/
Uint32 GetRGB() const;
/* --------------------------------------------------------------------------------------------
* Set the component values wxtracted from an integer value.
*/
void SetRGB(Uint32 p);
/* --------------------------------------------------------------------------------------------
* Get the component values packed inside an integer value.
*/
Uint32 GetRGBA() const;
/* --------------------------------------------------------------------------------------------
* Set the component values wxtracted from an integer value.
*/
void SetRGBA(Uint32 p);
/* --------------------------------------------------------------------------------------------
* Get the component values packed inside an integer value.
*/
Uint32 GetARGB() const;
/* --------------------------------------------------------------------------------------------
* Set the component values wxtracted from an integer value.
*/
void SetARGB(Uint32 p);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value min, Value max);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
r = 0, g = 0, b = 0;
}
/* --------------------------------------------------------------------------------------------
* Set the component values to a randomly chosen color.
*/
void Random();
/* --------------------------------------------------------------------------------------------
* Inverse the color.
*/
void Inverse();
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Color3 type from a string.
*/
static const Color3 & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Color3 type from a string.
*/
static const Color3 & GetEx( SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_COLOR3_HPP_

861
module/Base/Color4.cpp Normal file
View File

@ -0,0 +1,861 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Color4.hpp"
#include "Base/Color3.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Color4"))
// ------------------------------------------------------------------------------------------------
const Color4 Color4::NIL = Color4();
const Color4 Color4::MIN = Color4(std::numeric_limits< Color4::Value >::min());
const Color4 Color4::MAX = Color4(std::numeric_limits< Color4::Value >::max());
// ------------------------------------------------------------------------------------------------
SQChar Color4::Delim = ',';
// ------------------------------------------------------------------------------------------------
Color4::Color4()
: r(0), g(0), b(0), a(0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Color4::Color4(Value sv)
: r(sv), g(sv), b(sv), a(0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Color4::Color4(Value rv, Value gv, Value bv)
: r(rv), g(gv), b(bv), a(0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Color4::Color4(Value rv, Value gv, Value bv, Value av)
: r(rv), g(gv), b(bv), a(av)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator = (Value s)
{
r = s;
g = s;
b = s;
a = s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator = (const Color3 & c)
{
r = c.r;
g = c.g;
b = c.b;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator += (const Color4 & c)
{
r += c.r;
g += c.g;
b += c.b;
a += c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator -= (const Color4 & c)
{
r -= c.r;
g -= c.g;
b -= c.b;
a -= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator *= (const Color4 & c)
{
r *= c.r;
g *= c.g;
b *= c.b;
a *= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator /= (const Color4 & c)
{
r /= c.r;
g /= c.g;
b /= c.b;
a /= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator %= (const Color4 & c)
{
r %= c.r;
g %= c.g;
b %= c.b;
a %= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator &= (const Color4 & c)
{
r &= c.r;
g &= c.g;
b &= c.b;
a &= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator |= (const Color4 & c)
{
r |= c.r;
g |= c.g;
b |= c.b;
a |= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator ^= (const Color4 & c)
{
r ^= c.r;
g ^= c.g;
b ^= c.b;
a ^= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator <<= (const Color4 & c)
{
r <<= c.r;
g <<= c.g;
b <<= c.b;
a <<= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator >>= (const Color4 & c)
{
r >>= c.r;
g >>= c.g;
b >>= c.b;
a >>= c.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator += (Value s)
{
r += s;
g += s;
b += s;
a += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator -= (Value s)
{
r -= s;
g -= s;
b -= s;
a -= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator *= (Value s)
{
r *= s;
g *= s;
b *= s;
a *= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator /= (Value s)
{
r /= s;
g /= s;
b /= s;
a /= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator %= (Value s)
{
r %= s;
g %= s;
b %= s;
a %= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator &= (Value s)
{
r &= s;
g &= s;
b &= s;
a &= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator |= (Value s)
{
r |= s;
g |= s;
b |= s;
a |= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator ^= (Value s)
{
r ^= s;
g ^= s;
b ^= s;
a ^= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator <<= (Value s)
{
r <<= s;
g <<= s;
b <<= s;
a <<= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator >>= (Value s)
{
r >>= s;
g >>= s;
b >>= s;
a >>= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator ++ ()
{
++r;
++g;
++b;
++a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 & Color4::operator -- ()
{
--r;
--g;
--b;
--a;
return *this;
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator ++ (int)
{
Color4 state(*this);
++r;
++g;
++b;
++a;
return state;
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator -- (int)
{
Color4 state(*this);
--r;
--g;
--b;
--a;
return state;
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator + (const Color4 & c) const
{
return Color4(r + c.r, g + c.g, b + c.b, a + c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator - (const Color4 & c) const
{
return Color4(r - c.r, g - c.g, b - c.b, a - c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator * (const Color4 & c) const
{
return Color4(r * c.r, g * c.g, b * c.b, a * c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator / (const Color4 & c) const
{
return Color4(r / c.r, g / c.g, b / c.b, a / c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator % (const Color4 & c) const
{
return Color4(r % c.r, g % c.g, b % c.b, a % c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator & (const Color4 & c) const
{
return Color4(r & c.r, g & c.g, b & c.b, a & c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator | (const Color4 & c) const
{
return Color4(r | c.r, g | c.g, b | c.b, a | c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator ^ (const Color4 & c) const
{
return Color4(r ^ c.r, g ^ c.g, b ^ c.b, a ^ c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator << (const Color4 & c) const
{
return Color4(r << c.r, g << c.g, b << c.b, a << c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator >> (const Color4 & c) const
{
return Color4(r >> c.r, g >> c.g, b >> c.b, a >> c.a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator + (Value s) const
{
return Color4(r + s, g + s, b + s, a + s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator - (Value s) const
{
return Color4(r - s, g - s, b - s, a - s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator * (Value s) const
{
return Color4(r * s, g * s, b * s, a * s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator / (Value s) const
{
return Color4(r / s, g / s, b / s, a / s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator % (Value s) const
{
return Color4(r % s, g % s, b % s, a % s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator & (Value s) const
{
return Color4(r & s, g & s, b & s, a & s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator | (Value s) const
{
return Color4(r | s, g | s, b | s, a | s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator ^ (Value s) const
{
return Color4(r ^ s, g ^ s, b ^ s, a ^ s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator << (Value s) const
{
return Color4(r << s, g << s, b << s, a << s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator >> (Value s) const
{
return Color4(r >> s, g >> s, b >> s, a >> s);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator + () const
{
return Color4(r, g, b, a);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator - () const
{
return Color4(0, 0, 0, 0);
}
// ------------------------------------------------------------------------------------------------
Color4 Color4::operator ~ () const
{
return Color4(~r, ~g, ~b, ~a);
}
// ------------------------------------------------------------------------------------------------
bool Color4::operator == (const Color4 & c) const
{
return (r == c.r) && (g == c.g) && (b == c.b) && (a == c.a);
}
// ------------------------------------------------------------------------------------------------
bool Color4::operator != (const Color4 & c) const
{
return (r != c.r) || (g != c.g) || (b != c.b) || (a != c.a);
}
// ------------------------------------------------------------------------------------------------
bool Color4::operator < (const Color4 & c) const
{
return (r < c.r) && (g < c.g) && (b < c.b) && (a < c.a);
}
// ------------------------------------------------------------------------------------------------
bool Color4::operator > (const Color4 & c) const
{
return (r > c.r) && (g > c.g) && (b > c.b) && (a > c.a);
}
// ------------------------------------------------------------------------------------------------
bool Color4::operator <= (const Color4 & c) const
{
return (r <= c.r) && (g <= c.g) && (b <= c.b) && (a <= c.a);
}
// ------------------------------------------------------------------------------------------------
bool Color4::operator >= (const Color4 & c) const
{
return (r >= c.r) && (g >= c.g) && (b >= c.b) && (a >= c.a);
}
// ------------------------------------------------------------------------------------------------
Color4::operator Color3 () const
{
return Color3(r, g, b);
}
// ------------------------------------------------------------------------------------------------
Int32 Color4::Cmp(const Color4 & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Color4::ToString() const
{
return ToStrF("%u,%u,%u,%u", r, g, b, a);
}
// ------------------------------------------------------------------------------------------------
void Color4::SetScalar(Value ns)
{
r = ns;
g = ns;
b = ns;
a = ns;
}
// ------------------------------------------------------------------------------------------------
void Color4::SetColor3(const Color3 & c)
{
r = c.r;
g = c.g;
b = c.b;
a = 0;
}
// ------------------------------------------------------------------------------------------------
void Color4::SetColor3Ex(Value nr, Value ng, Value nb)
{
r = nr;
g = ng;
b = nb;
}
// ------------------------------------------------------------------------------------------------
void Color4::SetColor4(const Color4 & c)
{
r = c.r;
g = c.g;
b = c.b;
a = c.a;
}
// ------------------------------------------------------------------------------------------------
void Color4::SetColor4Ex(Value nr, Value ng, Value nb, Value na)
{
r = nr;
g = ng;
b = nb;
a = na;
}
// ------------------------------------------------------------------------------------------------
void Color4::SetStr(SQChar delim, StackStrF & values)
{
SetColor4(Color4::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Color4::SetName(StackStrF & name)
{
SetColor3(GetColor(name));
}
// ------------------------------------------------------------------------------------------------
Uint32 Color4::GetRGB() const
{
return Uint32(r << 16 | g << 8 | b);
}
// ------------------------------------------------------------------------------------------------
void Color4::SetRGB(Uint32 p)
{
r = static_cast< Value >((p >> 16) & 0xFF);
g = static_cast< Value >((p >> 8) & 0xFF);
b = static_cast< Value >((p) & 0xFF);
}
// ------------------------------------------------------------------------------------------------
Uint32 Color4::GetRGBA() const
{
return Uint32(r << 24 | g << 16 | b << 8 | a);
}
// ------------------------------------------------------------------------------------------------
void Color4::SetRGBA(Uint32 p)
{
r = static_cast< Value >((p >> 24) & 0xFF);
g = static_cast< Value >((p >> 16) & 0xFF);
b = static_cast< Value >((p >> 8) & 0xFF);
a = static_cast< Value >((p) & 0xFF);
}
// ------------------------------------------------------------------------------------------------
Uint32 Color4::GetARGB() const
{
return Uint32(a << 24 | r << 16 | g << 8 | b);
}
// ------------------------------------------------------------------------------------------------
void Color4::SetARGB(Uint32 p)
{
a = static_cast< Value >((p >> 24) & 0xFF);
r = static_cast< Value >((p >> 16) & 0xFF);
g = static_cast< Value >((p >> 8) & 0xFF);
b = static_cast< Value >((p) & 0xFF);
}
// ------------------------------------------------------------------------------------------------
void Color4::Generate()
{
r = GetRandomUint8();
g = GetRandomUint8();
b = GetRandomUint8();
a = GetRandomUint8();
}
// ------------------------------------------------------------------------------------------------
void Color4::Generate(Value min, Value max)
{
if (max < min)
{
STHROWF("max value is lower than min value");
}
r = GetRandomUint8(min, max);
g = GetRandomUint8(min, max);
b = GetRandomUint8(min, max);
a = GetRandomUint8(min, max);
}
// ------------------------------------------------------------------------------------------------
void Color4::Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax, Value amin, Value amax)
{
if (rmax < rmin || gmax < gmin || bmax < bmin || amax < amin)
{
STHROWF("max value is lower than min value");
}
r = GetRandomUint8(rmin, rmax);
g = GetRandomUint8(gmin, gmax);
b = GetRandomUint8(bmin, bmax);
a = GetRandomUint8(bmin, bmax);
}
// ------------------------------------------------------------------------------------------------
void Color4::Random()
{
SetColor3(GetRandomColor());
}
// ------------------------------------------------------------------------------------------------
void Color4::Inverse()
{
r = static_cast< Value >(~r);
g = static_cast< Value >(~g);
b = static_cast< Value >(~b);
a = static_cast< Value >(~a);
}
// ------------------------------------------------------------------------------------------------
const Color4 & Color4::Get(StackStrF & str)
{
return Color4::GetEx(Color4::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Color4 & Color4::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %u , %u , %u , %u ");
static Color4 col;
// The minimum and maximum values supported by the Color4 type
static const Uint32 min = std::numeric_limits< Color4::Value >::min();
static const Uint32 max = std::numeric_limits< Color4::Value >::max();
// Clear previous values, if any
col.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return col; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
fs[9] = delim;
fs[14] = delim;
// The sscanf function requires at least 32 bit integers
Uint32 r = 0, g = 0, b = 0, a = 0;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, fs, &r, &g, &b, &a);
// Cast the extracted integers to the value used by the Color4 type
col.r = static_cast< Color4::Value >(Clamp(r, min, max));
col.g = static_cast< Color4::Value >(Clamp(g, min, max));
col.b = static_cast< Color4::Value >(Clamp(b, min, max));
col.a = static_cast< Color4::Value >(Clamp(a, min, max));
// Return the resulted value
return col;
}
// ------------------------------------------------------------------------------------------------
const Color4 & GetColor4()
{
static Color4 col;
col.Clear();
return col;
}
// ------------------------------------------------------------------------------------------------
const Color4 & GetColor4(Uint8 sv)
{
static Color4 col;
col.SetScalar(sv);
return col;
}
// ------------------------------------------------------------------------------------------------
const Color4 & GetColor4(Uint8 rv, Uint8 gv, Uint8 bv)
{
static Color4 col;
col.SetColor3Ex(rv, gv, bv);
return col;
}
// ------------------------------------------------------------------------------------------------
const Color4 & GetColor4(Uint8 rv, Uint8 gv, Uint8 bv, Uint8 av)
{
static Color4 col;
col.SetColor4Ex(rv, gv, bv, av);
return col;
}
// ------------------------------------------------------------------------------------------------
const Color4 & GetColor4(const Color4 & o)
{
static Color4 col;
col.SetColor4(o);
return col;
}
// ================================================================================================
void Register_Color4(HSQUIRRELVM vm)
{
typedef Color4::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Color4 >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< Val, Val, Val >()
.Ctor< Val, Val, Val, Val >()
// Member Variables
.Var(_SC("r"), &Color4::r)
.Var(_SC("g"), &Color4::g)
.Var(_SC("b"), &Color4::b)
.Var(_SC("a"), &Color4::a)
.Var(_SC("R"), &Color4::r)
.Var(_SC("G"), &Color4::g)
.Var(_SC("B"), &Color4::b)
.Var(_SC("A"), &Color4::a)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Color4::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Color4 >, SQFloat, SQInteger, bool, std::nullptr_t, Color4 >)
.Func< Color4 (Color4::*)(void) const >(_SC("_unm"), &Color4::operator -)
// Properties
.Prop(_SC("RGB"), &Color4::GetRGB, &Color4::SetRGB)
.Prop(_SC("RGBA"), &Color4::GetRGBA, &Color4::SetRGBA)
.Prop(_SC("ARGB"), &Color4::GetARGB, &Color4::SetARGB)
// Member Methods
.Func(_SC("SetScalar"), &Color4::SetScalar)
.Func(_SC("SetColor3"), &Color4::SetColor3)
.Func(_SC("SetColor3Ex"), &Color4::SetColor3Ex)
.Func(_SC("SetColor4"), &Color4::SetColor4)
.Func(_SC("SetColor4Ex"), &Color4::SetColor4Ex)
.FmtFunc(_SC("SetStr"), &Color4::SetStr)
.FmtFunc(_SC("SetName"), &Color4::SetName)
.Func(_SC("Clear"), &Color4::Clear)
.Func(_SC("Random"), &Color4::Random)
.Func(_SC("Inverse"), &Color4::Inverse)
// Member Overloads
.Overload< void (Color4::*)(void) >(_SC("Generate"), &Color4::Generate)
.Overload< void (Color4::*)(Val, Val) >(_SC("Generate"), &Color4::Generate)
.Overload< void (Color4::*)(Val, Val, Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Color4::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Color4 >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Color4 >)
.StaticFmtFunc(_SC("FromStr"), &Color4::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Color4::GetEx)
// Operator Exposure
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opAddAssign"), &Color4::operator +=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opSubAssign"), &Color4::operator -=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opMulAssign"), &Color4::operator *=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opDivAssign"), &Color4::operator /=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opModAssign"), &Color4::operator %=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opAndAssign"), &Color4::operator &=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opOrAssign"), &Color4::operator |=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opXorAssign"), &Color4::operator ^=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opShlAssign"), &Color4::operator <<=)
.Func< Color4 & (Color4::*)(const Color4 &) >(_SC("opShrAssign"), &Color4::operator >>=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opAddAssignS"), &Color4::operator +=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opSubAssignS"), &Color4::operator -=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opMulAssignS"), &Color4::operator *=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opDivAssignS"), &Color4::operator /=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opModAssignS"), &Color4::operator %=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opAndAssignS"), &Color4::operator &=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opOrAssignS"), &Color4::operator |=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opXorAssignS"), &Color4::operator ^=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opShlAssignS"), &Color4::operator <<=)
.Func< Color4 & (Color4::*)(Color4::Value) >(_SC("opShrAssignS"), &Color4::operator >>=)
.Func< Color4 & (Color4::*)(void) >(_SC("opPreInc"), &Color4::operator ++)
.Func< Color4 & (Color4::*)(void) >(_SC("opPreDec"), &Color4::operator --)
.Func< Color4 (Color4::*)(int) >(_SC("opPostInc"), &Color4::operator ++)
.Func< Color4 (Color4::*)(int) >(_SC("opPostDec"), &Color4::operator --)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opAdd"), &Color4::operator +)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opSub"), &Color4::operator -)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opMul"), &Color4::operator *)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opDiv"), &Color4::operator /)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opMod"), &Color4::operator %)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opAnd"), &Color4::operator &)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opOr"), &Color4::operator |)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opShl"), &Color4::operator ^)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opShl"), &Color4::operator <<)
.Func< Color4 (Color4::*)(const Color4 &) const >(_SC("opShr"), &Color4::operator >>)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opAddS"), &Color4::operator +)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opSubS"), &Color4::operator -)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opMulS"), &Color4::operator *)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opDivS"), &Color4::operator /)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opModS"), &Color4::operator %)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opAndS"), &Color4::operator &)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opOrS"), &Color4::operator |)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opShlS"), &Color4::operator ^)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opShlS"), &Color4::operator <<)
.Func< Color4 (Color4::*)(Color4::Value) const >(_SC("opShrS"), &Color4::operator >>)
.Func< Color4 (Color4::*)(void) const >(_SC("opUnPlus"), &Color4::operator +)
.Func< Color4 (Color4::*)(void) const >(_SC("opUnMinus"), &Color4::operator -)
.Func< Color4 (Color4::*)(void) const >(_SC("opCom"), &Color4::operator ~)
.Func< bool (Color4::*)(const Color4 &) const >(_SC("opEqual"), &Color4::operator ==)
.Func< bool (Color4::*)(const Color4 &) const >(_SC("opNotEqual"), &Color4::operator !=)
.Func< bool (Color4::*)(const Color4 &) const >(_SC("opLessThan"), &Color4::operator <)
.Func< bool (Color4::*)(const Color4 &) const >(_SC("opGreaterThan"), &Color4::operator >)
.Func< bool (Color4::*)(const Color4 &) const >(_SC("opLessEqual"), &Color4::operator <=)
.Func< bool (Color4::*)(const Color4 &) const >(_SC("opGreaterEqual"), &Color4::operator >=)
);
}
} // Namespace:: SqMod

515
module/Base/Color4.hpp Normal file
View File

@ -0,0 +1,515 @@
#ifndef _BASE_COLOR4_HPP_
#define _BASE_COLOR4_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent a transparent RGBA color.
*/
struct Color4
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef unsigned char Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Color4 NIL;
static const Color4 MIN;
static const Color4 MAX;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The red, green and blue components of this type.
*/
Value r, g, b, a;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Color4();
/* --------------------------------------------------------------------------------------------
* Construct a color with all components with the same specified color.
*/
explicit Color4(Value sv);
/* --------------------------------------------------------------------------------------------
* Construct with individually specified red, green and blue colors.
*/
Color4(Value rv, Value gv, Value bv);
/* --------------------------------------------------------------------------------------------
* Construct with individually specified red, green, blue and alpha colors.
*/
Color4(Value rv, Value gv, Value bv, Value av);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Color4(const Color4 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Color4(Color4 && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Color4() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Color4 & operator = (const Color4 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Color4 & operator = (Color4 && o) = default;
/* --------------------------------------------------------------------------------------------
* Scalar value assignment operator.
*/
Color4 & operator = (Value s);
/* --------------------------------------------------------------------------------------------
* Opaque color assignment operator.
*/
Color4 & operator = (const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Color4 & operator += (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Color4 & operator -= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Color4 & operator *= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Color4 & operator /= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Color4 & operator %= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise AND assignment operator.
*/
Color4 & operator &= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise OR assignment operator.
*/
Color4 & operator |= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise XOR assignment operator.
*/
Color4 & operator ^= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise left shift assignment operator.
*/
Color4 & operator <<= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Bitwise right shift assignment operator.
*/
Color4 & operator >>= (const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Scalar value addition assignment operator.
*/
Color4 & operator += (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction assignment operator.
*/
Color4 & operator -= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication assignment operator.
*/
Color4 & operator *= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value division assignment operator.
*/
Color4 & operator /= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value modulo assignment operator.
*/
Color4 & operator %= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise AND assignment operator.
*/
Color4 & operator &= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise OR assignment operator.
*/
Color4 & operator |= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise XOR assignment operator.
*/
Color4 & operator ^= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise left shift assignment operator.
*/
Color4 & operator <<= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise right shift assignment operator.
*/
Color4 & operator >>= (Value s);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Color4 & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Color4 & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Color4 operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Color4 operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Color4 operator + (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Color4 operator - (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Color4 operator * (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Color4 operator / (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Color4 operator % (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise AND operator.
*/
Color4 operator & (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise OR operator.
*/
Color4 operator | (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise XOR operator.
*/
Color4 operator ^ (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise shift left operator.
*/
Color4 operator << (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Bitwise shift right operator.
*/
Color4 operator >> (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Scalar value addition operator.
*/
Color4 operator + (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction operator.
*/
Color4 operator - (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication operator.
*/
Color4 operator * (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value division operator.
*/
Color4 operator / (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value modulo operator.
*/
Color4 operator % (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise AND operator.
*/
Color4 operator & (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise OR operator.
*/
Color4 operator | (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise XOR operator.
*/
Color4 operator ^ (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise shift left operator.
*/
Color4 operator << (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise shift right operator.
*/
Color4 operator >> (Value s) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Color4 operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Color4 operator - () const;
/* --------------------------------------------------------------------------------------------
* Bitwise NOT operator.
*/
Color4 operator ~ () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Implicit conversion to opaque color.
*/
operator Color3 () const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Color4 & c) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Color4(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Color4(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Color4(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(Color4(static_cast< Value >(0)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value.
*/
void SetScalar(Value ns);
/* --------------------------------------------------------------------------------------------
* Copy the values from an opaque color.
*/
void SetColor3(const Color3 & c);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetColor3Ex(Value nr, Value ng, Value nb);
/* --------------------------------------------------------------------------------------------
* Copy the values from another instance of this type.
*/
void SetColor4(const Color4 & c);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetColor4Ex(Value nr, Value ng, Value nb, Value na);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & name);
/* --------------------------------------------------------------------------------------------
* Set the values from the identified color.
*/
void SetName(StackStrF & name);
/* --------------------------------------------------------------------------------------------
* Get the component values packed inside an integer value.
*/
Uint32 GetRGB() const;
/* --------------------------------------------------------------------------------------------
* Set the component values wxtracted from an integer value.
*/
void SetRGB(Uint32 p);
/* --------------------------------------------------------------------------------------------
* Get the component values packed inside an integer value.
*/
Uint32 GetRGBA() const;
/* --------------------------------------------------------------------------------------------
* Set the component values wxtracted from an integer value.
*/
void SetRGBA(Uint32 p);
/* --------------------------------------------------------------------------------------------
* Get the component values packed inside an integer value.
*/
Uint32 GetARGB() const;
/* --------------------------------------------------------------------------------------------
* Set the component values wxtracted from an integer value.
*/
void SetARGB(Uint32 p);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value min, Value max);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax, Value amin, Value amax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
r = 0, g = 0, b = 0, a = 0;
}
/* --------------------------------------------------------------------------------------------
* Set the component values to a randomly chosen color.
*/
void Random();
/* --------------------------------------------------------------------------------------------
* Inverse the color.
*/
void Inverse();
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Color4 type from a string.
*/
static const Color4 & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Color4 type from a string.
*/
static const Color4 & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_COLOR4_HPP_

809
module/Base/DynArg.hpp Normal file
View File

@ -0,0 +1,809 @@
#ifndef _BASE_DYNARG_HPP_
#define _BASE_DYNARG_HPP_
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class used to check if a certain operation is possible on the specified argument.
*/
template < typename U > struct SqDynArg
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INSTANCE);
}
template < typename F > static inline auto Do(F & fn, HSQUIRRELVM vm)
{
Var< U * > var(vm, 2);
// Validate the obtained instance
if (!var.value)
{
STHROWF("No such instance");
}
// Attempt to perform the requested operation
return fn(*var.value);
}
template < typename F > static inline auto Do(const F & fn, HSQUIRRELVM vm)
{
Var< U * > var(vm, 2);
// Validate the obtained instance
if (!var.value)
{
STHROWF("No such instance");
}
// Attempt to perform the requested operation
return fn(*var.value);
}
};
/* ------------------------------------------------------------------------------------------------
* Instance pointer specializations of the argument checking structure.
*/
template < typename U > struct SqDynArg< U * >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INSTANCE);
}
template < typename F > static inline auto Do(F & fn, HSQUIRRELVM vm)
{
Var< U * > var(vm, 2);
// Validate the obtained instance
if (!var.value)
{
STHROWF("No such instance");
}
// Attempt to perform the requested operation
return fn(var.value);
}
template < typename F > static inline auto Do(const F & fn, HSQUIRRELVM vm)
{
Var< U * > var(vm, 2);
// Validate the obtained instance
if (!var.value)
{
STHROWF("No such instance");
}
// Attempt to perform the requested operation
return fn(var.value);
}
};
/* ------------------------------------------------------------------------------------------------
* Instance pointer specializations of the argument checking structure.
*/
template < typename U > struct SqDynArg< const U * >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INSTANCE);
}
template < typename F > static inline auto Do(F & fn, HSQUIRRELVM vm)
{
Var< U * > var(vm, 2);
// Validate the obtained instance
if (!var.value)
{
STHROWF("No such instance");
}
// Attempt to perform the requested operation
return fn(*var.value);
}
template < typename F > static inline auto Do(const F & fn, HSQUIRRELVM vm)
{
Var< U * > var(vm, 2);
// Validate the obtained instance
if (!var.value)
{
STHROWF("No such instance");
}
// Attempt to perform the requested operation
return fn(*var.value);
}
};
/* ------------------------------------------------------------------------------------------------
* Inherited by the base specializations of the argument checking structure.
*/
template < typename U, SQObjectType SqT > struct SqDynArgBase
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == SqT);
}
template < typename F > static inline auto Do(F & fn, HSQUIRRELVM vm)
{
Var< U > var(vm, 2);
// Attempt to perform the requested operation
return fn(var.value);
}
template < typename F > static inline auto Do(const F & fn, HSQUIRRELVM vm)
{
Var< U > var(vm, 2);
// Attempt to perform the requested operation
return fn(var.value);
}
};
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< char >
: public SqDynArgBase< char, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< signed char >
: public SqDynArgBase< signed char, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< unsigned char >
: public SqDynArgBase< unsigned char, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< signed short >
: public SqDynArgBase< signed short, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< unsigned short >
: public SqDynArgBase< unsigned short, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< signed int >
: public SqDynArgBase< signed int, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< unsigned int >
: public SqDynArgBase< unsigned int, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< signed long >
: public SqDynArgBase< signed long, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< unsigned long >
: public SqDynArgBase< unsigned long, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< signed long long >
: public SqDynArgBase< signed long long, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< unsigned long long >
: public SqDynArgBase< unsigned long long, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< float >
: public SqDynArgBase< float, OT_FLOAT >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< double >
: public SqDynArgBase< double, OT_FLOAT >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< bool >
: public SqDynArgBase< bool, OT_BOOL >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< SQChar * >
: public SqDynArgBase< SQChar *, OT_STRING >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< const SQChar * >
: public SqDynArgBase< const SQChar *, OT_STRING >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< String >
: public SqDynArgBase< String, OT_STRING >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< Table >
: public SqDynArgBase< Table, OT_TABLE >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynArg< Array >
: public SqDynArgBase< Array, OT_ARRAY >
{ /* ... */ };
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure for functions.
*/
template < > struct SqDynArg< Function >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
const SQObjectType type = sq_gettype(vm, 2);
return (type == OT_CLOSURE || type == OT_NATIVECLOSURE);
}
template < typename F > static inline auto Do(F & fn, HSQUIRRELVM vm)
{
Var< Function > var(vm, 2);
// Attempt to perform the requested operation
return fn(var.value);
}
template < typename F > static inline auto Do(const F & fn, HSQUIRRELVM vm)
{
Var< Function > var(vm, 2);
// Attempt to perform the requested operation
return fn(var.value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure for objects.
*/
template < > struct SqDynArg< Object >
{
static inline bool CanPop(HSQUIRRELVM /*vm*/)
{
return true; // Objects can use any type.
}
template < typename F > static inline auto Do(F & fn, HSQUIRRELVM vm)
{
Var< Object > var(vm, 2);
// Attempt to perform the requested operation
return fn(var.value);
}
template < typename F > static inline auto Do(const F & fn, HSQUIRRELVM vm)
{
Var< Object > var(vm, 2);
// Attempt to perform the requested operation
return fn(var.value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure for null.
*/
template < > struct SqDynArg< std::nullptr_t >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_NULL);
}
template < typename F > static inline auto Do(F & fn, HSQUIRRELVM /*vm*/)
{
// Attempt to perform the requested operation
return fn(nullptr);
}
template < typename F > static inline auto Do(const F & fn, HSQUIRRELVM /*vm*/)
{
// Attempt to perform the requested operation
return fn(nullptr);
}
};
/* ------------------------------------------------------------------------------------------------
* Used to perform an operation on multiple types specified at compile time.
*/
template < typename... Ts > struct SqDynArgImpl;
/* ------------------------------------------------------------------------------------------------
* Zeroth case of the operation. No known operation of such pairs of types at this point.
*/
template < > struct SqDynArgImpl< >
{
template < typename T > static Int32 Try(const T & /*val*/, HSQUIRRELVM vm)
{
const String tn1(SqTypeName(vm, 1));
const String tn2(SqTypeName(vm, 2));
return sq_throwerror(vm, ToStrF("Such operation is not possible between (%s) and (%s)",
tn1.c_str(), tn2.c_str()));
}
};
/* ------------------------------------------------------------------------------------------------
* Argument pack type pealing. Attempt to perform the operation with a specified type.
*/
template < typename U, typename... Ts > struct SqDynArgImpl< U, Ts... >
{
template < typename F > static Int32 Try(F & fn, HSQUIRRELVM vm)
{
typedef typename std::decay< U >::type ArgType;
// Can the stack value be used with the current type?
if (SqDynArg< ArgType >::CanPop(vm))
{
// If not an instance then don't use a try catch block
if (sq_gettype(vm, 2) != OT_INSTANCE)
{
// Attempt to perform the operation and push the result on the stack
PushVar(vm, SqDynArg< ArgType >::Do(fn, vm));
// Specify that we completed the search and have a result
return 1;
}
// Instances require a try/catch block since we can't differentiate types
try
{
// Attempt to perform the operation and push the result on the stack
PushVar(vm, SqDynArg< ArgType >::Do(fn, vm));
// Specify that we completed the search and have a result
return 1;
}
catch (const Sqrat::Exception & e)
{
// Probably the wrong type
}
catch (...)
{
// Something very bad happened. At this point, we just don't want to let
// exceptions propagate to the virtual machine and we must end here.
// Either way, reaching this point is bad and we just shuved it under
// the rug. This is bad practice but circumstances forced me.
// Don't do this at home kids!
return -1;
}
}
// On to the next type
return SqDynArgImpl< Ts... >::Try(fn, vm);
}
};
/* ------------------------------------------------------------------------------------------------
* Squirrel function that forwards the call to the actual implementation.
*/
template < typename F, typename U, typename... Ts > SQInteger SqDynArgFwd(HSQUIRRELVM vm)
{
// Make sure that there are enough parameters on the stack
if (sq_gettop(vm) < 2)
{
return sq_throwerror(vm, "Insufficient parameters for such operation");
}
// Attempt to create the functor that performs the operation
F fn(vm);
// Is this functor in a valid state?
if (!fn)
{
return sq_throwerror(vm, "Functor failed to initialize");
}
// Attempt to perform the comparison
try
{
return SqDynArgImpl< U, Ts... >::Try(fn, vm);
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
catch (...)
{
return sq_throwerror(vm, "Unknown error occurred during comparison");
}
// We shouldn't really reach this point but something must be returned
return sq_throwerror(vm, "Operation encountered unknown behavior");
}
/* ------------------------------------------------------------------------------------------------
* Functor used to perform comparison.
*/
template < typename T > struct SqDynArgCmpFn
{
// --------------------------------------------------------------------------------------------
HSQUIRRELVM mVM; // The squirrel virtual machine.
Var< T * > mVar; // The instance of the base type.
/* --------------------------------------------------------------------------------------------
* Base constructor. (required)
*/
SqDynArgCmpFn(HSQUIRRELVM vm)
: mVM(vm), mVar(vm, 1)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean. (required)
*/
operator bool () const
{
return (mVar.value != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for references. (required)
*/
template < typename U > SQInteger operator () (U & v) const
{
return mVar.value->Cmp(v);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const references. (required)
*/
template < typename U > SQInteger operator () (const U & v) const
{
return mVar.value->Cmp(v);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for pointers. (required)
*/
template < typename U > SQInteger operator () (U * v) const
{
return mVar.value->Cmp(v);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const pointers. (required)
*/
template < typename U > SQInteger operator () (const U * v) const
{
return mVar.value->Cmp(v);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for null pointers. (required)
*/
SQInteger operator () (std::nullptr_t) const
{
return mVar.value->Cmp(nullptr);
}
};
/* ------------------------------------------------------------------------------------------------
* Functor used to perform addition.
*/
template < typename T > struct SqDynArgAddFn
{
// --------------------------------------------------------------------------------------------
HSQUIRRELVM mVM; // The squirrel virtual machine.
Var< T * > mVar; // The instance of the base type.
/* --------------------------------------------------------------------------------------------
* Base constructor. (required)
*/
SqDynArgAddFn(HSQUIRRELVM vm)
: mVM(vm), mVar(vm, 1)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean. (required)
*/
operator bool () const
{
return (mVar.value != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for references. (required)
*/
template < typename U > T operator () (U & v) const
{
return (*mVar.value) + v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const references. (required)
*/
template < typename U > T operator () (const U & v) const
{
return (*mVar.value) + v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for pointers. (required)
*/
template < typename U > T operator () (U * v) const
{
return (*mVar.value) + v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const pointers. (required)
*/
template < typename U > T operator () (const U * v) const
{
return (*mVar.value) + v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for null pointers. (required)
*/
T operator () (std::nullptr_t) const
{
return (*mVar.value);
}
};
/* ------------------------------------------------------------------------------------------------
* Functor used to perform subtraction.
*/
template < typename T > struct SqDynArgSubFn
{
// --------------------------------------------------------------------------------------------
HSQUIRRELVM mVM; // The squirrel virtual machine.
Var< T * > mVar; // The instance of the base type.
/* --------------------------------------------------------------------------------------------
* Base constructor. (required)
*/
SqDynArgSubFn(HSQUIRRELVM vm)
: mVM(vm), mVar(vm, 1)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean. (required)
*/
operator bool () const
{
return (mVar.value != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for references. (required)
*/
template < typename U > T operator () (U & v) const
{
return (*mVar.value) - v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const references. (required)
*/
template < typename U > T operator () (const U & v) const
{
return (*mVar.value) - v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for pointers. (required)
*/
template < typename U > T operator () (U * v) const
{
return (*mVar.value) - v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const pointers. (required)
*/
template < typename U > T operator () (const U * v) const
{
return (*mVar.value) - v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for null pointers. (required)
*/
T operator () (std::nullptr_t) const
{
return (*mVar.value);
}
};
/* ------------------------------------------------------------------------------------------------
* Functor used to perform multiplication.
*/
template < typename T > struct SqDynArgMulFn
{
// --------------------------------------------------------------------------------------------
HSQUIRRELVM mVM; // The squirrel virtual machine.
Var< T * > mVar; // The instance of the base type.
/* --------------------------------------------------------------------------------------------
* Base constructor. (required)
*/
SqDynArgMulFn(HSQUIRRELVM vm)
: mVM(vm), mVar(vm, 1)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean. (required)
*/
operator bool () const
{
return (mVar.value != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for references. (required)
*/
template < typename U > T operator () (U & v) const
{
return (*mVar.value) * v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const references. (required)
*/
template < typename U > T operator () (const U & v) const
{
return (*mVar.value) * v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for pointers. (required)
*/
template < typename U > T operator () (U * v) const
{
return (*mVar.value) * v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const pointers. (required)
*/
template < typename U > T operator () (const U * v) const
{
return (*mVar.value) * v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for null pointers. (required)
*/
T operator () (std::nullptr_t) const
{
return (*mVar.value) * static_cast< SQInteger >(0);
}
};
/* ------------------------------------------------------------------------------------------------
* Functor used to perform division.
*/
template < typename T > struct SqDynArgDivFn
{
// --------------------------------------------------------------------------------------------
HSQUIRRELVM mVM; // The squirrel virtual machine.
Var< T * > mVar; // The instance of the base type.
/* --------------------------------------------------------------------------------------------
* Base constructor. (required)
*/
SqDynArgDivFn(HSQUIRRELVM vm)
: mVM(vm), mVar(vm, 1)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean. (required)
*/
operator bool () const
{
return (mVar.value != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for references. (required)
*/
template < typename U > T operator () (U & v) const
{
return (*mVar.value) / v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const references. (required)
*/
template < typename U > T operator () (const U & v) const
{
return (*mVar.value) / v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for pointers. (required)
*/
template < typename U > T operator () (U * v) const
{
return (*mVar.value) / v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const pointers. (required)
*/
template < typename U > T operator () (const U * v) const
{
return (*mVar.value) / v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for null pointers. (required)
*/
T operator () (std::nullptr_t) const
{
return (*mVar.value) / static_cast< SQInteger >(0);
}
};
/* ------------------------------------------------------------------------------------------------
* Functor used to perform modulus.
*/
template < typename T > struct SqDynArgModFn
{
// --------------------------------------------------------------------------------------------
HSQUIRRELVM mVM; // The squirrel virtual machine.
Var< T * > mVar; // The instance of the base type.
/* --------------------------------------------------------------------------------------------
* Base constructor. (required)
*/
SqDynArgModFn(HSQUIRRELVM vm)
: mVM(vm), mVar(vm, 1)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean. (required)
*/
operator bool () const
{
return (mVar.value != nullptr);
}
/* --------------------------------------------------------------------------------------------
* Function call operator for references. (required)
*/
template < typename U > T operator () (U & v) const
{
return (*mVar.value) % v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const references. (required)
*/
template < typename U > T operator () (const U & v) const
{
return (*mVar.value) % v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for pointers. (required)
*/
template < typename U > T operator () (U * v) const
{
return (*mVar.value) % v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for const pointers. (required)
*/
template < typename U > T operator () (const U * v) const
{
return (*mVar.value) % v;
}
/* --------------------------------------------------------------------------------------------
* Function call operator for null pointers. (required)
*/
T operator () (std::nullptr_t) const
{
return (*mVar.value) % static_cast< SQInteger >(0);
}
};
} // Namespace:: SqMod
#endif // _BASE_DYNARG_HPP_

889
module/Base/Quaternion.cpp Normal file
View File

@ -0,0 +1,889 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Quaternion.hpp"
#include "Base/Vector3.hpp"
#include "Base/Vector4.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
#define STOVAL(v) static_cast< Quaternion::Value >(v)
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Quaternion"))
// ------------------------------------------------------------------------------------------------
const Quaternion Quaternion::NIL(0);
const Quaternion Quaternion::MIN(std::numeric_limits< Quaternion::Value >::min());
const Quaternion Quaternion::MAX(std::numeric_limits< Quaternion::Value >::max());
const Quaternion Quaternion::IDENTITY(1.0, 0.0, 0.0, 0.0);
// ------------------------------------------------------------------------------------------------
SQChar Quaternion::Delim = ',';
// ------------------------------------------------------------------------------------------------
Quaternion::Quaternion()
: x(0.0), y(0.0), z(0.0), w(0.0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Quaternion::Quaternion(Value sv)
: x(sv), y(sv), z(sv), w(sv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Quaternion::Quaternion(Value xv, Value yv, Value zv)
: x(xv), y(yv), z(zv), w(0.0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Quaternion::Quaternion(Value xv, Value yv, Value zv, Value wv)
: x(xv), y(yv), z(zv), w(wv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator = (Value s)
{
x = s;
y = s;
z = s;
w = s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator = (const Vector3 & q)
{
x = q.x;
y = q.y;
z = q.z;
w = 0.0;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator = (const Vector4 & q)
{
x = q.x;
y = q.y;
z = q.z;
w = q.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator += (const Quaternion & q)
{
x += q.x;
y += q.y;
z += q.z;
w += q.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator -= (const Quaternion & q)
{
x -= q.x;
y -= q.y;
z -= q.z;
w -= q.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator *= (const Quaternion & q)
{
x *= q.x;
y *= q.y;
z *= q.z;
w *= q.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator /= (const Quaternion & q)
{
x /= q.x;
y /= q.y;
z /= q.z;
w /= q.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator %= (const Quaternion & q)
{
x = std::fmod(x, q.x);
y = std::fmod(y, q.y);
z = std::fmod(z, q.z);
w = std::fmod(w, q.w);
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator += (Value s)
{
x += s;
y += s;
z += s;
w += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator -= (Value s)
{
x -= s;
y -= s;
z -= s;
w -= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator *= (Value s)
{
x *= s;
y *= s;
z *= s;
w *= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator /= (Value s)
{
x /= s;
y /= s;
z /= s;
w /= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator %= (Value s)
{
x = std::fmod(x, s);
y = std::fmod(y, s);
z = std::fmod(z, s);
w = std::fmod(w, s);
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator ++ ()
{
++x;
++y;
++z;
++w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion & Quaternion::operator -- ()
{
--x;
--y;
--z;
--w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator ++ (int)
{
Quaternion state(*this);
++x;
++y;
++z;
++w;
return state;
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator -- (int)
{
Quaternion state(*this);
--x;
--y;
--z;
--w;
return state;
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator + (const Quaternion & q) const
{
return Quaternion(x + q.x, y + q.y, z + q.z, w + q.w);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator + (Value s) const
{
return Quaternion(x + s, y + s, z + s, w + s);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator - (const Quaternion & q) const
{
return Quaternion(x - q.x, y - q.y, z - q.z, w - q.w);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator - (Value s) const
{
return Quaternion(x - s, y - s, z - s, w - s);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator * (const Quaternion & q) const
{
return Quaternion(x * q.x, y * q.y, z * q.z, w * q.w);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator * (Value s) const
{
return Quaternion(x * s, y * s, z * s, w * s);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator / (const Quaternion & q) const
{
return Quaternion(x / q.x, y / q.y, z / q.z, w / q.w);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator / (Value s) const
{
return Quaternion(x / s, y / s, z / s, w / s);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator % (const Quaternion & q) const
{
return Quaternion(std::fmod(x, q.x), std::fmod(y, q.y), std::fmod(z, q.z), std::fmod(w, q.w));
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator % (Value s) const
{
return Quaternion(std::fmod(x, s), std::fmod(y, s), std::fmod(z, s), std::fmod(w, s));
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator + () const
{
return Quaternion(std::fabs(x), std::fabs(y), std::fabs(z), std::fabs(w));
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::operator - () const
{
return Quaternion(-x, -y, -z, -w);
}
// ------------------------------------------------------------------------------------------------
bool Quaternion::operator == (const Quaternion & q) const
{
return EpsEq(x, q.x) && EpsEq(y, q.y) && EpsEq(z, q.z) && EpsEq(w, q.w);
}
// ------------------------------------------------------------------------------------------------
bool Quaternion::operator != (const Quaternion & q) const
{
return !EpsEq(x, q.x) || !EpsEq(y, q.y) || !EpsEq(z, q.z) || !EpsEq(w, q.w);
}
// ------------------------------------------------------------------------------------------------
bool Quaternion::operator < (const Quaternion & q) const
{
return EpsLt(x, q.x) && EpsLt(y, q.y) && EpsLt(z, q.z) && EpsLt(w, q.w);
}
// ------------------------------------------------------------------------------------------------
bool Quaternion::operator > (const Quaternion & q) const
{
return EpsGt(x, q.x) && EpsGt(y, q.y) && EpsGt(z, q.z) && EpsGt(w, q.w);
}
// ------------------------------------------------------------------------------------------------
bool Quaternion::operator <= (const Quaternion & q) const
{
return EpsLtEq(x, q.x) && EpsLtEq(y, q.y) && EpsLtEq(z, q.z) && EpsLtEq(w, q.w);
}
// ------------------------------------------------------------------------------------------------
bool Quaternion::operator >= (const Quaternion & q) const
{
return EpsGtEq(x, q.x) && EpsGtEq(y, q.y) && EpsGtEq(z, q.z) && EpsGtEq(w, q.w);
}
// ------------------------------------------------------------------------------------------------
Int32 Quaternion::Cmp(const Quaternion & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Quaternion::ToString() const
{
return ToStrF("%f,%f,%f,%f", x, y, z, w);
}
// ------------------------------------------------------------------------------------------------
void Quaternion::SetScalar(Value ns)
{
x = ns;
y = ns;
z = ns;
w = ns;
}
// ------------------------------------------------------------------------------------------------
void Quaternion::SetQuaternion(const Quaternion & q)
{
x = q.x;
y = q.y;
z = q.z;
w = q.w;
}
// ------------------------------------------------------------------------------------------------
void Quaternion::SetQuaternionEx(Value nx, Value ny, Value nz, Value nw)
{
x = nx;
y = ny;
z = nz;
w = nw;
}
// ------------------------------------------------------------------------------------------------
void Quaternion::SetVector3(const Vector3 & v)
{
SetVector3Ex(v.x, v.y, v.z);
}
// ------------------------------------------------------------------------------------------------
void Quaternion::SetVector3Ex(Value nx, Value ny, Value nz)
{
Float64 angle;
angle = (nx * 0.5);
const Float64 sr = std::sin(angle);
const Float64 cr = std::cos(angle);
angle = (ny * 0.5);
const Float64 sp = std::sin(angle);
const Float64 cp = std::cos(angle);
angle = (nz * 0.5);
const Float64 sy = std::sin(angle);
const Float64 cy = std::cos(angle);
const Float64 cpcy = (cp * cy);
const Float64 spcy = (sp * cy);
const Float64 cpsy = (cp * sy);
const Float64 spsy = (sp * sy);
x = STOVAL(sr * cpcy - cr * spsy);
y = STOVAL(cr * spcy + sr * cpsy);
z = STOVAL(cr * cpsy - sr * spcy);
w = STOVAL(cr * cpcy + sr * spsy);
Normalize();
}
// ------------------------------------------------------------------------------------------------
void Quaternion::SetVector4(const Vector4 & v)
{
x = v.x;
y = v.y;
z = v.z;
w = v.w;
}
// ------------------------------------------------------------------------------------------------
void Quaternion::SetStr(SQChar delim, StackStrF & values)
{
SetQuaternion(Quaternion::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Quaternion::Generate()
{
x = GetRandomFloat32();
y = GetRandomFloat32();
z = GetRandomFloat32();
w = GetRandomFloat32();
}
// ------------------------------------------------------------------------------------------------
void Quaternion::Generate(Value min, Value max)
{
if (EpsLt(max, min))
{
STHROWF("max value is lower than min value");
}
x = GetRandomFloat32(min, max);
y = GetRandomFloat32(min, max);
z = GetRandomFloat32(min, max);
y = GetRandomFloat32(min, max);
}
// ------------------------------------------------------------------------------------------------
void Quaternion::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax)
{
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(wmax, wmin))
{
STHROWF("max value is lower than min value");
}
x = GetRandomFloat32(xmin, xmax);
y = GetRandomFloat32(ymin, ymax);
z = GetRandomFloat32(zmin, zmax);
y = GetRandomFloat32(ymin, ymax);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::Abs() const
{
return Quaternion(std::fabs(x), std::fabs(y), std::fabs(z), std::fabs(w));
}
// ------------------------------------------------------------------------------------------------
bool Quaternion::IsNaN() const
{
return std::isnan(w) || std::isnan(x) || std::isnan(y) || std::isnan(z);
}
// ------------------------------------------------------------------------------------------------
Quaternion::Quaternion::Value Quaternion::LengthSquared() const
{
return (x * x) + (y * y) + (z * z) + (w * w);
}
// ------------------------------------------------------------------------------------------------
Quaternion::Value Quaternion::DotProduct(const Quaternion & quat) const
{
return (x * quat.x) + (y * quat.y) + (z * quat.z) + (w * quat.w);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::Conjugate() const
{
return Quaternion(-x, -y, -z, w);;
}
// ------------------------------------------------------------------------------------------------
void Quaternion::Normalize()
{
const Value len_squared = LengthSquared();
if (!EpsEq(len_squared, STOVAL(1.0)) && EpsGt(len_squared, STOVAL(0.0)))
{
const Value inv_len = STOVAL(1.0) / std::sqrt(len_squared);
x *= inv_len;
y *= inv_len;
z *= inv_len;
w *= inv_len;
}
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::Normalized() const
{
const Value len_squared = LengthSquared();
if (!EpsEq(len_squared, STOVAL(1.0)) && EpsGt(len_squared, STOVAL(0.0)))
{
Value inv_len = 1.0f / sqrtf(len_squared);
return ((*this) * inv_len);
}
else
{
return (*this);
}
}
// ------------------------------------------------------------------------------------------------
void Quaternion::FromAngleAxis(Value angle, const Vector3 & axis)
{
const Vector3 norm_axis = axis.Normalized();
angle *= SQMOD_DEGTORAD_2;
const Value sin_angle = std::sin(angle);
x = norm_axis.x * sin_angle;
y = norm_axis.y * sin_angle;
z = norm_axis.z * sin_angle;
w = std::cos(angle);
}
// ------------------------------------------------------------------------------------------------
void Quaternion::FromRotationTo(const Vector3 & start, const Vector3 & end)
{
const Vector3 norm_start = start.Normalized();
const Vector3 norm_end = end.Normalized();
const Value d = norm_start.DotProduct(norm_end);
if (EpsGt(d, STOVAL(-1.0)))
{
const Vector3 c = norm_start.CrossProduct(norm_end);
const Value s = std::sqrt((STOVAL(1.0) + d) * STOVAL(2.0));
const Value inv_s = STOVAL(1.0) / s;
x = c.x * inv_s;
y = c.y * inv_s;
z = c.z * inv_s;
w = STOVAL(0.5) * s;
}
else
{
Vector3 axis = Vector3::RIGHT.CrossProduct(norm_start);
if (EpsLt(axis.GetLength(), STOVAL(0.0)))
{
FromAngleAxis(STOVAL(180), Vector3::UP.CrossProduct(norm_start));
}
else
{
FromAngleAxis(STOVAL(180), axis);
}
}
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::Inverse() const
{
const Value len_squared = LengthSquared();
if (EpsEq(len_squared, STOVAL(1.0)))
{
return Conjugate();
}
else if (EpsGtEq(len_squared, STOVAL(0.0)))
{
return Conjugate() * (STOVAL(1.0) / len_squared);
}
else
{
return IDENTITY;
}
}
// ------------------------------------------------------------------------------------------------
Vector3 Quaternion::ToEuler() const
{
const Float64 sqw = (w * w);
const Float64 sqx = (x * x);
const Float64 sqy = (y * y);
const Float64 sqz = (z * z);
const Float64 test = 2.0 * ((y * w) - (x * z));
if (EpsEq(test, 1.0))
{
return Vector3(
// bank = rotation about x-axis
STOVAL(0.0),
// attitude = rotation about y-axis
STOVAL(SQMOD_PI64 / 2.0),
// heading = rotation about z-axis
STOVAL(-2.0 * std::atan2(x, w))
);
}
else if (EpsEq(test, -1.0))
{
return Vector3(
// bank = rotation about x-axis
STOVAL(0.0),
// attitude = rotation about y-axis
STOVAL(SQMOD_PI64 / -2.0),
// heading = rotation about z-axis
STOVAL(2.0 * std::atan2(x, w))
);
}
return Vector3(
// bank = rotation about x-axis
STOVAL(std::atan2(2.0 * ((y * z) + (x * w)), (-sqx - sqy + sqz + sqw))),
// attitude = rotation about y-axis
STOVAL(std::asin(Clamp(test, -1.0, 1.0))),
// heading = rotation about z-axis
STOVAL(std::atan2(2.0 * ((x * y) + (z * w)), (sqx - sqy - sqz + sqw)))
);
}
// ------------------------------------------------------------------------------------------------
Quaternion::Value Quaternion::YawAngle() const
{
return ToEuler().y;
}
// ------------------------------------------------------------------------------------------------
Quaternion::Value Quaternion::PitchAngle() const
{
return ToEuler().x;
}
// ------------------------------------------------------------------------------------------------
Quaternion::Value Quaternion::RollAngle() const
{
return ToEuler().z;
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::Slerp(Quaternion quat, Value t) const
{
// Favor accuracy for native code builds
Value cos_angle = DotProduct(quat);
// Enable shortest path rotation
if (EpsLt(cos_angle, STOVAL(0.0)))
{
cos_angle = -cos_angle;
quat = -quat;
}
const Value angle = std::acos(cos_angle);
Value sin_angle = std::sin(angle);
Value t1, t2;
if (sin_angle > STOVAL(0.001))
{
Value inv_sin_angle = STOVAL(1.0) / sin_angle;
t1 = std::sin((STOVAL(1.0) - t) * angle) * inv_sin_angle;
t2 = std::sin(t * angle) * inv_sin_angle;
}
else
{
t1 = STOVAL(1.0) - t;
t2 = t;
}
return ((*this) * t1 + quat * t2);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::Nlerp(const Quaternion & quat, Value t) const
{
return NlerpEx(quat, t, false);
}
// ------------------------------------------------------------------------------------------------
Quaternion Quaternion::NlerpEx(const Quaternion & quat, Value t, bool shortest_path) const
{
Quaternion result;
const Value fcos = DotProduct(quat);
if (EpsLt(fcos, STOVAL(0.0)) && shortest_path)
{
result = (*this) + (((-quat) - (*this)) * t);
}
else
{
result = (*this) + ((quat - (*this)) * t);
}
result.Normalize();
return result;
}
// ------------------------------------------------------------------------------------------------
const Quaternion & Quaternion::Get(StackStrF & str)
{
return Quaternion::GetEx(Quaternion::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Quaternion & Quaternion::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %f , %f , %f , %f ");
static Quaternion quat;
// Clear previous values, if any
quat.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return quat; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
fs[9] = delim;
fs[14] = delim;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, fs, &quat.x, &quat.y, &quat.z, &quat.w);
// Return the resulted value
return quat;
}
// ------------------------------------------------------------------------------------------------
const Quaternion & GetQuaternion()
{
static Quaternion quat;
quat.Clear();
return quat;
}
// ------------------------------------------------------------------------------------------------
const Quaternion & GetQuaternion(Float32 sv)
{
static Quaternion quat;
quat.SetScalar(sv);
return quat;
}
// ------------------------------------------------------------------------------------------------
const Quaternion & GetQuaternion(Float32 xv, Float32 yv, Float32 zv)
{
static Quaternion quat;
quat.SetVector3Ex(xv, yv, zv);
return quat;
}
// ------------------------------------------------------------------------------------------------
const Quaternion & GetQuaternion(Float32 xv, Float32 yv, Float32 zv, Float32 wv)
{
static Quaternion quat;
quat.SetQuaternionEx(xv, yv, zv, wv);
return quat;
}
// ------------------------------------------------------------------------------------------------
const Quaternion & GetQuaternion(const Quaternion & o)
{
static Quaternion quat;
quat.SetQuaternion(o);
return quat;
}
// ================================================================================================
void Register_Quaternion(HSQUIRRELVM vm)
{
typedef Quaternion::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Quaternion >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< Val, Val, Val >()
.Ctor< Val, Val, Val, Val >()
// Member Variables
.Var(_SC("x"), &Quaternion::x)
.Var(_SC("y"), &Quaternion::y)
.Var(_SC("z"), &Quaternion::z)
.Var(_SC("w"), &Quaternion::w)
.Var(_SC("X"), &Quaternion::x)
.Var(_SC("Y"), &Quaternion::y)
.Var(_SC("Z"), &Quaternion::z)
.Var(_SC("W"), &Quaternion::w)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Quaternion::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Quaternion >, SQFloat, SQInteger, bool, std::nullptr_t, Quaternion >)
.Func< Quaternion (Quaternion::*)(void) const >(_SC("_unm"), &Quaternion::operator -)
// Properties
.Prop(_SC("Abs"), &Quaternion::Abs)
.Prop(_SC("NaN"), &Quaternion::IsNaN)
.Prop(_SC("LengthSq"), &Quaternion::LengthSquared)
.Prop(_SC("Conjugate"), &Quaternion::Conjugate)
.Prop(_SC("Normalized"), &Quaternion::Normalized)
.Prop(_SC("Inverse"), &Quaternion::Inverse)
.Prop(_SC("Euler"), &Quaternion::ToEuler, &Quaternion::SetVector3)
.Prop(_SC("YawAngle"), &Quaternion::YawAngle)
.Prop(_SC("PitchAngle"), &Quaternion::PitchAngle)
.Prop(_SC("RollAngle"), &Quaternion::RollAngle)
// Member Methods
.Func(_SC("SetScalar"), &Quaternion::SetScalar)
.Func(_SC("SetQuaternion"), &Quaternion::SetQuaternion)
.Func(_SC("SetQuaternionEx"), &Quaternion::SetQuaternionEx)
.Func(_SC("SetVector3"), &Quaternion::SetVector3)
.Func(_SC("SetVector3Ex"), &Quaternion::SetVector3Ex)
.Func(_SC("SetVector4"), &Quaternion::SetVector4)
.FmtFunc(_SC("SetStr"), &Quaternion::SetStr)
.Func(_SC("Clear"), &Quaternion::Clear)
.Func(_SC("DotProduct"), &Quaternion::DotProduct)
.Func(_SC("Normalize"), &Quaternion::Normalize)
.Func(_SC("FromAngleAxis"), &Quaternion::FromAngleAxis)
.Func(_SC("FromRotationTo"), &Quaternion::FromRotationTo)
.Func(_SC("Slerp"), &Quaternion::Slerp)
.Func(_SC("Nlerp"), &Quaternion::Nlerp)
.Func(_SC("NlerpEx"), &Quaternion::NlerpEx)
// Member Overloads
.Overload< void (Quaternion::*)(void) >(_SC("Generate"), &Quaternion::Generate)
.Overload< void (Quaternion::*)(Val, Val) >(_SC("Generate"), &Quaternion::Generate)
.Overload< void (Quaternion::*)(Val, Val, Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Quaternion::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Quaternion >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Quaternion >)
.StaticFmtFunc(_SC("FromStr"), &Quaternion::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Quaternion::GetEx)
// Operator Exposure
.Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opAddAssign"), &Quaternion::operator +=)
.Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opSubAssign"), &Quaternion::operator -=)
.Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opMulAssign"), &Quaternion::operator *=)
.Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opDivAssign"), &Quaternion::operator /=)
.Func< Quaternion & (Quaternion::*)(const Quaternion &) >(_SC("opModAssign"), &Quaternion::operator %=)
.Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opAddAssignS"), &Quaternion::operator +=)
.Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opSubAssignS"), &Quaternion::operator -=)
.Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opMulAssignS"), &Quaternion::operator *=)
.Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opDivAssignS"), &Quaternion::operator /=)
.Func< Quaternion & (Quaternion::*)(Quaternion::Value) >(_SC("opModAssignS"), &Quaternion::operator %=)
.Func< Quaternion & (Quaternion::*)(void) >(_SC("opPreInc"), &Quaternion::operator ++)
.Func< Quaternion & (Quaternion::*)(void) >(_SC("opPreDec"), &Quaternion::operator --)
.Func< Quaternion (Quaternion::*)(int) >(_SC("opPostInc"), &Quaternion::operator ++)
.Func< Quaternion (Quaternion::*)(int) >(_SC("opPostDec"), &Quaternion::operator --)
.Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opAdd"), &Quaternion::operator +)
.Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opSub"), &Quaternion::operator -)
.Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opMul"), &Quaternion::operator *)
.Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opDiv"), &Quaternion::operator /)
.Func< Quaternion (Quaternion::*)(const Quaternion &) const >(_SC("opMod"), &Quaternion::operator %)
.Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opAddS"), &Quaternion::operator +)
.Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opSubS"), &Quaternion::operator -)
.Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opMulS"), &Quaternion::operator *)
.Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opDivS"), &Quaternion::operator /)
.Func< Quaternion (Quaternion::*)(Quaternion::Value) const >(_SC("opModS"), &Quaternion::operator %)
.Func< Quaternion (Quaternion::*)(void) const >(_SC("opUnPlus"), &Quaternion::operator +)
.Func< Quaternion (Quaternion::*)(void) const >(_SC("opUnMinus"), &Quaternion::operator -)
.Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opEqual"), &Quaternion::operator ==)
.Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opNotEqual"), &Quaternion::operator !=)
.Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opLessThan"), &Quaternion::operator <)
.Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opGreaterThan"), &Quaternion::operator >)
.Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opLessEqual"), &Quaternion::operator <=)
.Func< bool (Quaternion::*)(const Quaternion &) const >(_SC("opGreaterEqual"), &Quaternion::operator >=)
);
}
} // Namespace:: SqMod

456
module/Base/Quaternion.hpp Normal file
View File

@ -0,0 +1,456 @@
#ifndef _BASE_QUATERNION_HPP_
#define _BASE_QUATERNION_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Quaternion class for representing rotations.
*/
struct Quaternion
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef float Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Quaternion NIL;
static const Quaternion MIN;
static const Quaternion MAX;
static const Quaternion IDENTITY;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The x, y, z and w components of this type.
*/
Value x, y, z, w;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Quaternion();
/* --------------------------------------------------------------------------------------------
* Construct from scalar value.
*/
explicit Quaternion(Value sv);
/* --------------------------------------------------------------------------------------------
* Construct from Euler angles (in degrees.)
*/
Quaternion(Value xv, Value yv, Value zv);
/* --------------------------------------------------------------------------------------------
* Construct from individual values.
*/
Quaternion(Value xv, Value yv, Value zv, Value wv);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Quaternion(const Quaternion & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Quaternion(Quaternion && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Quaternion() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Quaternion & operator = (const Quaternion & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Quaternion & operator = (Quaternion && o) = default;
/* --------------------------------------------------------------------------------------------
* Scalar value assignment operator.
*/
Quaternion & operator = (Value s);
/* --------------------------------------------------------------------------------------------
* Euler assignment operator.
*/
Quaternion & operator = (const Vector3 & q);
/* --------------------------------------------------------------------------------------------
* Four-dimensional vector assignment operator threated as a three-dimensional vector.
*/
Quaternion & operator = (const Vector4 & q);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Quaternion & operator += (const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Quaternion & operator -= (const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Quaternion & operator *= (const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Quaternion & operator /= (const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Quaternion & operator %= (const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Scalar value addition assignment operator.
*/
Quaternion & operator += (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction assignment operator.
*/
Quaternion & operator -= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication assignment operator.
*/
Quaternion & operator *= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value division assignment operator.
*/
Quaternion & operator /= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value modulo assignment operator.
*/
Quaternion & operator %= (Value s);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Quaternion & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Quaternion & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Quaternion operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Quaternion operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Quaternion operator + (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Quaternion operator - (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Quaternion operator * (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Quaternion operator / (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Quaternion operator % (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Scalar value addition operator.
*/
Quaternion operator + (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction operator.
*/
Quaternion operator - (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication operator.
*/
Quaternion operator * (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value division operator.
*/
Quaternion operator / (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value modulo operator.
*/
Quaternion operator % (Value s) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Quaternion operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Quaternion operator - () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Quaternion & q) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Quaternion(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Quaternion(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Quaternion(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(Quaternion(static_cast< Value >(0)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value.
*/
void SetScalar(Value ns);
/* --------------------------------------------------------------------------------------------
* Copy the values from another instance of this type.
*/
void SetQuaternion(const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetQuaternionEx(Value nx, Value ny, Value nz, Value nw);
/* --------------------------------------------------------------------------------------------
* Copy the values from a three-dimensional vector as euler rotation.
*/
void SetVector3(const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Copy the values from a three-dimensional vector as euler rotation.
*/
void SetVector3Ex(Value nx, Value ny, Value nz);
/* --------------------------------------------------------------------------------------------
* Copy the values from a four-dimensional vector.
*/
void SetVector4(const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & values);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value min, Value max);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
x = 0.0, y = 0.0, z = 0.0, w = 0.0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a new instance of this type with absolute component values.
*/
Quaternion Abs() const;
/* --------------------------------------------------------------------------------------------
* Return whether is NaN.
*/
bool IsNaN() const;
/* --------------------------------------------------------------------------------------------
* Return squared length.
*/
Value LengthSquared() const;
/* --------------------------------------------------------------------------------------------
* Calculate dot product.
*/
Value DotProduct(const Quaternion & quat) const;
/* --------------------------------------------------------------------------------------------
* Return conjugate.
*/
Quaternion Conjugate() const;
/* --------------------------------------------------------------------------------------------
* Normalize to unit length.
*/
void Normalize();
/* --------------------------------------------------------------------------------------------
* Return normalized to unit length.
*/
Quaternion Normalized() const;
/* --------------------------------------------------------------------------------------------
* Define from an angle (in degrees) and axis.
*/
void FromAngleAxis(Value angle, const Vector3 & axis);
/* --------------------------------------------------------------------------------------------
* Define from the rotation difference between two direction vectors.
*/
void FromRotationTo(const Vector3 & start, const Vector3 & end);
/* --------------------------------------------------------------------------------------------
* Return inverse.
*/
Quaternion Inverse() const;
/* --------------------------------------------------------------------------------------------
* Return Euler angles in degrees.
*/
Vector3 ToEuler() const;
/* --------------------------------------------------------------------------------------------
* Return yaw angle in degrees.
*/
Value YawAngle() const;
/* --------------------------------------------------------------------------------------------
* Return pitch angle in degrees.
*/
Value PitchAngle() const;
/* --------------------------------------------------------------------------------------------
* Return roll angle in degrees.
*/
Value RollAngle() const;
/* --------------------------------------------------------------------------------------------
* Spherical interpolation with another quaternion.
*/
Quaternion Slerp(Quaternion quat, Value t) const;
/* --------------------------------------------------------------------------------------------
* Normalized linear interpolation with another quaternion.
*/
Quaternion Nlerp(const Quaternion & quat, Value t) const;
/* --------------------------------------------------------------------------------------------
* Normalized linear interpolation with another quaternion.
*/
Quaternion NlerpEx(const Quaternion & quat, Value t, bool shortest_path) const;
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Quaternion type from a string.
*/
static const Quaternion & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Quaternion type from a string.
*/
static const Quaternion & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_QUATERNION_HPP_

200
module/Base/ScriptSrc.cpp Normal file
View File

@ -0,0 +1,200 @@
// ------------------------------------------------------------------------------------------------
#include "Base/ScriptSrc.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <algorithm>
#include <stdexcept>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class to ensure the file handle is closed regardless of the situation.
*/
class FileHandle
{
public:
// --------------------------------------------------------------------------------------------
std::FILE * mFile; // Handle to the opened file.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
FileHandle(CSStr path)
: mFile(std::fopen(path, "rb"))
{
if (!mFile)
{
throw std::runtime_error(ToStrF("Unable to open script source (%s)", path));
}
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
FileHandle(const FileHandle & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
FileHandle(FileHandle && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~FileHandle()
{
if (mFile)
{
std::fclose(mFile);
}
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
FileHandle & operator = (const FileHandle & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
FileHandle & operator = (FileHandle && o) = delete;
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed file handle.
*/
operator std::FILE * ()
{
return mFile;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed file handle.
*/
operator std::FILE * () const
{
return mFile;
}
};
// ------------------------------------------------------------------------------------------------
void ScriptSrc::Process()
{
// Attempt to open the specified file
FileHandle fp(mPath.c_str());
// First 2 bytes of the file will tell if this is a compiled script
std::uint16_t tag;
// Go to the end of the file
std::fseek(fp, 0, SEEK_END);
// Calculate buffer size from beginning to current position
const LongI length = std::ftell(fp);
// Go back to the beginning
std::fseek(fp, 0, SEEK_SET);
// Read the first 2 bytes of the file and determine the file type
if ((length >= 2) && (std::fread(&tag, 1, 2, fp) != 2 || tag == SQ_BYTECODE_STREAM_TAG))
{
return; // Probably an empty file or compiled script
}
// Allocate enough space to hold the file data
mData.resize(length, 0);
// Go back to the beginning
std::fseek(fp, 0, SEEK_SET);
// Read the file contents into allocated data
std::fread(&mData[0], 1, length, fp);
// Where the last line ended
size_t line_start = 0, line_end = 0;
// Process the file data and locate new lines
for (String::const_iterator itr = mData.cbegin(); itr != mData.cend();)
{
// Is this a Unix style line ending?
if (*itr == '\n')
{
// Extract the line length
line_end = std::distance(mData.cbegin(), itr);
// Store the beginning of the line
mLine.emplace_back(line_start, line_end);
// Advance to the next line
line_start = line_end+1;
// The line end character was not included
++itr;
}
// Is this a Windows style line ending?
else if (*itr == '\r')
{
if (*(++itr) == '\n')
{
// Extract the line length
line_end = std::distance(mData.cbegin(), itr)-1;
// Store the beginning of the line
mLine.emplace_back(line_start, line_end);
// Advance to the next line
line_start = line_end+2;
// The line end character was not included
++itr;
}
}
else
{
++itr;
}
}
// Should we add the last line as well?
if (mData.size() - line_start > 0)
{
mLine.emplace_back(line_start, mData.size());
}
// Specify that this script contains line information
mInfo = true;
}
// ------------------------------------------------------------------------------------------------
ScriptSrc::ScriptSrc(HSQUIRRELVM vm, String && path, bool delay, bool info)
: mExec(vm)
, mPath(std::move(path))
, mData()
, mLine()
, mInfo(info)
, mDelay(delay)
{
// Is the specified virtual machine invalid?
if (!vm)
{
throw std::runtime_error("Invalid virtual machine pointer");
}
// Is the specified path empty?
else if (mPath.empty())
{
throw std::runtime_error("Invalid or empty script path");
}
// Should we load the file contents for debugging purposes?
else if (mInfo)
{
Process();
}
}
// ------------------------------------------------------------------------------------------------
String ScriptSrc::FetchLine(size_t line, bool trim) const
{
// Do we have such line?
if (line > mLine.size())
{
return String(); // Nope!
}
// Grab it's range in the file
Line::const_reference l = mLine.at(line);
// Grab the code from that line
String code = mData.substr(l.first, l.second - l.first);
// Trim whitespace from the beginning of the code code
if (trim)
{
code.erase(0, code.find_first_not_of(" \t\n\r\f\v"));
}
// Return the resulting string
return code;
}
} // Namespace:: SqMod

83
module/Base/ScriptSrc.hpp Normal file
View File

@ -0,0 +1,83 @@
#ifndef _BASE_SCRIPTSRC_HPP_
#define _BASE_SCRIPTSRC_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <vector>
#include <utility>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
class Core;
/* ------------------------------------------------------------------------------------------------
* Hold a information about loaded scripts as it's contents and executable code.
*/
class ScriptSrc
{
public:
// --------------------------------------------------------------------------------------------
typedef std::vector< std::pair< Uint32, Uint32 > > Line;
// --------------------------------------------------------------------------------------------
Script mExec; // Reference to the script object.
String mPath; // Path to the script file.
String mData; // The contents of the script file.
Line mLine; // List of lines of code in the data.
bool mInfo; // Whether this script contains line information.
bool mDelay; // Don't execute immediately after compilation.
/* --------------------------------------------------------------------------------------------
* Read file contents and calculate information about the lines of code.
*/
void Process();
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
ScriptSrc(HSQUIRRELVM vm, const String & path, bool delay = false, bool info = false)
: ScriptSrc(vm, String(path), delay, info)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
ScriptSrc(HSQUIRRELVM vm, String && path, bool delay = false, bool info = false);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
ScriptSrc(const ScriptSrc & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
ScriptSrc(ScriptSrc && o) = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
ScriptSrc & operator = (const ScriptSrc & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
ScriptSrc & operator = (ScriptSrc && o) = default;
/* --------------------------------------------------------------------------------------------
* Fetches a line from the code. Can also triim whitespace at the beginning.
*/
String FetchLine(size_t line, bool trim = true) const;
};
} // Namespace:: SqMod
#endif // _BASE_SCRIPTSRC_HPP_

1104
module/Base/Shared.cpp Normal file

File diff suppressed because it is too large Load Diff

259
module/Base/Shared.hpp Normal file
View File

@ -0,0 +1,259 @@
#ifndef _BASE_SHARED_HPP_
#define _BASE_SHARED_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper constants used by the bas types.
*/
constexpr Float32 SQMOD_PI = 3.14159265358979323846264338327950288f;
constexpr Float64 SQMOD_PI64 = 3.1415926535897932384626433832795028841971693993751d;
constexpr Float32 SQMOD_RECIPROCAL_PI = (1.0f / SQMOD_PI);
constexpr Float64 SQMOD_RECIPROCAL_PI64 = 1.0 / SQMOD_PI64;
constexpr Float32 SQMOD_HALF_PI = (SQMOD_PI * 0.5f);
constexpr Float32 SQMOD_HALF_PI64 = (SQMOD_PI64 * 0.5);
constexpr Float32 SQMOD_DEGTORAD = SQMOD_PI / 180.0f;
constexpr Float64 SQMOD_DEGTORAD64 = SQMOD_PI64 / 180.0;
constexpr Float32 SQMOD_DEGTORAD_2 = SQMOD_PI / 360.0f; // M_DEGTORAD / 2.f
constexpr Float64 SQMOD_DEGTORAD64_2 = SQMOD_PI64 / 360.0; // M_DEGTORAD / 2.f
constexpr Float32 SQMOD_RADTODEG = 1.0f / SQMOD_DEGTORAD;
constexpr Float64 SQMOD_RADTODEG64 = 1.0 / SQMOD_DEGTORAD64;
/* ------------------------------------------------------------------------------------------------
* Intersection test result.
*/
enum Intersection
{
SQMODI_OUTSIDE = 0,
SQMODI_INTERSECTS,
SQMODI_INSIDE,
};
/* ------------------------------------------------------------------------------------------------
* Helper used to reference and keep track of signal instances.
*/
typedef std::pair< Signal *, LightObj > SignalPair;
/* ------------------------------------------------------------------------------------------------
* Forward declarations of the logging functions to avoid including the logger everywhere.
* Primary logging functions.
*/
extern void LogDbg(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogUsr(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogScs(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogInf(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogWrn(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogErr(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogFtl(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
/* ------------------------------------------------------------------------------------------------
* Forward declarations of the logging functions to avoid including the logger everywhere.
* Secondary logging functions.
*/
extern void LogSDbg(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogSUsr(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogSScs(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogSInf(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogSWrn(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogSErr(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
extern void LogSFtl(CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 1, 2);
/* ------------------------------------------------------------------------------------------------
* Forward declarations of the logging functions to avoid including the logger everywhere.
* Primary conditional logging functions.
*/
extern bool cLogDbg(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogUsr(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogScs(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogInf(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogWrn(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogErr(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogFtl(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
/* ------------------------------------------------------------------------------------------------
* Forward declarations of the logging functions to avoid including the logger everywhere.
* Secondary conditional logging functions.
*/
extern bool cLogSDbg(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogSUsr(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogSScs(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogSInf(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogSWrn(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogSErr(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
extern bool cLogSFtl(bool exp, CCStr fmt, ...) SQMOD_FORMAT_ATTR(printf, 2, 3);
/* ------------------------------------------------------------------------------------------------
* Get a persistent AABB instance with the given values.
*/
extern const AABB & GetAABB();
extern const AABB & GetAABB(Float32 mins, Float32 maxs);
extern const AABB & GetAABB(Float32 xv, Float32 yv, Float32 zv);
extern const AABB & GetAABB(Float32 xmin, Float32 ymin, Float32 zmin, Float32 xmax, Float32 ymax, Float32 zmax);
extern const AABB & GetAABB(const Vector3 & vmin, const Vector3 & vmax);
extern const AABB & GetAABB(const AABB & o);
extern const AABB & GetAABB(AABB && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Circle instance with the given values.
*/
extern const Circle & GetCircle();
extern const Circle & GetCircle(Float32 rv);
extern const Circle & GetCircle(const Vector2 & pv, Float32 rv);
extern const Circle & GetCircle(Float32 xv, Float32 yv, Float32 rv);
extern const Circle & GetCircle(const Circle & o);
extern const Circle & GetCircle(Circle && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Color3 instance with the given values.
*/
extern const Color3 & GetColor3();
extern const Color3 & GetColor3(Uint8 sv);
extern const Color3 & GetColor3(Uint8 rv, Uint8 gv, Uint8 bv);
extern const Color3 & GetColor3(const Color3 & o);
extern const Color3 & GetColor3(Color3 && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Color4 instance with the given values.
*/
extern const Color4 & GetColor4();
extern const Color4 & GetColor4(Uint8 sv);
extern const Color4 & GetColor4(Uint8 rv, Uint8 gv, Uint8 bv);
extern const Color4 & GetColor4(Uint8 rv, Uint8 gv, Uint8 bv, Uint8 av);
extern const Color4 & GetColor4(const Color4 & o);
extern const Color4 & GetColor4(Color4 && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Quaternion instance with the given values.
*/
extern const Quaternion & GetQuaternion();
extern const Quaternion & GetQuaternion(Float32 sv);
extern const Quaternion & GetQuaternion(Float32 xv, Float32 yv, Float32 zv);
extern const Quaternion & GetQuaternion(Float32 xv, Float32 yv, Float32 zv, Float32 wv);
extern const Quaternion & GetQuaternion(const Quaternion & o);
extern const Quaternion & GetQuaternion(Quaternion && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Sphere instance with the given values.
*/
extern const Sphere & GetSphere();
extern const Sphere & GetSphere(Float32 rv);
extern const Sphere & GetSphere(const Vector3 & pv, Float32 rv);
extern const Sphere & GetSphere(Float32 xv, Float32 yv, Float32 zv, Float32 rv);
extern const Sphere & GetSphere(const Sphere & o);
extern const Sphere & GetSphere(Sphere && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Vector2 instance with the given values.
*/
extern const Vector2 & GetVector2();
extern const Vector2 & GetVector2(Float32 sv);
extern const Vector2 & GetVector2(Float32 xv, Float32 yv);
extern const Vector2 & GetVector2(const Vector2 & o);
extern const Vector2 & GetVector2(Vector2 && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Vector2i instance with the given values.
*/
extern const Vector2i & GetVector2i();
extern const Vector2i & GetVector2i(Int32 sv);
extern const Vector2i & GetVector2i(Int32 xv, Int32 yv);
extern const Vector2i & GetVector2i(const Vector2i & o);
extern const Vector2i & GetVector2i(Vector2i && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Vector3 instance with the given values.
*/
extern const Vector3 & GetVector3();
extern const Vector3 & GetVector3(Float32 sv);
extern const Vector3 & GetVector3(Float32 xv, Float32 yv, Float32 zv);
extern const Vector3 & GetVector3(const Vector3 & o);
extern const Vector3 & GetVector3(Vector3 && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent Vector4 instance with the given values.
*/
extern const Vector4 & GetVector4();
extern const Vector4 & GetVector4(Float32 sv);
extern const Vector4 & GetVector4(Float32 xv, Float32 yv, Float32 zv);
extern const Vector4 & GetVector4(Float32 xv, Float32 yv, Float32 zv, Float32 wv);
extern const Vector4 & GetVector4(const Vector4 & o);
extern const Vector4 & GetVector4(Vector4 && o);
/* ------------------------------------------------------------------------------------------------
* Get a persistent LongInt instance with the given values.
*/
const SLongInt & GetSLongInt();
const SLongInt & GetSLongInt(Int64 n);
const SLongInt & GetSLongInt(CSStr s);
const ULongInt & GetULongInt();
const ULongInt & GetULongInt(Uint64 n);
const ULongInt & GetULongInt(CSStr s);
/* ------------------------------------------------------------------------------------------------
* Initialize a signal instance into the specified pair.
*/
extern void InitSignalPair(SignalPair & sp, LightObj & et, const char * name);
/* ------------------------------------------------------------------------------------------------
* Reset/release the specified signal pair.
*/
extern void ResetSignalPair(SignalPair & sp, bool clear = true);
/* ------------------------------------------------------------------------------------------------
* A simple implementation of name filtering.
*/
bool NameFilterCheck(CSStr filter, CSStr name);
/* ------------------------------------------------------------------------------------------------
* A simple implementation of name filtering without case sensitivity.
*/
bool NameFilterCheckInsensitive(CSStr filter, CSStr name);
/* ------------------------------------------------------------------------------------------------
* Obtain a randomly chosen color from a list of known colors.
*/
const Color3 & GetRandomColor();
/* ------------------------------------------------------------------------------------------------
* Attempt to identify the color in the specified name and return it.
*/
Color3 GetColorStr(CSStr name);
/* ------------------------------------------------------------------------------------------------
* Attempt to identify the color in the specified name and return it.
*/
Color3 GetColor(StackStrF & name);
/* ------------------------------------------------------------------------------------------------
* Throw the last system error as an exception.
*/
void SqThrowLastF(CSStr msg, ...);
/* ------------------------------------------------------------------------------------------------
* Retrieve the string delimiter of a base type.
*/
template < typename T > inline SQInteger SqGetDelimiter()
{
return T::Delim;
}
/* ------------------------------------------------------------------------------------------------
* Modify the string delimiter of a base type.
*/
template < typename T > inline void SqSetDelimiter(SQInteger c)
{
T::Delim = ConvTo< SQChar >::From(c);
}
} // Namespace:: SqMod
#endif // _BASE_SHARED_HPP_

634
module/Base/Sphere.cpp Normal file
View File

@ -0,0 +1,634 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Sphere.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Sphere"))
// ------------------------------------------------------------------------------------------------
const Sphere Sphere::NIL = Sphere();
const Sphere Sphere::MIN = Sphere(0.0);
const Sphere Sphere::MAX = Sphere(std::numeric_limits< Sphere::Value >::max());
// ------------------------------------------------------------------------------------------------
SQChar Sphere::Delim = ',';
// ------------------------------------------------------------------------------------------------
Sphere::Sphere()
: pos(0.0), rad(0.0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Sphere::Sphere(Value rv)
: pos(0.0), rad(rv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Sphere::Sphere(const Vector3 & pv, Value rv)
: pos(pv), rad(rv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Sphere::Sphere(Value xv, Value yv, Value zv, Value rv)
: pos(xv, yv, zv), rad(rv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator = (Value r)
{
rad = r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator = (const Vector3 & p)
{
pos = p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator += (const Sphere & s)
{
pos += s.pos;
rad += s.rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator -= (const Sphere & s)
{
pos -= s.pos;
rad -= s.rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator *= (const Sphere & s)
{
pos *= s.pos;
rad *= s.rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator /= (const Sphere & s)
{
pos /= s.pos;
rad /= s.rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator %= (const Sphere & s)
{
pos %= s.pos;
rad = std::fmod(rad, s.rad);
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator += (Value r)
{
rad += r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator -= (Value r)
{
rad -= r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator *= (Value r)
{
rad *= r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator /= (Value r)
{
rad /= r;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator %= (Value r)
{
rad = std::fmod(rad, r);
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator += (const Vector3 & p)
{
pos += p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator -= (const Vector3 & p)
{
pos -= p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator *= (const Vector3 & p)
{
pos *= p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator /= (const Vector3 & p)
{
pos /= p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator %= (const Vector3 & p)
{
pos %= p;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator ++ ()
{
++pos;
++rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere & Sphere::operator -- ()
{
--pos;
--rad;
return *this;
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator ++ (int)
{
Sphere state(*this);
++pos;
++rad;
return state;
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator -- (int)
{
Sphere state(*this);
--pos;
--rad;
return state;
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator + (const Sphere & s) const
{
return Sphere(pos + s.pos, rad + s.rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator - (const Sphere & s) const
{
return Sphere(pos - s.pos, rad - s.rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator * (const Sphere & s) const
{
return Sphere(pos * s.pos, rad * s.rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator / (const Sphere & s) const
{
return Sphere(pos / s.pos, rad / s.rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator % (const Sphere & s) const
{
return Sphere(pos % s.pos, std::fmod(rad, s.rad));
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator + (Value r) const
{
return Sphere(rad + r);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator - (Value r) const
{
return Sphere(rad - r);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator * (Value r) const
{
return Sphere(rad * r);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator / (Value r) const
{
return Sphere(rad / r);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator % (Value r) const
{
return Sphere(std::fmod(rad, r));
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator + (const Vector3 & p) const
{
return Sphere(pos + p, rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator - (const Vector3 & p) const
{
return Sphere(pos - p, rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator * (const Vector3 & p) const
{
return Sphere(pos * p, rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator / (const Vector3 & p) const
{
return Sphere(pos / p, rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator % (const Vector3 & p) const
{
return Sphere(pos % p, rad);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator + () const
{
return Sphere(pos.Abs(), std::fabs(rad));
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::operator - () const
{
return Sphere(-pos, -rad);
}
// ------------------------------------------------------------------------------------------------
bool Sphere::operator == (const Sphere & s) const
{
return EpsEq(rad, s.rad) && (pos == s.pos);
}
// ------------------------------------------------------------------------------------------------
bool Sphere::operator != (const Sphere & s) const
{
return !EpsEq(rad, s.rad) || (pos != s.pos);
}
// ------------------------------------------------------------------------------------------------
bool Sphere::operator < (const Sphere & s) const
{
return EpsLt(rad, s.rad) && (pos < s.pos);
}
// ------------------------------------------------------------------------------------------------
bool Sphere::operator > (const Sphere & s) const
{
return EpsGt(rad, s.rad) && (pos > s.pos);
}
// ------------------------------------------------------------------------------------------------
bool Sphere::operator <= (const Sphere & s) const
{
return EpsLtEq(rad, s.rad) && (pos <= s.pos);
}
// ------------------------------------------------------------------------------------------------
bool Sphere::operator >= (const Sphere & s) const
{
return EpsGtEq(rad, s.rad) && (pos >= s.pos);
}
// ------------------------------------------------------------------------------------------------
Int32 Sphere::Cmp(const Sphere & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Sphere::ToString() const
{
return ToStrF("%f,%f,%f,%f", pos.x, pos.y, pos.z, rad);
}
// ------------------------------------------------------------------------------------------------
void Sphere::SetRadius(Value nr)
{
rad = nr;
}
// ------------------------------------------------------------------------------------------------
void Sphere::SetSphere(const Sphere & ns)
{
pos = ns.pos;
rad = ns.rad;
}
// ------------------------------------------------------------------------------------------------
void Sphere::SetSphereEx(Value nx, Value ny, Value nz, Value nr)
{
pos.SetVector3Ex(nx, ny, nz);
rad = nr;
}
// ------------------------------------------------------------------------------------------------
void Sphere::SetValues(const Vector3 & np, Value nr)
{
pos = np;
rad = nr;
}
// ------------------------------------------------------------------------------------------------
void Sphere::SetPosition(const Vector3 & np)
{
pos = np;
}
// ------------------------------------------------------------------------------------------------
void Sphere::SetPositionEx(Value nx, Value ny, Value nz)
{
pos.SetVector3Ex(nx, ny, nz);
}
// ------------------------------------------------------------------------------------------------
void Sphere::SetStr(SQChar delim, StackStrF & values)
{
SetSphere(Sphere::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Sphere::Generate()
{
pos.Generate();
rad = GetRandomFloat32();
}
// ------------------------------------------------------------------------------------------------
void Sphere::Generate(Value min, Value max, bool r)
{
if (EpsLt(max, min))
{
STHROWF("max value is lower than min value");
}
else if (r)
{
rad = GetRandomFloat32(min, max);
}
else
{
pos.Generate(min, max);
}
}
// ------------------------------------------------------------------------------------------------
void Sphere::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax)
{
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin))
{
STHROWF("max value is lower than min value");
}
pos.Generate(xmin, xmax, ymin, ymax, zmin, zmax);
}
// ------------------------------------------------------------------------------------------------
void Sphere::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value rmin, Value rmax)
{
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(rmax, rmin))
{
STHROWF("max value is lower than min value");
}
pos.Generate(xmin, xmax, ymin, ymax, zmin, zmax);
rad = GetRandomFloat32(rmin, rmax);
}
// ------------------------------------------------------------------------------------------------
Sphere Sphere::Abs() const
{
return Sphere(pos.Abs(), std::fabs(rad));
}
// ------------------------------------------------------------------------------------------------
const Sphere & Sphere::Get(StackStrF & str)
{
return Sphere::GetEx(Sphere::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Sphere & Sphere::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %f , %f , %f , %f ");
static Sphere sphere;
// Clear previous values, if any
sphere.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return sphere; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
fs[9] = delim;
fs[14] = delim;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, fs, &sphere.pos.x, &sphere.pos.y, &sphere.pos.z, &sphere.rad);
// Return the resulted value
return sphere;
}
// ------------------------------------------------------------------------------------------------
const Sphere & GetSphere()
{
static Sphere sphere;
sphere.Clear();
return sphere;
}
// ------------------------------------------------------------------------------------------------
const Sphere & GetSphere(Float32 rv)
{
static Sphere sphere;
sphere.SetRadius(rv);
return sphere;
}
// ------------------------------------------------------------------------------------------------
const Sphere & GetSphere(const Vector3 & pv, Float32 rv)
{
static Sphere sphere;
sphere.SetValues(pv, rv);
return sphere;
}
// ------------------------------------------------------------------------------------------------
const Sphere & GetSphere(Float32 xv, Float32 yv, Float32 zv, Float32 rv)
{
static Sphere sphere;
sphere.SetSphereEx(xv, yv, zv, rv);
return sphere;
}
// ------------------------------------------------------------------------------------------------
const Sphere & GetSphere(const Sphere & o)
{
static Sphere sphere;
sphere.SetSphere(o);
return sphere;
}
// ================================================================================================
void Register_Sphere(HSQUIRRELVM vm)
{
typedef Sphere::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Sphere >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< const Vector3 &, Val >()
.Ctor< Val, Val, Val, Val >()
// Member Variables
.Var(_SC("pos"), &Sphere::pos)
.Var(_SC("rad"), &Sphere::rad)
.Var(_SC("Pos"), &Sphere::pos)
.Var(_SC("Rad"), &Sphere::rad)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Sphere::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Sphere >, SQFloat, SQInteger, bool, std::nullptr_t, Sphere >)
.Func< Sphere (Sphere::*)(void) const >(_SC("_unm"), &Sphere::operator -)
// Properties
.Prop(_SC("Abs"), &Sphere::Abs)
// Member Methods
.Func(_SC("SetRadius"), &Sphere::SetRadius)
.Func(_SC("SetSphere"), &Sphere::SetSphere)
.Func(_SC("SetSphereEx"), &Sphere::SetSphereEx)
.Func(_SC("SetValues"), &Sphere::SetValues)
.Func(_SC("SetPosition"), &Sphere::SetPosition)
.Func(_SC("SetPositionEx"), &Sphere::SetPositionEx)
.FmtFunc(_SC("SetStr"), &Sphere::SetStr)
.Func(_SC("Clear"), &Sphere::Clear)
// Member Overloads
.Overload< void (Sphere::*)(void) >(_SC("Generate"), &Sphere::Generate)
.Overload< void (Sphere::*)(Val, Val, bool) >(_SC("Generate"), &Sphere::Generate)
.Overload< void (Sphere::*)(Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Sphere::Generate)
.Overload< void (Sphere::*)(Val, Val, Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Sphere::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Sphere >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Sphere >)
.StaticFmtFunc(_SC("FromStr"), &Sphere::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Sphere::GetEx)
// Operator Exposure
.Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opAddAssign"), &Sphere::operator +=)
.Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opSubAssign"), &Sphere::operator -=)
.Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opMulAssign"), &Sphere::operator *=)
.Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opDivAssign"), &Sphere::operator /=)
.Func< Sphere & (Sphere::*)(const Sphere &) >(_SC("opModAssign"), &Sphere::operator %=)
.Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opAddAssignR"), &Sphere::operator +=)
.Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opSubAssignR"), &Sphere::operator -=)
.Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opMulAssignR"), &Sphere::operator *=)
.Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opDivAssignR"), &Sphere::operator /=)
.Func< Sphere & (Sphere::*)(Sphere::Value) >(_SC("opModAssignR"), &Sphere::operator %=)
.Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opAddAssignP"), &Sphere::operator +=)
.Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opSubAssignP"), &Sphere::operator -=)
.Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opMulAssignP"), &Sphere::operator *=)
.Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opDivAssignP"), &Sphere::operator /=)
.Func< Sphere & (Sphere::*)(const Vector3 &) >(_SC("opModAssignP"), &Sphere::operator %=)
.Func< Sphere & (Sphere::*)(void) >(_SC("opPreInc"), &Sphere::operator ++)
.Func< Sphere & (Sphere::*)(void) >(_SC("opPreDec"), &Sphere::operator --)
.Func< Sphere (Sphere::*)(int) >(_SC("opPostInc"), &Sphere::operator ++)
.Func< Sphere (Sphere::*)(int) >(_SC("opPostDec"), &Sphere::operator --)
.Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opAdd"), &Sphere::operator +)
.Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opSub"), &Sphere::operator -)
.Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opMul"), &Sphere::operator *)
.Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opDiv"), &Sphere::operator /)
.Func< Sphere (Sphere::*)(const Sphere &) const >(_SC("opMod"), &Sphere::operator %)
.Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opAddR"), &Sphere::operator +)
.Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opSubR"), &Sphere::operator -)
.Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opMulR"), &Sphere::operator *)
.Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opDivR"), &Sphere::operator /)
.Func< Sphere (Sphere::*)(Sphere::Value) const >(_SC("opModR"), &Sphere::operator %)
.Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opAddP"), &Sphere::operator +)
.Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opSubP"), &Sphere::operator -)
.Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opMulP"), &Sphere::operator *)
.Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opDivP"), &Sphere::operator /)
.Func< Sphere (Sphere::*)(const Vector3 &) const >(_SC("opModP"), &Sphere::operator %)
.Func< Sphere (Sphere::*)(void) const >(_SC("opUnPlus"), &Sphere::operator +)
.Func< Sphere (Sphere::*)(void) const >(_SC("opUnMinus"), &Sphere::operator -)
.Func< bool (Sphere::*)(const Sphere &) const >(_SC("opEqual"), &Sphere::operator ==)
.Func< bool (Sphere::*)(const Sphere &) const >(_SC("opNotEqual"), &Sphere::operator !=)
.Func< bool (Sphere::*)(const Sphere &) const >(_SC("opLessThan"), &Sphere::operator <)
.Func< bool (Sphere::*)(const Sphere &) const >(_SC("opGreaterThan"), &Sphere::operator >)
.Func< bool (Sphere::*)(const Sphere &) const >(_SC("opLessEqual"), &Sphere::operator <=)
.Func< bool (Sphere::*)(const Sphere &) const >(_SC("opGreaterEqual"), &Sphere::operator >=)
);
}
} // Namespace:: SqMod

427
module/Base/Sphere.hpp Normal file
View File

@ -0,0 +1,427 @@
#ifndef _BASE_SPHERE_HPP_
#define _BASE_SPHERE_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
#include "Base/Vector3.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent a three-dimensional sphere.
*/
struct Sphere
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef float Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Sphere NIL;
static const Sphere MIN;
static const Sphere MAX;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The position and radius components of this type.
*/
Vector3 pos;
Value rad;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Sphere();
/* --------------------------------------------------------------------------------------------
* Construct a sphere at position 0,0,0 using the specified radius.
*/
explicit Sphere(Value rv);
/* --------------------------------------------------------------------------------------------
* Construct a sphere at the specified position using the specified radius.
*/
Sphere(const Vector3 & pv, Value rv);
/* --------------------------------------------------------------------------------------------
* Construct a sphere at the specified position using the specified radius.
*/
Sphere(Value xv, Value yv, Value zv, Value rv);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Sphere(const Sphere & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Sphere(Sphere && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Sphere() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Sphere & operator = (const Sphere & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Sphere & operator = (Sphere && o) = default;
/* --------------------------------------------------------------------------------------------
* Radius assignment operator.
*/
Sphere & operator = (Value r);
/* --------------------------------------------------------------------------------------------
* Position assignment operator.
*/
Sphere & operator = (const Vector3 & p);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Sphere & operator += (const Sphere & s);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Sphere & operator -= (const Sphere & s);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Sphere & operator *= (const Sphere & s);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Sphere & operator /= (const Sphere & s);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Sphere & operator %= (const Sphere & s);
/* --------------------------------------------------------------------------------------------
* Radius addition assignment operator.
*/
Sphere & operator += (Value r);
/* --------------------------------------------------------------------------------------------
* Radius subtraction assignment operator.
*/
Sphere & operator -= (Value r);
/* --------------------------------------------------------------------------------------------
* Radius multiplication assignment operator.
*/
Sphere & operator *= (Value r);
/* --------------------------------------------------------------------------------------------
* Radius division assignment operator.
*/
Sphere & operator /= (Value r);
/* --------------------------------------------------------------------------------------------
* Radius modulo assignment operator.
*/
Sphere & operator %= (Value r);
/* --------------------------------------------------------------------------------------------
* Position addition assignment operator.
*/
Sphere & operator += (const Vector3 & p);
/* --------------------------------------------------------------------------------------------
* Position subtraction assignment operator.
*/
Sphere & operator -= (const Vector3 & p);
/* --------------------------------------------------------------------------------------------
* Position multiplication assignment operator.
*/
Sphere & operator *= (const Vector3 & p);
/* --------------------------------------------------------------------------------------------
* Position division assignment operator.
*/
Sphere & operator /= (const Vector3 & p);
/* --------------------------------------------------------------------------------------------
* Position modulo assignment operator.
*/
Sphere & operator %= (const Vector3 & p);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Sphere & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Sphere & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Sphere operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Sphere operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Sphere operator + (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Sphere operator - (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Sphere operator * (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Sphere operator / (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Sphere operator % (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Radius addition operator.
*/
Sphere operator + (Value r) const;
/* --------------------------------------------------------------------------------------------
* Radius subtraction operator.
*/
Sphere operator - (Value r) const;
/* --------------------------------------------------------------------------------------------
* Radius multiplication operator.
*/
Sphere operator * (Value r) const;
/* --------------------------------------------------------------------------------------------
* Radius division operator.
*/
Sphere operator / (Value r) const;
/* --------------------------------------------------------------------------------------------
* Radius modulo operator.
*/
Sphere operator % (Value r) const;
/* --------------------------------------------------------------------------------------------
* Position addition operator.
*/
Sphere operator + (const Vector3 & p) const;
/* --------------------------------------------------------------------------------------------
* Position subtraction operator.
*/
Sphere operator - (const Vector3 & p) const;
/* --------------------------------------------------------------------------------------------
* Position multiplication operator.
*/
Sphere operator * (const Vector3 & p) const;
/* --------------------------------------------------------------------------------------------
* Position division operator.
*/
Sphere operator / (const Vector3 & p) const;
/* --------------------------------------------------------------------------------------------
* Position modulo operator.
*/
Sphere operator % (const Vector3 & p) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Sphere operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Sphere operator - () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Sphere & s) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Sphere(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Sphere(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Sphere(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(Sphere(static_cast< Value >(0)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set the specified radius.
*/
void SetRadius(Value nr);
/* --------------------------------------------------------------------------------------------
* Copy the sphere from another instance of this type.
*/
void SetSphere(const Sphere & ns);
/* --------------------------------------------------------------------------------------------
* Set the specified position and radius.
*/
void SetSphereEx(Value nx, Value ny, Value nz, Value nr);
/* --------------------------------------------------------------------------------------------
* Set the specified position and radius.
*/
void SetValues(const Vector3 & np, Value nr);
/* --------------------------------------------------------------------------------------------
* Set the position from the specified position.
*/
void SetPosition(const Vector3 & np);
/* --------------------------------------------------------------------------------------------
* Set the specified position.
*/
void SetPositionEx(Value nx, Value ny, Value nz);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & values);
/* --------------------------------------------------------------------------------------------
* Generate a randomly sized and positioned sphere.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate a randomly sized or positioned sphere within the specified bounds.
*/
void Generate(Value min, Value max, bool r);
/* --------------------------------------------------------------------------------------------
* Generate a randomly positioned sphere within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax);
/* --------------------------------------------------------------------------------------------
* Generate a randomly sized and positioned sphere within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value rmin, Value rmax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
pos.Clear(); rad = 0.0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a new instance of this type with absolute component values.
*/
Sphere Abs() const;
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Sphere type from a string.
*/
static const Sphere & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Sphere type from a string.
*/
static const Sphere & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_SPHERE_HPP_

1087
module/Base/Utility.cpp Normal file

File diff suppressed because it is too large Load Diff

1522
module/Base/Utility.hpp Normal file

File diff suppressed because it is too large Load Diff

518
module/Base/Vector2.cpp Normal file
View File

@ -0,0 +1,518 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Vector2.hpp"
#include "Base/Vector2i.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Vector2"))
// ------------------------------------------------------------------------------------------------
const Vector2 Vector2::NIL = Vector2(0);
const Vector2 Vector2::MIN = Vector2(std::numeric_limits< Vector2::Value >::min());
const Vector2 Vector2::MAX = Vector2(std::numeric_limits< Vector2::Value >::max());
// ------------------------------------------------------------------------------------------------
SQChar Vector2::Delim = ',';
// ------------------------------------------------------------------------------------------------
Vector2::Vector2()
: x(0.0), y(0.0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector2::Vector2(Value sv)
: x(sv), y(sv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector2::Vector2(Value xv, Value yv)
: x(xv), y(yv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator = (Value s)
{
x = s;
y = s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator = (const Vector2i & v)
{
x = ConvTo< Value >::From(v.x);
y = ConvTo< Value >::From(v.y);
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator += (const Vector2 & v)
{
x += v.x;
y += v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator -= (const Vector2 & v)
{
x -= v.x;
y -= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator *= (const Vector2 & v)
{
x *= v.x;
y *= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator /= (const Vector2 & v)
{
x /= v.x;
y /= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator %= (const Vector2 & v)
{
x = std::fmod(x, v.x);
y = std::fmod(y, v.y);
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator += (Value s)
{
x += s;
y += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator -= (Value s)
{
x -= s;
y -= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator *= (Value s)
{
x *= s;
y *= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator /= (Value s)
{
x /= s;
y /= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator %= (Value s)
{
x = std::fmod(x, s);
y = std::fmod(y, s);
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator ++ ()
{
++x;
++y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 & Vector2::operator -- ()
{
--x;
--y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator ++ (int)
{
Vector2 state(*this);
++x;
++y;
return state;
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator -- (int)
{
Vector2 state(*this);
--x;
--y;
return state;
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator + (const Vector2 & v) const
{
return Vector2(x + v.x, y + v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator - (const Vector2 & v) const
{
return Vector2(x - v.x, y - v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator * (const Vector2 & v) const
{
return Vector2(x * v.x, y * v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator / (const Vector2 & v) const
{
return Vector2(x / v.x, y / v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator % (const Vector2 & v) const
{
return Vector2(std::fmod(x, v.x), std::fmod(y, v.y));
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator + (Value s) const
{
return Vector2(x + s, y + s);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator - (Value s) const
{
return Vector2(x - s, y - s);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator * (Value s) const
{
return Vector2(x * s, y * s);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator / (Value s) const
{
return Vector2(x / s, y / s);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator % (Value s) const
{
return Vector2(std::fmod(x, s), std::fmod(y, s));
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator + () const
{
return Vector2(std::fabs(x), std::fabs(y));
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::operator - () const
{
return Vector2(-x, -y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2::operator == (const Vector2 & v) const
{
return EpsEq(x, v.x) && EpsEq(y, v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2::operator != (const Vector2 & v) const
{
return !EpsEq(x, v.x) || !EpsEq(y, v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2::operator < (const Vector2 & v) const
{
return EpsLt(x, v.x) && EpsLt(y, v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2::operator > (const Vector2 & v) const
{
return EpsGt(x, v.x) && EpsGt(y, v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2::operator <= (const Vector2 & v) const
{
return EpsLtEq(x, v.x) && EpsLtEq(y, v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2::operator >= (const Vector2 & v) const
{
return EpsGtEq(x, v.x) && EpsGtEq(y, v.y);
}
// ------------------------------------------------------------------------------------------------
Int32 Vector2::Cmp(const Vector2 & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Vector2::ToString() const
{
return ToStrF("%f,%f", x, y);
}
// ------------------------------------------------------------------------------------------------
void Vector2::SetScalar(Value ns)
{
x = ns;
y = ns;
}
// ------------------------------------------------------------------------------------------------
void Vector2::SetVector2(const Vector2 & v)
{
x = v.x;
y = v.y;
}
// ------------------------------------------------------------------------------------------------
void Vector2::SetVector2Ex(Value nx, Value ny)
{
x = nx;
y = ny;
}
// ------------------------------------------------------------------------------------------------
void Vector2::SetVector2i(const Vector2i & v)
{
x = ConvTo< Value >::From(v.x);
y = ConvTo< Value >::From(v.y);
}
// ------------------------------------------------------------------------------------------------
void Vector2::SetStr(SQChar delim, StackStrF & values)
{
SetVector2(Vector2::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Vector2::Generate()
{
x = GetRandomFloat32();
y = GetRandomFloat32();
}
// ------------------------------------------------------------------------------------------------
void Vector2::Generate(Value min, Value max)
{
if (EpsLt(max, min))
{
STHROWF("max value is lower than min value");
}
x = GetRandomFloat32(min, max);
y = GetRandomFloat32(min, max);
}
// ------------------------------------------------------------------------------------------------
void Vector2::Generate(Value xmin, Value xmax, Value ymin, Value ymax)
{
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin))
{
STHROWF("max value is lower than min value");
}
x = GetRandomFloat32(ymin, ymax);
y = GetRandomFloat32(xmin, xmax);
}
// ------------------------------------------------------------------------------------------------
Vector2 Vector2::Abs() const
{
return Vector2(std::fabs(x), std::fabs(y));
}
// ------------------------------------------------------------------------------------------------
const Vector2 & Vector2::Get(StackStrF & str)
{
return Vector2::GetEx(Vector2::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Vector2 & Vector2::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %f , %f ");
static Vector2 vec;
// Clear previous values, if any
vec.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return vec; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, fs, &vec.x, &vec.y);
// Return the resulted value
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector2 & GetVector2()
{
static Vector2 vec;
vec.Clear();
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector2 & GetVector2(Float32 sv)
{
static Vector2 vec;
vec.SetScalar(sv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector2 & GetVector2(Float32 xv, Float32 yv)
{
static Vector2 vec;
vec.SetVector2Ex(xv, yv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector2 & GetVector2(const Vector2 & o)
{
static Vector2 vec;
vec.SetVector2(o);
return vec;
}
// ================================================================================================
void Register_Vector2(HSQUIRRELVM vm)
{
typedef Vector2::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Vector2 >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< Val, Val >()
// Member Variables
.Var(_SC("x"), &Vector2::x)
.Var(_SC("y"), &Vector2::y)
.Var(_SC("X"), &Vector2::x)
.Var(_SC("Y"), &Vector2::y)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Vector2::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Vector2 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2 >)
.Func< Vector2 (Vector2::*)(void) const >(_SC("_unm"), &Vector2::operator -)
// Properties
.Prop(_SC("Abs"), &Vector2::Abs)
// Member Methods
.Func(_SC("SetScalar"), &Vector2::SetScalar)
.Func(_SC("SetVector2"), &Vector2::SetVector2)
.Func(_SC("SetVector2Ex"), &Vector2::SetVector2Ex)
.Func(_SC("SetVector2i"), &Vector2::SetVector2i)
.FmtFunc(_SC("SetStr"), &Vector2::SetStr)
.Func(_SC("Clear"), &Vector2::Clear)
// Member Overloads
.Overload< void (Vector2::*)(void) >(_SC("Generate"), &Vector2::Generate)
.Overload< void (Vector2::*)(Val, Val) >(_SC("Generate"), &Vector2::Generate)
.Overload< void (Vector2::*)(Val, Val, Val, Val) >(_SC("Generate"), &Vector2::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Vector2 >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Vector2 >)
.StaticFmtFunc(_SC("FromStr"), &Vector2::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Vector2::GetEx)
// Operator Exposure
.Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opAddAssign"), &Vector2::operator +=)
.Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opSubAssign"), &Vector2::operator -=)
.Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opMulAssign"), &Vector2::operator *=)
.Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opDivAssign"), &Vector2::operator /=)
.Func< Vector2 & (Vector2::*)(const Vector2 &) >(_SC("opModAssign"), &Vector2::operator %=)
.Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opAddAssignS"), &Vector2::operator +=)
.Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opSubAssignS"), &Vector2::operator -=)
.Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opMulAssignS"), &Vector2::operator *=)
.Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opDivAssignS"), &Vector2::operator /=)
.Func< Vector2 & (Vector2::*)(Vector2::Value) >(_SC("opModAssignS"), &Vector2::operator %=)
.Func< Vector2 & (Vector2::*)(void) >(_SC("opPreInc"), &Vector2::operator ++)
.Func< Vector2 & (Vector2::*)(void) >(_SC("opPreDec"), &Vector2::operator --)
.Func< Vector2 (Vector2::*)(int) >(_SC("opPostInc"), &Vector2::operator ++)
.Func< Vector2 (Vector2::*)(int) >(_SC("opPostDec"), &Vector2::operator --)
.Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opAdd"), &Vector2::operator +)
.Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opSub"), &Vector2::operator -)
.Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opMul"), &Vector2::operator *)
.Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opDiv"), &Vector2::operator /)
.Func< Vector2 (Vector2::*)(const Vector2 &) const >(_SC("opMod"), &Vector2::operator %)
.Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opAddS"), &Vector2::operator +)
.Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opSubS"), &Vector2::operator -)
.Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opMulS"), &Vector2::operator *)
.Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opDivS"), &Vector2::operator /)
.Func< Vector2 (Vector2::*)(Vector2::Value) const >(_SC("opModS"), &Vector2::operator %)
.Func< Vector2 (Vector2::*)(void) const >(_SC("opUnPlus"), &Vector2::operator +)
.Func< Vector2 (Vector2::*)(void) const >(_SC("opUnMinus"), &Vector2::operator -)
.Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opEqual"), &Vector2::operator ==)
.Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opNotEqual"), &Vector2::operator !=)
.Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opLessThan"), &Vector2::operator <)
.Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opGreaterThan"), &Vector2::operator >)
.Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opLessEqual"), &Vector2::operator <=)
.Func< bool (Vector2::*)(const Vector2 &) const >(_SC("opGreaterEqual"), &Vector2::operator >=)
);
}
} // Namespace:: SqMod

360
module/Base/Vector2.hpp Normal file
View File

@ -0,0 +1,360 @@
#ifndef _BASE_VECTOR2_HPP_
#define _BASE_VECTOR2_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent a two-dimensional vector.
*/
struct Vector2
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef float Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Vector2 NIL;
static const Vector2 MIN;
static const Vector2 MAX;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The x and y components of this type.
*/
Value x, y;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Vector2();
/* --------------------------------------------------------------------------------------------
* Construct a vector with the same scalar value for all components.
*/
explicit Vector2(Value sv);
/* --------------------------------------------------------------------------------------------
* Construct a vector with the specified component values.
*/
Vector2(Value xv, Value yv);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Vector2(const Vector2 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Vector2(Vector2 && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Vector2() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Vector2 & operator = (const Vector2 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Vector2 & operator = (Vector2 && o) = default;
/* --------------------------------------------------------------------------------------------
* Scalar value assignment operator.
*/
Vector2 & operator = (Value s);
/* --------------------------------------------------------------------------------------------
* String assignment operator.
*/
Vector2 & operator = (CSStr values);
/* --------------------------------------------------------------------------------------------
* Integral two-dimensional vector assignment.
*/
Vector2 & operator = (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Vector2 & operator += (const Vector2 & v);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Vector2 & operator -= (const Vector2 & v);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Vector2 & operator *= (const Vector2 & v);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Vector2 & operator /= (const Vector2 & v);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Vector2 & operator %= (const Vector2 & v);
/* --------------------------------------------------------------------------------------------
* Scalar value addition assignment operator.
*/
Vector2 & operator += (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction assignment operator.
*/
Vector2 & operator -= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication assignment operator.
*/
Vector2 & operator *= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value division assignment operator.
*/
Vector2 & operator /= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value modulo assignment operator.
*/
Vector2 & operator %= (Value s);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Vector2 & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Vector2 & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Vector2 operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Vector2 operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Vector2 operator + (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Vector2 operator - (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Vector2 operator * (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Vector2 operator / (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Vector2 operator % (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Scalar value addition operator.
*/
Vector2 operator + (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction operator.
*/
Vector2 operator - (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication operator.
*/
Vector2 operator * (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value division operator.
*/
Vector2 operator / (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value modulo operator.
*/
Vector2 operator % (Value s) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Vector2 operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Vector2 operator - () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Vector2 & v) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Vector2(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Vector2(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Vector2(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(Vector2(static_cast< Value >(0)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value.
*/
void SetScalar(Value ns);
/* --------------------------------------------------------------------------------------------
* Copy the values from another instance of this type.
*/
void SetVector2(const Vector2 & v);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetVector2Ex(Value nx, Value ny);
/* --------------------------------------------------------------------------------------------
* Copy the values from an integral two-dimensional vector.
*/
void SetVector2i(const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & values);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value min, Value max);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
x = 0.0, y = 0.0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a new instance of this type with absolute component values.
*/
Vector2 Abs() const;
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector2 type from a string.
*/
static const Vector2 & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector2 type from a string.
*/
static const Vector2 & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_VECTOR2_HPP_

685
module/Base/Vector2i.cpp Normal file
View File

@ -0,0 +1,685 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Vector2i.hpp"
#include "Base/Vector2.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Vector2i"))
// ------------------------------------------------------------------------------------------------
const Vector2i Vector2i::NIL = Vector2i(0);
const Vector2i Vector2i::MIN = Vector2i(std::numeric_limits< Vector2i::Value >::min());
const Vector2i Vector2i::MAX = Vector2i(std::numeric_limits< Vector2i::Value >::max());
// ------------------------------------------------------------------------------------------------
SQChar Vector2i::Delim = ',';
// ------------------------------------------------------------------------------------------------
Vector2i::Vector2i()
: x(0), y(0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector2i::Vector2i(Value sv)
: x(sv), y(sv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector2i::Vector2i(Value xv, Value yv)
: x(xv), y(yv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator = (Value s)
{
x = s;
y = s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator = (const Vector2 & v)
{
x = ConvTo< Value >::From(v.x);
y = ConvTo< Value >::From(v.y);
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator += (const Vector2i & v)
{
x += v.x;
y += v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator -= (const Vector2i & v)
{
x -= v.x;
y -= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator *= (const Vector2i & v)
{
x *= v.x;
y *= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator /= (const Vector2i & v)
{
x /= v.x;
y /= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator %= (const Vector2i & v)
{
x %= v.x;
y %= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator &= (const Vector2i & v)
{
x &= v.x;
y &= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator |= (const Vector2i & v)
{
x |= v.x;
y |= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator ^= (const Vector2i & v)
{
x ^= v.x;
y ^= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator <<= (const Vector2i & v)
{
x <<= v.x;
y <<= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator >>= (const Vector2i & v)
{
x >>= v.x;
y >>= v.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator += (Value s)
{
x += s;
y += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator -= (Value s)
{
x -= s;
y -= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator *= (Value s)
{
x *= s;
y *= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator /= (Value s)
{
x /= s;
y /= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator %= (Value s)
{
x %= s;
y %= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator &= (Value s)
{
x &= s;
y &= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator |= (Value s)
{
x |= s;
y |= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator ^= (Value s)
{
x += s;
y += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator <<= (Value s)
{
x <<= s;
y <<= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator >>= (Value s)
{
x >>= s;
y >>= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator ++ ()
{
++x;
++y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i & Vector2i::operator -- ()
{
--x;
--y;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator ++ (int)
{
Vector2i state(*this);
++x;
++y;
return state;
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator -- (int)
{
Vector2i state(*this);
--x;
--y;
return state;
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator + (const Vector2i & v) const
{
return Vector2i(x + v.x, y + v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator - (const Vector2i & v) const
{
return Vector2i(x - v.x, y - v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator * (const Vector2i & v) const
{
return Vector2i(x * v.x, y * v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator / (const Vector2i & v) const
{
return Vector2i(x / v.x, y / v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator % (const Vector2i & v) const
{
return Vector2i(x % v.x, y % v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator & (const Vector2i & v) const
{
return Vector2i(x & v.x, y & v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator | (const Vector2i & v) const
{
return Vector2i(x | v.x, y | v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator ^ (const Vector2i & v) const
{
return Vector2i(x ^ v.x, y ^ v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator << (const Vector2i & v) const
{
return Vector2i(x << v.x, y << v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator >> (const Vector2i & v) const
{
return Vector2i(x >> v.x, y >> v.y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator + (Value s) const
{
return Vector2i(x + s, y + s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator - (Value s) const
{
return Vector2i(x - s, y - s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator * (Value s) const
{
return Vector2i(x * s, y * s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator / (Value s) const
{
return Vector2i(x / s, y / s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator % (Value s) const
{
return Vector2i(x % s, y % s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator & (Value s) const
{
return Vector2i(x & s, y & s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator | (Value s) const
{
return Vector2i(x | s, y | s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator ^ (Value s) const
{
return Vector2i(x ^ s, y ^ s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator << (Value s) const
{
return Vector2i(x < s, y < s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator >> (Value s) const
{
return Vector2i(x >> s, y >> s);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator + () const
{
return Vector2i(std::abs(x), std::abs(y));
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator - () const
{
return Vector2i(-x, -y);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::operator ~ () const
{
return Vector2i(~x, ~y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2i::operator == (const Vector2i & v) const
{
return (x == v.x) && (y == v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2i::operator != (const Vector2i & v) const
{
return (x != v.x) || (y != v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2i::operator < (const Vector2i & v) const
{
return (x < v.x) && (y < v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2i::operator > (const Vector2i & v) const
{
return (x > v.x) && (y > v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2i::operator <= (const Vector2i & v) const
{
return (x <= v.x) && (y <= v.y);
}
// ------------------------------------------------------------------------------------------------
bool Vector2i::operator >= (const Vector2i & v) const
{
return (x >= v.x) && (y >= v.y);
}
// ------------------------------------------------------------------------------------------------
Int32 Vector2i::Cmp(const Vector2i & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Vector2i::ToString() const
{
return ToStrF("%d,%d", x, y);
}
// ------------------------------------------------------------------------------------------------
void Vector2i::SetScalar(Value ns)
{
x = ns;
y = ns;
}
// ------------------------------------------------------------------------------------------------
void Vector2i::SetVector2i(const Vector2i & v)
{
x = v.x;
y = v.y;
}
// ------------------------------------------------------------------------------------------------
void Vector2i::SetVector2iEx(Value nx, Value ny)
{
x = nx;
y = ny;
}
// ------------------------------------------------------------------------------------------------
void Vector2i::SetVector2(const Vector2 & v)
{
x = ConvTo< Value >::From(v.x);
y = ConvTo< Value >::From(v.y);
}
// ------------------------------------------------------------------------------------------------
void Vector2i::SetStr(SQChar delim, StackStrF & values)
{
SetVector2i(Vector2i::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Vector2i::Generate()
{
x = GetRandomInt32();
y = GetRandomInt32();
}
// ------------------------------------------------------------------------------------------------
void Vector2i::Generate(Value min, Value max)
{
if (max < min)
{
STHROWF("max value is lower than min value");
}
x = GetRandomInt32(min, max);
y = GetRandomInt32(min, max);
}
// ------------------------------------------------------------------------------------------------
void Vector2i::Generate(Value xmin, Value xmax, Value ymin, Value ymax)
{
if (xmax < xmin || ymax < ymin)
{
STHROWF("max value is lower than min value");
}
x = GetRandomInt32(ymin, ymax);
y = GetRandomInt32(xmin, xmax);
}
// ------------------------------------------------------------------------------------------------
Vector2i Vector2i::Abs() const
{
return Vector2i(std::abs(x), std::abs(y));
}
// ------------------------------------------------------------------------------------------------
const Vector2i & Vector2i::Get(StackStrF & str)
{
return Vector2i::GetEx(Vector2i::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Vector2i & Vector2i::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %d , %d ");
static Vector2i vec;
// Clear previous values, if any
vec.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return vec; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, &fs[0], &vec.x, &vec.y);
// Return the resulted value
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector2i & GetVector2i()
{
static Vector2i vec;
vec.Clear();
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector2i & GetVector2i(Int32 sv)
{
static Vector2i vec;
vec.SetScalar(sv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector2i & GetVector2i(Int32 xv, Int32 yv)
{
static Vector2i vec;
vec.SetVector2iEx(xv, yv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector2i & GetVector2i(const Vector2i & o)
{
static Vector2i vec;
vec.SetVector2i(o);
return vec;
}
// ================================================================================================
void Register_Vector2i(HSQUIRRELVM vm)
{
typedef Vector2i::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Vector2i >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< Val, Val >()
// Member Variables
.Var(_SC("x"), &Vector2i::x)
.Var(_SC("y"), &Vector2i::y)
.Var(_SC("X"), &Vector2i::x)
.Var(_SC("Y"), &Vector2i::y)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Vector2i::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Vector2i >, SQFloat, SQInteger, bool, std::nullptr_t, Vector2i >)
.Func< Vector2i (Vector2i::*)(void) const >(_SC("_unm"), &Vector2i::operator -)
// Properties
.Prop(_SC("Abs"), &Vector2i::Abs)
// Member Methods
.Func(_SC("SetScalar"), &Vector2i::SetScalar)
.Func(_SC("SetVector2i"), &Vector2i::SetVector2i)
.Func(_SC("SetVector2iEx"), &Vector2i::SetVector2iEx)
.Func(_SC("SetVector2"), &Vector2i::SetVector2)
.FmtFunc(_SC("SetStr"), &Vector2i::SetStr)
.Func(_SC("Clear"), &Vector2i::Clear)
// Member Overloads
.Overload< void (Vector2i::*)(void) >(_SC("Generate"), &Vector2i::Generate)
.Overload< void (Vector2i::*)(Val, Val) >(_SC("Generate"), &Vector2i::Generate)
.Overload< void (Vector2i::*)(Val, Val, Val, Val) >(_SC("Generate"), &Vector2i::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Vector2i >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Vector2i >)
.StaticFmtFunc(_SC("FromStr"), &Vector2i::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Vector2i::GetEx)
// Operator Exposure
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opAddAssign"), &Vector2i::operator +=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opSubAssign"), &Vector2i::operator -=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opMulAssign"), &Vector2i::operator *=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opDivAssign"), &Vector2i::operator /=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opModAssign"), &Vector2i::operator %=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opAndAssign"), &Vector2i::operator &=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opOrAssign"), &Vector2i::operator |=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opXorAssign"), &Vector2i::operator ^=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opShlAssign"), &Vector2i::operator <<=)
.Func< Vector2i & (Vector2i::*)(const Vector2i &) >(_SC("opShrAssign"), &Vector2i::operator >>=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opAddAssignS"), &Vector2i::operator +=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opSubAssignS"), &Vector2i::operator -=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opMulAssignS"), &Vector2i::operator *=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opDivAssignS"), &Vector2i::operator /=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opModAssignS"), &Vector2i::operator %=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opAndAssignS"), &Vector2i::operator &=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opOrAssignS"), &Vector2i::operator |=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opXorAssignS"), &Vector2i::operator ^=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opShlAssignS"), &Vector2i::operator <<=)
.Func< Vector2i & (Vector2i::*)(Vector2i::Value) >(_SC("opShrAssignS"), &Vector2i::operator >>=)
.Func< Vector2i & (Vector2i::*)(void) >(_SC("opPreInc"), &Vector2i::operator ++)
.Func< Vector2i & (Vector2i::*)(void) >(_SC("opPreDec"), &Vector2i::operator --)
.Func< Vector2i (Vector2i::*)(int) >(_SC("opPostInc"), &Vector2i::operator ++)
.Func< Vector2i (Vector2i::*)(int) >(_SC("opPostDec"), &Vector2i::operator --)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opAdd"), &Vector2i::operator +)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opSub"), &Vector2i::operator -)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opMul"), &Vector2i::operator *)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opDiv"), &Vector2i::operator /)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opMod"), &Vector2i::operator %)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opAnd"), &Vector2i::operator &)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opOr"), &Vector2i::operator |)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opShl"), &Vector2i::operator ^)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opShl"), &Vector2i::operator <<)
.Func< Vector2i (Vector2i::*)(const Vector2i &) const >(_SC("opShr"), &Vector2i::operator >>)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opAddS"), &Vector2i::operator +)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opSubS"), &Vector2i::operator -)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opMulS"), &Vector2i::operator *)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opDivS"), &Vector2i::operator /)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opModS"), &Vector2i::operator %)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opAndS"), &Vector2i::operator &)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opOrS"), &Vector2i::operator |)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opShlS"), &Vector2i::operator ^)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opShlS"), &Vector2i::operator <<)
.Func< Vector2i (Vector2i::*)(Vector2i::Value) const >(_SC("opShrS"), &Vector2i::operator >>)
.Func< Vector2i (Vector2i::*)(void) const >(_SC("opUnPlus"), &Vector2i::operator +)
.Func< Vector2i (Vector2i::*)(void) const >(_SC("opUnMinus"), &Vector2i::operator -)
.Func< Vector2i (Vector2i::*)(void) const >(_SC("opCom"), &Vector2i::operator ~)
.Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opEqual"), &Vector2i::operator ==)
.Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opNotEqual"), &Vector2i::operator !=)
.Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opLessThan"), &Vector2i::operator <)
.Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opGreaterThan"), &Vector2i::operator >)
.Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opLessEqual"), &Vector2i::operator <=)
.Func< bool (Vector2i::*)(const Vector2i &) const >(_SC("opGreaterEqual"), &Vector2i::operator >=)
);
}
} // Namespace:: SqMod

461
module/Base/Vector2i.hpp Normal file
View File

@ -0,0 +1,461 @@
#ifndef _BASE_VECTOR2I_HPP_
#define _BASE_VECTOR2I_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent a two-dimensional vector using integral values.
*/
struct Vector2i
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef int Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Vector2i NIL;
static const Vector2i MIN;
static const Vector2i MAX;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The x and y components of this type.
*/
Value x, y;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Vector2i();
/* --------------------------------------------------------------------------------------------
* Construct a vector with the same scalar value for all components.
*/
explicit Vector2i(Value sv);
/* --------------------------------------------------------------------------------------------
* Construct a vector with the specified component values.
*/
Vector2i(Value xv, Value yv);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Vector2i(const Vector2i & o) = default;
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Vector2i(Vector2i && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Vector2i() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Vector2i & operator = (const Vector2i & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Vector2i & operator = (Vector2i && o) = default;
/* --------------------------------------------------------------------------------------------
* Scalar value assignment operator.
*/
Vector2i & operator = (Value s);
/* --------------------------------------------------------------------------------------------
* Real two-dimensional vector assignment.
*/
Vector2i & operator = (const Vector2 & v);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Vector2i & operator += (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Vector2i & operator -= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Vector2i & operator *= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Vector2i & operator /= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Vector2i & operator %= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Bitwise AND assignment operator.
*/
Vector2i & operator &= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Bitwise OR assignment operator.
*/
Vector2i & operator |= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Bitwise XOR assignment operator.
*/
Vector2i & operator ^= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Bitwise left shift assignment operator.
*/
Vector2i & operator <<= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Bitwise right shift assignment operator.
*/
Vector2i & operator >>= (const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Scalar value addition assignment operator.
*/
Vector2i & operator += (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction assignment operator.
*/
Vector2i & operator -= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication assignment operator.
*/
Vector2i & operator *= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value division assignment operator.
*/
Vector2i & operator /= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value modulo assignment operator.
*/
Vector2i & operator %= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise AND assignment operator.
*/
Vector2i & operator &= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise OR assignment operator.
*/
Vector2i & operator |= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise XOR assignment operator.
*/
Vector2i & operator ^= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise left shift assignment operator.
*/
Vector2i & operator <<= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise right shift assignment operator.
*/
Vector2i & operator >>= (Value s);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Vector2i & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Vector2i & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Vector2i operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Vector2i operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Vector2i operator + (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Vector2i operator - (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Vector2i operator * (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Vector2i operator / (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Vector2i operator % (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Bitwise AND operator.
*/
Vector2i operator & (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Bitwise OR operator.
*/
Vector2i operator | (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Bitwise XOR operator.
*/
Vector2i operator ^ (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Bitwise shift left operator.
*/
Vector2i operator << (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Bitwise shift right operator.
*/
Vector2i operator >> (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Scalar value addition operator.
*/
Vector2i operator + (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction operator.
*/
Vector2i operator - (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication operator.
*/
Vector2i operator * (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value division operator.
*/
Vector2i operator / (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value modulo operator.
*/
Vector2i operator % (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise AND operator.
*/
Vector2i operator & (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise OR operator.
*/
Vector2i operator | (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise XOR operator.
*/
Vector2i operator ^ (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise shift left operator.
*/
Vector2i operator << (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value bitwise shift right operator.
*/
Vector2i operator >> (Value s) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Vector2i operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Vector2i operator - () const;
/* --------------------------------------------------------------------------------------------
* Bitwise NOT operator.
*/
Vector2i operator ~ () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Vector2i & v) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Vector2i(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Vector2i(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Vector2i(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(Vector2i(static_cast< Value >(0)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value.
*/
void SetScalar(Value ns);
/* --------------------------------------------------------------------------------------------
* Copy the values from another instance of this type.
*/
void SetVector2i(const Vector2i & v);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetVector2iEx(Value nx, Value ny);
/* --------------------------------------------------------------------------------------------
* Copy the values from a real two-dimensional vector.
*/
void SetVector2(const Vector2 & v);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & values);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value min, Value max);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
x = 0, y = 0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a new instance of this type with absolute component values.
*/
Vector2i Abs() const;
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector2i type from a string.
*/
static const Vector2i & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector2i type from a string.
*/
static const Vector2i & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_VECTOR2I_HPP_

809
module/Base/Vector3.cpp Normal file
View File

@ -0,0 +1,809 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Vector3.hpp"
#include "Base/Vector4.hpp"
#include "Base/Quaternion.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
#define STOVAL(v) static_cast< Vector3::Value >(v)
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Vector3"))
// ------------------------------------------------------------------------------------------------
const Vector3 Vector3::NIL(STOVAL(0.0));
const Vector3 Vector3::MIN(std::numeric_limits< Vector3::Value >::min());
const Vector3 Vector3::MAX(std::numeric_limits< Vector3::Value >::max());
const Vector3 Vector3::LEFT(STOVAL(-1.0), STOVAL(0.0), STOVAL(0.0));
const Vector3 Vector3::RIGHT(STOVAL(1.0), STOVAL(0.0), STOVAL(0.0));
const Vector3 Vector3::UP(STOVAL(0.0), STOVAL(1.0), STOVAL(0.0));
const Vector3 Vector3::DOWN(STOVAL(0.0), STOVAL(-1.0), STOVAL(0.0));
const Vector3 Vector3::FORWARD(STOVAL(0.0), STOVAL(0.0), STOVAL(1.0));
const Vector3 Vector3::BACK(STOVAL(0.0), STOVAL(0.0), STOVAL(-1.0));
const Vector3 Vector3::ONE(STOVAL(1.0), STOVAL(1.0), STOVAL(1.0));
// ------------------------------------------------------------------------------------------------
SQChar Vector3::Delim = ',';
// ------------------------------------------------------------------------------------------------
Vector3::Vector3()
: x(0.0), y(0.0), z(0.0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector3::Vector3(Value sv)
: x(sv), y(sv), z(sv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector3::Vector3(Value xv, Value yv, Value zv)
: x(xv), y(yv), z(zv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator = (Value s)
{
x = s;
y = s;
z = s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator = (const Vector4 & v)
{
x = v.x;
y = v.y;
z = v.z;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator = (const Quaternion & q)
{
x = q.x;
y = q.y;
z = q.z;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator += (const Vector3 & v)
{
x += v.x;
y += v.y;
z += v.z;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator -= (const Vector3 & v)
{
x -= v.x;
y -= v.y;
z -= v.z;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator *= (const Vector3 & v)
{
x *= v.x;
y *= v.y;
z *= v.z;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator /= (const Vector3 & v)
{
x /= v.x;
y /= v.y;
z /= v.z;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator %= (const Vector3 & v)
{
x = std::fmod(x, v.x);
y = std::fmod(y, v.y);
z = std::fmod(z, v.z);
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator += (Value s)
{
x += s;
y += s;
z += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator -= (Value s)
{
x -= s;
y -= s;
z -= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator *= (Value s)
{
x *= s;
y *= s;
z *= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator /= (Value s)
{
x /= s;
y /= s;
z /= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator %= (Value s)
{
x = std::fmod(x, s);
y = std::fmod(y, s);
z = std::fmod(z, s);
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator ++ ()
{
++x;
++y;
++z;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 & Vector3::operator -- ()
{
--x;
--y;
--z;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator ++ (int)
{
Vector3 state(*this);
++x;
++y;
++z;
return state;
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator -- (int)
{
Vector3 state(*this);
--x;
--y;
--z;
return state;
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator + (const Vector3 & v) const
{
return Vector3(x + v.x, y + v.y, z + v.z);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator - (const Vector3 & v) const
{
return Vector3(x - v.x, y - v.y, z - v.z);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator * (const Vector3 & v) const
{
return Vector3(x * v.x, y * v.y, z * v.z);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator / (const Vector3 & v) const
{
return Vector3(x / v.x, y / v.y, z / v.z);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator % (const Vector3 & v) const
{
return Vector3(std::fmod(x, v.x), std::fmod(y, v.y), std::fmod(z, v.z));
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator + (Value s) const
{
return Vector3(x + s, y + s, z + s);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator - (Value s) const
{
return Vector3(x - s, y - s, z - s);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator * (Value s) const
{
return Vector3(x * s, y * s, z * s);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator / (Value s) const
{
return Vector3(x / s, y / s, z / s);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator % (Value s) const
{
return Vector3(std::fmod(x, s), std::fmod(y, s), std::fmod(z, s));
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator + () const
{
return Vector3(std::fabs(x), std::fabs(y), std::fabs(z));
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::operator - () const
{
return Vector3(-x, -y, -z);
}
// ------------------------------------------------------------------------------------------------
bool Vector3::operator == (const Vector3 & v) const
{
return EpsEq(x, v.x) && EpsEq(y, v.y) && EpsEq(z, v.z);
}
// ------------------------------------------------------------------------------------------------
bool Vector3::operator != (const Vector3 & v) const
{
return !EpsEq(x, v.x) || !EpsEq(y, v.y) || !EpsEq(z, v.z);
}
// ------------------------------------------------------------------------------------------------
bool Vector3::operator < (const Vector3 & v) const
{
return EpsLt(x, v.x) && EpsLt(y, v.y) && EpsLt(z, v.z);
}
// ------------------------------------------------------------------------------------------------
bool Vector3::operator > (const Vector3 & v) const
{
return EpsGt(x, v.x) && EpsGt(y, v.y) && EpsGt(z, v.z);
}
// ------------------------------------------------------------------------------------------------
bool Vector3::operator <= (const Vector3 & v) const
{
return EpsLtEq(x, v.x) && EpsLtEq(y, v.y) && EpsLtEq(z, v.z);
}
// ------------------------------------------------------------------------------------------------
bool Vector3::operator >= (const Vector3 & v) const
{
return EpsGtEq(x, v.x) && EpsGtEq(y, v.y) && EpsGtEq(z, v.z);
}
// ------------------------------------------------------------------------------------------------
Int32 Vector3::Cmp(const Vector3 & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Vector3::ToString() const
{
return ToStrF("%f,%f,%f", x, y, z);
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetScalar(Value ns)
{
x = ns;
y = ns;
z = ns;
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetVector3(const Vector3 & v)
{
x = v.x;
y = v.y;
z = v.z;
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetVector3Ex(Value nx, Value ny, Value nz)
{
x = nx;
y = ny;
z = nz;
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetVector4(const Vector4 & v)
{
x = v.x;
y = v.y;
z = v.z;
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetVector4Ex(Value nx, Value ny, Value nz, Value /*nw*/)
{
x = nx;
y = ny;
z = nz;
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetQuaternion(const Quaternion & q)
{
SetQuaternionEx(q.x, q.y, q.z, q.w);
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetQuaternionEx(Value qx, Value qy, Value qz, Value qw)
{
// Quick conversion to Euler angles to give tilt to user
const Value sqx = (qx * qx), sqy = (qy * qy), sqz = (qz * qz), sqw = (qw * qw);
y = std::asin(STOVAL(2.0) * ((qw * qy) - (qx * qz)));
if (EpsGt((SQMOD_PI * STOVAL(0.5)) - std::abs(y), STOVAL(1e-10)))
{
z = std::atan2(STOVAL(2.0) * ((qx * qy) + (qw * qz)), sqx - sqy - sqz + sqw);
x = std::atan2(STOVAL(2.0) * ((qw * qx) + (qy * qz)), sqw - sqx - sqy + sqz);
}
else
{
// Compute heading from local 'down' vector
z = std::atan2((STOVAL(2.0) * qy * qz) - (STOVAL(2.0) * qx * qw),
(STOVAL(2.0) * qx * qz) + (STOVAL(2.0) * qy * qw));
x = STOVAL(0.0);
// If facing down, reverse yaw
if (EpsLt(y, STOVAL(0.0)))
{
z -= SQMOD_PI;
}
}
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetStr(SQChar delim, StackStrF & values)
{
SetVector3(Vector3::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Vector3::Generate()
{
x = GetRandomFloat32();
y = GetRandomFloat32();
z = GetRandomFloat32();
}
// ------------------------------------------------------------------------------------------------
void Vector3::Generate(Value min, Value max)
{
if (EpsLt(max, min))
{
STHROWF("max value is lower than min value");
}
x = GetRandomFloat32(min, max);
y = GetRandomFloat32(min, max);
z = GetRandomFloat32(min, max);
}
// ------------------------------------------------------------------------------------------------
void Vector3::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax)
{
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin))
{
STHROWF("max value is lower than min value");
}
x = GetRandomFloat32(xmin, xmax);
y = GetRandomFloat32(ymin, ymax);
z = GetRandomFloat32(zmin, zmax);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::Abs() const
{
return Vector3(std::fabs(x), std::fabs(y), std::fabs(z));
}
// ------------------------------------------------------------------------------------------------
bool Vector3::IsNaN() const
{
return std::isnan(x) || std::isnan(y) || std::isnan(z);
}
// ------------------------------------------------------------------------------------------------
Vector3::Value Vector3::GetLength() const
{
return std::sqrt((x * x) + (y * y) + (z * z));
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetLength(Value length)
{
Normalize();
// Assign the specified length
*this *= length;
}
// ------------------------------------------------------------------------------------------------
Vector3::Value Vector3::GetLengthSquared() const
{
return ((x * x) + (y * y) + (z * z));
}
// ------------------------------------------------------------------------------------------------
void Vector3::SetLengthSquared(Value length)
{
Normalize();
// Assign the specified length
*this *= std::sqrt(length);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::Normalized() const
{
const Value len_squared = GetLengthSquared();
if (!EpsEq(len_squared, STOVAL(1.0)) && EpsLt(len_squared, STOVAL(0.0)))
{
return (*this * (STOVAL(1.0) / std::sqrt(len_squared)));
}
else
{
return *this;
}
}
// ------------------------------------------------------------------------------------------------
void Vector3::Normalize()
{
const Value len_squared = GetLengthSquared();
if (!EpsEq(len_squared, STOVAL(1.0)) && EpsGt(len_squared, STOVAL(0.0)))
{
const Value inv_len = STOVAL(1.0) / std::sqrt(len_squared);
x *= inv_len;
y *= inv_len;
z *= inv_len;
}
}
// ------------------------------------------------------------------------------------------------
Vector3::Value Vector3::DotProduct(const Vector3 & vec) const
{
return ((x * vec.x) + (y * vec.y) + (z * vec.z));
}
// ------------------------------------------------------------------------------------------------
Vector3::Value Vector3::AbsDotProduct(const Vector3 & vec) const
{
return (std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z));
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::CrossProduct(const Vector3 & vec) const
{
return Vector3((y * vec.z) - (z * vec.y), (z * vec.x) - (x * vec.z), (x * vec.y) - (y * vec.x));
}
// ------------------------------------------------------------------------------------------------
Vector3::Value Vector3::Angle(const Vector3 & vec) const
{
return std::acos(DotProduct(vec) / (GetLength() * vec.GetLength()));
}
// ------------------------------------------------------------------------------------------------
Vector3::Value Vector3::GetDistanceTo(const Vector3 & vec) const
{
return std::sqrt(std::pow(x - vec.x, 2) + std::pow(y - vec.y, 2) + std::pow(z - vec.z, 2));
}
// ------------------------------------------------------------------------------------------------
Vector3::Value Vector3::GetSquaredDistanceTo(const Vector3 & vec) const
{
return (std::pow(x - vec.x, 2) + std::pow(y - vec.y, 2) + std::pow(z - vec.z, 2));
}
// ------------------------------------------------------------------------------------------------
bool Vector3::IsBetweenPoints(const Vector3 & begin, const Vector3 & end) const
{
const Value length = (end - begin).GetLengthSquared();
return EpsLtEq(GetSquaredDistanceTo(begin), length) && EpsLtEq(GetSquaredDistanceTo(end), length);
}
// ------------------------------------------------------------------------------------------------
void Vector3::Interpolate(const Vector3 & a, const Vector3 & b, Value d)
{
x = STOVAL(static_cast< Float64 >(b.x) + ((a.x - b.x) * d));
y = STOVAL(static_cast< Float64 >(b.y) + ((a.y - b.y) * d));
z = STOVAL(static_cast< Float64 >(b.z) + ((a.z - b.z) * d));
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::Interpolated(const Vector3 & vec, Value d) const
{
const Float64 inv = 1.0 - d;
return Vector3(
STOVAL((vec.x * inv) + (x * d)),
STOVAL((vec.y * inv) + (y * d)),
STOVAL((vec.z * inv) + (z * d))
);
}
// ------------------------------------------------------------------------------------------------
Vector3 Vector3::Rotated(const Vector3 & axis, Value angle) const
{
const Vector3 o(axis * axis.DotProduct(*this));
return (o + ((*this - o) * std::cos(angle)) + (axis.CrossProduct(*this) * std::sin(angle)));
}
// ------------------------------------------------------------------------------------------------
void Vector3::CenterRotateXZBy(Value degrees, const Vector3 & center)
{
degrees *= SQMOD_DEGTORAD;
const Value cs = std::cos(degrees);
const Value sn = std::sin(degrees);
x -= center.x;
z -= center.z;
x = static_cast< Value >((x * cs) - (z * sn)) + center.x;
z = static_cast< Value >((x * sn) + (z * cs)) + center.z;
}
// ------------------------------------------------------------------------------------------------
void Vector3::CenterRotateXYBy(Value degrees, const Vector3 & center)
{
degrees *= SQMOD_DEGTORAD;
const Value cs = std::cos(degrees);
const Value sn = std::sin(degrees);
x -= center.x;
y -= center.y;
x = static_cast< Value >((x * cs) - (y * sn)) + center.x;
y = static_cast< Value >((x * sn) + (y * cs)) + center.y;
}
// ------------------------------------------------------------------------------------------------
void Vector3::CenterRotateYZBy(Value degrees, const Vector3 & center)
{
degrees *= SQMOD_DEGTORAD;
const Value cs = std::cos(degrees);
const Value sn = std::sin(degrees);
z -= center.z;
y -= center.y;
y = static_cast< Value >((y * cs) - (z * sn)) + center.z;
z = static_cast< Value >((y * sn) + (z * cs)) + center.y;
}
// ------------------------------------------------------------------------------------------------
const Vector3 & Vector3::Get(StackStrF & str)
{
return Vector3::GetEx(Vector3::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Vector3 & Vector3::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %f , %f , %f ");
static Vector3 vec;
// Clear previous values, if any
vec.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return vec; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
fs[9] = delim;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, &fs[0], &vec.x, &vec.y, &vec.z);
// Return the resulted value
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector3 & GetVector3()
{
static Vector3 vec;
vec.Clear();
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector3 & GetVector3(Float32 sv)
{
static Vector3 vec;
vec.SetScalar(sv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector3 & GetVector3(Float32 xv, Float32 yv, Float32 zv)
{
static Vector3 vec;
vec.SetVector3Ex(xv, yv, zv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector3 & GetVector3(const Vector3 & o)
{
static Vector3 vec;
vec.SetVector3(o);
return vec;
}
// ================================================================================================
void Register_Vector3(HSQUIRRELVM vm)
{
typedef Vector3::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Vector3 >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< Val, Val, Val >()
// Static variables
.SetStaticValue(_SC("NIL"), &Vector3::NIL)
.SetStaticValue(_SC("MIN"), &Vector3::MIN)
.SetStaticValue(_SC("MAX"), &Vector3::MAX)
.SetStaticValue(_SC("LEFT"), &Vector3::LEFT)
.SetStaticValue(_SC("RIGHT"), &Vector3::RIGHT)
.SetStaticValue(_SC("UP"), &Vector3::UP)
.SetStaticValue(_SC("DOWN"), &Vector3::DOWN)
.SetStaticValue(_SC("FORWARD"), &Vector3::FORWARD)
.SetStaticValue(_SC("BACK"), &Vector3::BACK)
.SetStaticValue(_SC("ONE"), &Vector3::ONE)
// Member Variables
.Var(_SC("x"), &Vector3::x)
.Var(_SC("y"), &Vector3::y)
.Var(_SC("z"), &Vector3::z)
.Var(_SC("X"), &Vector3::x)
.Var(_SC("Y"), &Vector3::y)
.Var(_SC("Z"), &Vector3::z)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Vector3::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Vector3 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector3 >)
.Func< Vector3 (Vector3::*)(void) const >(_SC("_unm"), &Vector3::operator -)
// Properties
.Prop(_SC("Abs"), &Vector3::Abs)
.Prop(_SC("NaN"), &Vector3::IsNaN)
.Prop(_SC("Length"), &Vector3::GetLength, &Vector3::SetLength)
.Prop(_SC("LengthSq"), &Vector3::GetLengthSquared, &Vector3::SetLengthSquared)
.Prop(_SC("Normalized"), &Vector3::Normalized)
// Member Methods
.Func(_SC("SetScalar"), &Vector3::SetScalar)
.Func(_SC("SetVector3"), &Vector3::SetVector3)
.Func(_SC("SetVector3Ex"), &Vector3::SetVector3Ex)
.Func(_SC("SetVector4"), &Vector3::SetVector4)
.Func(_SC("SetVector4Ex"), &Vector3::SetVector4Ex)
.Func(_SC("SetQuaternion"), &Vector3::SetQuaternion)
.Func(_SC("SetQuaternionEx"), &Vector3::SetQuaternionEx)
.FmtFunc(_SC("SetStr"), &Vector3::SetStr)
.Func(_SC("Clear"), &Vector3::Clear)
.Func(_SC("Normalize"), &Vector3::Normalize)
.Func(_SC("Dot"), &Vector3::DotProduct)
.Func(_SC("AbsDot"), &Vector3::AbsDotProduct)
.Func(_SC("Cross"), &Vector3::CrossProduct)
.Func(_SC("Angle"), &Vector3::Angle)
.Func(_SC("DistanceTo"), &Vector3::GetDistanceTo)
.Func(_SC("SqDistanceTo"), &Vector3::GetSquaredDistanceTo)
.Func(_SC("IsBetweenPoints"), &Vector3::IsBetweenPoints)
.Func(_SC("Interpolate"), &Vector3::Interpolate)
.Func(_SC("Interpolated"), &Vector3::Interpolated)
.Func(_SC("Rotated"), &Vector3::Rotated)
.Func(_SC("RotateXZBy"), &Vector3::RotateXZBy)
.Func(_SC("CenterRotateXZBy"), &Vector3::CenterRotateXZBy)
.Func(_SC("RotateXYBy"), &Vector3::RotateXYBy)
.Func(_SC("CenterRotateXYBy"), &Vector3::CenterRotateXYBy)
.Func(_SC("RotateYZBy"), &Vector3::RotateYZBy)
.Func(_SC("CenterRotateYZBy"), &Vector3::CenterRotateYZBy)
// Member Overloads
.Overload< void (Vector3::*)(void) >(_SC("Generate"), &Vector3::Generate)
.Overload< void (Vector3::*)(Val, Val) >(_SC("Generate"), &Vector3::Generate)
.Overload< void (Vector3::*)(Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Vector3::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Vector3 >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Vector3 >)
.StaticFmtFunc(_SC("FromStr"), &Vector3::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Vector3::GetEx)
// Operator Exposure
.Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opAddAssign"), &Vector3::operator +=)
.Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opSubAssign"), &Vector3::operator -=)
.Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opMulAssign"), &Vector3::operator *=)
.Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opDivAssign"), &Vector3::operator /=)
.Func< Vector3 & (Vector3::*)(const Vector3 &) >(_SC("opModAssign"), &Vector3::operator %=)
.Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opAddAssignS"), &Vector3::operator +=)
.Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opSubAssignS"), &Vector3::operator -=)
.Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opMulAssignS"), &Vector3::operator *=)
.Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opDivAssignS"), &Vector3::operator /=)
.Func< Vector3 & (Vector3::*)(Vector3::Value) >(_SC("opModAssignS"), &Vector3::operator %=)
.Func< Vector3 & (Vector3::*)(void) >(_SC("opPreInc"), &Vector3::operator ++)
.Func< Vector3 & (Vector3::*)(void) >(_SC("opPreDec"), &Vector3::operator --)
.Func< Vector3 (Vector3::*)(int) >(_SC("opPostInc"), &Vector3::operator ++)
.Func< Vector3 (Vector3::*)(int) >(_SC("opPostDec"), &Vector3::operator --)
.Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opAdd"), &Vector3::operator +)
.Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opSub"), &Vector3::operator -)
.Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opMul"), &Vector3::operator *)
.Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opDiv"), &Vector3::operator /)
.Func< Vector3 (Vector3::*)(const Vector3 &) const >(_SC("opMod"), &Vector3::operator %)
.Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opAddS"), &Vector3::operator +)
.Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opSubS"), &Vector3::operator -)
.Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opMulS"), &Vector3::operator *)
.Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opDivS"), &Vector3::operator /)
.Func< Vector3 (Vector3::*)(Vector3::Value) const >(_SC("opModS"), &Vector3::operator %)
.Func< Vector3 (Vector3::*)(void) const >(_SC("opUnPlus"), &Vector3::operator +)
.Func< Vector3 (Vector3::*)(void) const >(_SC("opUnMinus"), &Vector3::operator -)
.Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opEqual"), &Vector3::operator ==)
.Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opNotEqual"), &Vector3::operator !=)
.Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opLessThan"), &Vector3::operator <)
.Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opGreaterThan"), &Vector3::operator >)
.Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opLessEqual"), &Vector3::operator <=)
.Func< bool (Vector3::*)(const Vector3 &) const >(_SC("opGreaterEqual"), &Vector3::operator >=)
);
}
} // Namespace:: SqMod

507
module/Base/Vector3.hpp Normal file
View File

@ -0,0 +1,507 @@
#ifndef _BASE_VECTOR3_HPP_
#define _BASE_VECTOR3_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent a three-dimensional vector.
*/
struct Vector3
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef float Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Vector3 NIL; // ( 0, 0, 0)
static const Vector3 MIN; // (<0, <0, <0)
static const Vector3 MAX; // (>0, >0, >0)
static const Vector3 LEFT; // (-1, 0, 0)
static const Vector3 RIGHT; // ( 1, 0, 0)
static const Vector3 UP; // ( 0, 1, 0)
static const Vector3 DOWN; // ( 0, -1, 0)
static const Vector3 FORWARD; // ( 0, 0, 1)
static const Vector3 BACK; // ( 0, 0, -1)
static const Vector3 ONE; // ( 1, 1, 1)
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The x, y and z components of this type.
*/
Value x, y, z;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Vector3();
/* --------------------------------------------------------------------------------------------
* Construct a vector with the same scalar value for all components.
*/
explicit Vector3(Value sv);
/* --------------------------------------------------------------------------------------------
* Construct a vector with the specified component values.
*/
Vector3(Value xv, Value yv, Value zv);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Vector3(const Vector3 & o) = default;
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Vector3(Vector3 && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Vector3() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Vector3 & operator = (const Vector3 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Vector3 & operator = (Vector3 && o) = default;
/* --------------------------------------------------------------------------------------------
* Scalar value assignment operator.
*/
Vector3 & operator = (Value s);
/* --------------------------------------------------------------------------------------------
* Four-dimensional vector assignment.
*/
Vector3 & operator = (const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Quaternion rotation assignment.
*/
Vector3 & operator = (const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Vector3 & operator += (const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Vector3 & operator -= (const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Vector3 & operator *= (const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Vector3 & operator /= (const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Vector3 & operator %= (const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Scalar value addition assignment operator.
*/
Vector3 & operator += (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction assignment operator.
*/
Vector3 & operator -= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication assignment operator.
*/
Vector3 & operator *= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value division assignment operator.
*/
Vector3 & operator /= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value modulo assignment operator.
*/
Vector3 & operator %= (Value s);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Vector3 & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Vector3 & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Vector3 operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Vector3 operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Vector3 operator + (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Vector3 operator - (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Vector3 operator * (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Vector3 operator / (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Vector3 operator % (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Scalar value addition operator.
*/
Vector3 operator + (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction operator.
*/
Vector3 operator - (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication operator.
*/
Vector3 operator * (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value division operator.
*/
Vector3 operator / (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value modulo operator.
*/
Vector3 operator % (Value s) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Vector3 operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Vector3 operator - () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Vector3 & v) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Vector3(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Vector3(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Vector3(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(static_cast< Value >(0));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value.
*/
void SetScalar(Value ns);
/* --------------------------------------------------------------------------------------------
* Copy the values from another instance of this type.
*/
void SetVector3(const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetVector3Ex(Value nx, Value ny, Value nz);
/* --------------------------------------------------------------------------------------------
* Copy the values from a four-dimensional vector.
*/
void SetVector4(const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetVector4Ex(Value nx, Value ny, Value nz, Value nw);
/* --------------------------------------------------------------------------------------------
* Copy the values from a quaternion rotation.
*/
void SetQuaternion(const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Copy the values from a quaternion rotation.
*/
void SetQuaternionEx(Value nx, Value ny, Value nz, Value nw);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & values);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value min, Value max);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
x = 0.0, y = 0.0, z = 0.0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a new instance of this type with absolute component values.
*/
Vector3 Abs() const;
/* --------------------------------------------------------------------------------------------
* Return whether is NaN.
*/
bool IsNaN() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the length.
*/
Value GetLength() const;
/* --------------------------------------------------------------------------------------------
* Assign the length.
*/
void SetLength(Value length);
/* --------------------------------------------------------------------------------------------
* Return the squared length.
*/
Value GetLengthSquared() const;
/* --------------------------------------------------------------------------------------------
* Assign the squared length.
*/
void SetLengthSquared(Value length);
/* --------------------------------------------------------------------------------------------
* Return normalized to unit length.
*/
Vector3 Normalized() const;
/* --------------------------------------------------------------------------------------------
* Normalize to unit length.
*/
void Normalize();
/* --------------------------------------------------------------------------------------------
* Calculate dot product.
*/
Value DotProduct(const Vector3 & vec) const;
/* --------------------------------------------------------------------------------------------
* Calculate absolute dot product.
*/
Value AbsDotProduct(const Vector3 & vec) const;
/* --------------------------------------------------------------------------------------------
* Calculate cross product.
*/
Vector3 CrossProduct(const Vector3 & vec) const;
/* --------------------------------------------------------------------------------------------
* Returns the angle between this vector and another vector in degrees.
*/
Value Angle(const Vector3 & vec) const;
/* --------------------------------------------------------------------------------------------
* Return the distance between this vector and another vector.
*/
Value GetDistanceTo(const Vector3 & vec) const;
/* --------------------------------------------------------------------------------------------
* Return the squared distance between this vector and another vector.
*/
Value GetSquaredDistanceTo(const Vector3 & vec) const;
/* --------------------------------------------------------------------------------------------
* Linear interpolation with another vector.
*/
bool IsBetweenPoints(const Vector3 & begin, const Vector3 & end) const;
/* --------------------------------------------------------------------------------------------
* Sets this vector to the linearly interpolated vector between a and b.
*/
void Interpolate(const Vector3 & a, const Vector3 & b, Value d);
/* --------------------------------------------------------------------------------------------
* Sets this vector to the linearly interpolated vector between a and b.
*/
Vector3 Interpolated(const Vector3 & vec, Value d) const;
/* --------------------------------------------------------------------------------------------
* Rotates the vector by a specified number of degrees around the Y axis and the specified center.
*/
Vector3 Rotated(const Vector3 & axis, Value angle) const;
/* --------------------------------------------------------------------------------------------
* Rotates the vector by a specified number of degrees around the Y axis and the specified center.
*/
void RotateXZBy(Value degrees)
{
CenterRotateXZBy(degrees, NIL);
}
/* --------------------------------------------------------------------------------------------
* Rotates the vector by a specified number of degrees around the Y axis and the specified center.
*/
void CenterRotateXZBy(Value degrees, const Vector3 & center);
/* --------------------------------------------------------------------------------------------
* Rotates the vector by a specified number of degrees around the Z axis and the specified center.
*/
void RotateXYBy(Value degrees)
{
CenterRotateXYBy(degrees, NIL);
}
/* --------------------------------------------------------------------------------------------
* Rotates the vector by a specified number of degrees around the Z axis and the specified center.
*/
void CenterRotateXYBy(Value degrees, const Vector3 & center);
/* --------------------------------------------------------------------------------------------
* Rotates the vector by a specified number of degrees around the X axis and the specified center.
*/
void RotateYZBy(Value degrees)
{
CenterRotateYZBy(degrees, NIL);
}
/* --------------------------------------------------------------------------------------------
* Rotates the vector by a specified number of degrees around the X axis and the specified center.
*/
void CenterRotateYZBy(Value degrees, const Vector3 & center);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector3 type from a string.
*/
static const Vector3 & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector3 type from a string.
*/
static const Vector3 & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_VECTOR3_HPP_

625
module/Base/Vector4.cpp Normal file
View File

@ -0,0 +1,625 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Vector4.hpp"
#include "Base/Vector3.hpp"
#include "Base/Quaternion.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
#include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------
#include <limits>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("Vector4"))
// ------------------------------------------------------------------------------------------------
const Vector4 Vector4::NIL = Vector4(0);
const Vector4 Vector4::MIN = Vector4(std::numeric_limits< Vector4::Value >::min());
const Vector4 Vector4::MAX = Vector4(std::numeric_limits< Vector4::Value >::max());
// ------------------------------------------------------------------------------------------------
SQChar Vector4::Delim = ',';
// ------------------------------------------------------------------------------------------------
Vector4::Vector4()
: x(0.0), y(0.0), z(0.0), w(0.0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector4::Vector4(Value sv)
: x(sv), y(sv), z(sv), w(sv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector4::Vector4(Value xv, Value yv, Value zv)
: x(xv), y(yv), z(zv), w(0.0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector4::Vector4(Value xv, Value yv, Value zv, Value wv)
: x(xv), y(yv), z(zv), w(wv)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator = (Value s)
{
x = s;
y = s;
z = s;
w = s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator = (const Vector3 & v)
{
x = v.x;
y = v.y;
z = v.z;
w = 0.0;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator = (const Quaternion & q)
{
x = q.x;
y = q.y;
z = q.z;
w = q.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator += (const Vector4 & v)
{
x += v.x;
y += v.y;
z += v.z;
w += v.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator -= (const Vector4 & v)
{
x -= v.x;
y -= v.y;
z -= v.z;
w -= v.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator *= (const Vector4 & v)
{
x *= v.x;
y *= v.y;
z *= v.z;
w *= v.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator /= (const Vector4 & v)
{
x /= v.x;
y /= v.y;
z /= v.z;
w /= v.w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator %= (const Vector4 & v)
{
x = std::fmod(x, v.x);
y = std::fmod(y, v.y);
z = std::fmod(z, v.z);
w = std::fmod(w, v.w);
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator += (Value s)
{
x += s;
y += s;
z += s;
w += s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator -= (Value s)
{
x -= s;
y -= s;
z -= s;
w -= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator *= (Value s)
{
x *= s;
y *= s;
z *= s;
w *= s;
return *this;
}
Vector4 & Vector4::operator /= (Value s)
{
x /= s;
y /= s;
z /= s;
w /= s;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator %= (Value s)
{
x = std::fmod(x, s);
y = std::fmod(y, s);
z = std::fmod(z, s);
w = std::fmod(w, s);
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator ++ ()
{
++x;
++y;
++z;
++w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 & Vector4::operator -- ()
{
--x;
--y;
--z;
--w;
return *this;
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator ++ (int)
{
Vector4 state(*this);
++x;
++y;
++z;
++w;
return state;
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator -- (int)
{
Vector4 state(*this);
--x;
--y;
--z;
--w;
return state;
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator + (const Vector4 & v) const
{
return Vector4(x + v.x, y + v.y, z + v.z, w + v.w);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator - (const Vector4 & v) const
{
return Vector4(x - v.x, y - v.y, z - v.z, w - v.w);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator * (const Vector4 & v) const
{
return Vector4(x * v.x, y * v.y, z * v.z, w * v.w);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator / (const Vector4 & v) const
{
return Vector4(x / v.x, y / v.y, z / v.z, w / v.w);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator % (const Vector4 & v) const
{
return Vector4(std::fmod(x, v.x), std::fmod(y, v.y), std::fmod(z, v.z), std::fmod(w, v.w));
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator + (Value s) const
{
return Vector4(x + s, y + s, z + s, w + s);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator - (Value s) const
{
return Vector4(x - s, y - s, z - s, w - s);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator * (Value s) const
{
return Vector4(x * s, y * s, z * s, w * s);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator / (Value s) const
{
return Vector4(x / s, y / s, z / s, w / s);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator % (Value s) const
{
return Vector4(std::fmod(x, s), std::fmod(y, s), std::fmod(z, s), std::fmod(w, s));
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator + () const
{
return Vector4(std::fabs(x), std::fabs(y), std::fabs(z), std::fabs(w));
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::operator - () const
{
return Vector4(-x, -y, -z, -w);
}
// ------------------------------------------------------------------------------------------------
bool Vector4::operator == (const Vector4 & v) const
{
return EpsEq(x, v.x) && EpsEq(y, v.y) && EpsEq(z, v.z) && EpsEq(w, v.w);
}
// ------------------------------------------------------------------------------------------------
bool Vector4::operator != (const Vector4 & v) const
{
return !EpsEq(x, v.x) || !EpsEq(y, v.y) || !EpsEq(z, v.z) || !EpsEq(w, v.w);
}
// ------------------------------------------------------------------------------------------------
bool Vector4::operator < (const Vector4 & v) const
{
return EpsLt(x, v.x) && EpsLt(y, v.y) && EpsLt(z, v.z) && EpsLt(w, v.w);
}
// ------------------------------------------------------------------------------------------------
bool Vector4::operator > (const Vector4 & v) const
{
return EpsGt(x, v.x) && EpsGt(y, v.y) && EpsGt(z, v.z) && EpsGt(w, v.w);
}
// ------------------------------------------------------------------------------------------------
bool Vector4::operator <= (const Vector4 & v) const
{
return EpsLtEq(x, v.x) && EpsLtEq(y, v.y) && EpsLtEq(z, v.z) && EpsLtEq(w, v.w);
}
// ------------------------------------------------------------------------------------------------
bool Vector4::operator >= (const Vector4 & v) const
{
return EpsGtEq(x, v.x) && EpsGtEq(y, v.y) && EpsGtEq(z, v.z) && EpsGtEq(w, v.w);
}
// ------------------------------------------------------------------------------------------------
Int32 Vector4::Cmp(const Vector4 & o) const
{
if (*this == o)
{
return 0;
}
else if (*this > o)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Vector4::ToString() const
{
return ToStrF("%f,%f,%f,%f", x, y, z, w);
}
// ------------------------------------------------------------------------------------------------
void Vector4::SetScalar(Value ns)
{
x = ns;
y = ns;
z = ns;
w = ns;
}
// ------------------------------------------------------------------------------------------------
void Vector4::SetVector4(const Vector4 & v)
{
x = v.x;
y = v.y;
z = v.z;
w = v.w;
}
// ------------------------------------------------------------------------------------------------
void Vector4::SetVector4Ex(Value nx, Value ny, Value nz, Value nw)
{
x = nx;
y = ny;
z = nz;
w = nw;
}
// ------------------------------------------------------------------------------------------------
void Vector4::SetVector3(const Vector3 & v)
{
x = v.x;
y = v.y;
z = v.z;
w = 0.0;
}
// ------------------------------------------------------------------------------------------------
void Vector4::SetVector3Ex(Value nx, Value ny, Value nz)
{
x = nx;
y = ny;
z = nz;
}
// ------------------------------------------------------------------------------------------------
void Vector4::SetQuaternion(const Quaternion & q)
{
x = q.x;
y = q.y;
z = q.z;
w = q.w;
}
// ------------------------------------------------------------------------------------------------
void Vector4::SetQuaternionEx(Value nx, Value ny, Value nz, Value nw)
{
x = nx;
y = ny;
z = nz;
w = nw;
}
// ------------------------------------------------------------------------------------------------
void Vector4::SetStr(SQChar delim, StackStrF & values)
{
SetVector4(Vector4::GetEx(delim, values));
}
// ------------------------------------------------------------------------------------------------
void Vector4::Generate()
{
x = GetRandomFloat32();
y = GetRandomFloat32();
z = GetRandomFloat32();
w = GetRandomFloat32();
}
// ------------------------------------------------------------------------------------------------
void Vector4::Generate(Value min, Value max)
{
if (max < min)
{
STHROWF("max value is lower than min value");
}
x = GetRandomFloat32(min, max);
y = GetRandomFloat32(min, max);
z = GetRandomFloat32(min, max);
y = GetRandomFloat32(min, max);
}
// ------------------------------------------------------------------------------------------------
void Vector4::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax)
{
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(wmax, wmin))
{
STHROWF("max value is lower than min value");
}
x = GetRandomFloat32(xmin, xmax);
y = GetRandomFloat32(ymin, ymax);
z = GetRandomFloat32(zmin, zmax);
y = GetRandomFloat32(ymin, ymax);
}
// ------------------------------------------------------------------------------------------------
Vector4 Vector4::Abs() const
{
return Vector4(std::fabs(x), std::fabs(y), std::fabs(z), std::fabs(w));
}
// ------------------------------------------------------------------------------------------------
const Vector4 & Vector4::Get(StackStrF & str)
{
return Vector4::GetEx(Vector4::Delim, str);
}
// ------------------------------------------------------------------------------------------------
const Vector4 & Vector4::GetEx(SQChar delim, StackStrF & str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %f , %f , %f , %f ");
static Vector4 vec;
// Clear previous values, if any
vec.Clear();
// Is the specified string empty?
if (str.mLen <= 0)
{
return vec; // Return the value as is!
}
// Assign the specified delimiter
fs[4] = delim;
fs[9] = delim;
fs[14] = delim;
// Attempt to extract the component values from the specified string
std::sscanf(str.mPtr, &fs[0], &vec.x, &vec.y, &vec.z, &vec.w);
// Return the resulted value
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector4 & GetVector4()
{
static Vector4 vec;
vec.Clear();
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector4 & GetVector4(Float32 sv)
{
static Vector4 vec;
vec.SetScalar(sv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector4 & GetVector4(Float32 xv, Float32 yv, Float32 zv)
{
static Vector4 vec;
vec.SetVector3Ex(xv, yv, zv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector4 & GetVector4(Float32 xv, Float32 yv, Float32 zv, Float32 wv)
{
static Vector4 vec;
vec.SetVector4Ex(xv, yv, zv, wv);
return vec;
}
// ------------------------------------------------------------------------------------------------
const Vector4 & GetVector4(const Vector4 & o)
{
static Vector4 vec;
vec.SetVector4(o);
return vec;
}
// ================================================================================================
void Register_Vector4(HSQUIRRELVM vm)
{
typedef Vector4::Value Val;
RootTable(vm).Bind(Typename::Str,
Class< Vector4 >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Val >()
.Ctor< Val, Val, Val >()
.Ctor< Val, Val, Val, Val >()
// Member Variables
.Var(_SC("x"), &Vector4::x)
.Var(_SC("y"), &Vector4::y)
.Var(_SC("z"), &Vector4::z)
.Var(_SC("w"), &Vector4::w)
.Var(_SC("X"), &Vector4::x)
.Var(_SC("Y"), &Vector4::y)
.Var(_SC("Z"), &Vector4::z)
.Var(_SC("W"), &Vector4::w)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >)
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Vector4::ToString)
// Meta-methods
.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("_mul"), &SqDynArgFwd< SqDynArgMulFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< Vector4 >, SQFloat, SQInteger, bool, std::nullptr_t, Vector4 >)
.Func< Vector4 (Vector4::*)(void) const >(_SC("_unm"), &Vector4::operator -)
// Properties
.Prop(_SC("Abs"), &Vector4::Abs)
// Member Methods
.Func(_SC("SetScalar"), &Vector4::SetScalar)
.Func(_SC("SetVector4"), &Vector4::SetVector4)
.Func(_SC("SetVector4Ex"), &Vector4::SetVector4Ex)
.Func(_SC("SetVector3"), &Vector4::SetVector3)
.Func(_SC("SetVector3Ex"), &Vector4::SetVector3Ex)
.Func(_SC("SetQuaternion"), &Vector4::SetQuaternion)
.Func(_SC("SetQuaternionEx"), &Vector4::SetQuaternionEx)
.FmtFunc(_SC("SetStr"), &Vector4::SetStr)
.Func(_SC("Clear"), &Vector4::Clear)
// Member Overloads
.Overload< void (Vector4::*)(void) >(_SC("Generate"), &Vector4::Generate)
.Overload< void (Vector4::*)(Val, Val) >(_SC("Generate"), &Vector4::Generate)
.Overload< void (Vector4::*)(Val, Val, Val, Val, Val, Val, Val, Val) >(_SC("Generate"), &Vector4::Generate)
// Static Functions
.StaticFunc(_SC("GetDelimiter"), &SqGetDelimiter< Vector4 >)
.StaticFunc(_SC("SetDelimiter"), &SqSetDelimiter< Vector4 >)
.StaticFmtFunc(_SC("FromStr"), &Vector4::Get)
.StaticFmtFunc(_SC("FromStrEx"), &Vector4::GetEx)
// Operator Exposure
.Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opAddAssign"), &Vector4::operator +=)
.Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opSubAssign"), &Vector4::operator -=)
.Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opMulAssign"), &Vector4::operator *=)
.Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opDivAssign"), &Vector4::operator /=)
.Func< Vector4 & (Vector4::*)(const Vector4 &) >(_SC("opModAssign"), &Vector4::operator %=)
.Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opAddAssignS"), &Vector4::operator +=)
.Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opSubAssignS"), &Vector4::operator -=)
.Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opMulAssignS"), &Vector4::operator *=)
.Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opDivAssignS"), &Vector4::operator /=)
.Func< Vector4 & (Vector4::*)(Vector4::Value) >(_SC("opModAssignS"), &Vector4::operator %=)
.Func< Vector4 & (Vector4::*)(void) >(_SC("opPreInc"), &Vector4::operator ++)
.Func< Vector4 & (Vector4::*)(void) >(_SC("opPreDec"), &Vector4::operator --)
.Func< Vector4 (Vector4::*)(int) >(_SC("opPostInc"), &Vector4::operator ++)
.Func< Vector4 (Vector4::*)(int) >(_SC("opPostDec"), &Vector4::operator --)
.Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opAdd"), &Vector4::operator +)
.Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opSub"), &Vector4::operator -)
.Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opMul"), &Vector4::operator *)
.Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opDiv"), &Vector4::operator /)
.Func< Vector4 (Vector4::*)(const Vector4 &) const >(_SC("opMod"), &Vector4::operator %)
.Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opAddS"), &Vector4::operator +)
.Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opSubS"), &Vector4::operator -)
.Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opMulS"), &Vector4::operator *)
.Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opDivS"), &Vector4::operator /)
.Func< Vector4 (Vector4::*)(Vector4::Value) const >(_SC("opModS"), &Vector4::operator %)
.Func< Vector4 (Vector4::*)(void) const >(_SC("opUnPlus"), &Vector4::operator +)
.Func< Vector4 (Vector4::*)(void) const >(_SC("opUnMinus"), &Vector4::operator -)
.Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opEqual"), &Vector4::operator ==)
.Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opNotEqual"), &Vector4::operator !=)
.Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opLessThan"), &Vector4::operator <)
.Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opGreaterThan"), &Vector4::operator >)
.Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opLessEqual"), &Vector4::operator <=)
.Func< bool (Vector4::*)(const Vector4 &) const >(_SC("opGreaterEqual"), &Vector4::operator >=)
);
}
} // Namespace:: SqMod

381
module/Base/Vector4.hpp Normal file
View File

@ -0,0 +1,381 @@
#ifndef _BASE_VECTOR4_HPP_
#define _BASE_VECTOR4_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class used to represent a four-dimensional vector.
*/
struct Vector4
{
/* --------------------------------------------------------------------------------------------
* The type of value used by components of type.
*/
typedef float Value;
/* --------------------------------------------------------------------------------------------
* Helper instances for common values mostly used as return types or comparison.
*/
static const Vector4 NIL;
static const Vector4 MIN;
static const Vector4 MAX;
/* --------------------------------------------------------------------------------------------
* The delimiter character to be used when extracting values from strings.
*/
static SQChar Delim;
/* --------------------------------------------------------------------------------------------
* The x, y, z and w components of this type.
*/
Value x, y, z, w;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Vector4();
/* --------------------------------------------------------------------------------------------
* Construct a vector with the same scalar value for all components.
*/
explicit Vector4(Value sv);
/* --------------------------------------------------------------------------------------------
* Construct a vector with the specified component values.
*/
Vector4(Value xv, Value yv, Value zv);
/* --------------------------------------------------------------------------------------------
* Construct a vector with the specified component values.
*/
Vector4(Value xv, Value yv, Value zv, Value wv);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Vector4(const Vector4 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Vector4(Vector4 && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Vector4() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Vector4 & operator = (const Vector4 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Vector4 & operator = (Vector4 && o) = default;
/* --------------------------------------------------------------------------------------------
* Scalar value assignment operator.
*/
Vector4 & operator = (Value s);
/* --------------------------------------------------------------------------------------------
* Three-dimensional vector assignment operator.
*/
Vector4 & operator = (const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Quaternion rotation assignment operator.
*/
Vector4 & operator = (const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Addition assignment operator.
*/
Vector4 & operator += (const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Subtraction assignment operator.
*/
Vector4 & operator -= (const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Multiplication assignment operator.
*/
Vector4 & operator *= (const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Division assignment operator.
*/
Vector4 & operator /= (const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Modulo assignment operator.
*/
Vector4 & operator %= (const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Scalar value addition assignment operator.
*/
Vector4 & operator += (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction assignment operator.
*/
Vector4 & operator -= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication assignment operator.
*/
Vector4 & operator *= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value division assignment operator.
*/
Vector4 & operator /= (Value s);
/* --------------------------------------------------------------------------------------------
* Scalar value modulo assignment operator.
*/
Vector4 & operator %= (Value s);
/* --------------------------------------------------------------------------------------------
* Pre-increment operator.
*/
Vector4 & operator ++ ();
/* --------------------------------------------------------------------------------------------
* Pre-decrement operator.
*/
Vector4 & operator -- ();
/* --------------------------------------------------------------------------------------------
* Post-increment operator.
*/
Vector4 operator ++ (int);
/* --------------------------------------------------------------------------------------------
* Post-decrement operator.
*/
Vector4 operator -- (int);
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Vector4 operator + (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Vector4 operator - (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Vector4 operator * (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Vector4 operator / (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Modulo operator.
*/
Vector4 operator % (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Scalar value addition operator.
*/
Vector4 operator + (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value subtraction operator.
*/
Vector4 operator - (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value multiplication operator.
*/
Vector4 operator * (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value division operator.
*/
Vector4 operator / (Value s) const;
/* --------------------------------------------------------------------------------------------
* Scalar value modulo operator.
*/
Vector4 operator % (Value s) const;
/* --------------------------------------------------------------------------------------------
* Unary plus operator.
*/
Vector4 operator + () const;
/* --------------------------------------------------------------------------------------------
* Unary minus operator.
*/
Vector4 operator - () const;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Vector4 & v) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQFloat s) const
{
return Cmp(Vector4(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(SQInteger s) const
{
return Cmp(Vector4(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(bool s) const
{
return Cmp(Vector4(static_cast< Value >(s)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare an instance of this type with a scalar value.
*/
Int32 Cmp(std::nullptr_t) const
{
return Cmp(Vector4(static_cast< Value >(0)));
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Set all components to the specified scalar value.
*/
void SetScalar(Value ns);
/* --------------------------------------------------------------------------------------------
* Copy the values from another instance of this type.
*/
void SetVector4(const Vector4 & v);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetVector4Ex(Value nx, Value ny, Value nz, Value nw);
/* --------------------------------------------------------------------------------------------
* Copy the values from a three-dimensional vector.
*/
void SetVector3(const Vector3 & v);
/* --------------------------------------------------------------------------------------------
* Set all components to the specified values.
*/
void SetVector3Ex(Value nx, Value ny, Value nz);
/* --------------------------------------------------------------------------------------------
* Copy the values from a quaternion rotation.
*/
void SetQuaternion(const Quaternion & q);
/* --------------------------------------------------------------------------------------------
* Copy the values from a quaternion rotation.
*/
void SetQuaternionEx(Value nx, Value ny, Value nz, Value nw);
/* --------------------------------------------------------------------------------------------
* Set the values extracted from the specified string using the specified delimiter.
*/
void SetStr(SQChar delim, StackStrF & values);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance.
*/
void Generate();
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value min, Value max);
/* --------------------------------------------------------------------------------------------
* Generate random values for all components of this instance within the specified bounds.
*/
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax);
/* --------------------------------------------------------------------------------------------
* Clear the component values to default.
*/
void Clear()
{
x = 0.0, y = 0.0, z = 0.0, w = 0.0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve a new instance of this type with absolute component values.
*/
Vector4 Abs() const;
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector4 type from a string.
*/
static const Vector4 & Get(StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector4 type from a string.
*/
static const Vector4 & GetEx(SQChar delim, StackStrF & str);
};
} // Namespace:: SqMod
#endif // _BASE_VECTOR4_HPP_

104
module/CMakeLists.txt Normal file
View File

@ -0,0 +1,104 @@
# Include third-party libraries
add_subdirectory(Vendor)
# Create the Squirrel module
add_library(SqModule MODULE
SqBase.hpp
Main.cpp
Register.cpp
Core.cpp Core.hpp
Logger.cpp Logger.hpp
Base/DynArg.hpp
Base/AABB.cpp Base/AABB.hpp
Base/Buffer.cpp Base/Buffer.hpp
Base/Circle.cpp Base/Circle.hpp
Base/Color3.cpp Base/Color3.hpp
Base/Color4.cpp Base/Color4.hpp
Base/Quaternion.cpp Base/Quaternion.hpp
Base/ScriptSrc.cpp Base/ScriptSrc.hpp
Base/Shared.cpp Base/Shared.hpp
Base/Sphere.cpp Base/Sphere.hpp
Base/Utility.cpp Base/Utility.hpp
Base/Vector2.cpp Base/Vector2.hpp
Base/Vector2i.cpp Base/Vector2i.hpp
Base/Vector3.cpp Base/Vector3.hpp
Base/Vector4.cpp Base/Vector4.hpp
Entity/Blip.cpp Entity/Blip.hpp
Entity/Checkpoint.cpp Entity/Checkpoint.hpp
Entity/Keybind.cpp Entity/Keybind.hpp
Entity/Object.cpp Entity/Object.hpp
Entity/Pickup.cpp Entity/Pickup.hpp
Entity/Player.cpp Entity/Player.hpp
Entity/Vehicle.cpp Entity/Vehicle.hpp
Library/Chrono.cpp Library/Chrono.hpp
Library/Chrono/Date.cpp Library/Chrono/Date.hpp
Library/Chrono/Datetime.cpp Library/Chrono/Datetime.hpp
Library/Chrono/Time.cpp Library/Chrono/Time.hpp
Library/Chrono/Timer.cpp Library/Chrono/Timer.hpp
Library/Chrono/Timestamp.cpp Library/Chrono/Timestamp.hpp
Library/Crypt.cpp Library/Crypt.hpp
Library/Crypt/AES.cpp Library/Crypt/AES.hpp
Library/Crypt/Hash.cpp Library/Crypt/Hash.hpp
Library/IO.cpp Library/IO.hpp
Library/IO/File.cpp Library/IO/File.hpp
Library/IO/INI.cpp Library/IO/INI.hpp
Library/Numeric.cpp Library/Numeric.hpp
Library/Numeric/LongInt.cpp Library/Numeric/LongInt.hpp
Library/Numeric/Math.cpp Library/Numeric/Math.hpp
Library/Numeric/Random.cpp Library/Numeric/Random.hpp
Library/String.cpp Library/String.hpp
Library/System.cpp Library/System.hpp
Library/System/Dir.cpp Library/System/Dir.hpp
Library/System/Environment.cpp Library/System/Environment.hpp
Library/System/Path.cpp Library/System/Path.hpp
Library/Utils.cpp Library/Utils.hpp
Library/Utils/Buffer.cpp Library/Utils/Buffer.hpp
Misc/Broadcast.cpp
Misc/Constants.cpp
Misc/Exports.cpp
Misc/Register.cpp
Misc/Algo.cpp Misc/Algo.hpp
Misc/Areas.cpp Misc/Areas.hpp
Misc/Command.cpp Misc/Command.hpp
Misc/Functions.cpp Misc/Functions.hpp
Misc/Model.cpp Misc/Model.hpp
Misc/Player.cpp Misc/Player.hpp
Misc/Routine.cpp Misc/Routine.hpp
Misc/Signal.cpp Misc/Signal.hpp
Misc/Tasks.cpp Misc/Tasks.hpp
Misc/Vehicle.cpp Misc/Vehicle.hpp
Misc/Weapon.cpp Misc/Weapon.hpp
)
# Link to base libraries
target_link_libraries(SqModule VCMP Squirrel Sqrat SqSDK)
# Link to third-party libraries
target_link_libraries(SqModule SimpleINI HashLib B64Lib AES256Lib WhirlpoolLib TinyDir)
#
if(FORCE_32BIT_BIN)
set_target_properties(SqModule PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
target_compile_definitions(SqModule PRIVATE _SQ64)
endif()
set_target_properties(SqModule PROPERTIES PREFIX "")
if(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT FORCE_32BIT_BIN)
set_target_properties(SqModule PROPERTIES OUTPUT_NAME "mod_squirrel_64")
else()
set_target_properties(SqModule PROPERTIES OUTPUT_NAME "mod_squirrel_32")
endif()
else(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT FORCE_32BIT_BIN)
set_target_properties(SqModule PROPERTIES OUTPUT_NAME "mod_squirrel_64")
else()
set_target_properties(SqModule PROPERTIES OUTPUT_NAME "mod_squirrel_32")
endif()
endif(WIN32)
target_include_directories(SqModule PRIVATE ${CMAKE_CURRENT_LIST_DIR})
if(WIN32)
target_link_libraries(SqModule wsock32 ws2_32)
endif()

949
module/Core.cpp Normal file
View File

@ -0,0 +1,949 @@
// ------------------------------------------------------------------------------------------------
#include "Core.hpp"
#include "Logger.hpp"
#include "Misc/Signal.hpp"
#include "Misc/Areas.hpp"
#include "Misc/Signal.hpp"
#include "Base/Buffer.hpp"
#include "Library/Utils/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
#include "Entity/Blip.hpp"
#include "Entity/Checkpoint.hpp"
#include "Entity/Keybind.hpp"
#include "Entity/Object.hpp"
#include "Entity/Pickup.hpp"
#include "Entity/Player.hpp"
#include "Entity/Vehicle.hpp"
// ------------------------------------------------------------------------------------------------
#include <SqMod.h>
#include <sqstdio.h>
#include <sqstdblob.h>
#include <sqstdmath.h>
#include <sqstdsystem.h>
#include <sqstdstring.h>
#include <SimpleIni.h>
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdarg>
#include <exception>
#include <stdexcept>
#include <algorithm>
// ------------------------------------------------------------------------------------------------
#ifdef GetObject
#undef GetObject
#endif // ef you MS
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern bool RegisterAPI(HSQUIRRELVM vm);
// ------------------------------------------------------------------------------------------------
extern void InitializeTasks();
extern void InitializeRoutines();
extern void TerminateAreas();
extern void TerminateTasks();
extern void TerminateRoutines();
extern void TerminateCommands();
extern void TerminateSignals();
// ------------------------------------------------------------------------------------------------
extern Buffer GetRealFilePath(CSStr path);
/* ------------------------------------------------------------------------------------------------
* Loader used to process a section from the configuration file and look for scripts to load.
*/
class ScriptLoader
{
// --------------------------------------------------------------------------------------------
CSimpleIniA & m_Config; // The processed configuration.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ScriptLoader(CSimpleIniA & conf)
: m_Config(conf)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Function call operator.
*/
bool operator () (CCStr key, CCStr val) const
{
// Validate the specified key
if (!key || *key == '\0')
{
return true; // Move to the next element!
}
// Identify the load option
if (std::strcmp(key, "Section") == 0)
{
return m_Config.ProcAllValues(val, ScriptLoader(m_Config));
}
else if (std::strcmp(key, "Compile") == 0)
{
return Core::Get().LoadScript(val, true);
}
else if (std::strcmp(key, "Execute") == 0)
{
return Core::Get().LoadScript(val, false);
}
// Move to the next element!
return true;
}
};
/* ------------------------------------------------------------------------------------------------
* Implements RAII to make sure that entity containers area cleaned up at all costs.
*/
class ContainerCleaner
{
// --------------------------------------------------------------------------------------------
EntityType m_Type; // The type of entity container to clear.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
template < typename T > ContainerCleaner(T & container, EntityType type, bool destroy)
: m_Type(type)
{
for (auto & ent : container)
{
ent.Destroy(destroy, SQMOD_DESTROY_CLEANUP, NullLightObj());
}
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~ContainerCleaner()
{
Core::Get().ClearContainer(m_Type);
}
};
// ------------------------------------------------------------------------------------------------
Core Core::s_Inst;
// ------------------------------------------------------------------------------------------------
Core::Core()
: m_State(0)
, m_VM(nullptr)
, m_Scripts()
, m_PendingScripts()
, m_Options()
, m_Blips()
, m_Checkpoints()
, m_Keybinds()
, m_Objects()
, m_Pickups()
, m_Players()
, m_Vehicles()
, m_Events()
, m_CircularLocks(0)
, m_ReloadHeader(0)
, m_ReloadPayload()
, m_IncomingNameBuffer(nullptr)
, m_IncomingNameCapacity(0)
, m_AreasEnabled(false)
, m_Debugging(false)
, m_Executed(false)
, m_Shutdown(false)
, m_LockPreLoadSignal(false)
, m_LockPostLoadSignal(false)
, m_LockUnloadSignal(false)
, m_EmptyInit(false)
, m_Verbosity(1)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Core::~Core()
{
if (m_VM)
{
Terminate(true);
}
}
// ------------------------------------------------------------------------------------------------
bool Core::Initialize()
{
// Make sure the plug-in was not already initialized
if (m_VM != nullptr)
{
OutputError("Plug-in was already initialized");
return true;
}
CSimpleIniA conf(false, true, true);
// Attempt to load the configurations from disk
SI_Error ini_ret = conf.LoadFile("sqmod.ini");
// See if the configurations could be loaded
if (ini_ret < 0)
{
switch (ini_ret)
{
case SI_FAIL:
{
OutputError("Failed to load the configuration file. Probably invalid");
} break;
case SI_NOMEM:
{
OutputError("Run out of memory while loading the configuration file");
} break;
case SI_FILE:
{
OutputError("Failed to load the configuration file. %s", std::strerror(errno));
} break;
default: OutputError("Failed to load the configuration file for some unforeseen reason");
}
// Failed to load the configuration file
return false;
}
// See if debugging options should be enabled
m_Debugging = conf.GetBoolValue("Squirrel", "Debugging", m_Debugging);
// Configure the empty initialization
m_EmptyInit = conf.GetBoolValue("Squirrel", "EmptyInit", false);
// Configure the verbosity level
m_Verbosity = conf.GetLongValue("Log", "VerbosityLevel", 1);
// Initialize the log filename
Logger::Get().SetLogFilename(conf.GetValue("Log", "Filename", nullptr));
// Configure the logging timestamps
Logger::Get().ToggleConsoleTime(conf.GetBoolValue("Log", "ConsoleTimestamp", false));
Logger::Get().ToggleLogFileTime(conf.GetBoolValue("Log", "LogFileTimestamp", true));
// Apply the specified logging filters only after initialization was completed
Logger::Get().ToggleConsoleLevel(LOGL_DBG, conf.GetBoolValue("Log", "ConsoleDebug", true));
Logger::Get().ToggleConsoleLevel(LOGL_USR, conf.GetBoolValue("Log", "ConsoleUser", true));
Logger::Get().ToggleConsoleLevel(LOGL_SCS, conf.GetBoolValue("Log", "ConsoleSuccess", true));
Logger::Get().ToggleConsoleLevel(LOGL_INF, conf.GetBoolValue("Log", "ConsoleInfo", true));
Logger::Get().ToggleConsoleLevel(LOGL_WRN, conf.GetBoolValue("Log", "ConsoleWarning", true));
Logger::Get().ToggleConsoleLevel(LOGL_ERR, conf.GetBoolValue("Log", "ConsoleError", true));
Logger::Get().ToggleConsoleLevel(LOGL_FTL, conf.GetBoolValue("Log", "ConsoleFatal", true));
Logger::Get().ToggleLogFileLevel(LOGL_DBG, conf.GetBoolValue("Log", "LogFileDebug", true));
Logger::Get().ToggleLogFileLevel(LOGL_USR, conf.GetBoolValue("Log", "LogFileUser", true));
Logger::Get().ToggleLogFileLevel(LOGL_SCS, conf.GetBoolValue("Log", "LogFileSuccess", true));
Logger::Get().ToggleLogFileLevel(LOGL_INF, conf.GetBoolValue("Log", "LogFileInfo", true));
Logger::Get().ToggleLogFileLevel(LOGL_WRN, conf.GetBoolValue("Log", "LogFileWarning", true));
Logger::Get().ToggleLogFileLevel(LOGL_ERR, conf.GetBoolValue("Log", "LogFileError", true));
Logger::Get().ToggleLogFileLevel(LOGL_FTL, conf.GetBoolValue("Log", "LogFileFatal", true));
cLogDbg(m_Verbosity >= 1, "Resizing the entity containers");
// Make sure the entity containers have the proper size
m_Blips.resize(SQMOD_BLIP_POOL);
m_Checkpoints.resize(SQMOD_CHECKPOINT_POOL);
m_Keybinds.resize(SQMOD_KEYBIND_POOL);
m_Objects.resize(SQMOD_OBJECT_POOL);
m_Pickups.resize(SQMOD_PICKUP_POOL);
m_Players.resize(SQMOD_PLAYER_POOL);
m_Vehicles.resize(SQMOD_VEHICLE_POOL);
// Attempt to read the virtual machine stack size
const LongI stack_size = conf.GetLongValue("Squirrel", "StackSize", SQMOD_STACK_SIZE);
// Make sure that the retrieved number is within range
if (!stack_size)
{
LogWrn("Invalid virtual machine stack size: %lu", stack_size);
// Stop the initialization process
return false;
}
cLogDbg(m_Verbosity >= 1, "Creating a virtual machine (%ld stack size)", stack_size);
// Attempt to create the script virtual machine
m_VM = sq_open(ConvTo< SQInteger >::From(stack_size));
// See if the virtual machine could be created
if (cLogFtl(!m_VM, "Unable to create the virtual machine"))
{
return false; // Unable to load the plug-in properly!
}
// Set this as the default VM
DefaultVM::Set(m_VM);
// Configure error handling
ErrorHandling::Enable(conf.GetBoolValue("Squirrel", "ErrorHandling", true));
// Prevent common null objects from using dead virtual machines
NullArray() = Array();
NullTable() = Table();
NullObject() = Object();
NullLightObj() = LightObj();
NullFunction() = Function();
cLogDbg(m_Verbosity >= 1, "Registering the standard libraries");
// Push the root table on the stack
sq_pushroottable(m_VM);
// Register the standard library on the pushed table
sqstd_register_iolib(m_VM);
sqstd_register_bloblib(m_VM);
sqstd_register_mathlib(m_VM);
sqstd_register_systemlib(m_VM);
sqstd_register_stringlib(m_VM);
// Pop the root table from the stack
sq_pop(m_VM, 1);
cLogDbg(m_Verbosity >= 1, "Setting the script output function");
// Tell the VM to use these functions to output user on error messages
sq_setprintfunc(m_VM, PrintFunc, ErrorFunc);
cLogDbg(m_Verbosity >= 1, "Setting the script error handlers");
// Tell the VM to trigger this function on compile time errors
sq_setcompilererrorhandler(m_VM, CompilerErrorHandler);
// Push the runtime error handler on the stack and create a closure
sq_newclosure(m_VM, RuntimeErrorHandler, 0);
// Tell the VM to trigger this function on runtime errors
sq_seterrorhandler(m_VM);
cLogDbg(m_Verbosity >= 1, "Registering the plug-in API");
// Attempt to register the plug-in API
if (cLogFtl(!RegisterAPI(m_VM), "Unable to register the plug-in API"))
{
return false; // Can't execute scripts without a valid API!
}
// Initialize the module global events
InitEvents();
// Initialize load stage signals
InitSignalPair(mOnPreLoad, NullLightObj(), nullptr);
InitSignalPair(mOnPostLoad, NullLightObj(), nullptr);
InitSignalPair(mOnUnload, NullLightObj(), nullptr);
CSimpleIniA::TNamesDepend scripts;
// Attempt to retrieve the list of keys to make sure there's actually something to process
if (conf.GetAllKeys("Scripts", scripts) && scripts.size() > 0)
{
// Attempt to load the specified scripts
if (!conf.ProcAllValues("Scripts", ScriptLoader(conf)))
{
LogErr("Unable to load the specified scripts");
// Either no script was found or failed to load
return false;
}
}
// See if any script could be queued for loading
if (m_PendingScripts.empty() && !m_EmptyInit)
{
LogErr("No scripts loaded. No reason to load the plug-in");
// No point in loading the plug-in
return false;
}
cLogDbg(m_Verbosity >= 1, "Reading the options from the general section");
// Read options only after loading was successful
CSimpleIniA::TNamesDepend options;
// Are there any options to read?
if (conf.GetAllKeys("Options", options) || options.size() > 0)
{
cLogDbg(m_Verbosity >= 1, "Found (%" PRINT_SZ_FMT ") options in the configuration file",
static_cast< SQUnsignedInteger >(options.size()));
// Process all the specified keys under the [Options] section
for (const auto & option : options)
{
CSimpleIniA::TNamesDepend values;
// Get the values of all keys with the same name
if (!conf.GetAllValues("Options", option.pItem, values))
{
continue;
}
// Sort the keys in their original order
values.sort(CSimpleIniA::Entry::LoadOrder());
// Save each option option and overwrite existing value
for (const auto & value : values)
{
m_Options[option.pItem] = value.pItem;
}
}
}
// Initialize routines and tasks
InitializeRoutines();
InitializeTasks();
// Initialization successful
return true;
}
// ------------------------------------------------------------------------------------------------
bool Core::Execute()
{
// Are there any scripts to execute?
if (m_PendingScripts.empty())
{
// Are we allowed to continue without any scripts?
if (m_EmptyInit)
{
LogWrn("No scripts to execute. Empty initialization was forced");
// Allow empty initialization since it was requested
return true;
}
LogWrn("No scripts to execute. Plug-in has no purpose");
// No reason to execute the plug-in
return false;
}
// Unlock signal containers
m_LockPreLoadSignal = false;
m_LockPostLoadSignal = false;
m_LockUnloadSignal = false;
cLogDbg(m_Verbosity >= 1, "Signaling outside plug-ins to register their API");
// Tell modules to do their monkey business
_Func->SendPluginCommand(SQMOD_LOAD_CMD, "");
// Load pending scripts while we're in the bounds of the allowed recursiveness
for (unsigned levels = 0; (m_PendingScripts.empty() == false) && (levels < 8); ++levels)
{
// Remember the last script from the pool
const Scripts::size_type last = m_Scripts.size();
// Push pending scripts to the back of the list
std::move(m_PendingScripts.begin(), m_PendingScripts.end(), std::back_inserter(m_Scripts));
// Clear all pending scripts, if any
m_PendingScripts.clear();
// Process all pending scripts
if (DoScripts(m_Scripts.begin() + last, m_Scripts.end()) == false)
{
return false; // One of the scripts failed to execute
}
cLogDbg(m_Verbosity >= 2, "Completed execution of stage (%u) scripts. Pending scripts %" PRINT_SZ_FMT,
levels, static_cast< SQUnsignedInteger >(m_PendingScripts.size()));
}
// Force enable null entities if not already enabled by script
EnableNullEntities();
m_LockPreLoadSignal = true;
// Trigger callbacks that must initialize stuff before the loaded event is triggered
(*mOnPreLoad.first)();
// Clear the callbacks
ResetSignalPair(mOnPreLoad);
// Notify the script callback that the scripts were loaded
EmitScriptLoaded();
m_LockPostLoadSignal = true;
// Trigger callbacks that must initialize stuff after the loaded event is triggered
(*mOnPostLoad.first)();
// Clear the callbacks
ResetSignalPair(mOnPostLoad);
// Import already existing entities
ImportPlayers();
ImportBlips();
ImportCheckpoints();
ImportKeybinds();
ImportObjects();
ImportPickups();
ImportVehicles();
// Successfully executed
return (m_Executed = true);
}
// ------------------------------------------------------------------------------------------------
void Core::Terminate(bool shutdown)
{
m_Shutdown = shutdown;
// Is there a virtual machine present?
if (m_VM)
{
m_LockUnloadSignal = true;
// Trigger callbacks that must de-initialize stuff before the scripts are unloaded
(*mOnUnload.first)();
// Clear the callbacks
ResetSignalPair(mOnUnload);
cLogDbg(m_Verbosity >= 1, "Signaling outside plug-ins to release their resources");
// Tell modules to do their monkey business
_Func->SendPluginCommand(SQMOD_TERMINATE_CMD, "");
}
cLogDbg(m_Verbosity >= 1, "Clearing the entity containers");
// Release all entity resources by clearing the containers
const ContainerCleaner cc_players(m_Players, ENT_PLAYER, !shutdown);
const ContainerCleaner cc_vehicles(m_Vehicles, ENT_VEHICLE, !shutdown);
const ContainerCleaner cc_objects(m_Objects, ENT_OBJECT, !shutdown);
const ContainerCleaner cc_pickups(m_Pickups, ENT_PICKUP, !shutdown);
const ContainerCleaner cc_checkpoints(m_Checkpoints, ENT_CHECKPOINT, !shutdown);
const ContainerCleaner cc_blips(m_Blips, ENT_BLIP, !shutdown);
const ContainerCleaner cc_keybinds(m_Keybinds, ENT_KEYBIND, !shutdown);
cLogDbg(m_Verbosity >= 1, "Terminating routines an commands");
// Release all resources from routines and tasks
TerminateRoutines();
TerminateTasks();
// Release all resources from command managers
TerminateCommands();
// Release all resources from signals
TerminateSignals();
// Release all managed areas
TerminateAreas();
// In case there's a payload for reload
m_ReloadPayload.Release();
// Release null objects in case any reference to valid objects is stored in them
NullArray().Release();
NullTable().Release();
NullObject().Release();
NullLightObj().Release();
NullFunction().ReleaseGently();
// Release null entity instances
m_NullBlip.Release();
m_NullCheckpoint.Release();
m_NullKeybind.Release();
m_NullObject.Release();
m_NullPickup.Release();
m_NullPlayer.Release();
m_NullVehicle.Release();
// Is there a VM to close?
if (m_VM)
{
cLogDbg(m_Verbosity >= 1, "Releasing any final resources and all loaded scripts");
// Release all script callbacks
DropEvents();
// Release the script instances
m_Scripts.clear();
m_PendingScripts.clear(); // Just in case
// Specify that no scripts are left executed
m_Executed = false;
// Assertions during close may cause double delete/close!
HSQUIRRELVM sq_vm = m_VM;
m_VM = nullptr;
cLogDbg(m_Verbosity >= 1, "Signaling outside plug-ins the virtual machine is closing");
// Tell modules to do their monkey business
_Func->SendPluginCommand(SQMOD_CLOSING_CMD, "");
// Release any callbacks from the logger
Logger::Get().Release();
// Attempt to close the VM
sq_close(sq_vm);
cLogDbg(m_Verbosity >= 1, "Signaling outside plug-ins to release the virtual machine");
// Tell modules to do their monkey business
_Func->SendPluginCommand(SQMOD_RELEASED_CMD, "");
}
OutputMessage("Squirrel plug-in was successfully terminated");
}
// ------------------------------------------------------------------------------------------------
bool Core::Reload()
{
// Are we already reloading?
if (m_CircularLocks & CCL_RELOAD_SCRIPTS)
{
return false; // Already reloading!
}
// Prevent circular reloads when we send plug-in commands
const BitGuardU32 bg(m_CircularLocks, static_cast< Uint32 >(CCL_RELOAD_SCRIPTS));
// Allow reloading by default
Core::Get().SetState(1);
// Emit the reload event
Core::Get().EmitScriptReload(m_ReloadHeader, m_ReloadPayload);
// Are we allowed to reload?
if (!Core::Get().GetState())
{
return false; // Request denied!
}
// Terminate the current VM and release resources
Terminate(false);
// Reset the reload header after termination
m_ReloadHeader = -1;
// Attempt to initialize the central core and load resources
return (Initialize() && Execute());
}
// ------------------------------------------------------------------------------------------------
void Core::EnableNullEntities()
{
// Create the null entity instances
if (m_NullBlip.IsNull()) m_NullBlip = LightObj(new CBlip(-1));
if (m_NullCheckpoint.IsNull()) m_NullBlip = LightObj(new CCheckpoint(-1));
if (m_NullKeybind.IsNull()) m_NullBlip = LightObj(new CKeybind(-1));
if (m_NullObject.IsNull()) m_NullBlip = LightObj(new CObject(-1));
if (m_NullPickup.IsNull()) m_NullBlip = LightObj(new CPickup(-1));
if (m_NullPlayer.IsNull()) m_NullBlip = LightObj(new CPlayer(-1));
if (m_NullVehicle.IsNull()) m_NullBlip = LightObj(new CVehicle(-1));
}
// ------------------------------------------------------------------------------------------------
CSStr Core::GetOption(CSStr name) const
{
Options::const_iterator elem = m_Options.find(name);
return (elem == m_Options.end()) ? _SC("") : elem->second.c_str();
}
// ------------------------------------------------------------------------------------------------
CSStr Core::GetOption(CSStr name, CSStr value) const
{
Options::const_iterator elem = m_Options.find(name);
return (elem == m_Options.end()) ? value : elem->second.c_str();
}
// ------------------------------------------------------------------------------------------------
void Core::SetOption(CSStr name, CSStr value)
{
m_Options[name] = value;
}
// ------------------------------------------------------------------------------------------------
Core::Scripts::iterator Core::FindScript(const CSStr src)
{
// Iterate over loaded scripts
for (Scripts::iterator itr = m_Scripts.begin(); itr != m_Scripts.end(); ++itr)
{
// Is this script the source we're looking for?
if (itr->mPath.compare(0, String::npos, src) == 0)
{
return itr;
}
}
// Not found!
return m_Scripts.end();
}
// ------------------------------------------------------------------------------------------------
Core::Scripts::iterator Core::FindPendingScript(const CSStr src)
{
// Iterate over loaded scripts
for (Scripts::iterator itr = m_PendingScripts.begin(); itr != m_PendingScripts.end(); ++itr)
{
// Is this script the source we're looking for?
if (itr->mPath.compare(0, String::npos, src) == 0)
{
return itr;
}
}
// Not found!
return m_PendingScripts.end();
}
// ------------------------------------------------------------------------------------------------
bool Core::LoadScript(CSStr filepath, bool delay)
{
// Is the specified path empty?
if (!filepath || *filepath == '\0')
{
LogErr("Cannot load script with empty or invalid path");
// Failed to load
return false;
}
Buffer bpath;
// Attempt to get the real file path
try
{
bpath = GetRealFilePath(filepath);
}
catch (const Sqrat::Exception & e)
{
LogErr("Unable to load script: %s", e.what());
// Failed to load
return false;
}
catch (const std::exception & e)
{
LogErr("Unable to load script: %s", e.what());
// Failed to load
return false;
}
// Make the path into a string
String path(bpath.Data(), bpath.Position());
// See if it wasn't already loaded
if (std::find_if(m_Scripts.cbegin(), m_Scripts.cend(), [&path](Scripts::const_reference s) {
return (s.mPath == path);
}) != m_Scripts.end())
{
LogWrn("Script was specified before: %s", path.c_str());
}
// Also check the pending scripts container
else if (std::find_if(m_PendingScripts.cbegin(), m_PendingScripts.cend(), [&path](Scripts::const_reference s) {
return (s.mPath == path);
}) != m_PendingScripts.end())
{
LogWrn("Script was specified before: %s", path.c_str());
}
// Were the scripts already executed? Then there's no need to queue them
else if (m_Executed)
{
// Create a new script container and insert it into the script pool
m_Scripts.emplace_back(m_VM, std::move(path), delay, m_Debugging);
// Attempt to load and compile the script file
try
{
m_Scripts.back().mExec.CompileFile(m_Scripts.back().mPath);
}
catch (const Sqrat::Exception & e)
{
LogFtl("Unable to compile: %s", m_Scripts.back().mPath.c_str());
// Remove the script container since it's invalid
m_Scripts.pop_back();
// Failed to compile properly
return false;
}
// At this point the script should be completely loaded
cLogDbg(m_Verbosity >= 3, "Compiled script: %s", m_Scripts.back().mPath.c_str());
// Attempt to execute the compiled script code
try
{
m_Scripts.back().mExec.Run();
}
catch (const Sqrat::Exception & e)
{
LogFtl("Unable to execute: %s", m_Scripts.back().mPath.c_str());
// Remove the script container since it's invalid
m_Scripts.pop_back();
// Failed to execute properly
return false;
}
// At this point the script should be completely loaded
cLogScs(m_Verbosity >= 2, "Executed script: %s", m_Scripts.back().mPath.c_str());
}
// We don't compile the scripts yet. We just store their path and prepare the objects
else
{
cLogDbg(m_Verbosity >= 2, "Pending %s script: %s", (delay ? "deferred" : "immediate"), path.c_str());
// Create a new script container and insert it into the pending script pool
m_PendingScripts.emplace_back(m_VM, std::move(path), delay, m_Debugging);
}
// At this point the script exists in one of the pools
return true;
}
// ------------------------------------------------------------------------------------------------
void Core::SetIncomingName(CSStr name)
{
// Is there an incoming connection buffer that we can write to?
if (!m_IncomingNameBuffer)
{
STHROWF("No incoming player name buffer available");
}
// Is the specified name valid?
else if (!name || *name == '\0')
{
STHROWF("Invalid player name for incoming connection");
}
// Calculate the length of the specified name
const size_t len = std::strlen(name);
// Is the length of the name out of bounds?
if (len > m_IncomingNameCapacity)
{
STHROWF("The specified name exceeds the designated buffer");
}
// Does the name satisfy the minimum length required?
else if (len < 2)
{
STHROWF("The specified name needs to be at least 2 characters: %zu", len);
}
// Copy the specified name to the assigned buffer
std::strncpy(m_IncomingNameBuffer, name, m_IncomingNameCapacity);
// Make sure that the name inside the buffer is null terminated
m_IncomingNameBuffer[len] = '\0';
}
// ------------------------------------------------------------------------------------------------
String Core::FetchCodeLine(CSStr src, SQInteger line, bool trim)
{
// Find the script we're looking for
Scripts::iterator script = FindScript(src);
// Do we have a valid script and line?
if ((script == m_Scripts.end()) || !(script->mInfo) || (static_cast< SQInteger >(script->mLine.size()) < line))
{
return String{}; // No such script!
}
// Fetch the line of code
return script->FetchLine(line, trim);
}
// ------------------------------------------------------------------------------------------------
bool Core::DoScripts(Scripts::iterator itr, Scripts::iterator end)
{
Scripts::iterator itr_state = itr;
cLogDbg(Get().m_Verbosity >= 1, "Attempting to compile the specified scripts");
// Compile scripts first so that the constants can take effect
for (; itr != end; ++itr)
{
// Is this script already compiled?
if (!(*itr).mExec.IsNull())
{
continue; // Already compiled!
}
// Attempt to load and compile the script file
try
{
(*itr).mExec.CompileFile((*itr).mPath);
}
catch (const Sqrat::Exception & e)
{
LogFtl("Unable to compile: %s", (*itr).mPath.c_str());
// Failed to execute properly
return false;
}
cLogDbg(Get().m_Verbosity >= 3, "Compiled script: %s", (*itr).mPath.c_str());
// Should we delay the execution of this script?
if ((*itr).mDelay)
{
continue; // Execute later!
}
// Attempt to execute the compiled script code
try
{
(*itr).mExec.Run();
}
catch (const Sqrat::Exception & e)
{
LogFtl("Unable to execute: %s", (*itr).mPath.c_str());
// Failed to execute properly
return false;
}
cLogScs(Get().m_Verbosity >= 2, "Executed script: %s", (*itr).mPath.c_str());
}
cLogDbg(Get().m_Verbosity >= 1, "Attempting to execute the delayed scripts");
// Execute scripts only after compilation successful
for (itr = itr_state; itr != end; ++itr)
{
// Was this script delayed from execution?
if (!(*itr).mDelay)
{
continue; // Already executed!
}
// Attempt to execute the compiled script code
try
{
(*itr).mExec.Run();
}
catch (const Sqrat::Exception & e)
{
LogFtl("Unable to execute: %s", (*itr).mPath.c_str());
// Failed to execute properly
return false;
}
cLogScs(Get().m_Verbosity >= 2, "Executed script: %s", (*itr).mPath.c_str());
}
// At this point the scripts were loaded and executed successfully
return true;
}
// ------------------------------------------------------------------------------------------------
void Core::PrintFunc(HSQUIRRELVM /*vm*/, CSStr msg, ...)
{
// Initialize the variable argument list
va_list args;
va_start(args, msg);
// Forward the message to the logger
Logger::Get().Send(LOGL_USR, false, msg, args);
// Finalize the variable argument list
va_end(args);
}
// ------------------------------------------------------------------------------------------------
void Core::ErrorFunc(HSQUIRRELVM /*vm*/, CSStr msg, ...)
{
// Initialize the variable argument list
va_list args;
va_start(args, msg);
// Tell the logger to display debugging information
Logger::Get().Debug(msg, args);
// Finalize the variable argument list
va_end(args);
}
// ------------------------------------------------------------------------------------------------
SQInteger Core::RuntimeErrorHandler(HSQUIRRELVM vm)
{
// Was there a value thrown?
if (sq_gettop(vm) < 1)
{
return SQ_OK; // No error to display!
}
// Attempt to generate the string value
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(false)))
{
Logger::Get().Debug(_SC("Unknown runtime error has occurred"));
}
else
{
Logger::Get().Debug(_SC("%s"), val.mPtr);
}
// We handled the error
return SQ_OK;
}
// ------------------------------------------------------------------------------------------------
void Core::CompilerErrorHandler(HSQUIRRELVM /*vm*/, CSStr desc, CSStr src, SQInteger line, SQInteger column)
{
// Should we include code in output? (we count lines from 0, squirrel counts from 1)
if ((line <= 0) || !Core::Get().IsDebugging() || !Core::Get().CompilerErrorHandlerEx(desc, src, --line, column)) {
LogFtl("Message: %s\n[\n=>Location: %s\n=>Line: %" PRINT_INT_FMT "\n=>Column: %" PRINT_INT_FMT "\n]", desc, src, line, column);
}
}
// ------------------------------------------------------------------------------------------------
bool Core::CompilerErrorHandlerEx(CSStr desc, CSStr src, SQInteger line, SQInteger column)
{
// Grab the associated line of code
String code = FetchCodeLine(src, line, true);
// Contains an arrow pointing at the exact column
String point;
// Do we have a valid column?
if (column >= 0)
{
// The `=>Code: ` is included as white space
point.resize(8, ' ');
// The line towards the arrow
point.resize(column+7, '-');
// Append the actual arrow
point.push_back('^');
// Include the new line here
point.push_back('\n');
}
// Valid line of code?
if (!code.empty())
{
// Display the error message with the code included
LogFtl("Message: %s\n[\n=>Location: %s\n=>Line: %" PRINT_SZ_FMT "\n=>Column: %" PRINT_INT_FMT "\n=>Code: %s\n%s]",
desc, src, ++line, column, code.c_str(), point.c_str());
// We displayed the information
return true;
}
// No code to show. Fall back to normal message
return true;
}
} // Namespace:: SqMod
/* ------------------------------------------------------------------------------------------------
* Include remaining functionality.
*/
#include "Core/Inst.inc"
#include "Core/Entity.inc"
#include "Core/Events.inc"
#include "Core/Utils.inc"
#include "Core/Funcs.inc"

1523
module/Core.hpp Normal file

File diff suppressed because it is too large Load Diff

826
module/Core/Entity.inc Normal file
View File

@ -0,0 +1,826 @@
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// --------------------------------------------------------------------------------------------
void Core::ImportBlips()
{
// Information about the blip entity
Int32 world = -1, scale = -1, sprid = -1;
Uint32 color = 0;
Float32 x = 0.0, y = 0.0, z = 0.0;
for (Int32 i = 0; i < SQMOD_BLIP_POOL; ++i)
{
// See if this entity exists on the server and whether was not allocated already
if (_Func->CheckEntityExists(vcmpEntityPoolBlip, i) && INVALID_ENTITY(m_Blips[i].mID))
{
_Func->GetCoordBlipInfo(i, &world, &x, &y, &z, &scale, &color, &sprid);
// Make the properties available before triggering the event
m_Blips[i].mWorld = world;
m_Blips[i].mScale = scale;
m_Blips[i].mSprID = sprid;
m_Blips[i].mPosition.SetVector3Ex(x, y, z);
m_Blips[i].mColor.SetRGBA(color);
// Attempt to allocate the instance
AllocBlip(i, false, SQMOD_CREATE_IMPORT, NullLightObj());
}
}
}
// ------------------------------------------------------------------------------------------------
void Core::ImportCheckpoints()
{
for (Int32 i = 0; i < SQMOD_CHECKPOINT_POOL; ++i)
{
// See if this entity exists on the server and whether was not allocated already
if (_Func->CheckEntityExists(vcmpEntityPoolCheckPoint, i) && INVALID_ENTITY(m_Checkpoints[i].mID))
{
AllocCheckpoint(i, false, SQMOD_CREATE_IMPORT, NullLightObj());
}
}
}
// ------------------------------------------------------------------------------------------------
void Core::ImportKeybinds()
{
/* @NOTE This function is disabled because VC:MP server seems bugged
* and does not return vcmpErrorNoSuchEntity when the keybind does not exist.
* Therefore causing incorrect behavior in the plugin.
*/
return;
// Information about the key-bind entity
Uint8 release = 0;
Int32 first = -1, second = -1, third = -1;
for (Int32 i = 0; i < SQMOD_KEYBIND_POOL; ++i)
{
// See if this entity exists on the server and whether was not allocated already
if ((_Func->GetKeyBindData(i, &release, &first, &second, &third) != vcmpErrorNoSuchEntity)
&& (INVALID_ENTITY(m_Keybinds[i].mID)))
{
// Make the properties available before triggering the event
m_Keybinds[i].mFirst = first;
m_Keybinds[i].mSecond = second;
m_Keybinds[i].mThird = third;
m_Keybinds[i].mRelease = release;
// Attempt to allocate the instance
AllocKeybind(i, false, SQMOD_CREATE_IMPORT, NullLightObj());
}
}
}
// ------------------------------------------------------------------------------------------------
void Core::ImportObjects()
{
for (Int32 i = 0; i < SQMOD_OBJECT_POOL; ++i)
{
// See if this entity exists on the server and whether was not allocated already
if (_Func->CheckEntityExists(vcmpEntityPoolObject, i) && INVALID_ENTITY(m_Objects[i].mID))
{
AllocObject(i, false, SQMOD_CREATE_IMPORT, NullLightObj());
}
}
}
// ------------------------------------------------------------------------------------------------
void Core::ImportPickups()
{
for (Int32 i = 0; i < SQMOD_PICKUP_POOL; ++i)
{
// See if this entity exists on the server and whether was not allocated already
if (_Func->CheckEntityExists(vcmpEntityPoolPickup, i) && (INVALID_ENTITY(m_Pickups[i].mID)))
{
AllocPickup(i, false, SQMOD_CREATE_IMPORT, NullLightObj());
}
}
}
// ------------------------------------------------------------------------------------------------
void Core::ImportPlayers()
{
for (Int32 i = 0; i < SQMOD_PLAYER_POOL; ++i)
{
// See if this entity exists on the server and whether was not allocated already
if (_Func->IsPlayerConnected(i) && (INVALID_ENTITY(m_Players[i].mID)))
{
ConnectPlayer(i, SQMOD_CREATE_IMPORT, NullLightObj());
}
}
}
// ------------------------------------------------------------------------------------------------
void Core::ImportVehicles()
{
for (Int32 i = 0; i < SQMOD_VEHICLE_POOL; ++i)
{
// See if this entity exists on the server and whether was not allocated already
if (_Func->CheckEntityExists(vcmpEntityPoolVehicle, i) && INVALID_ENTITY(m_Vehicles[i].mID))
{
AllocVehicle(i, false, SQMOD_CREATE_IMPORT, NullLightObj());
}
}
}
// --------------------------------------------------------------------------------------------
Core::BlipInst & Core::AllocBlip(Int32 id, bool owned, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL))
{
STHROWF("Cannot allocate blip with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
BlipInst & inst = m_Blips[id];
// Make sure that the instance isn't already allocated
if (VALID_ENTITY(inst.mID))
{
return inst; // Return the existing instance
}
// Instantiate the entity manager
DeleteGuard< CBlip > dg(new CBlip(id));
// Create the script object
inst.mObj = LightObj(dg.Get(), m_VM);
// Store the manager instance itself
inst.mInst = dg.Get();
// The instance is now managed by the script
dg.Release();
// Make sure that both the instance and script object could be created
if (!inst.mInst || inst.mObj.IsNull())
{
inst.ResetInstance();
// Now we can throw the error
STHROWF("Unable to create a blip instance for: %d", id);
}
// Assign the specified entity identifier
inst.mID = id;
// Specify whether the entity is owned by this plug-in
if (owned)
{
inst.mFlags |= ENF_OWNED;
}
else if (inst.mFlags & ENF_OWNED)
{
inst.mFlags ^= ENF_OWNED;
}
// Initialize the instance events
inst.InitEvents();
// Let the script callbacks know about this entity
EmitBlipCreated(id, header, payload);
// Return the allocated instance
return inst;
}
// --------------------------------------------------------------------------------------------
Core::CheckpointInst & Core::AllocCheckpoint(Int32 id, bool owned, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL))
{
STHROWF("Cannot allocate checkpoint with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
CheckpointInst & inst = m_Checkpoints[id];
// Make sure that the instance isn't already allocated
if (VALID_ENTITY(inst.mID))
{
return inst; // Return the existing instance
}
// Instantiate the entity manager
DeleteGuard< CCheckpoint > dg(new CCheckpoint(id));
// Create the script object
inst.mObj = LightObj(dg.Get(), m_VM);
// Store the manager instance itself
inst.mInst = dg.Get();
// The instance is now managed by the script
dg.Release();
// Make sure that both the instance and script object could be created
if (!inst.mInst || inst.mObj.IsNull())
{
inst.ResetInstance();
// Now we can throw the error
STHROWF("Unable to create a checkpoint instance for: %d", id);
}
// Assign the specified entity identifier
inst.mID = id;
// Specify whether the entity is owned by this plug-in
if (owned)
{
inst.mFlags |= ENF_OWNED;
}
else if (inst.mFlags & ENF_OWNED)
{
inst.mFlags ^= ENF_OWNED;
}
// Initialize the instance events
inst.InitEvents();
// Let the script callbacks know about this entity
EmitCheckpointCreated(id, header, payload);
// Return the allocated instance
return inst;
}
// --------------------------------------------------------------------------------------------
Core::KeybindInst & Core::AllocKeybind(Int32 id, bool owned, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL))
{
STHROWF("Cannot allocate keybind with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
KeybindInst & inst = m_Keybinds[id];
// Make sure that the instance isn't already allocated
if (VALID_ENTITY(inst.mID))
{
return inst; // Return the existing instance
}
// Instantiate the entity manager
DeleteGuard< CKeybind > dg(new CKeybind(id));
// Create the script object
inst.mObj = LightObj(dg.Get(), m_VM);
// Store the manager instance itself
inst.mInst = dg.Get();
// The instance is now managed by the script
dg.Release();
// Make sure that both the instance and script object could be created
if (!inst.mInst || inst.mObj.IsNull())
{
inst.ResetInstance();
// Now we can throw the error
STHROWF("Unable to create a keybind instance for: %d", id);
}
// Assign the specified entity identifier
inst.mID = id;
// Specify whether the entity is owned by this plug-in
if (owned)
{
inst.mFlags |= ENF_OWNED;
}
else if (inst.mFlags & ENF_OWNED)
{
inst.mFlags ^= ENF_OWNED;
}
// Initialize the instance events
inst.InitEvents();
// Let the script callbacks know about this entity
EmitKeybindCreated(id, header, payload);
// Return the allocated instance
return inst;
}
// --------------------------------------------------------------------------------------------
Core::ObjectInst & Core::AllocObject(Int32 id, bool owned, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL))
{
STHROWF("Cannot allocate object with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
ObjectInst & inst = m_Objects[id];
// Make sure that the instance isn't already allocated
if (VALID_ENTITY(inst.mID))
{
return inst; // Return the existing instance
}
// Instantiate the entity manager
DeleteGuard< CObject > dg(new CObject(id));
// Create the script object
inst.mObj = LightObj(dg.Get(), m_VM);
// Store the manager instance itself
inst.mInst = dg.Get();
// The instance is now managed by the script
dg.Release();
// Make sure that both the instance and script object could be created
if (!inst.mInst || inst.mObj.IsNull())
{
inst.ResetInstance();
// Now we can throw the error
STHROWF("Unable to create a object instance for: %d", id);
}
// Assign the specified entity identifier
inst.mID = id;
// Specify whether the entity is owned by this plug-in
if (owned)
{
inst.mFlags |= ENF_OWNED;
}
else if (inst.mFlags & ENF_OWNED)
{
inst.mFlags ^= ENF_OWNED;
}
// Initialize the instance events
inst.InitEvents();
// Let the script callbacks know about this entity
EmitObjectCreated(id, header, payload);
// Return the allocated instance
return inst;
}
// --------------------------------------------------------------------------------------------
Core::PickupInst & Core::AllocPickup(Int32 id, bool owned, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL))
{
STHROWF("Cannot allocate pickup with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
PickupInst & inst = m_Pickups[id];
// Make sure that the instance isn't already allocated
if (VALID_ENTITY(inst.mID))
{
return inst; // Return the existing instance
}
// Instantiate the entity manager
DeleteGuard< CPickup > dg(new CPickup(id));
// Create the script object
inst.mObj = LightObj(dg.Get(), m_VM);
// Store the manager instance itself
inst.mInst = dg.Get();
// The instance is now managed by the script
dg.Release();
// Make sure that both the instance and script object could be created
if (!inst.mInst || inst.mObj.IsNull())
{
inst.ResetInstance();
// Now we can throw the error
STHROWF("Unable to create a pickup instance for: %d", id);
}
// Assign the specified entity identifier
inst.mID = id;
// Specify whether the entity is owned by this plug-in
if (owned)
{
inst.mFlags |= ENF_OWNED;
}
else if (inst.mFlags & ENF_OWNED)
{
inst.mFlags ^= ENF_OWNED;
}
// Initialize the instance events
inst.InitEvents();
// Let the script callbacks know about this entity
EmitPickupCreated(id, header, payload);
// Return the allocated instance
return inst;
}
// --------------------------------------------------------------------------------------------
Core::VehicleInst & Core::AllocVehicle(Int32 id, bool owned, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL))
{
STHROWF("Cannot allocate vehicle with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
VehicleInst & inst = m_Vehicles[id];
// Make sure that the instance isn't already allocated
if (VALID_ENTITY(inst.mID))
{
return inst; // Return the existing instance
}
// Instantiate the entity manager
DeleteGuard< CVehicle > dg(new CVehicle(id));
// Create the script object
inst.mObj = LightObj(dg.Get(), m_VM);
// Store the manager instance itself
inst.mInst = dg.Get();
// The instance is now managed by the script
dg.Release();
// Make sure that both the instance and script object could be created
if (!inst.mInst || inst.mObj.IsNull())
{
inst.ResetInstance();
// Now we can throw the error
STHROWF("Unable to create a vehicle instance for: %d", id);
}
// Assign the specified entity identifier
inst.mID = id;
// Specify whether the entity is owned by this plug-in
if (owned)
{
inst.mFlags |= ENF_OWNED;
}
else if (inst.mFlags & ENF_OWNED)
{
inst.mFlags ^= ENF_OWNED;
}
// Should we enable area tracking?
if (m_AreasEnabled)
{
inst.mFlags |= ENF_AREA_TRACK;
}
// Initialize the instance events
inst.InitEvents();
// Let the script callbacks know about this entity
EmitVehicleCreated(id, header, payload);
// Return the allocated instance
return inst;
}
// --------------------------------------------------------------------------------------------
void Core::DeallocBlip(Int32 id, bool destroy, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL))
{
STHROWF("Cannot deallocate blip with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
BlipInst & inst = m_Blips[id];
// Make sure that the instance is even allocated and we are allowed to destroy it
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
{
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
}
}
// --------------------------------------------------------------------------------------------
void Core::DeallocCheckpoint(Int32 id, bool destroy, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL))
{
STHROWF("Cannot deallocate checkpoint with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
CheckpointInst & inst = m_Checkpoints[id];
// Make sure that the instance is even allocated and we are allowed to destroy it
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
{
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
}
}
// --------------------------------------------------------------------------------------------
void Core::DeallocKeybind(Int32 id, bool destroy, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL))
{
STHROWF("Cannot deallocate keybind with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
KeybindInst & inst = m_Keybinds[id];
// Make sure that the instance is even allocated and we are allowed to destroy it
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
{
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
}
}
// --------------------------------------------------------------------------------------------
void Core::DeallocObject(Int32 id, bool destroy, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL))
{
STHROWF("Cannot deallocate object with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
ObjectInst & inst = m_Objects[id];
// Make sure that the instance is even allocated and we are allowed to destroy it
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
{
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
}
}
// --------------------------------------------------------------------------------------------
void Core::DeallocPickup(Int32 id, bool destroy, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL))
{
STHROWF("Cannot deallocate pickup with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
PickupInst & inst = m_Pickups[id];
// Make sure that the instance is even allocated and we are allowed to destroy it
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
{
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
}
}
// --------------------------------------------------------------------------------------------
void Core::DeallocVehicle(Int32 id, bool destroy, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL))
{
STHROWF("Cannot deallocate vehicle with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
VehicleInst & inst = m_Vehicles[id];
// Make sure that the instance is even allocated and we are allowed to destroy it
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
{
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
}
}
// --------------------------------------------------------------------------------------------
LightObj & Core::NewBlip(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z,
Int32 scale, Uint32 color, Int32 sprid,
Int32 header, LightObj & payload)
{
// Request the server to create this entity
const Int32 id = _Func->CreateCoordBlip(index, world, x, y, z, scale, color, sprid);
// See if the entity creation failed on the server
if (_Func->GetLastError() == vcmpErrorPoolExhausted)
{
STHROWF("Blip pool was exhausted: %d", id);
}
// Validate the identifier returned by the server
else if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL))
{
STHROWF("Server returned invalid blip: %d", id);
}
// Attempt to allocate this entity and grab the reference to the instance
BlipInst & inst = AllocBlip(id, true, header, payload);
// Just in case it was created during the notification for changes in entity pool
if (VALID_ENTITY(inst.mID))
{
inst.mFlags |= ENF_OWNED;
}
// Now we can return the script object
return inst.mObj;
}
// --------------------------------------------------------------------------------------------
LightObj & Core::NewCheckpoint(Int32 player, Int32 world, bool sphere, Float32 x, Float32 y, Float32 z,
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius,
Int32 header, LightObj & payload)
{
// Request the server to create this entity
const Int32 id = _Func->CreateCheckPoint(player, world, sphere, x, y, z, r, g, b, a, radius);
// See if the entity creation failed on the server
if (_Func->GetLastError() == vcmpErrorNoSuchEntity)
{
STHROWF("Invalid player reference: %d", player);
}
else if (_Func->GetLastError() == vcmpErrorPoolExhausted)
{
STHROWF("Checkpoint pool was exhausted: %d", id);
}
// Validate the identifier returned by the server
else if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL))
{
STHROWF("Server returned invalid checkpoint: %d", id);
}
// Attempt to allocate this entity and grab the reference to the instance
CheckpointInst & inst = AllocCheckpoint(id, true, header, payload);
// Just in case it was created during the notification for changes in entity pool
if (VALID_ENTITY(inst.mID))
{
inst.mFlags |= ENF_OWNED;
}
// Now we can return the script object
return inst.mObj;
}
// --------------------------------------------------------------------------------------------
LightObj & Core::NewKeybind(Int32 slot, bool release, Int32 primary, Int32 secondary, Int32 alternative,
Int32 header, LightObj & payload)
{
// Should we obtain a new keybind slot automatically?
if (slot < 0)
{
slot = _Func->GetKeyBindUnusedSlot();
}
// Validate the keybind slot returned by the server
if (INVALID_ENTITYEX(slot, SQMOD_KEYBIND_POOL))
{
STHROWF("Server returned invalid keybind slot: %d", slot);
}
// Request the server to create this entity
const vcmpError result = _Func->RegisterKeyBind(slot, release, primary, secondary, alternative);
// See if the entity creation failed on the server
if (result == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Out of bounds keybind argument: %d", slot);
}
// Attempt to allocate this entity and grab the reference to the instance
KeybindInst & inst = AllocKeybind(slot, true, header, payload);
// Just in case it was created during the notification for changes in entity pool
if (VALID_ENTITY(inst.mID))
{
inst.mFlags |= ENF_OWNED;
}
// Now we can return the script object
return inst.mObj;
}
// --------------------------------------------------------------------------------------------
LightObj & Core::NewObject(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z, Int32 alpha,
Int32 header, LightObj & payload)
{
// Request the server to create this entity
const Int32 id = _Func->CreateObject(model, world, x, y, z, alpha);
// See if the entity creation failed on the server
if (_Func->GetLastError() == vcmpErrorPoolExhausted)
{
STHROWF("Object pool was exhausted: %d", id);
}
// Validate the identifier returned by the server
else if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL))
{
STHROWF("Server returned invalid object: %d", id);
}
// Attempt to allocate this entity and grab the reference to the instance
ObjectInst & inst = AllocObject(id, true, header, payload);
// Just in case it was created during the notification for changes in entity pool
if (VALID_ENTITY(inst.mID))
{
inst.mFlags |= ENF_OWNED;
}
// Now we can return the script object
return inst.mObj;
}
// --------------------------------------------------------------------------------------------
LightObj & Core::NewPickup(Int32 model, Int32 world, Int32 quantity,
Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic,
Int32 header, LightObj & payload)
{
// Request the server to create this entity
const Int32 id = _Func->CreatePickup(model, world, quantity, x, y, z, alpha, automatic);
// See if the entity creation failed on the server
if (_Func->GetLastError() == vcmpErrorPoolExhausted)
{
STHROWF("Pickup pool was exhausted: %d", id);
}
// Validate the identifier returned by the server
else if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL))
{
STHROWF("Server returned invalid pickup: %d", id);
}
// Attempt to allocate this entity and grab the reference to the instance
PickupInst & inst = AllocPickup(id, true, header, payload);
// Just in case it was created during the notification for changes in entity pool
if (VALID_ENTITY(inst.mID))
{
inst.mFlags |= ENF_OWNED;
}
// Now we can return the script object
return inst.mObj;
}
// --------------------------------------------------------------------------------------------
LightObj & Core::NewVehicle(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z,
Float32 angle, Int32 primary, Int32 secondary,
Int32 header, LightObj & payload)
{
// Request the server to create this entity
const Int32 id = _Func->CreateVehicle(model, world, x, y, z, angle, primary, secondary);
// See if the entity creation failed on the server
if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Out of bounds vehicle argument: %d", id);
}
else if (_Func->GetLastError() == vcmpErrorPoolExhausted)
{
STHROWF("Vehicle pool was exhausted: %d", id);
}
// Validate the identifier returned by the server
else if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL))
{
STHROWF("Server returned invalid vehicle: %d", id);
}
// Attempt to allocate this entity and grab the reference to the instance
VehicleInst & inst = AllocVehicle(id, true, header, payload);
// Just in case it was created during the notification for changes in entity pool
if (VALID_ENTITY(inst.mID))
{
inst.mFlags |= ENF_OWNED;
}
// Now we can return the script object
return inst.mObj;
}
// --------------------------------------------------------------------------------------------
bool Core::DelBlip(Int32 id, Int32 header, LightObj & payload)
{
// Attempt to destroy and deallocate the specified entity instance
DeallocBlip(id, true, header, payload);
// The entity could be destroyed
return true;
}
// ------------------------------------------------------------------------------------------------
bool Core::DelCheckpoint(Int32 id, Int32 header, LightObj & payload)
{
// Attempt to destroy and deallocate the specified entity instance
DeallocCheckpoint(id, true, header, payload);
// The entity could be destroyed
return true;
}
// ------------------------------------------------------------------------------------------------
bool Core::DelKeybind(Int32 id, Int32 header, LightObj & payload)
{
// Attempt to destroy and deallocate the specified entity instance
DeallocKeybind(id, true, header, payload);
// The entity could be destroyed
return true;
}
// ------------------------------------------------------------------------------------------------
bool Core::DelObject(Int32 id, Int32 header, LightObj & payload)
{
// Attempt to destroy and deallocate the specified entity instance
DeallocObject(id, true, header, payload);
// The entity could be destroyed
return true;
}
// ------------------------------------------------------------------------------------------------
bool Core::DelPickup(Int32 id, Int32 header, LightObj & payload)
{
// Attempt to destroy and deallocate the specified entity instance
DeallocPickup(id, true, header, payload);
// The entity could be destroyed
return true;
}
// ------------------------------------------------------------------------------------------------
bool Core::DelVehicle(Int32 id, Int32 header, LightObj & payload)
{
// Attempt to destroy and deallocate the specified entity instance
DeallocVehicle(id, true, header, payload);
// The entity could be destroyed
return true;
}
// ------------------------------------------------------------------------------------------------
void Core::ConnectPlayer(Int32 id, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL))
{
STHROWF("Cannot allocate player with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
PlayerInst & inst = m_Players[id];
// Make sure that the instance isn't already allocated
if (VALID_ENTITY(inst.mID))
{
return; // Nothing to allocate!
}
// Instantiate the entity manager
DeleteGuard< CPlayer > dg(new CPlayer(id));
// Create the script object
inst.mObj = LightObj(dg.Get(), m_VM);
// Store the manager instance itself
inst.mInst = dg.Get();
// The instance is now managed by the script
dg.Release();
// Make sure that both the instance and script object could be created
if (!inst.mInst || inst.mObj.IsNull())
{
inst.ResetInstance();
STHROWF("Unable to create a player instance for: %d", id);
}
// Assign the specified entity identifier
inst.mID = id;
// Should we enable area tracking?
if (m_AreasEnabled)
{
inst.mFlags |= ENF_AREA_TRACK;
}
// Initialize the position
_Func->GetPlayerPosition(id, &inst.mLastPosition.x, &inst.mLastPosition.y, &inst.mLastPosition.z);
// Initialize the remaining attributes
inst.mLastWeapon = _Func->GetPlayerWeapon(id);
inst.mLastHealth = _Func->GetPlayerHealth(id);
inst.mLastArmour = _Func->GetPlayerArmour(id);
inst.mLastHeading = _Func->GetPlayerHeading(id);
// Initialize the instance events
inst.InitEvents();
// Let the script callbacks know about this entity
EmitPlayerCreated(id, header, payload);
}
// ------------------------------------------------------------------------------------------------
void Core::DisconnectPlayer(Int32 id, Int32 header, LightObj & payload)
{
// Make sure that the specified entity identifier is valid
if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL))
{
STHROWF("Cannot deallocate player with invalid identifier: %d", id);
}
// Retrieve the specified entity instance
PlayerInst & inst = m_Players[id];
// Make sure that the instance is even allocated and we are allowed to destroy it
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
{
inst.Destroy(false, header, payload); // Now attempt to destroy the entity from the server
}
}
} // Namespace:: SqMod

1858
module/Core/Events.inc Normal file

File diff suppressed because it is too large Load Diff

368
module/Core/Funcs.inc Normal file
View File

@ -0,0 +1,368 @@
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern bool GetReloadStatus();
extern void SetReloadStatus(bool toggle);
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(CoreStateTypename, _SC("SqCoreState"))
// ------------------------------------------------------------------------------------------------
static SQInteger SqLoadScript(HSQUIRRELVM vm)
{
const Int32 top = sq_gettop(vm);
// Was the delay option specified?
if (top <= 1)
{
return sq_throwerror(vm, "Missing delay parameter");
}
// Was the script path specified?
else if (top <= 2)
{
return sq_throwerror(vm, "Missing script path");
}
// Whether the script execution is delayed
SQBool delay = SQFalse;
// Attempt to generate the string value
StackStrF val(vm, 3);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
else if (SQ_FAILED(sq_getbool(vm, 2, &delay)))
{
return sq_throwerror(vm, "Failed to retrieve the delay parameter");
}
// Forward the call to the actual implementation
sq_pushbool(vm, Core::Get().LoadScript(val.mPtr, static_cast< bool >(delay)));
// We have an argument on the stack
return 1;
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqGetEvents(HSQUIRRELVM vm)
{
// Push the events table object on the stack
sq_pushobject(vm, Core::Get().GetEvents().mObj);
// Specify that we're returning a value
return 1;
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqForceEnableNullEntities(HSQUIRRELVM vm)
{
Core::Get().EnableNullEntities();
return 0;
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetPreLoadEvent()
{
return Core::Get().GetPreLoadEvent();
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetPostLoadEvent()
{
return Core::Get().GetPostLoadEvent();
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetUnloadEvent()
{
return Core::Get().GetUnloadEvent();
}
// ------------------------------------------------------------------------------------------------
static bool SqGetReloadStatus()
{
return GetReloadStatus();
}
// ------------------------------------------------------------------------------------------------
static void SqSetReloadStatus(bool toggle)
{
SetReloadStatus(toggle);
}
// ------------------------------------------------------------------------------------------------
static void SqReloadBecause(Int32 header, LightObj & payload)
{
// Assign the reload info
Core::Get().SetReloadInfo(header, payload);
// Enable reloading
SetReloadStatus(true);
}
// ------------------------------------------------------------------------------------------------
static void SqSetReloadInfo(Int32 header, LightObj & payload)
{
Core::Get().SetReloadInfo(header, payload);
}
// ------------------------------------------------------------------------------------------------
static Int32 SqGetReloadHeader()
{
return Core::Get().GetReloadHeader();
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetReloadPayload()
{
return Core::Get().GetReloadPayload();
}
// ------------------------------------------------------------------------------------------------
static Int32 SqGetState()
{
return Core::Get().GetState();
}
// ------------------------------------------------------------------------------------------------
static void SqSetState(Int32 value)
{
return Core::Get().SetState(value);
}
// ------------------------------------------------------------------------------------------------
static bool SqGetAreasEnabled()
{
return Core::Get().AreasEnabled();
}
// ------------------------------------------------------------------------------------------------
static void SqSetAreasEnabled(bool toggle)
{
Core::Get().AreasEnabled(toggle);
}
// ------------------------------------------------------------------------------------------------
static CSStr SqGetOption(CSStr name)
{
return Core::Get().GetOption(name);
}
// ------------------------------------------------------------------------------------------------
static CSStr SqGetOptionOr(CSStr name, CSStr value)
{
return Core::Get().GetOption(name, value);
}
// ------------------------------------------------------------------------------------------------
static void SqSetOption(CSStr name, CSStr value)
{
return Core::Get().SetOption(name, value);
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetBlip(Int32 id)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL))
{
STHROWF("Out of range blip identifier: %d", id);
}
// Return the requested information
return Core::Get().GetBlip(id).mObj;
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetCheckpoint(Int32 id)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL))
{
STHROWF("Out of range checkpoint identifier: %d", id);
}
// Return the requested information
return Core::Get().GetCheckpoint(id).mObj;
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetKeybind(Int32 id)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL))
{
STHROWF("Out of range keybind identifier: %d", id);
}
// Return the requested information
return Core::Get().GetKeybind(id).mObj;
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetObject(Int32 id)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL))
{
STHROWF("Out of range object identifier: %d", id);
}
// Return the requested information
return Core::Get().GetObject(id).mObj;
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetPickup(Int32 id)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL))
{
STHROWF("Out of range blip identifier: %d", id);
}
// Return the requested information
return Core::Get().GetPickup(id).mObj;
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetPlayer(Int32 id)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL))
{
STHROWF("Out of range player identifier: %d", id);
}
// Return the requested information
return Core::Get().GetPlayer(id).mObj;
}
// ------------------------------------------------------------------------------------------------
static LightObj & SqGetVehicle(Int32 id)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL))
{
STHROWF("Out of range vehicle identifier: %d", id);
}
// Return the requested information
return Core::Get().GetVehicle(id).mObj;
}
// ------------------------------------------------------------------------------------------------
static bool SqDelBlip(Int32 id, Int32 header, LightObj & payload)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL))
{
STHROWF("Out of range blip identifier: %d", id);
}
// Perform the requested operation
return Core::Get().DelBlip(id, header, payload);
}
// ------------------------------------------------------------------------------------------------
static bool SqDelCheckpoint(Int32 id, Int32 header, LightObj & payload)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL))
{
STHROWF("Out of range checkpoint identifier: %d", id);
}
// Perform the requested operation
return Core::Get().DelCheckpoint(id, header, payload);
}
// ------------------------------------------------------------------------------------------------
static bool SqDelKeybind(Int32 id, Int32 header, LightObj & payload)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL))
{
STHROWF("Out of range keybind identifier: %d", id);
}
// Perform the requested operation
return Core::Get().DelKeybind(id, header, payload);
}
// ------------------------------------------------------------------------------------------------
static bool SqDelObject(Int32 id, Int32 header, LightObj & payload)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL))
{
STHROWF("Out of range object identifier: %d", id);
}
// Perform the requested operation
return Core::Get().DelObject(id, header, payload);
}
// ------------------------------------------------------------------------------------------------
static bool SqDelPickup(Int32 id, Int32 header, LightObj & payload)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL))
{
STHROWF("Out of range blip identifier: %d", id);
}
// Perform the requested operation
return Core::Get().DelPickup(id, header, payload);
}
// ------------------------------------------------------------------------------------------------
static bool SqDelVehicle(Int32 id, Int32 header, LightObj & payload)
{
// Validate the identifier first
if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL))
{
STHROWF("Out of range vehicle identifier: %d", id);
}
// Perform the requested operation
return Core::Get().DelVehicle(id, header, payload);
}
// ================================================================================================
void Register_Core(HSQUIRRELVM vm)
{
Table corens(vm);
corens.Bind(_SC("State"),
Class< CoreState, NoCopy< CoreState > >(vm, CoreStateTypename::Str)
// Constructors
.Ctor()
.Ctor< int >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &CoreStateTypename::Fn)
// Member Properties
.Prop(_SC("Value"), &CoreState::GetValue)
);
corens
.Func(_SC("Reload"), &SqSetReloadStatus)
.Func(_SC("Reloading"), &SqGetReloadStatus)
.Func(_SC("ReloadBecause"), &SqReloadBecause)
.Func(_SC("SetReloadInfo"), &SqSetReloadInfo)
.Func(_SC("GetReloadHeader"), &SqGetReloadHeader)
.Func(_SC("GetReloadPayload"), &SqGetReloadPayload)
.Func(_SC("GetState"), &SqGetState)
.Func(_SC("SetState"), &SqSetState)
.Func(_SC("AreasEnabled"), &SqGetAreasEnabled)
.Func(_SC("SetAreasEnabled"), &SqSetAreasEnabled)
.Func(_SC("GetOption"), &SqGetOption)
.Func(_SC("GetOptionOr"), &SqGetOptionOr)
.Func(_SC("SetOption"), &SqSetOption)
.Func(_SC("GetBlip"), &SqGetBlip)
.Func(_SC("GetCheckpoint"), &SqGetCheckpoint)
.Func(_SC("GetKeybind"), &SqGetKeybind)
.Func(_SC("GetObject"), &SqGetObject)
.Func(_SC("GetPickup"), &SqGetPickup)
.Func(_SC("GetPlayer"), &SqGetPlayer)
.Func(_SC("GetVehicle"), &SqGetVehicle)
.Func(_SC("DestroyBlip"), &SqDelBlip)
.Func(_SC("DestroyCheckpoint"), &SqDelCheckpoint)
.Func(_SC("DestroyKeybind"), &SqDelKeybind)
.Func(_SC("DestroyObject"), &SqDelObject)
.Func(_SC("DestroyPickup"), &SqDelPickup)
.Func(_SC("DestroyVehicle"), &SqDelVehicle)
.Func(_SC("OnPreLoad"), &SqGetPreLoadEvent)
.Func(_SC("OnPostLoad"), &SqGetPostLoadEvent)
.Func(_SC("OnUnload"), &SqGetUnloadEvent)
.SquirrelFunc(_SC("ForceEnableNullEntities"), &SqForceEnableNullEntities)
.SquirrelFunc(_SC("LoadScript"), &SqLoadScript)
.SquirrelFunc(_SC("On"), &SqGetEvents);
RootTable(vm).Bind(_SC("SqCore"), corens);
}
} // Namespace:: SqMod

825
module/Core/Inst.inc Normal file
View File

@ -0,0 +1,825 @@
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// --------------------------------------------------------------------------------------------
#define SQMOD_CATCH_EVENT_EXCEPTION(action) /*
*/ catch (const Sqrat::Exception & e) /*
*/ { /*
*/ LogErr("Squirrel exception caught " action); /*
*/ Logger::Get().Debug("%s", e.what()); /*
*/ } /*
*/
// ------------------------------------------------------------------------------------------------
extern void CleanupTasks(Int32 id, Int32 type);
// ------------------------------------------------------------------------------------------------
void Core::BlipInst::Destroy(bool destroy, Int32 header, LightObj & payload)
{
// Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID))
{
// Don't leave exceptions to prevent us from releasing this instance
try
{
Core::Get().EmitBlipDestroyed(mID, header, payload);
}
SQMOD_CATCH_EVENT_EXCEPTION("while destroying blip")
}
// Is there a manager instance associated with this entity?
if (mInst)
{
// Prevent further use of this entity
mInst->m_ID = -1;
// Release user data to avoid dangling or circular references
mInst->m_Data.Release();
}
// Prevent further use of the manager instance
mInst = nullptr;
// Release the script object, if any
mObj.Release();
// Release tasks, if any
CleanupTasks(mID, ENT_BLIP);
// Are we supposed to clean up this entity? (only at reload)
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
{
// Block the entity pool changes notification from triggering the destroy event
const BitGuardU32 bg(mFlags, static_cast< Uint32 >(ENF_LOCKED));
// Now attempt to destroy this entity from the server
_Func->DestroyCoordBlip(mID);
}
// Reset the instance to it's initial state
ResetInstance();
// Don't release the callbacks abruptly
DropEvents();
}
// ------------------------------------------------------------------------------------------------
void Core::CheckpointInst::Destroy(bool destroy, Int32 header, LightObj & payload)
{
// Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID))
{
// Don't leave exceptions to prevent us from releasing this instance
try
{
Core::Get().EmitCheckpointDestroyed(mID, header, payload);
}
SQMOD_CATCH_EVENT_EXCEPTION("while destroying checkpoint")
}
// Is there a manager instance associated with this entity?
if (mInst)
{
// Prevent further use of this entity
mInst->m_ID = -1;
// Release user data to avoid dangling or circular references
mInst->m_Data.Release();
}
// Prevent further use of the manager instance
mInst = nullptr;
// Release the script object, if any
mObj.Release();
// Release tasks, if any
CleanupTasks(mID, ENT_CHECKPOINT);
// Are we supposed to clean up this entity? (only at reload)
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
{
// Block the entity pool changes notification from triggering the destroy event
const BitGuardU32 bg(mFlags, static_cast< Uint32 >(ENF_LOCKED));
// Now attempt to destroy this entity from the server
_Func->DeleteCheckPoint(mID);
}
// Reset the instance to it's initial state
ResetInstance();
// Don't release the callbacks abruptly
DropEvents();
}
// ------------------------------------------------------------------------------------------------
void Core::KeybindInst::Destroy(bool destroy, Int32 header, LightObj & payload)
{
// Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID))
{
// Don't leave exceptions to prevent us from releasing this instance
try
{
Core::Get().EmitKeybindDestroyed(mID, header, payload);
}
SQMOD_CATCH_EVENT_EXCEPTION("while destroying keybind")
}
// Is there a manager instance associated with this entity?
if (mInst)
{
// Prevent further use of this entity
mInst->m_ID = -1;
// Release user data to avoid dangling or circular references
mInst->m_Data.Release();
}
// Prevent further use of the manager instance
mInst = nullptr;
// Release the script object, if any
mObj.Release();
// Release tasks, if any
CleanupTasks(mID, ENT_KEYBIND);
// Are we supposed to clean up this entity? (only at reload)
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
{
// Block the entity pool changes notification from triggering the destroy event
const BitGuardU32 bg(mFlags, static_cast< Uint32 >(ENF_LOCKED));
// Now attempt to destroy this entity from the server
_Func->RemoveKeyBind(mID);
}
// Reset the instance to it's initial state
ResetInstance();
// Don't release the callbacks abruptly
DropEvents();
}
// ------------------------------------------------------------------------------------------------
void Core::ObjectInst::Destroy(bool destroy, Int32 header, LightObj & payload)
{
// Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID))
{
// Don't leave exceptions to prevent us from releasing this instance
try
{
Core::Get().EmitObjectDestroyed(mID, header, payload);
}
SQMOD_CATCH_EVENT_EXCEPTION("while destroying object")
}
// Is there a manager instance associated with this entity?
if (mInst)
{
// Prevent further use of this entity
mInst->m_ID = -1;
// Release user data to avoid dangling or circular references
mInst->m_Data.Release();
}
// Prevent further use of the manager instance
mInst = nullptr;
// Release the script object, if any
mObj.Release();
// Release tasks, if any
CleanupTasks(mID, ENT_OBJECT);
// Are we supposed to clean up this entity? (only at reload)
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
{
// Block the entity pool changes notification from triggering the destroy event
const BitGuardU32 bg(mFlags, static_cast< Uint32 >(ENF_LOCKED));
// Now attempt to destroy this entity from the server
_Func->DeleteObject(mID);
}
// Reset the instance to it's initial state
ResetInstance();
// Don't release the callbacks abruptly
DropEvents();
}
// ------------------------------------------------------------------------------------------------
void Core::PickupInst::Destroy(bool destroy, Int32 header, LightObj & payload)
{
// Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID))
{
// Don't leave exceptions to prevent us from releasing this instance
try
{
Core::Get().EmitPickupDestroyed(mID, header, payload);
}
SQMOD_CATCH_EVENT_EXCEPTION("while destroying pickup")
}
// Is there a manager instance associated with this entity?
if (mInst)
{
// Prevent further use of this entity
mInst->m_ID = -1;
// Release user data to avoid dangling or circular references
mInst->m_Data.Release();
}
// Prevent further use of the manager instance
mInst = nullptr;
// Release the script object, if any
mObj.Release();
// Release tasks, if any
CleanupTasks(mID, ENT_PICKUP);
// Are we supposed to clean up this entity? (only at reload)
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
{
// Block the entity pool changes notification from triggering the destroy event
const BitGuardU32 bg(mFlags, static_cast< Uint32 >(ENF_LOCKED));
// Now attempt to destroy this entity from the server
_Func->DeletePickup(mID);
}
// Reset the instance to it's initial state
ResetInstance();
// Don't release the callbacks abruptly
DropEvents();
}
// ------------------------------------------------------------------------------------------------
void Core::PlayerInst::Destroy(bool /*destroy*/, Int32 header, LightObj & payload)
{
// Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID))
{
// Don't leave exceptions to prevent us from releasing this instance
try
{
Core::Get().EmitPlayerDestroyed(mID, header, payload);
}
SQMOD_CATCH_EVENT_EXCEPTION("while destroying player")
}
// Is there a manager instance associated with this entity?
if (mInst)
{
// Prevent further use of this entity
mInst->m_ID = -1;
// Release user data to avoid dangling or circular references
mInst->m_Data.Release();
// Release the used memory buffer
mInst->m_Buffer.ResetAll();
}
// Prevent further use of the manager instance
mInst = nullptr;
// Release the script object, if any
mObj.Release();
// Release tasks, if any
CleanupTasks(mID, ENT_PLAYER);
// Reset the instance to it's initial state
ResetInstance();
// Don't release the callbacks abruptly
DropEvents();
}
// ------------------------------------------------------------------------------------------------
void Core::VehicleInst::Destroy(bool destroy, Int32 header, LightObj & payload)
{
// Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID))
{
// Don't leave exceptions to prevent us from releasing this instance
try
{
Core::Get().EmitVehicleDestroyed(mID, header, payload);
}
SQMOD_CATCH_EVENT_EXCEPTION("while destroying vehicle")
}
// Is there a manager instance associated with this entity?
if (mInst)
{
// Prevent further use of this entity
mInst->m_ID = -1;
// Release user data to avoid dangling or circular references
mInst->m_Data.Release();
}
// Prevent further use of the manager instance
mInst = nullptr;
// Release the script object, if any
mObj.Release();
// Release tasks, if any
CleanupTasks(mID, ENT_VEHICLE);
// Are we supposed to clean up this entity? (only at reload)
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
{
// Block the entity pool changes notification from triggering the destroy event
const BitGuardU32 bg(mFlags, static_cast< Uint32 >(ENF_LOCKED));
// Now attempt to destroy this entity from the server
_Func->DeleteVehicle(mID);
}
// Reset the instance to it's initial state
ResetInstance();
// Don't release the callbacks abruptly
DropEvents();
}
// ------------------------------------------------------------------------------------------------
void Core::BlipInst::ResetInstance()
{
mID = -1;
mFlags = ENF_DEFAULT;
mWorld = -1;
mScale = -1;
mSprID = -1;
mPosition.Clear();
mColor.Clear();
}
// ------------------------------------------------------------------------------------------------
void Core::CheckpointInst::ResetInstance()
{
mID = -1;
mFlags = ENF_DEFAULT;
}
// ------------------------------------------------------------------------------------------------
void Core::KeybindInst::ResetInstance()
{
mID = -1;
mFlags = ENF_DEFAULT;
mFirst = -1;
mSecond = -1;
mThird = -1;
mRelease = -1;
}
// ------------------------------------------------------------------------------------------------
void Core::ObjectInst::ResetInstance()
{
mID = -1;
mFlags = ENF_DEFAULT;
}
// ------------------------------------------------------------------------------------------------
void Core::PickupInst::ResetInstance()
{
mID = -1;
mFlags = ENF_DEFAULT;
}
// ------------------------------------------------------------------------------------------------
void Core::PlayerInst::ResetInstance()
{
mID = -1;
mFlags = ENF_DEFAULT;
mAreas.clear();
mTrackPosition = 0;
mTrackHeading = 0;
mTrackPositionHeader = 0;
mTrackPositionPayload.Release();
mKickBanHeader = 0;
mKickBanPayload.Release();
mLastWeapon = -1;
mLastHealth = 0.0;
mLastArmour = 0.0;
mLastHeading = 0.0;
mLastPosition.Clear();
mAuthority = 0;
}
// ------------------------------------------------------------------------------------------------
void Core::VehicleInst::ResetInstance()
{
mID = -1;
mFlags = ENF_DEFAULT;
mAreas.clear();
mTrackPosition = 0;
mTrackRotation = 0;
mLastPrimaryColor = -1;
mLastSecondaryColor = -1;
mLastHealth = 0.0;
mLastPosition.Clear();
mLastRotation.Clear();
}
// ------------------------------------------------------------------------------------------------
void Core::BlipInst::InitEvents()
{
// Ignore the call if already initialized
if (!mEvents.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(DefaultVM::Get(), 4);
// Grab the table object from the stack
mEvents = LightObj(-1, DefaultVM::Get());
// Pop the table object from the stack
sq_pop(DefaultVM::Get(), 1);
// Proceed to initializing the events
InitSignalPair(mOnDestroyed, mEvents, "Destroyed");
InitSignalPair(mOnCustom, mEvents, "Custom");
}
// ------------------------------------------------------------------------------------------------
void Core::BlipInst::DropEvents()
{
ResetSignalPair(mOnDestroyed);
ResetSignalPair(mOnCustom);
mEvents.Release();
}
// ------------------------------------------------------------------------------------------------
void Core::CheckpointInst::InitEvents()
{
// Ignore the call if already initialized
if (!mEvents.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(DefaultVM::Get(), 8);
// Grab the table object from the stack
mEvents = LightObj(-1, DefaultVM::Get());
// Pop the table object from the stack
sq_pop(DefaultVM::Get(), 1);
// Proceed to initializing the events
InitSignalPair(mOnDestroyed, mEvents, "Destroyed");
InitSignalPair(mOnCustom, mEvents, "Custom");
#if SQMOD_SDK_LEAST(2, 1)
InitSignalPair(mOnStream, mEvents, "Stream");
#endif
InitSignalPair(mOnEntered, mEvents, "Entered");
InitSignalPair(mOnExited, mEvents, "Exited");
InitSignalPair(mOnWorld, mEvents, "World");
InitSignalPair(mOnRadius, mEvents, "Radius");
}
// ------------------------------------------------------------------------------------------------
void Core::CheckpointInst::DropEvents()
{
ResetSignalPair(mOnDestroyed);
ResetSignalPair(mOnCustom);
#if SQMOD_SDK_LEAST(2, 1)
ResetSignalPair(mOnStream);
#endif
ResetSignalPair(mOnEntered);
ResetSignalPair(mOnExited);
ResetSignalPair(mOnWorld);
ResetSignalPair(mOnRadius);
mEvents.Release();
}
// ------------------------------------------------------------------------------------------------
void Core::KeybindInst::InitEvents()
{
// Ignore the call if already initialized
if (!mEvents.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(DefaultVM::Get(), 8);
// Grab the table object from the stack
mEvents = LightObj(-1, DefaultVM::Get());
// Pop the table object from the stack
sq_pop(DefaultVM::Get(), 1);
// Proceed to initializing the events
InitSignalPair(mOnDestroyed, mEvents, "Destroyed");
InitSignalPair(mOnCustom, mEvents, "Custom");
InitSignalPair(mOnKeyPress, mEvents, "KeyPress");
InitSignalPair(mOnKeyRelease, mEvents, "KeyRelease");
}
// ------------------------------------------------------------------------------------------------
void Core::KeybindInst::DropEvents()
{
ResetSignalPair(mOnDestroyed);
ResetSignalPair(mOnCustom);
ResetSignalPair(mOnKeyPress);
ResetSignalPair(mOnKeyRelease);
mEvents.Release();
}
// ------------------------------------------------------------------------------------------------
void Core::ObjectInst::InitEvents()
{
// Ignore the call if already initialized
if (!mEvents.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(DefaultVM::Get(), 12);
// Grab the table object from the stack
mEvents = LightObj(-1, DefaultVM::Get());
// Pop the table object from the stack
sq_pop(DefaultVM::Get(), 1);
// Proceed to initializing the events
InitSignalPair(mOnDestroyed, mEvents, "Destroyed");
InitSignalPair(mOnCustom, mEvents, "Custom");
#if SQMOD_SDK_LEAST(2, 1)
InitSignalPair(mOnStream, mEvents, "Stream");
#endif
InitSignalPair(mOnShot, mEvents, "Shot");
InitSignalPair(mOnTouched, mEvents, "Touched");
InitSignalPair(mOnWorld, mEvents, "World");
InitSignalPair(mOnAlpha, mEvents, "Alpha");
InitSignalPair(mOnReport, mEvents, "Report");
}
// ------------------------------------------------------------------------------------------------
void Core::ObjectInst::DropEvents()
{
ResetSignalPair(mOnDestroyed);
ResetSignalPair(mOnCustom);
#if SQMOD_SDK_LEAST(2, 1)
ResetSignalPair(mOnStream);
#endif
ResetSignalPair(mOnShot);
ResetSignalPair(mOnTouched);
ResetSignalPair(mOnWorld);
ResetSignalPair(mOnAlpha);
ResetSignalPair(mOnReport);
mEvents.Release();
}
// ------------------------------------------------------------------------------------------------
void Core::PickupInst::InitEvents()
{
// Ignore the call if already initialized
if (!mEvents.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(DefaultVM::Get(), 16);
// Grab the table object from the stack
mEvents = LightObj(-1, DefaultVM::Get());
// Pop the table object from the stack
sq_pop(DefaultVM::Get(), 1);
// Proceed to initializing the events
InitSignalPair(mOnDestroyed, mEvents, "Destroyed");
InitSignalPair(mOnCustom, mEvents, "Custom");
#if SQMOD_SDK_LEAST(2, 1)
InitSignalPair(mOnStream, mEvents, "Stream");
#endif
InitSignalPair(mOnRespawn, mEvents, "Respawn");
InitSignalPair(mOnClaimed, mEvents, "Claimed");
InitSignalPair(mOnCollected, mEvents, "Collected");
InitSignalPair(mOnWorld, mEvents, "World");
InitSignalPair(mOnAlpha, mEvents, "Alpha");
InitSignalPair(mOnAutomatic, mEvents, "Automatic");
InitSignalPair(mOnAutoTimer, mEvents, "AutoTimer");
InitSignalPair(mOnOption, mEvents, "Option");
}
// ------------------------------------------------------------------------------------------------
void Core::PickupInst::DropEvents()
{
ResetSignalPair(mOnDestroyed);
ResetSignalPair(mOnCustom);
#if SQMOD_SDK_LEAST(2, 1)
ResetSignalPair(mOnStream);
#endif
ResetSignalPair(mOnRespawn);
ResetSignalPair(mOnClaimed);
ResetSignalPair(mOnCollected);
ResetSignalPair(mOnWorld);
ResetSignalPair(mOnAlpha);
ResetSignalPair(mOnAutomatic);
ResetSignalPair(mOnAutoTimer);
ResetSignalPair(mOnOption);
mEvents.Release();
}
// ------------------------------------------------------------------------------------------------
void Core::PlayerInst::InitEvents()
{
// Ignore the call if already initialized
if (!mEvents.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(DefaultVM::Get(), 86);
// Grab the table object from the stack
mEvents = LightObj(-1, DefaultVM::Get());
// Pop the table object from the stack
sq_pop(DefaultVM::Get(), 1);
// Proceed to initializing the events
InitSignalPair(mOnDestroyed, mEvents, "Destroyed");
InitSignalPair(mOnCustom, mEvents, "Custom");
#if SQMOD_SDK_LEAST(2, 1)
InitSignalPair(mOnStream, mEvents, "Stream");
#endif
InitSignalPair(mOnRequestClass, mEvents, "RequestClass");
InitSignalPair(mOnRequestSpawn, mEvents, "RequestSpawn");
InitSignalPair(mOnSpawn, mEvents, "Spawn");
InitSignalPair(mOnWasted, mEvents, "Wasted");
InitSignalPair(mOnKilled, mEvents, "Killed");
InitSignalPair(mOnEmbarking, mEvents, "Embarking");
InitSignalPair(mOnEmbarked, mEvents, "Embarked");
InitSignalPair(mOnDisembark, mEvents, "Disembark");
InitSignalPair(mOnRename, mEvents, "Rename");
InitSignalPair(mOnState, mEvents, "State");
InitSignalPair(mOnStateNone, mEvents, "StateNone");
InitSignalPair(mOnStateNormal, mEvents, "StateNormal");
InitSignalPair(mOnStateAim, mEvents, "StateAim");
InitSignalPair(mOnStateDriver, mEvents, "StateDriver");
InitSignalPair(mOnStatePassenger, mEvents, "StatePassenger");
InitSignalPair(mOnStateEnterDriver, mEvents, "StateEnterDriver");
InitSignalPair(mOnStateEnterPassenger, mEvents, "StateEnterPassenger");
InitSignalPair(mOnStateExit, mEvents, "StateExit");
InitSignalPair(mOnStateUnspawned, mEvents, "StateUnspawned");
InitSignalPair(mOnAction, mEvents, "Action");
InitSignalPair(mOnActionNone, mEvents, "ActionNone");
InitSignalPair(mOnActionNormal, mEvents, "ActionNormal");
InitSignalPair(mOnActionAiming, mEvents, "ActionAiming");
InitSignalPair(mOnActionShooting, mEvents, "ActionShooting");
InitSignalPair(mOnActionJumping, mEvents, "ActionJumping");
InitSignalPair(mOnActionLieDown, mEvents, "ActionLieDown");
InitSignalPair(mOnActionGettingUp, mEvents, "ActionGettingUp");
InitSignalPair(mOnActionJumpVehicle, mEvents, "ActionJumpVehicle");
InitSignalPair(mOnActionDriving, mEvents, "ActionDriving");
InitSignalPair(mOnActionDying, mEvents, "ActionDying");
InitSignalPair(mOnActionWasted, mEvents, "ActionWasted");
InitSignalPair(mOnActionEmbarking, mEvents, "ActionEmbarking");
InitSignalPair(mOnActionDisembarking, mEvents, "ActionDisembarking");
InitSignalPair(mOnBurning, mEvents, "Burning");
InitSignalPair(mOnCrouching, mEvents, "Crouching");
InitSignalPair(mOnGameKeys, mEvents, "GameKeys");
InitSignalPair(mOnStartTyping, mEvents, "StartTyping");
InitSignalPair(mOnStopTyping, mEvents, "StopTyping");
InitSignalPair(mOnAway, mEvents, "Away");
InitSignalPair(mOnMessage, mEvents, "Message");
InitSignalPair(mOnCommand, mEvents, "Command");
InitSignalPair(mOnPrivateMessage, mEvents, "PrivateMessage");
InitSignalPair(mOnKeyPress, mEvents, "KeyPress");
InitSignalPair(mOnKeyRelease, mEvents, "KeyRelease");
InitSignalPair(mOnSpectate, mEvents, "Spectate");
InitSignalPair(mOnUnspectate, mEvents, "Unspectate");
InitSignalPair(mOnCrashreport, mEvents, "Crashreport");
InitSignalPair(mOnModuleList, mEvents, "ModuleList");
InitSignalPair(mOnObjectShot, mEvents, "ObjectShot");
InitSignalPair(mOnObjectTouched, mEvents, "ObjectTouched");
InitSignalPair(mOnPickupClaimed, mEvents, "PickupClaimed");
InitSignalPair(mOnPickupCollected, mEvents, "PickupCollected");
InitSignalPair(mOnCheckpointEntered, mEvents, "CheckpointEntered");
InitSignalPair(mOnCheckpointExited, mEvents, "CheckpointExited");
InitSignalPair(mOnClientScriptData, mEvents, "ClientScriptData");
#if SQMOD_SDK_LEAST(2, 1)
InitSignalPair(mOnEntityStream, mEvents, "EntityStream");
#endif
InitSignalPair(mOnUpdate, mEvents, "Update");
InitSignalPair(mOnHealth, mEvents, "Health");
InitSignalPair(mOnArmour, mEvents, "Armour");
InitSignalPair(mOnWeapon, mEvents, "Weapon");
InitSignalPair(mOnHeading, mEvents, "Heading");
InitSignalPair(mOnPosition, mEvents, "Position");
InitSignalPair(mOnOption, mEvents, "Option");
InitSignalPair(mOnAdmin, mEvents, "Admin");
InitSignalPair(mOnWorld, mEvents, "World");
InitSignalPair(mOnTeam, mEvents, "Team");
InitSignalPair(mOnSkin, mEvents, "Skin");
InitSignalPair(mOnMoney, mEvents, "Money");
InitSignalPair(mOnScore, mEvents, "Score");
InitSignalPair(mOnWantedLevel, mEvents, "WantedLevel");
InitSignalPair(mOnImmunity, mEvents, "Immunity");
InitSignalPair(mOnAlpha, mEvents, "Alpha");
InitSignalPair(mOnEnterArea, mEvents, "EnterArea");
InitSignalPair(mOnLeaveArea, mEvents, "LeaveArea");
}
// ------------------------------------------------------------------------------------------------
void Core::PlayerInst::DropEvents()
{
ResetSignalPair(mOnDestroyed);
ResetSignalPair(mOnCustom);
#if SQMOD_SDK_LEAST(2, 1)
ResetSignalPair(mOnStream);
#endif
ResetSignalPair(mOnRequestClass);
ResetSignalPair(mOnRequestSpawn);
ResetSignalPair(mOnSpawn);
ResetSignalPair(mOnWasted);
ResetSignalPair(mOnKilled);
ResetSignalPair(mOnEmbarking);
ResetSignalPair(mOnEmbarked);
ResetSignalPair(mOnDisembark);
ResetSignalPair(mOnRename);
ResetSignalPair(mOnState);
ResetSignalPair(mOnStateNone);
ResetSignalPair(mOnStateNormal);
ResetSignalPair(mOnStateAim);
ResetSignalPair(mOnStateDriver);
ResetSignalPair(mOnStatePassenger);
ResetSignalPair(mOnStateEnterDriver);
ResetSignalPair(mOnStateEnterPassenger);
ResetSignalPair(mOnStateExit);
ResetSignalPair(mOnStateUnspawned);
ResetSignalPair(mOnAction);
ResetSignalPair(mOnActionNone);
ResetSignalPair(mOnActionNormal);
ResetSignalPair(mOnActionAiming);
ResetSignalPair(mOnActionShooting);
ResetSignalPair(mOnActionJumping);
ResetSignalPair(mOnActionLieDown);
ResetSignalPair(mOnActionGettingUp);
ResetSignalPair(mOnActionJumpVehicle);
ResetSignalPair(mOnActionDriving);
ResetSignalPair(mOnActionDying);
ResetSignalPair(mOnActionWasted);
ResetSignalPair(mOnActionEmbarking);
ResetSignalPair(mOnActionDisembarking);
ResetSignalPair(mOnBurning);
ResetSignalPair(mOnCrouching);
ResetSignalPair(mOnGameKeys);
ResetSignalPair(mOnStartTyping);
ResetSignalPair(mOnStopTyping);
ResetSignalPair(mOnAway);
ResetSignalPair(mOnMessage);
ResetSignalPair(mOnCommand);
ResetSignalPair(mOnPrivateMessage);
ResetSignalPair(mOnKeyPress);
ResetSignalPair(mOnKeyRelease);
ResetSignalPair(mOnSpectate);
ResetSignalPair(mOnUnspectate);
ResetSignalPair(mOnCrashreport);
ResetSignalPair(mOnModuleList);
ResetSignalPair(mOnObjectShot);
ResetSignalPair(mOnObjectTouched);
ResetSignalPair(mOnPickupClaimed);
ResetSignalPair(mOnPickupCollected);
ResetSignalPair(mOnCheckpointEntered);
ResetSignalPair(mOnCheckpointExited);
ResetSignalPair(mOnClientScriptData);
#if SQMOD_SDK_LEAST(2, 1)
ResetSignalPair(mOnEntityStream);
#endif
ResetSignalPair(mOnUpdate);
ResetSignalPair(mOnHealth);
ResetSignalPair(mOnArmour);
ResetSignalPair(mOnWeapon);
ResetSignalPair(mOnHeading);
ResetSignalPair(mOnPosition);
ResetSignalPair(mOnOption);
ResetSignalPair(mOnAdmin);
ResetSignalPair(mOnWorld);
ResetSignalPair(mOnTeam);
ResetSignalPair(mOnSkin);
ResetSignalPair(mOnMoney);
ResetSignalPair(mOnScore);
ResetSignalPair(mOnWantedLevel);
ResetSignalPair(mOnImmunity);
ResetSignalPair(mOnAlpha);
ResetSignalPair(mOnEnterArea);
ResetSignalPair(mOnLeaveArea);
mEvents.Release();
}
// ------------------------------------------------------------------------------------------------
void Core::VehicleInst::InitEvents()
{
// Ignore the call if already initialized
if (!mEvents.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(DefaultVM::Get(), 32);
// Grab the table object from the stack
mEvents = LightObj(-1, DefaultVM::Get());
// Pop the table object from the stack
sq_pop(DefaultVM::Get(), 1);
// Proceed to initializing the events
InitSignalPair(mOnDestroyed, mEvents, "Destroyed");
InitSignalPair(mOnCustom, mEvents, "Custom");
#if SQMOD_SDK_LEAST(2, 1)
InitSignalPair(mOnStream, mEvents, "Stream");
#endif
InitSignalPair(mOnEmbarking, mEvents, "Embarking");
InitSignalPair(mOnEmbarked, mEvents, "Embarked");
InitSignalPair(mOnDisembark, mEvents, "Disembark");
InitSignalPair(mOnExplode, mEvents, "Explode");
InitSignalPair(mOnRespawn, mEvents, "Respawn");
InitSignalPair(mOnUpdate, mEvents, "Update");
InitSignalPair(mOnColor, mEvents, "Color");
InitSignalPair(mOnHealth, mEvents, "Health");
InitSignalPair(mOnPosition, mEvents, "Position");
InitSignalPair(mOnRotation, mEvents, "Rotation");
InitSignalPair(mOnOption, mEvents, "Option");
InitSignalPair(mOnWorld, mEvents, "World");
InitSignalPair(mOnImmunity, mEvents, "Immunity");
InitSignalPair(mOnPartStatus, mEvents, "PartStatus");
InitSignalPair(mOnTyreStatus, mEvents, "TyreStatus");
InitSignalPair(mOnDamageData, mEvents, "DamageData");
InitSignalPair(mOnRadio, mEvents, "Radio");
InitSignalPair(mOnHandlingRule, mEvents, "HandlingRule");
InitSignalPair(mOnEnterArea, mEvents, "EnterArea");
InitSignalPair(mOnLeaveArea, mEvents, "LeaveArea");
}
// ------------------------------------------------------------------------------------------------
void Core::VehicleInst::DropEvents()
{
ResetSignalPair(mOnDestroyed);
ResetSignalPair(mOnCustom);
#if SQMOD_SDK_LEAST(2, 1)
ResetSignalPair(mOnStream);
#endif
ResetSignalPair(mOnEmbarking);
ResetSignalPair(mOnEmbarked);
ResetSignalPair(mOnDisembark);
ResetSignalPair(mOnExplode);
ResetSignalPair(mOnRespawn);
ResetSignalPair(mOnUpdate);
ResetSignalPair(mOnColor);
ResetSignalPair(mOnHealth);
ResetSignalPair(mOnPosition);
ResetSignalPair(mOnRotation);
ResetSignalPair(mOnOption);
ResetSignalPair(mOnWorld);
ResetSignalPair(mOnImmunity);
ResetSignalPair(mOnPartStatus);
ResetSignalPair(mOnTyreStatus);
ResetSignalPair(mOnDamageData);
ResetSignalPair(mOnRadio);
ResetSignalPair(mOnHandlingRule);
ResetSignalPair(mOnEnterArea);
ResetSignalPair(mOnLeaveArea);
mEvents.Release();
}
} // Namespace:: SqMod

345
module/Core/Utils.inc Normal file
View File

@ -0,0 +1,345 @@
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void Core::ClearContainer(EntityType type)
{
switch (type)
{
case ENT_BLIP:
{
m_Blips.clear();
} break;
case ENT_CHECKPOINT:
{
m_Checkpoints.clear();
} break;
case ENT_KEYBIND:
{
m_Keybinds.clear();
} break;
case ENT_OBJECT:
{
m_Objects.clear();
} break;
case ENT_PICKUP:
{
m_Pickups.clear();
} break;
case ENT_PLAYER:
{
m_Players.clear();
} break;
case ENT_VEHICLE:
{
m_Vehicles.clear();
} break;
default: STHROWF("Cannot clear unknown entity type container");
}
}
// ------------------------------------------------------------------------------------------------
void Core::InitEvents()
{
// Ignore the call if already initialized
if (!m_Events.IsNull())
{
return;
}
// Create a new table on the stack
sq_newtableex(DefaultVM::Get(), 128);
// Grab the table object from the stack
m_Events = LightObj(-1, DefaultVM::Get());
// Pop the table object from the stack
sq_pop(DefaultVM::Get(), 1);
// Proceed to initializing the events
InitSignalPair(mOnCustomEvent, m_Events, "CustomEvent");
InitSignalPair(mOnBlipCreated, m_Events, "BlipCreated");
InitSignalPair(mOnCheckpointCreated, m_Events, "CheckpointCreated");
InitSignalPair(mOnKeybindCreated, m_Events, "KeybindCreated");
InitSignalPair(mOnObjectCreated, m_Events, "ObjectCreated");
InitSignalPair(mOnPickupCreated, m_Events, "PickupCreated");
InitSignalPair(mOnPlayerCreated, m_Events, "PlayerCreated");
InitSignalPair(mOnVehicleCreated, m_Events, "VehicleCreated");
InitSignalPair(mOnBlipDestroyed, m_Events, "BlipDestroyed");
InitSignalPair(mOnCheckpointDestroyed, m_Events, "CheckpointDestroyed");
InitSignalPair(mOnKeybindDestroyed, m_Events, "KeybindDestroyed");
InitSignalPair(mOnObjectDestroyed, m_Events, "ObjectDestroyed");
InitSignalPair(mOnPickupDestroyed, m_Events, "PickupDestroyed");
InitSignalPair(mOnPlayerDestroyed, m_Events, "PlayerDestroyed");
InitSignalPair(mOnVehicleDestroyed, m_Events, "VehicleDestroyed");
InitSignalPair(mOnBlipCustom, m_Events, "BlipCustom");
InitSignalPair(mOnCheckpointCustom, m_Events, "CheckpointCustom");
InitSignalPair(mOnKeybindCustom, m_Events, "KeybindCustom");
InitSignalPair(mOnObjectCustom, m_Events, "ObjectCustom");
InitSignalPair(mOnPickupCustom, m_Events, "PickupCustom");
InitSignalPair(mOnPlayerCustom, m_Events, "PlayerCustom");
InitSignalPair(mOnVehicleCustom, m_Events, "VehicleCustom");
#if SQMOD_SDK_LEAST(2, 1)
InitSignalPair(mOnCheckpointStream, m_Events, "CheckpointStream");
InitSignalPair(mOnObjectStream, m_Events, "ObjectStream");
InitSignalPair(mOnPickupStream, m_Events, "PickupStream");
InitSignalPair(mOnPlayerStream, m_Events, "PlayerStream");
InitSignalPair(mOnVehicleStream, m_Events, "VehicleStream");
#endif
InitSignalPair(mOnServerStartup, m_Events, "ServerStartup");
InitSignalPair(mOnServerShutdown, m_Events, "ServerShutdown");
InitSignalPair(mOnServerFrame, m_Events, "ServerFrame");
InitSignalPair(mOnIncomingConnection, m_Events, "IncomingConnection");
InitSignalPair(mOnPlayerRequestClass, m_Events, "PlayerRequestClass");
InitSignalPair(mOnPlayerRequestSpawn, m_Events, "PlayerRequestSpawn");
InitSignalPair(mOnPlayerSpawn, m_Events, "PlayerSpawn");
InitSignalPair(mOnPlayerWasted, m_Events, "PlayerWasted");
InitSignalPair(mOnPlayerKilled, m_Events, "PlayerKilled");
InitSignalPair(mOnPlayerEmbarking, m_Events, "PlayerEmbarking");
InitSignalPair(mOnPlayerEmbarked, m_Events, "PlayerEmbarked");
InitSignalPair(mOnPlayerDisembark, m_Events, "PlayerDisembark");
InitSignalPair(mOnPlayerRename, m_Events, "PlayerRename");
InitSignalPair(mOnPlayerState, m_Events, "PlayerState");
InitSignalPair(mOnStateNone, m_Events, "StateNone");
InitSignalPair(mOnStateNormal, m_Events, "StateNormal");
InitSignalPair(mOnStateAim, m_Events, "StateAim");
InitSignalPair(mOnStateDriver, m_Events, "StateDriver");
InitSignalPair(mOnStatePassenger, m_Events, "StatePassenger");
InitSignalPair(mOnStateEnterDriver, m_Events, "StateEnterDriver");
InitSignalPair(mOnStateEnterPassenger, m_Events, "StateEnterPassenger");
InitSignalPair(mOnStateExit, m_Events, "StateExit");
InitSignalPair(mOnStateUnspawned, m_Events, "StateUnspawned");
InitSignalPair(mOnPlayerAction, m_Events, "PlayerAction");
InitSignalPair(mOnActionNone, m_Events, "ActionNone");
InitSignalPair(mOnActionNormal, m_Events, "ActionNormal");
InitSignalPair(mOnActionAiming, m_Events, "ActionAiming");
InitSignalPair(mOnActionShooting, m_Events, "ActionShooting");
InitSignalPair(mOnActionJumping, m_Events, "ActionJumping");
InitSignalPair(mOnActionLieDown, m_Events, "ActionLieDown");
InitSignalPair(mOnActionGettingUp, m_Events, "ActionGettingUp");
InitSignalPair(mOnActionJumpVehicle, m_Events, "ActionJumpVehicle");
InitSignalPair(mOnActionDriving, m_Events, "ActionDriving");
InitSignalPair(mOnActionDying, m_Events, "ActionDying");
InitSignalPair(mOnActionWasted, m_Events, "ActionWasted");
InitSignalPair(mOnActionEmbarking, m_Events, "ActionEmbarking");
InitSignalPair(mOnActionDisembarking, m_Events, "ActionDisembarking");
InitSignalPair(mOnPlayerBurning, m_Events, "PlayerBurning");
InitSignalPair(mOnPlayerCrouching, m_Events, "PlayerCrouching");
InitSignalPair(mOnPlayerGameKeys, m_Events, "PlayerGameKeys");
InitSignalPair(mOnPlayerStartTyping, m_Events, "PlayerStartTyping");
InitSignalPair(mOnPlayerStopTyping, m_Events, "PlayerStopTyping");
InitSignalPair(mOnPlayerAway, m_Events, "PlayerAway");
InitSignalPair(mOnPlayerMessage, m_Events, "PlayerMessage");
InitSignalPair(mOnPlayerCommand, m_Events, "PlayerCommand");
InitSignalPair(mOnPlayerPrivateMessage, m_Events, "PlayerPrivateMessage");
InitSignalPair(mOnPlayerKeyPress, m_Events, "PlayerKeyPress");
InitSignalPair(mOnPlayerKeyRelease, m_Events, "PlayerKeyRelease");
InitSignalPair(mOnPlayerSpectate, m_Events, "PlayerSpectate");
InitSignalPair(mOnPlayerUnspectate, m_Events, "PlayerUnspectate");
InitSignalPair(mOnPlayerCrashreport, m_Events, "PlayerCrashreport");
InitSignalPair(mOnPlayerModuleList, m_Events, "PlayerModuleList");
InitSignalPair(mOnVehicleExplode, m_Events, "VehicleExplode");
InitSignalPair(mOnVehicleRespawn, m_Events, "VehicleRespawn");
InitSignalPair(mOnObjectShot, m_Events, "ObjectShot");
InitSignalPair(mOnObjectTouched, m_Events, "ObjectTouched");
InitSignalPair(mOnObjectWorld, m_Events, "ObjectWorld");
InitSignalPair(mOnObjectAlpha, m_Events, "ObjectAlpha");
InitSignalPair(mOnObjectReport, m_Events, "ObjectReport");
InitSignalPair(mOnPickupClaimed, m_Events, "PickupClaimed");
InitSignalPair(mOnPickupCollected, m_Events, "PickupCollected");
InitSignalPair(mOnPickupRespawn, m_Events, "PickupRespawn");
InitSignalPair(mOnPickupWorld, m_Events, "PickupWorld");
InitSignalPair(mOnPickupAlpha, m_Events, "PickupAlpha");
InitSignalPair(mOnPickupAutomatic, m_Events, "PickupAutomatic");
InitSignalPair(mOnPickupAutoTimer, m_Events, "PickupAutoTimer");
InitSignalPair(mOnPickupOption, m_Events, "PickupOption");
InitSignalPair(mOnCheckpointEntered, m_Events, "CheckpointEntered");
InitSignalPair(mOnCheckpointExited, m_Events, "CheckpointExited");
InitSignalPair(mOnCheckpointWorld, m_Events, "CheckpointWorld");
InitSignalPair(mOnCheckpointRadius, m_Events, "CheckpointRadius");
InitSignalPair(mOnEntityPool, m_Events, "EntityPool");
InitSignalPair(mOnClientScriptData, m_Events, "ClientScriptData");
InitSignalPair(mOnPlayerUpdate, m_Events, "PlayerUpdate");
InitSignalPair(mOnVehicleUpdate, m_Events, "VehicleUpdate");
InitSignalPair(mOnPlayerHealth, m_Events, "PlayerHealth");
InitSignalPair(mOnPlayerArmour, m_Events, "PlayerArmour");
InitSignalPair(mOnPlayerWeapon, m_Events, "PlayerWeapon");
InitSignalPair(mOnPlayerHeading, m_Events, "PlayerHeading");
InitSignalPair(mOnPlayerPosition, m_Events, "PlayerPosition");
InitSignalPair(mOnPlayerOption, m_Events, "PlayerOption");
InitSignalPair(mOnPlayerAdmin, m_Events, "PlayerAdmin");
InitSignalPair(mOnPlayerWorld, m_Events, "PlayerWorld");
InitSignalPair(mOnPlayerTeam, m_Events, "PlayerTeam");
InitSignalPair(mOnPlayerSkin, m_Events, "PlayerSkin");
InitSignalPair(mOnPlayerMoney, m_Events, "PlayerMoney");
InitSignalPair(mOnPlayerScore, m_Events, "PlayerScore");
InitSignalPair(mOnPlayerWantedLevel, m_Events, "PlayerWantedLevel");
InitSignalPair(mOnPlayerImmunity, m_Events, "PlayerImmunity");
InitSignalPair(mOnPlayerAlpha, m_Events, "PlayerAlpha");
InitSignalPair(mOnPlayerEnterArea, m_Events, "PlayerEnterArea");
InitSignalPair(mOnPlayerLeaveArea, m_Events, "PlayerLeaveArea");
InitSignalPair(mOnVehicleColor, m_Events, "VehicleColor");
InitSignalPair(mOnVehicleHealth, m_Events, "VehicleHealth");
InitSignalPair(mOnVehiclePosition, m_Events, "VehiclePosition");
InitSignalPair(mOnVehicleRotation, m_Events, "VehicleRotation");
InitSignalPair(mOnVehicleOption, m_Events, "VehicleOption");
InitSignalPair(mOnVehicleWorld, m_Events, "VehicleWorld");
InitSignalPair(mOnVehicleImmunity, m_Events, "VehicleImmunity");
InitSignalPair(mOnVehiclePartStatus, m_Events, "VehiclePartStatus");
InitSignalPair(mOnVehicleTyreStatus, m_Events, "VehicleTyreStatus");
InitSignalPair(mOnVehicleDamageData, m_Events, "VehicleDamageData");
InitSignalPair(mOnVehicleRadio, m_Events, "VehicleRadio");
InitSignalPair(mOnVehicleHandlingRule, m_Events, "VehicleHandlingRule");
InitSignalPair(mOnVehicleEnterArea, m_Events, "VehicleEnterArea");
InitSignalPair(mOnVehicleLeaveArea, m_Events, "VehicleLeaveArea");
#if SQMOD_SDK_LEAST(2, 1)
InitSignalPair(mOnEntityStream, m_Events, "EntityStream");
#endif
InitSignalPair(mOnServerOption, m_Events, "ServerOption");
InitSignalPair(mOnScriptReload, m_Events, "ScriptReload");
InitSignalPair(mOnScriptLoaded, m_Events, "ScriptLoaded");
}
// ------------------------------------------------------------------------------------------------
void Core::DropEvents()
{
ResetSignalPair(mOnCustomEvent);
ResetSignalPair(mOnBlipCreated);
ResetSignalPair(mOnCheckpointCreated);
ResetSignalPair(mOnKeybindCreated);
ResetSignalPair(mOnObjectCreated);
ResetSignalPair(mOnPickupCreated);
ResetSignalPair(mOnPlayerCreated);
ResetSignalPair(mOnVehicleCreated);
ResetSignalPair(mOnBlipDestroyed);
ResetSignalPair(mOnCheckpointDestroyed);
ResetSignalPair(mOnKeybindDestroyed);
ResetSignalPair(mOnObjectDestroyed);
ResetSignalPair(mOnPickupDestroyed);
ResetSignalPair(mOnPlayerDestroyed);
ResetSignalPair(mOnVehicleDestroyed);
ResetSignalPair(mOnBlipCustom);
ResetSignalPair(mOnCheckpointCustom);
ResetSignalPair(mOnKeybindCustom);
ResetSignalPair(mOnObjectCustom);
ResetSignalPair(mOnPickupCustom);
ResetSignalPair(mOnPlayerCustom);
ResetSignalPair(mOnVehicleCustom);
#if SQMOD_SDK_LEAST(2, 1)
ResetSignalPair(mOnCheckpointStream);
ResetSignalPair(mOnObjectStream);
ResetSignalPair(mOnPickupStream);
ResetSignalPair(mOnPlayerStream);
ResetSignalPair(mOnVehicleStream);
#endif
ResetSignalPair(mOnServerStartup);
ResetSignalPair(mOnServerShutdown);
ResetSignalPair(mOnServerFrame);
ResetSignalPair(mOnIncomingConnection);
ResetSignalPair(mOnPlayerRequestClass);
ResetSignalPair(mOnPlayerRequestSpawn);
ResetSignalPair(mOnPlayerSpawn);
ResetSignalPair(mOnPlayerWasted);
ResetSignalPair(mOnPlayerKilled);
ResetSignalPair(mOnPlayerEmbarking);
ResetSignalPair(mOnPlayerEmbarked);
ResetSignalPair(mOnPlayerDisembark);
ResetSignalPair(mOnPlayerRename);
ResetSignalPair(mOnPlayerState);
ResetSignalPair(mOnStateNone);
ResetSignalPair(mOnStateNormal);
ResetSignalPair(mOnStateAim);
ResetSignalPair(mOnStateDriver);
ResetSignalPair(mOnStatePassenger);
ResetSignalPair(mOnStateEnterDriver);
ResetSignalPair(mOnStateEnterPassenger);
ResetSignalPair(mOnStateExit);
ResetSignalPair(mOnStateUnspawned);
ResetSignalPair(mOnPlayerAction);
ResetSignalPair(mOnActionNone);
ResetSignalPair(mOnActionNormal);
ResetSignalPair(mOnActionAiming);
ResetSignalPair(mOnActionShooting);
ResetSignalPair(mOnActionJumping);
ResetSignalPair(mOnActionLieDown);
ResetSignalPair(mOnActionGettingUp);
ResetSignalPair(mOnActionJumpVehicle);
ResetSignalPair(mOnActionDriving);
ResetSignalPair(mOnActionDying);
ResetSignalPair(mOnActionWasted);
ResetSignalPair(mOnActionEmbarking);
ResetSignalPair(mOnActionDisembarking);
ResetSignalPair(mOnPlayerBurning);
ResetSignalPair(mOnPlayerCrouching);
ResetSignalPair(mOnPlayerGameKeys);
ResetSignalPair(mOnPlayerStartTyping);
ResetSignalPair(mOnPlayerStopTyping);
ResetSignalPair(mOnPlayerAway);
ResetSignalPair(mOnPlayerMessage);
ResetSignalPair(mOnPlayerCommand);
ResetSignalPair(mOnPlayerPrivateMessage);
ResetSignalPair(mOnPlayerKeyPress);
ResetSignalPair(mOnPlayerKeyRelease);
ResetSignalPair(mOnPlayerSpectate);
ResetSignalPair(mOnPlayerUnspectate);
ResetSignalPair(mOnPlayerCrashreport);
ResetSignalPair(mOnPlayerModuleList);
ResetSignalPair(mOnVehicleExplode);
ResetSignalPair(mOnVehicleRespawn);
ResetSignalPair(mOnObjectShot);
ResetSignalPair(mOnObjectTouched);
ResetSignalPair(mOnObjectWorld);
ResetSignalPair(mOnObjectAlpha);
ResetSignalPair(mOnObjectReport);
ResetSignalPair(mOnPickupClaimed);
ResetSignalPair(mOnPickupCollected);
ResetSignalPair(mOnPickupRespawn);
ResetSignalPair(mOnPickupWorld);
ResetSignalPair(mOnPickupAlpha);
ResetSignalPair(mOnPickupAutomatic);
ResetSignalPair(mOnPickupAutoTimer);
ResetSignalPair(mOnPickupOption);
ResetSignalPair(mOnCheckpointEntered);
ResetSignalPair(mOnCheckpointExited);
ResetSignalPair(mOnCheckpointWorld);
ResetSignalPair(mOnCheckpointRadius);
ResetSignalPair(mOnEntityPool);
ResetSignalPair(mOnClientScriptData);
ResetSignalPair(mOnPlayerUpdate);
ResetSignalPair(mOnVehicleUpdate);
ResetSignalPair(mOnPlayerHealth);
ResetSignalPair(mOnPlayerArmour);
ResetSignalPair(mOnPlayerWeapon);
ResetSignalPair(mOnPlayerHeading);
ResetSignalPair(mOnPlayerPosition);
ResetSignalPair(mOnPlayerOption);
ResetSignalPair(mOnPlayerAdmin);
ResetSignalPair(mOnPlayerWorld);
ResetSignalPair(mOnPlayerTeam);
ResetSignalPair(mOnPlayerSkin);
ResetSignalPair(mOnPlayerMoney);
ResetSignalPair(mOnPlayerScore);
ResetSignalPair(mOnPlayerWantedLevel);
ResetSignalPair(mOnPlayerImmunity);
ResetSignalPair(mOnPlayerAlpha);
ResetSignalPair(mOnPlayerEnterArea);
ResetSignalPair(mOnPlayerLeaveArea);
ResetSignalPair(mOnVehicleColor);
ResetSignalPair(mOnVehicleHealth);
ResetSignalPair(mOnVehiclePosition);
ResetSignalPair(mOnVehicleRotation);
ResetSignalPair(mOnVehicleOption);
ResetSignalPair(mOnVehicleWorld);
ResetSignalPair(mOnVehicleImmunity);
ResetSignalPair(mOnVehiclePartStatus);
ResetSignalPair(mOnVehicleTyreStatus);
ResetSignalPair(mOnVehicleDamageData);
ResetSignalPair(mOnVehicleRadio);
ResetSignalPair(mOnVehicleHandlingRule);
ResetSignalPair(mOnVehicleEnterArea);
ResetSignalPair(mOnVehicleLeaveArea);
#if SQMOD_SDK_LEAST(2, 1)
ResetSignalPair(mOnEntityStream);
#endif
ResetSignalPair(mOnServerOption);
ResetSignalPair(mOnScriptReload);
ResetSignalPair(mOnScriptLoaded);
m_Events.Release();
}
} // Namespace:: SqMod

353
module/Entity/Blip.cpp Normal file
View File

@ -0,0 +1,353 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Blip.hpp"
#include "Core.hpp"
#include "Misc/Tasks.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqBlip"))
// ------------------------------------------------------------------------------------------------
const Int32 CBlip::Max = SQMOD_BLIP_POOL;
// ------------------------------------------------------------------------------------------------
SQInteger CBlip::SqGetNull(HSQUIRRELVM vm)
{
sq_pushobject(vm, Core::Get().GetNullBlip().GetObject());
return 1;
}
// ------------------------------------------------------------------------------------------------
LightObj & CBlip::GetNull()
{
return Core::Get().GetNullBlip();
}
// ------------------------------------------------------------------------------------------------
CBlip::CBlip(Int32 id)
: m_ID(VALID_ENTITYGETEX(id, SQMOD_BLIP_POOL))
, m_Tag(ToStrF("%d", id))
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
CBlip::~CBlip()
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
const String & CBlip::ToString() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
const String & CBlip::GetTag() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
void CBlip::SetTag(StackStrF & tag)
{
if (tag.mLen > 0)
{
m_Tag.assign(tag.mPtr, tag.mLen);
}
else
{
m_Tag.clear();
}
}
// ------------------------------------------------------------------------------------------------
CBlip & CBlip::ApplyTag(StackStrF & tag)
{
SetTag(tag);
return *this;
}
// ------------------------------------------------------------------------------------------------
LightObj & CBlip::GetData()
{
// Validate the managed identifier
Validate();
// Return the requested information
return m_Data;
}
// ------------------------------------------------------------------------------------------------
void CBlip::SetData(LightObj & data)
{
// Validate the managed identifier
Validate();
// Apply the specified value
m_Data = data;
}
// ------------------------------------------------------------------------------------------------
bool CBlip::Destroy(Int32 header, LightObj & payload)
{
// Validate the managed identifier
Validate();
// Perform the requested operation
return Core::Get().DelBlip(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
LightObj & CBlip::GetEvents() const
{
// Validate the managed identifier
Validate();
// Return the associated event table
return Core::Get().GetBlip(m_ID).mEvents;
}
// ------------------------------------------------------------------------------------------------
void CBlip::CustomEvent(Int32 header, LightObj & payload) const
{
// Validate the managed identifier
Validate();
// Perfrom the requested action
Core::Get().EmitBlipCustom(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
Int32 CBlip::GetWorld() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mWorld;
}
// ------------------------------------------------------------------------------------------------
Int32 CBlip::GetScale() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mScale;
}
// ------------------------------------------------------------------------------------------------
const Vector3 & CBlip::GetPosition() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mPosition;
}
// ------------------------------------------------------------------------------------------------
const Color4 & CBlip::GetColor() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mColor;
}
// ------------------------------------------------------------------------------------------------
Int32 CBlip::GetSprID() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mSprID;
}
// ------------------------------------------------------------------------------------------------
Float32 CBlip::GetPositionX() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mPosition.x;
}
// ------------------------------------------------------------------------------------------------
Float32 CBlip::GetPositionY() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mPosition.y;
}
// ------------------------------------------------------------------------------------------------
Float32 CBlip::GetPositionZ() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mPosition.z;
}
// ------------------------------------------------------------------------------------------------
Int32 CBlip::GetColorR() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mColor.r;
}
// ------------------------------------------------------------------------------------------------
Int32 CBlip::GetColorG() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mColor.g;
}
// ------------------------------------------------------------------------------------------------
Int32 CBlip::GetColorB() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mColor.b;
}
// ------------------------------------------------------------------------------------------------
Int32 CBlip::GetColorA() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetBlip(m_ID).mColor.a;
}
// ------------------------------------------------------------------------------------------------
static LightObj & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid)
{
return Core::Get().NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid,
Int32 header, LightObj & payload)
{
return Core::Get().NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid,
header, payload);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z,
Int32 scale, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid)
{
return Core::Get().NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid,
Int32 header, LightObj & payload)
{
return Core::Get().NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid,
header, payload);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color,
Int32 sprid)
{
return Core::Get().NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color,
Int32 sprid, Int32 header, LightObj & payload)
{
return Core::Get().NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid,
header, payload);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale,
const Color4 & color, Int32 sprid)
{
return Core::Get().NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale,
const Color4 & color, Int32 sprid, Int32 header, LightObj & payload)
{
return Core::Get().NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid,
header, payload);
}
// ================================================================================================
void Register_CBlip(HSQUIRRELVM vm)
{
RootTable(vm).Bind(Typename::Str,
Class< CBlip, NoConstructor< CBlip > >(vm, Typename::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &CBlip::ToString)
// Static Values
.SetStaticValue(_SC("MaxID"), CBlip::Max)
// Core Properties
.Prop(_SC("On"), &CBlip::GetEvents)
.Prop(_SC("ID"), &CBlip::GetID)
.Prop(_SC("Tag"), &CBlip::GetTag, &CBlip::SetTag)
.Prop(_SC("Data"), &CBlip::GetData, &CBlip::SetData)
.Prop(_SC("Active"), &CBlip::IsActive)
// Core Methods
.FmtFunc(_SC("SetTag"), &CBlip::ApplyTag)
.Func(_SC("CustomEvent"), &CBlip::CustomEvent)
// Core Overloads
.Overload< bool (CBlip::*)(void) >(_SC("Destroy"), &CBlip::Destroy)
.Overload< bool (CBlip::*)(Int32) >(_SC("Destroy"), &CBlip::Destroy)
.Overload< bool (CBlip::*)(Int32, LightObj &) >(_SC("Destroy"), &CBlip::Destroy)
// Properties
.Prop(_SC("World"), &CBlip::GetWorld)
.Prop(_SC("Scale"), &CBlip::GetScale)
.Prop(_SC("Pos"), &CBlip::GetPosition)
.Prop(_SC("Position"), &CBlip::GetPosition)
.Prop(_SC("Color"), &CBlip::GetColor)
.Prop(_SC("Colour"), &CBlip::GetColor)
.Prop(_SC("SprID"), &CBlip::GetSprID)
.Prop(_SC("PosX"), &CBlip::GetPositionX)
.Prop(_SC("PosY"), &CBlip::GetPositionY)
.Prop(_SC("PosZ"), &CBlip::GetPositionZ)
.Prop(_SC("Red"), &CBlip::GetColorR)
.Prop(_SC("Green"), &CBlip::GetColorG)
.Prop(_SC("Blue"), &CBlip::GetColorB)
.Prop(_SC("Alpha"), &CBlip::GetColorA)
// Static Overloads
.StaticOverload< LightObj & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) >
(_SC("CreateEx"), &Blip_CreateEx)
.StaticOverload< LightObj & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, LightObj &) >
(_SC("CreateEx"), &Blip_CreateEx)
.StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) >
(_SC("CreateEx"), &Blip_CreateEx)
.StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, LightObj &) >
(_SC("CreateEx"), &Blip_CreateEx)
.StaticOverload< LightObj & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32) >
(_SC("Create"), &Blip_Create)
.StaticOverload< LightObj & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, LightObj &) >
(_SC("Create"), &Blip_Create)
.StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32) >
(_SC("Create"), &Blip_Create)
.StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, LightObj &) >
(_SC("Create"), &Blip_Create)
// Raw Squirrel Methods
.SquirrelFunc(_SC("NullInst"), &CBlip::SqGetNull)
.SquirrelFunc(_SC("MakeTask"), &Tasks::MakeTask< CBlip, ENT_BLIP >)
.SquirrelFunc(_SC("DropTask"), &Tasks::DropTask< CBlip, ENT_BLIP >)
.SquirrelFunc(_SC("DoesTask"), &Tasks::DoesTask< CBlip, ENT_BLIP >)
.SquirrelFunc(_SC("FindTask"), &Tasks::FindTask< CBlip, ENT_BLIP >)
);
}
} // Namespace:: SqMod

233
module/Entity/Blip.hpp Normal file
View File

@ -0,0 +1,233 @@
#ifndef _ENTITY_BLIP_HPP_
#define _ENTITY_BLIP_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Manages a single blip entity.
*/
class CBlip
{
// --------------------------------------------------------------------------------------------
friend class Core;
private:
/* --------------------------------------------------------------------------------------------
* Identifier of the managed entity.
*/
Int32 m_ID;
/* --------------------------------------------------------------------------------------------
* User tag associated with this instance.
*/
String m_Tag;
/* --------------------------------------------------------------------------------------------
* User data associated with this instance.
*/
LightObj m_Data;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
CBlip(Int32 id);
public:
/* --------------------------------------------------------------------------------------------
* Maximum possible number that could represent an identifier for this entity type.
*/
static const Int32 Max;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
CBlip(const CBlip &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
CBlip(CBlip &&) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CBlip();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
CBlip & operator = (const CBlip &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
CBlip & operator = (CBlip &&) = delete;
/* --------------------------------------------------------------------------------------------
* See whether this instance manages a valid entity otherwise throw an exception.
*/
void Validate() const
{
if (INVALID_ENTITY(m_ID))
{
STHROWF("Invalid blip reference [%s]", m_Tag.c_str());
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static SQInteger SqGetNull(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static LightObj & GetNull();
/* --------------------------------------------------------------------------------------------
* Retrieve the identifier of the entity managed by this instance.
*/
Int32 GetID() const
{
return m_ID;
}
/* --------------------------------------------------------------------------------------------
* Check whether this instance manages a valid entity.
*/
bool IsActive() const
{
return VALID_ENTITY(m_ID);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user tag.
*/
const String & GetTag() const;
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
void SetTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
CBlip & ApplyTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user data.
*/
LightObj & GetData();
/* --------------------------------------------------------------------------------------------
* Modify the associated user data.
*/
void SetData(LightObj & data);
/* --------------------------------------------------------------------------------------------
* Destroy the managed blip entity.
*/
bool Destroy()
{
return Destroy(0, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed blip entity.
*/
bool Destroy(Int32 header)
{
return Destroy(header, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed blip entity.
*/
bool Destroy(Int32 header, LightObj & payload);
/* --------------------------------------------------------------------------------------------
* Retrieve the events table of this entity.
*/
LightObj & GetEvents() const;
/* --------------------------------------------------------------------------------------------
* Emit a custom event for the managed entity
*/
void CustomEvent(Int32 header, LightObj & payload) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the world in which the referenced blip entity exists.
*/
Int32 GetWorld() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the scale of the managed blip entity.
*/
Int32 GetScale() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position of the managed blip entity.
*/
const Vector3 & GetPosition() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the color of the managed blip entity.
*/
const Color4 & GetColor() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the identifier of the sprite used by the managed blip entity.
*/
Int32 GetSprID() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the x axis of the managed blip entity.
*/
Float32 GetPositionX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the y axis of the managed blip entity.
*/
Float32 GetPositionY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the z axis of the managed blip entity.
*/
Float32 GetPositionZ() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the red color of the managed blip entity.
*/
Int32 GetColorR() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the green color of the managed blip entity.
*/
Int32 GetColorG() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the blue color of the managed blip entity.
*/
Int32 GetColorB() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the alpha transparency of the managed blip entity.
*/
Int32 GetColorA() const;
};
} // Namespace:: SqMod
#endif // _ENTITY_BLIP_HPP_

View File

@ -0,0 +1,577 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Checkpoint.hpp"
#include "Entity/Player.hpp"
#include "Base/Color4.hpp"
#include "Base/Vector3.hpp"
#include "Core.hpp"
#include "Misc/Tasks.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqCheckpoint"))
// ------------------------------------------------------------------------------------------------
const Int32 CCheckpoint::Max = SQMOD_CHECKPOINT_POOL;
// ------------------------------------------------------------------------------------------------
SQInteger CCheckpoint::SqGetNull(HSQUIRRELVM vm)
{
sq_pushobject(vm, Core::Get().GetNullCheckpoint().GetObject());
return 1;
}
// ------------------------------------------------------------------------------------------------
LightObj & CCheckpoint::GetNull()
{
return Core::Get().GetNullCheckpoint();
}
// ------------------------------------------------------------------------------------------------
CCheckpoint::CCheckpoint(Int32 id)
: m_ID(VALID_ENTITYGETEX(id, SQMOD_CHECKPOINT_POOL))
, m_Tag(ToStrF("%d", id)), m_Data(), m_CircularLocks(0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
CCheckpoint::~CCheckpoint()
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
const String & CCheckpoint::ToString() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
const String & CCheckpoint::GetTag() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetTag(StackStrF & tag)
{
if (tag.mLen > 0)
{
m_Tag.assign(tag.mPtr, tag.mLen);
}
else
{
m_Tag.clear();
}
}
// ------------------------------------------------------------------------------------------------
CCheckpoint & CCheckpoint::ApplyTag(StackStrF & tag)
{
SetTag(tag);
return *this;
}
// ------------------------------------------------------------------------------------------------
LightObj & CCheckpoint::GetData()
{
// Validate the managed identifier
Validate();
// Return the requested information
return m_Data;
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetData(LightObj & data)
{
// Validate the managed identifier
Validate();
// Apply the specified value
m_Data = data;
}
// ------------------------------------------------------------------------------------------------
bool CCheckpoint::Destroy(Int32 header, LightObj & payload)
{
// Validate the managed identifier
Validate();
// Perform the requested operation
return Core::Get().DelCheckpoint(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
LightObj & CCheckpoint::GetEvents() const
{
// Validate the managed identifier
Validate();
// Return the associated event table
return Core::Get().GetCheckpoint(m_ID).mEvents;
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::CustomEvent(Int32 header, LightObj & payload) const
{
// Validate the managed identifier
Validate();
// Perfrom the requested action
Core::Get().EmitCheckpointCustom(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
bool CCheckpoint::IsStreamedFor(CPlayer & player) const
{
// Is the specified player even valid?
if (!player.IsActive())
{
STHROWF("Invalid player argument: null");
}
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->IsCheckPointStreamedForPlayer(m_ID, player.GetID());
}
// ------------------------------------------------------------------------------------------------
bool CCheckpoint::IsSphere() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->IsCheckPointSphere(m_ID);
}
// ------------------------------------------------------------------------------------------------
Int32 CCheckpoint::GetWorld() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetCheckPointWorld(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetWorld(Int32 world)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const Int32 current = _Func->GetCheckPointWorld(m_ID);
// Don't even bother if it's the same value
if (current == world)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetCheckPointWorld(m_ID, world);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & CHECKPOINTCL_EMIT_CHECKPOINT_WORLD))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, CHECKPOINTCL_EMIT_CHECKPOINT_WORLD);
// Now forward the event call
Core::Get().EmitCheckpointWorld(m_ID, current, world);
}
}
// ------------------------------------------------------------------------------------------------
Color4 CCheckpoint::GetColor() const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the color information
Int32 r, g, b, a;
// Query the server for the color values
_Func->GetCheckPointColour(m_ID, &r, &g, &b, &a);
// Return the requested information
return Color4(ConvTo< Color4::Value >::From(r), ConvTo< Color4::Value >::From(g),
ConvTo< Color4::Value >::From(b), ConvTo< Color4::Value >::From(a));
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetColor(const Color4 & col) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetCheckPointColour(m_ID, col.r, col.g, col.b, col.a);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetColorEx(Uint8 r, Uint8 g, Uint8 b) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetCheckPointColour(m_ID, r, g, b, 0xFF);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetColorEx(Uint8 r, Uint8 g, Uint8 b, Uint8 a) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetCheckPointColour(m_ID, r, g, b, a);
}
// ------------------------------------------------------------------------------------------------
Vector3 CCheckpoint::GetPosition() const
{
// Validate the managed identifier
Validate();
// Create a default vector instance
Vector3 vec;
// Query the server for the position values
_Func->GetCheckPointPosition(m_ID, &vec.x, &vec.y, &vec.z);
// Return the requested information
return vec;
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetPosition(const Vector3 & pos) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetCheckPointPosition(m_ID, pos.x, pos.y, pos.z);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetPositionEx(Float32 x, Float32 y, Float32 z) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetCheckPointPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
Float32 CCheckpoint::GetRadius() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetCheckPointRadius(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetRadius(Float32 radius)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const Float32 current = _Func->GetCheckPointRadius(m_ID);
// Avoid property unwind from a recursive call
_Func->SetCheckPointRadius(m_ID, radius);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & CHECKPOINTCL_EMIT_CHECKPOINT_RADIUS))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, CHECKPOINTCL_EMIT_CHECKPOINT_RADIUS);
// Now forward the event call
Core::Get().EmitCheckpointRadius(m_ID, current, radius);
}
}
// ------------------------------------------------------------------------------------------------
LightObj & CCheckpoint::GetOwner() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetPlayer(_Func->GetCheckPointOwner(m_ID)).mObj;
}
// ------------------------------------------------------------------------------------------------
Int32 CCheckpoint::GetOwnerID() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetCheckPointOwner(m_ID);
}
// ------------------------------------------------------------------------------------------------
Float32 CCheckpoint::GetPositionX() const
{
// Validate the managed identifier
Validate();
// Clear previous position information, if any
Float32 x = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetCheckPointPosition(m_ID, &x, &dummy, &dummy);
// Return the requested information
return x;
}
// ------------------------------------------------------------------------------------------------
Float32 CCheckpoint::GetPositionY() const
{
// Validate the managed identifier
Validate();
// Clear previous position information, if any
Float32 y = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetCheckPointPosition(m_ID, &dummy, &y, &dummy);
// Return the requested information
return y;
}
// ------------------------------------------------------------------------------------------------
Float32 CCheckpoint::GetPositionZ() const
{
// Validate the managed identifier
Validate();
// Clear previous position information, if any
Float32 z = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetCheckPointPosition(m_ID, &dummy, &dummy, &z);
// Return the requested information
return z;
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetPositionX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 y, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetCheckPointPosition(m_ID, &dummy, &y, &z);
// Perform the requested operation
_Func->SetCheckPointPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetPositionY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetCheckPointPosition(m_ID, &x, &dummy, &z);
// Perform the requested operation
_Func->SetCheckPointPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetPositionZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, y, dummy;
// Retrieve the current values for unchanged components
_Func->GetCheckPointPosition(m_ID, &x, &y, &dummy);
// Perform the requested operation
_Func->SetCheckPointPosition(m_ID, z, y, z);
}
// ------------------------------------------------------------------------------------------------
Int32 CCheckpoint::GetColorR() const
{
// Validate the managed identifier
Validate();
// Clear previous color information, if any
Int32 r = 0, dummy;
// Query the server for the requested component value
_Func->GetCheckPointColour(m_ID, &r, &dummy, &dummy, &dummy);
// Return the requested information
return r;
}
// ------------------------------------------------------------------------------------------------
Int32 CCheckpoint::GetColorG() const
{
// Validate the managed identifier
Validate();
// Clear previous color information, if any
Int32 g = 0, dummy;
// Query the server for the requested component value
_Func->GetCheckPointColour(m_ID, &dummy, &g, &dummy, &dummy);
// Return the requested information
return g;
}
// ------------------------------------------------------------------------------------------------
Int32 CCheckpoint::GetColorB() const
{
// Validate the managed identifier
Validate();
// Clear previous color information, if any
Int32 b = 0, dummy;
// Query the server for the requested component value
_Func->GetCheckPointColour(m_ID, &dummy, &dummy, &b, &dummy);
// Return the requested information
return b;
}
// ------------------------------------------------------------------------------------------------
Int32 CCheckpoint::GetColorA() const
{
// Validate the managed identifier
Validate();
// Clear previous color information, if any
Int32 a = 0, dummy;
// Query the server for the requested component value
_Func->GetCheckPointColour(m_ID, &dummy, &dummy, &dummy, &a);
// Return the requested information
return a;
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetColorR(Int32 r) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary integers to retrieve the missing components
Int32 g, b, a, dummy;
// Retrieve the current values for unchanged components
_Func->GetCheckPointColour(m_ID, &dummy, &g, &b, &a);
// Perform the requested operation
_Func->SetCheckPointColour(m_ID, r, g, b, a);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetColorG(Int32 g) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary integers to retrieve the missing components
Int32 r, b, a, dummy;
// Retrieve the current values for unchanged components
_Func->GetCheckPointColour(m_ID, &r, &dummy, &b, &a);
// Perform the requested operation
_Func->SetCheckPointColour(m_ID, r, g, b, a);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetColorB(Int32 b) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary integers to retrieve the missing components
Int32 r, g, a, dummy;
// Retrieve the current values for unchanged components
_Func->GetCheckPointColour(m_ID, &r, &g, &dummy, &a);
// Perform the requested operation
_Func->SetCheckPointColour(m_ID, r, g, b, a);
}
// ------------------------------------------------------------------------------------------------
void CCheckpoint::SetColorA(Int32 a) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary integers to retrieve the missing components
Int32 r, g, b, dummy;
// Retrieve the current values for unchanged components
_Func->GetCheckPointColour(m_ID, &r, &g, &b, &dummy);
// Perform the requested operation
_Func->SetCheckPointColour(m_ID, r, g, b, a);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Checkpoint_CreateEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z,
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius)
{
return Core::Get().NewCheckpoint(-1, world, sphere, x, y, z, r, g, b, a, radius,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Checkpoint_CreateEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z,
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius,
Int32 header, LightObj & payload)
{
return Core::Get().NewCheckpoint(-1, world, sphere, x, y, z, r, g, b, a,
radius, header, payload);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Checkpoint_Create(Int32 world, bool sphere, const Vector3 & pos,
const Color4 & color, Float32 radius)
{
return Core::Get().NewCheckpoint(-1, world, sphere, pos.x, pos.y, pos.z,
color.r, color.g, color.b, color.a, radius,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Checkpoint_Create(Int32 world, bool sphere, const Vector3 & pos,
const Color4 & color, Float32 radius, Int32 header, LightObj & payload)
{
return Core::Get().NewCheckpoint(-1, world, sphere, pos.x, pos.y, pos.z,
color.r, color.g, color.b, color.a, radius, header, payload);
}
// ================================================================================================
void Register_CCheckpoint(HSQUIRRELVM vm)
{
RootTable(vm).Bind(Typename::Str,
Class< CCheckpoint, NoConstructor< CCheckpoint > >(vm, Typename::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &CCheckpoint::ToString)
// Static Values
.SetStaticValue(_SC("MaxID"), CCheckpoint::Max)
// Core Properties
.Prop(_SC("On"), &CCheckpoint::GetEvents)
.Prop(_SC("ID"), &CCheckpoint::GetID)
.Prop(_SC("Tag"), &CCheckpoint::GetTag, &CCheckpoint::SetTag)
.Prop(_SC("Data"), &CCheckpoint::GetData, &CCheckpoint::SetData)
.Prop(_SC("Active"), &CCheckpoint::IsActive)
// Core Methods
.FmtFunc(_SC("SetTag"), &CCheckpoint::ApplyTag)
.Func(_SC("CustomEvent"), &CCheckpoint::CustomEvent)
// Core Overloads
.Overload< bool (CCheckpoint::*)(void) >(_SC("Destroy"), &CCheckpoint::Destroy)
.Overload< bool (CCheckpoint::*)(Int32) >(_SC("Destroy"), &CCheckpoint::Destroy)
.Overload< bool (CCheckpoint::*)(Int32, LightObj &) >(_SC("Destroy"), &CCheckpoint::Destroy)
// Properties
.Prop(_SC("Sphere"), &CCheckpoint::IsSphere)
.Prop(_SC("World"), &CCheckpoint::GetWorld, &CCheckpoint::SetWorld)
.Prop(_SC("Color"), &CCheckpoint::GetColor, &CCheckpoint::SetColor)
.Prop(_SC("Colour"), &CCheckpoint::GetColor, &CCheckpoint::SetColor)
.Prop(_SC("Pos"), &CCheckpoint::GetPosition, &CCheckpoint::SetPosition)
.Prop(_SC("Position"), &CCheckpoint::GetPosition, &CCheckpoint::SetPosition)
.Prop(_SC("Radius"), &CCheckpoint::GetRadius, &CCheckpoint::SetRadius)
.Prop(_SC("Owner"), &CCheckpoint::GetOwner)
.Prop(_SC("OwnerID"), &CCheckpoint::GetOwnerID)
.Prop(_SC("PosX"), &CCheckpoint::GetPositionX, &CCheckpoint::SetPositionX)
.Prop(_SC("PosY"), &CCheckpoint::GetPositionY, &CCheckpoint::SetPositionY)
.Prop(_SC("PosZ"), &CCheckpoint::GetPositionZ, &CCheckpoint::SetPositionZ)
.Prop(_SC("Red"), &CCheckpoint::GetColorR, &CCheckpoint::SetColorR)
.Prop(_SC("Green"), &CCheckpoint::GetColorG, &CCheckpoint::SetColorG)
.Prop(_SC("Blue"), &CCheckpoint::GetColorB, &CCheckpoint::SetColorB)
.Prop(_SC("Alpha"), &CCheckpoint::GetColorA, &CCheckpoint::SetColorA)
// Member Methods
.Func(_SC("StreamedFor"), &CCheckpoint::IsStreamedFor)
.Func(_SC("SetPos"), &CCheckpoint::SetPositionEx)
.Func(_SC("SetPosition"), &CCheckpoint::SetPositionEx)
// Member Overloads
.Overload< void (CCheckpoint::*)(Uint8, Uint8, Uint8) const >
(_SC("SetColor"), &CCheckpoint::SetColorEx)
.Overload< void (CCheckpoint::*)(Uint8, Uint8, Uint8, Uint8) const >
(_SC("SetColor"), &CCheckpoint::SetColorEx)
// Static Overloads
.StaticOverload< LightObj & (*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) >
(_SC("CreateEx"), &Checkpoint_CreateEx)
.StaticOverload< LightObj & (*)(Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, LightObj &) >
(_SC("CreateEx"), &Checkpoint_CreateEx)
.StaticOverload< LightObj & (*)(Int32, bool, const Vector3 &, const Color4 &, Float32) >
(_SC("Create"), &Checkpoint_Create)
.StaticOverload< LightObj & (*)(Int32, bool, const Vector3 &, const Color4 &, Float32, Int32, LightObj &) >
(_SC("Create"), &Checkpoint_Create)
// Raw Squirrel Methods
.SquirrelFunc(_SC("NullInst"), &CCheckpoint::SqGetNull)
.SquirrelFunc(_SC("MakeTask"), &Tasks::MakeTask< CCheckpoint, ENT_CHECKPOINT >)
.SquirrelFunc(_SC("DropTask"), &Tasks::DropTask< CCheckpoint, ENT_CHECKPOINT >)
.SquirrelFunc(_SC("DoesTask"), &Tasks::DoesTask< CCheckpoint, ENT_CHECKPOINT >)
.SquirrelFunc(_SC("FindTask"), &Tasks::FindTask< CCheckpoint, ENT_CHECKPOINT >)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,332 @@
#ifndef _ENTITY_CHECKPOINT_HPP_
#define _ENTITY_CHECKPOINT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Circular locks employed by the checkpoint manager.
*/
enum CheckpointCircularLocks
{
CHECKPOINTCL_EMIT_CHECKPOINT_WORLD = (1 << 0),
CHECKPOINTCL_EMIT_CHECKPOINT_RADIUS = (1 << 1)
};
/* ------------------------------------------------------------------------------------------------
* Manages a single checkpoint entity.
*/
class CCheckpoint
{
// --------------------------------------------------------------------------------------------
friend class Core;
private:
/* --------------------------------------------------------------------------------------------
* Identifier of the managed entity.
*/
Int32 m_ID;
/* --------------------------------------------------------------------------------------------
* User tag associated with this instance.
*/
String m_Tag;
/* --------------------------------------------------------------------------------------------
* User data associated with this instance.
*/
LightObj m_Data;
/* --------------------------------------------------------------------------------------------
* Prevent events from triggering themselves.
*/
Uint32 m_CircularLocks;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
CCheckpoint(Int32 id);
public:
/* --------------------------------------------------------------------------------------------
* Maximum possible number that could represent an identifier for this entity type.
*/
static const Int32 Max;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
CCheckpoint(const CCheckpoint &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
CCheckpoint(CCheckpoint &&) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CCheckpoint();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
CCheckpoint & operator = (const CCheckpoint &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
CCheckpoint & operator = (CCheckpoint &&) = delete;
/* --------------------------------------------------------------------------------------------
* See whether this instance manages a valid entity otherwise throw an exception.
*/
void Validate() const
{
if (INVALID_ENTITY(m_ID))
{
STHROWF("Invalid checkpoint reference [%s]", m_Tag.c_str());
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static SQInteger SqGetNull(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static LightObj & GetNull();
/* --------------------------------------------------------------------------------------------
* Retrieve the identifier of the entity managed by this instance.
*/
Int32 GetID() const
{
return m_ID;
}
/* --------------------------------------------------------------------------------------------
* Check whether this instance manages a valid entity.
*/
bool IsActive() const
{
return VALID_ENTITY(m_ID);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user tag.
*/
const String & GetTag() const;
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
void SetTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
CCheckpoint & ApplyTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user data.
*/
LightObj & GetData();
/* --------------------------------------------------------------------------------------------
* Modify the associated user data.
*/
void SetData(LightObj & data);
/* --------------------------------------------------------------------------------------------
* Destroy the managed checkpoint entity.
*/
bool Destroy()
{
return Destroy(0, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed checkpoint entity.
*/
bool Destroy(Int32 header)
{
return Destroy(header, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed checkpoint entity.
*/
bool Destroy(Int32 header, LightObj & payload);
/* --------------------------------------------------------------------------------------------
* Retrieve the events table of this entity.
*/
LightObj & GetEvents() const;
/* --------------------------------------------------------------------------------------------
* Emit a custom event for the managed entity
*/
void CustomEvent(Int32 header, LightObj & payload) const;
/* --------------------------------------------------------------------------------------------
* See if the managed checkpoint entity is streamed for the specified player.
*/
bool IsStreamedFor(CPlayer & player) const;
/* --------------------------------------------------------------------------------------------
* See if the managed checkpoint entity of sphere type.
*/
bool IsSphere() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the world in which the managed checkpoint entity exists.
*/
Int32 GetWorld() const;
/* --------------------------------------------------------------------------------------------
* Modify the world in which the managed checkpoint entity exists.
*/
void SetWorld(Int32 world);
/* --------------------------------------------------------------------------------------------
* Retrieve the color of the managed checkpoint entity.
*/
Color4 GetColor() const;
/* --------------------------------------------------------------------------------------------
* Modify the color of the managed checkpoint entity.
*/
void SetColor(const Color4 & col) const;
/* --------------------------------------------------------------------------------------------
* Modify the color of the managed checkpoint entity.
*/
void SetColorEx(Uint8 r, Uint8 g, Uint8 b) const;
/* --------------------------------------------------------------------------------------------
* Modify the color of the managed checkpoint entity.
*/
void SetColorEx(Uint8 r, Uint8 g, Uint8 b, Uint8 a) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position of the managed checkpoint entity.
*/
Vector3 GetPosition() const;
/* --------------------------------------------------------------------------------------------
* Modify the position of the managed checkpoint entity.
*/
void SetPosition(const Vector3 & pos) const;
/* --------------------------------------------------------------------------------------------
* Modify the position of the managed checkpoint entity.
*/
void SetPositionEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the radius of the managed checkpoint entity.
*/
Float32 GetRadius() const;
/* --------------------------------------------------------------------------------------------
* Modify the radius of the managed checkpoint entity.
*/
void SetRadius(Float32 radius);
/* --------------------------------------------------------------------------------------------
* Retrieve the owner of the managed checkpoint entity.
*/
LightObj & GetOwner() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the owner identifier of the managed checkpoint entity.
*/
Int32 GetOwnerID() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the x axis of the managed checkpoint entity.
*/
Float32 GetPositionX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the y axis of the managed checkpoint entity.
*/
Float32 GetPositionY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the z axis of the managed checkpoint entity.
*/
Float32 GetPositionZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the x axis of the managed checkpoint entity.
*/
void SetPositionX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the y axis of the managed checkpoint entity.
*/
void SetPositionY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the z axis of the managed checkpoint entity.
*/
void SetPositionZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the red color of the managed checkpoint entity.
*/
Int32 GetColorR() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the green color of the managed checkpoint entity.
*/
Int32 GetColorG() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the blue color of the managed checkpoint entity.
*/
Int32 GetColorB() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the alpha transparency of the managed checkpoint entity.
*/
Int32 GetColorA() const;
/* --------------------------------------------------------------------------------------------
* Modify the red color of the managed checkpoint entity.
*/
void SetColorR(Int32 r) const;
/* --------------------------------------------------------------------------------------------
* Modify the green color of the managed checkpoint entity.
*/
void SetColorG(Int32 g) const;
/* --------------------------------------------------------------------------------------------
* Modify the blue color of the managed checkpoint entity.
*/
void SetColorB(Int32 b) const;
/* --------------------------------------------------------------------------------------------
* Modify the alpha transparency of the managed checkpoint entity.
*/
void SetColorA(Int32 a) const;
};
} // Namespace:: SqMod
#endif // _ENTITY_CHECKPOINT_HPP_

236
module/Entity/Keybind.cpp Normal file
View File

@ -0,0 +1,236 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Keybind.hpp"
#include "Core.hpp"
#include "Misc/Tasks.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqKeybind"))
// ------------------------------------------------------------------------------------------------
const Int32 CKeybind::Max = SQMOD_KEYBIND_POOL;
// ------------------------------------------------------------------------------------------------
SQInteger CKeybind::SqGetNull(HSQUIRRELVM vm)
{
sq_pushobject(vm, Core::Get().GetNullKeybind().GetObject());
return 1;
}
// ------------------------------------------------------------------------------------------------
LightObj & CKeybind::GetNull()
{
return Core::Get().GetNullKeybind();
}
// ------------------------------------------------------------------------------------------------
CKeybind::CKeybind(Int32 id)
: m_ID(VALID_ENTITYGETEX(id, SQMOD_KEYBIND_POOL))
, m_Tag(ToStrF("%d", id))
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
CKeybind::~CKeybind()
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
const String & CKeybind::ToString() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
const String & CKeybind::GetTag() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
void CKeybind::SetTag(StackStrF & tag)
{
if (tag.mLen > 0)
{
m_Tag.assign(tag.mPtr, tag.mLen);
}
else
{
m_Tag.clear();
}
}
// ------------------------------------------------------------------------------------------------
CKeybind & CKeybind::ApplyTag(StackStrF & tag)
{
SetTag(tag);
return *this;
}
// ------------------------------------------------------------------------------------------------
LightObj & CKeybind::GetData()
{
// Validate the managed identifier
Validate();
// Return the requested information
return m_Data;
}
// ------------------------------------------------------------------------------------------------
void CKeybind::SetData(LightObj & data)
{
// Validate the managed identifier
Validate();
// Apply the specified value
m_Data = data;
}
// ------------------------------------------------------------------------------------------------
bool CKeybind::Destroy(Int32 header, LightObj & payload)
{
// Validate the managed identifier
Validate();
// Perform the requested operation
return Core::Get().DelKeybind(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
LightObj & CKeybind::GetEvents() const
{
// Validate the managed identifier
Validate();
// Return the associated event table
return Core::Get().GetKeybind(m_ID).mEvents;
}
// ------------------------------------------------------------------------------------------------
void CKeybind::CustomEvent(Int32 header, LightObj & payload) const
{
// Validate the managed identifier
Validate();
// Perfrom the requested action
Core::Get().EmitKeybindCustom(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
Int32 CKeybind::GetFirst() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetKeybind(m_ID).mFirst;
}
// ------------------------------------------------------------------------------------------------
Int32 CKeybind::GetSecond() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetKeybind(m_ID).mSecond;
}
// ------------------------------------------------------------------------------------------------
Int32 CKeybind::GetThird() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetKeybind(m_ID).mThird;
}
// ------------------------------------------------------------------------------------------------
bool CKeybind::IsRelease() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return Core::Get().GetKeybind(m_ID).mRelease;
}
// ------------------------------------------------------------------------------------------------
static LightObj & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary,
Int32 alternative)
{
return Core::Get().NewKeybind(slot, release, primary, secondary, alternative,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary,
Int32 alternative, Int32 header, LightObj & payload)
{
return Core::Get().NewKeybind(slot, release, primary, secondary, alternative, header, payload);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative)
{
return Core::Get().NewKeybind(-1, release, primary, secondary, alternative,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative,
Int32 header, LightObj & payload)
{
return Core::Get().NewKeybind(-1, release, primary, secondary, alternative, header, payload);
}
// ------------------------------------------------------------------------------------------------
static SQInteger Keybind_UnusedSlot()
{
return _Func->GetKeyBindUnusedSlot();
}
// ================================================================================================
void Register_CKeybind(HSQUIRRELVM vm)
{
RootTable(vm).Bind(Typename::Str,
Class< CKeybind, NoConstructor< CKeybind > >(vm, Typename::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &CKeybind::ToString)
// Static Values
.SetStaticValue(_SC("MaxID"), CKeybind::Max)
// Core Properties
.Prop(_SC("On"), &CKeybind::GetEvents)
.Prop(_SC("ID"), &CKeybind::GetID)
.Prop(_SC("Tag"), &CKeybind::GetTag, &CKeybind::SetTag)
.Prop(_SC("Data"), &CKeybind::GetData, &CKeybind::SetData)
.Prop(_SC("Active"), &CKeybind::IsActive)
// Core Methods
.FmtFunc(_SC("SetTag"), &CKeybind::ApplyTag)
.Func(_SC("CustomEvent"), &CKeybind::CustomEvent)
// Core Overloads
.Overload< bool (CKeybind::*)(void) >(_SC("Destroy"), &CKeybind::Destroy)
.Overload< bool (CKeybind::*)(Int32) >(_SC("Destroy"), &CKeybind::Destroy)
.Overload< bool (CKeybind::*)(Int32, LightObj &) >(_SC("Destroy"), &CKeybind::Destroy)
// Properties
.Prop(_SC("First"), &CKeybind::GetFirst)
.Prop(_SC("Second"), &CKeybind::GetSecond)
.Prop(_SC("Third"), &CKeybind::GetThird)
.Prop(_SC("Release"), &CKeybind::IsRelease)
// Static Functions
.StaticFunc(_SC("UnusedSlot"), &Keybind_UnusedSlot)
// Static Overloads
.StaticOverload< LightObj & (*)(Int32, bool, Int32, Int32, Int32) >
(_SC("CreateEx"), &Keybind_CreateEx)
.StaticOverload< LightObj & (*)(Int32, bool, Int32, Int32, Int32, Int32, LightObj &) >
(_SC("CreateEx"), &Keybind_CreateEx)
.StaticOverload< LightObj & (*)(bool, Int32, Int32, Int32) >
(_SC("Create"), &Keybind_Create)
.StaticOverload< LightObj & (*)(bool, Int32, Int32, Int32, Int32, LightObj &) >
(_SC("Create"), &Keybind_Create)
// Raw Squirrel Methods
.SquirrelFunc(_SC("NullInst"), &CKeybind::SqGetNull)
.SquirrelFunc(_SC("MakeTask"), &Tasks::MakeTask< CKeybind, ENT_KEYBIND >)
.SquirrelFunc(_SC("DropTask"), &Tasks::DropTask< CKeybind, ENT_KEYBIND >)
.SquirrelFunc(_SC("DoesTask"), &Tasks::DoesTask< CKeybind, ENT_KEYBIND >)
.SquirrelFunc(_SC("FindTask"), &Tasks::FindTask< CKeybind, ENT_KEYBIND >)
);
}
} // Namespace:: SqMod

193
module/Entity/Keybind.hpp Normal file
View File

@ -0,0 +1,193 @@
#ifndef _ENTITY_KEYBIND_HPP_
#define _ENTITY_KEYBIND_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Manages a single keybind entity.
*/
class CKeybind
{
// --------------------------------------------------------------------------------------------
friend class Core;
private:
/* --------------------------------------------------------------------------------------------
* Identifier of the managed entity.
*/
Int32 m_ID;
/* --------------------------------------------------------------------------------------------
* User tag associated with this instance.
*/
String m_Tag;
/* --------------------------------------------------------------------------------------------
* User data associated with this instance.
*/
LightObj m_Data;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
CKeybind(Int32 id);
public:
/* --------------------------------------------------------------------------------------------
* Maximum possible number that could represent an identifier for this entity type.
*/
static const Int32 Max;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
CKeybind(const CKeybind &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
CKeybind(CKeybind &&) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CKeybind();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
CKeybind & operator = (const CKeybind &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
CKeybind & operator = (CKeybind &&) = delete;
/* --------------------------------------------------------------------------------------------
* See whether this instance manages a valid entity instance otherwise throw an exception.
*/
void Validate() const
{
if (INVALID_ENTITY(m_ID))
{
STHROWF("Invalid keybind reference [%s]", m_Tag.c_str());
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static SQInteger SqGetNull(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static LightObj & GetNull();
/* --------------------------------------------------------------------------------------------
* Retrieve the identifier of the entity managed by this instance.
*/
Int32 GetID() const
{
return m_ID;
}
/* --------------------------------------------------------------------------------------------
* Check whether this instance manages a valid entity.
*/
bool IsActive() const
{
return VALID_ENTITY(m_ID);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user tag.
*/
const String & GetTag() const;
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
void SetTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
CKeybind & ApplyTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user data.
*/
LightObj & GetData();
/* --------------------------------------------------------------------------------------------
* Modify the associated user data.
*/
void SetData(LightObj & data);
/* --------------------------------------------------------------------------------------------
* Destroy the managed destroy entity.
*/
bool Destroy()
{
return Destroy(0, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed destroy entity.
*/
bool Destroy(Int32 header)
{
return Destroy(header, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed destroy entity.
*/
bool Destroy(Int32 header, LightObj & payload);
/* --------------------------------------------------------------------------------------------
* Retrieve the events table of this entity.
*/
LightObj & GetEvents() const;
/* --------------------------------------------------------------------------------------------
* Emit a custom event for the managed entity
*/
void CustomEvent(Int32 header, LightObj & payload) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the first key code of the managed keybind entity.
*/
Int32 GetFirst() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the second key code of the managed keybind entity.
*/
Int32 GetSecond() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the third key code of the managed keybind entity.
*/
Int32 GetThird() const;
/* --------------------------------------------------------------------------------------------
* See whether the managed keybind entity reacts to key release events.
*/
bool IsRelease() const;
};
} // Namespace:: SqMod
#endif // _ENTITY_KEYBIND_HPP_

989
module/Entity/Object.cpp Normal file
View File

@ -0,0 +1,989 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Object.hpp"
#include "Entity/Player.hpp"
#include "Base/Quaternion.hpp"
#include "Base/Vector3.hpp"
#include "Core.hpp"
#include "Misc/Tasks.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqObject"))
// ------------------------------------------------------------------------------------------------
const Int32 CObject::Max = SQMOD_OBJECT_POOL;
// ------------------------------------------------------------------------------------------------
SQInteger CObject::SqGetNull(HSQUIRRELVM vm)
{
sq_pushobject(vm, Core::Get().GetNullObject().GetObject());
return 1;
}
// ------------------------------------------------------------------------------------------------
LightObj & CObject::GetNull()
{
return Core::Get().GetNullObject();
}
// ------------------------------------------------------------------------------------------------
CObject::CObject(Int32 id)
: m_ID(VALID_ENTITYGETEX(id, SQMOD_OBJECT_POOL))
, m_Tag(ToStrF("%d", id)), m_Data(), m_CircularLocks(0)
, mMoveToDuration(0)
, mMoveByDuration(0)
, mRotateToDuration(0)
, mRotateByDuration(0)
, mRotateToEulerDuration(0)
, mRotateByEulerDuration(0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
CObject::~CObject()
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
const String & CObject::ToString() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
const String & CObject::GetTag() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
void CObject::SetTag(StackStrF & tag)
{
if (tag.mLen > 0)
{
m_Tag.assign(tag.mPtr, tag.mLen);
}
else
{
m_Tag.clear();
}
}
// ------------------------------------------------------------------------------------------------
CObject & CObject::ApplyTag(StackStrF & tag)
{
SetTag(tag);
return *this;
}
// ------------------------------------------------------------------------------------------------
LightObj & CObject::GetData()
{
// Validate the managed identifier
Validate();
// Return the requested information
return m_Data;
}
// ------------------------------------------------------------------------------------------------
void CObject::SetData(LightObj & data)
{
// Validate the managed identifier
Validate();
// Apply the specified value
m_Data = data;
}
// ------------------------------------------------------------------------------------------------
bool CObject::Destroy(Int32 header, LightObj & payload)
{
// Validate the managed identifier
Validate();
// Perform the requested operation
return Core::Get().DelObject(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
LightObj & CObject::GetEvents() const
{
// Validate the managed identifier
Validate();
// Return the associated event table
return Core::Get().GetObject(m_ID).mEvents;
}
// ------------------------------------------------------------------------------------------------
void CObject::CustomEvent(Int32 header, LightObj & payload) const
{
// Validate the managed identifier
Validate();
// Perfrom the requested action
Core::Get().EmitObjectCustom(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
bool CObject::IsStreamedFor(CPlayer & player) const
{
// Is the specified player even valid?
if (!player.IsActive())
{
STHROWF("Invalid player argument: null");
}
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->IsObjectStreamedForPlayer(m_ID, player.GetID());
}
// ------------------------------------------------------------------------------------------------
Int32 CObject::GetModel() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetObjectModel(m_ID);
}
// ------------------------------------------------------------------------------------------------
Int32 CObject::GetWorld() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetObjectWorld(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CObject::SetWorld(Int32 world)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const Int32 current = _Func->GetObjectWorld(m_ID);
// Don't even bother if it's the same value
if (current == world)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetObjectWorld(m_ID, world);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_WORLD))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_WORLD);
// Now forward the event call
Core::Get().EmitObjectWorld(m_ID, current, world);
}
}
// ------------------------------------------------------------------------------------------------
Int32 CObject::GetAlpha() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetObjectAlpha(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CObject::SetAlpha(Int32 alpha)
{
SetAlphaEx(alpha, 0);
}
// ------------------------------------------------------------------------------------------------
void CObject::SetAlphaEx(Int32 alpha, Uint32 time)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const Int32 current = _Func->GetObjectAlpha(m_ID);
// Don't even bother if it's the same value
if (current == alpha)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetObjectAlpha(m_ID, alpha, time);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_ALPHA))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_ALPHA);
// Now forward the event call
Core::Get().EmitObjectAlpha(m_ID, current, alpha, time);
}
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveTo(const Vector3 & pos, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->MoveObjectTo(m_ID, pos.x, pos.y, pos.z, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveToEx(Float32 x, Float32 y, Float32 z, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->MoveObjectTo(m_ID, x, y, z, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveBy(const Vector3 & pos, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->MoveObjectBy(m_ID, pos.x, pos.y, pos.z, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveByEx(Float32 x, Float32 y, Float32 z, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->MoveObjectBy(m_ID, x, y, z, time);
}
// ------------------------------------------------------------------------------------------------
Vector3 CObject::GetPosition()
{
// Validate the managed identifier
Validate();
// Create a default vector instance
Vector3 vec;
// Query the server for the values
_Func->GetObjectPosition(m_ID, &vec.x, &vec.y, &vec.z);
// Return the requested information
return vec;
}
// ------------------------------------------------------------------------------------------------
void CObject::SetPosition(const Vector3 & pos) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetObjectPosition(m_ID, pos.x, pos.y, pos.z);
}
// ------------------------------------------------------------------------------------------------
void CObject::SetPositionEx(Float32 x, Float32 y, Float32 z) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetObjectPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateTo(const Quaternion & rot, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectTo(m_ID, rot.x, rot.y, rot.z, rot.w, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToEx(Float32 x, Float32 y, Float32 z, Float32 w, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectTo(m_ID, x, y, z, w, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToEuler(const Vector3 & rot, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectToEuler(m_ID, rot.x, rot.y, rot.z, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToEulerEx(Float32 x, Float32 y, Float32 z, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectToEuler(m_ID, x, y, z, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateBy(const Quaternion & rot, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectBy(m_ID, rot.x, rot.y, rot.z, rot.w, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByEx(Float32 x, Float32 y, Float32 z, Float32 w, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectBy(m_ID, x, y, z, w, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByEuler(const Vector3 & rot, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectByEuler(m_ID, rot.x, rot.y, rot.z, time);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByEulerEx(Float32 x, Float32 y, Float32 z, Uint32 time) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectByEuler(m_ID, x, y, z, time);
}
// ------------------------------------------------------------------------------------------------
Quaternion CObject::GetRotation()
{
// Validate the managed identifier
Validate();
// Create a default quaternion instance
Quaternion quat;
// Query the server for the values
_Func->GetObjectRotation(m_ID, &quat.x, &quat.y, &quat.z, &quat.w);
// Return the requested information
return quat;
}
// ------------------------------------------------------------------------------------------------
Vector3 CObject::GetRotationEuler()
{
// Validate the managed identifier
Validate();
// Create a default vector instance
Vector3 vec;
// Query the server for the values
_Func->GetObjectRotationEuler(m_ID, &vec.x, &vec.y, &vec.z);
// Return the requested information
return vec;
}
// ------------------------------------------------------------------------------------------------
bool CObject::GetShotReport() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->IsObjectShotReportEnabled(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CObject::SetShotReport(bool toggle)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const bool current = _Func->IsObjectShotReportEnabled(m_ID);
// Don't even bother if it's the same value
if (current == toggle)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetObjectShotReportEnabled(m_ID, toggle);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_REPORT))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_REPORT);
// Now forward the event call
Core::Get().EmitObjectReport(m_ID, current, toggle, false);
}
}
// ------------------------------------------------------------------------------------------------
bool CObject::GetTouchedReport() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->IsObjectTouchedReportEnabled(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CObject::SetTouchedReport(bool toggle)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const bool current = _Func->IsObjectTouchedReportEnabled(m_ID);
// Don't even bother if it's the same value
if (current == toggle)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetObjectTouchedReportEnabled(m_ID, toggle);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & OBJECTCL_EMIT_OBJECT_REPORT))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, OBJECTCL_EMIT_OBJECT_REPORT);
// Now forward the event call
Core::Get().EmitObjectReport(m_ID, current, toggle, true);
}
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetPositionX() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 x = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectPosition(m_ID, &x, &dummy, &dummy);
// Return the requested information
return x;
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetPositionY() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 y = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectPosition(m_ID, &dummy, &y, &dummy);
// Return the requested information
return y;
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetPositionZ() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 z = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectPosition(m_ID, &dummy, &dummy, &z);
// Return the requested information
return z;
}
// ------------------------------------------------------------------------------------------------
void CObject::SetPositionX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 y, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectPosition(m_ID, &dummy, &y, &z);
// Perform the requested operation
_Func->SetObjectPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
void CObject::SetPositionY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectPosition(m_ID, &x, &dummy, &z);
// Perform the requested operation
_Func->SetObjectPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
void CObject::SetPositionZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, y, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectPosition(m_ID, &x, &y, &dummy);
// Perform the requested operation
_Func->SetObjectPosition(m_ID, z, y, z);
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetRotationX() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 x = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectRotation(m_ID, &x, &dummy, &dummy, &dummy);
// Return the requested information
return x;
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetRotationY() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 y = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectRotation(m_ID, &dummy, &y, &dummy, &dummy);
// Return the requested information
return y;
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetRotationZ() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 z = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectRotation(m_ID, &dummy, &dummy, &z, &dummy);
// Return the requested information
return z;
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetRotationW() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 w = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectRotation(m_ID, &dummy, &dummy, &dummy, &w);
// Return the requested information
return w;
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetEulerRotationX() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 x = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectRotationEuler(m_ID, &x, &dummy, &dummy);
// Return the requested information
return x;
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetEulerRotationY() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 y = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectRotationEuler(m_ID, &dummy, &y, &dummy);
// Return the requested information
return y;
}
// ------------------------------------------------------------------------------------------------
Float32 CObject::GetEulerRotationZ() const
{
// Validate the managed identifier
Validate();
// Clear previous information, if any
Float32 z = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetObjectRotationEuler(m_ID, &dummy, &dummy, &z);
// Return the requested information
return z;
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveToX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 y, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectPosition(m_ID, &dummy, &y, &z);
// Perform the requested operation
_Func->MoveObjectTo(m_ID, x, y, z, mMoveToDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveToY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectPosition(m_ID, &x, &dummy, &z);
// Perform the requested operation
_Func->MoveObjectTo(m_ID, x, y, z, mMoveToDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveToZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, y, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectPosition(m_ID, &x, &y, &dummy);
// Perform the requested operation
_Func->MoveObjectTo(m_ID, z, y, z, mMoveToDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveByX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->MoveObjectBy(m_ID, x, 0.0f, 0.0f, mMoveByDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveByY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->MoveObjectBy(m_ID, 0.0f, y, 0.0f, mMoveByDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::MoveByZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->MoveObjectBy(m_ID, 0.0f, 0.0f, z, mMoveByDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 y, z, w, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectRotation(m_ID, &dummy, &y, &z, &w);
// Perform the requested operation
_Func->RotateObjectTo(m_ID, x, y, z, w, mRotateToDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, z, w, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectRotation(m_ID, &x, &dummy, &z, &w);
// Perform the requested operation
_Func->RotateObjectTo(m_ID, x, y, z, w, mRotateToDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, y, w, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectRotation(m_ID, &x, &y, &dummy, &w);
// Perform the requested operation
_Func->RotateObjectTo(m_ID, x, y, z, w, mRotateToDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToW(Float32 w) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, y, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectRotation(m_ID, &x, &y, &z, &dummy);
// Perform the requested operation
_Func->RotateObjectTo(m_ID, x, y, z, w, mRotateToDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectBy(m_ID, x, 0.0f, 0.0f, 0.0f, mRotateByDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectBy(m_ID, 0.0f, y, 0.0f, 0.0f, mRotateByDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectBy(m_ID, 0.0f, 0.0f, z, 0.0f, mRotateByDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByW(Float32 w) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectBy(m_ID, 0.0f, 0.0f, 0.0f, w, mRotateByDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToEulerX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 y, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectRotationEuler(m_ID, &dummy, &y, &z);
// Perform the requested operation
_Func->RotateObjectToEuler(m_ID, x, y, z, mRotateToEulerDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToEulerY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectRotationEuler(m_ID, &x, &dummy, &z);
// Perform the requested operation
_Func->RotateObjectToEuler(m_ID, x, y, z, mRotateToEulerDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateToEulerZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, y, dummy;
// Retrieve the current values for unchanged components
_Func->GetObjectRotationEuler(m_ID, &x, &y, &dummy);
// Perform the requested operation
_Func->RotateObjectToEuler(m_ID, z, y, z, mRotateToEulerDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByEulerX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectByEuler(m_ID, x, 0.0f, 0.0f, mRotateByEulerDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByEulerY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectByEuler(m_ID, 0.0f, y, 0.0f, mRotateByEulerDuration);
}
// ------------------------------------------------------------------------------------------------
void CObject::RotateByEulerZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RotateObjectByEuler(m_ID, 0.0f, 0.0f, z, mRotateByEulerDuration);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z,
Int32 alpha)
{
return Core::Get().NewObject(model, world, x, y, z, alpha, SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z,
Int32 alpha, Int32 header, LightObj & payload)
{
return Core::Get().NewObject(model, world, x, y, z, alpha, header, payload);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha)
{
return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha,
Int32 header, LightObj & payload)
{
return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha, header, payload);
}
// ================================================================================================
void Register_CObject(HSQUIRRELVM vm)
{
RootTable(vm).Bind(Typename::Str,
Class< CObject, NoConstructor< CObject > >(vm, Typename::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &CObject::ToString)
// Static Values
.SetStaticValue(_SC("MaxID"), CObject::Max)
// Member Variables
.Var(_SC("MoveToDuration"), &CObject::mMoveToDuration)
.Var(_SC("MoveByDuration"), &CObject::mMoveByDuration)
.Var(_SC("RotateToDuration"), &CObject::mRotateToDuration)
.Var(_SC("RotateByDuration"), &CObject::mRotateByDuration)
.Var(_SC("RotateToEulerDuration"), &CObject::mRotateToEulerDuration)
.Var(_SC("RotateByEulerDuration"), &CObject::mRotateByEulerDuration)
// Core Properties
.Prop(_SC("On"), &CObject::GetEvents)
.Prop(_SC("ID"), &CObject::GetID)
.Prop(_SC("Tag"), &CObject::GetTag, &CObject::SetTag)
.Prop(_SC("Data"), &CObject::GetData, &CObject::SetData)
.Prop(_SC("Active"), &CObject::IsActive)
// Core Methods
.FmtFunc(_SC("SetTag"), &CObject::ApplyTag)
.Func(_SC("CustomEvent"), &CObject::CustomEvent)
// Core Overloads
.Overload< bool (CObject::*)(void) >(_SC("Destroy"), &CObject::Destroy)
.Overload< bool (CObject::*)(Int32) >(_SC("Destroy"), &CObject::Destroy)
.Overload< bool (CObject::*)(Int32, LightObj &) >(_SC("Destroy"), &CObject::Destroy)
// Properties
.Prop(_SC("Model"), &CObject::GetModel)
.Prop(_SC("World"), &CObject::GetWorld, &CObject::SetWorld)
.Prop(_SC("Alpha"), &CObject::GetAlpha, &CObject::SetAlpha)
.Prop(_SC("Pos"), &CObject::GetPosition, &CObject::SetPosition)
.Prop(_SC("Position"), &CObject::GetPosition, &CObject::SetPosition)
.Prop(_SC("Rot"), &CObject::GetRotation)
.Prop(_SC("Rotation"), &CObject::GetRotation)
.Prop(_SC("EulerRot"), &CObject::GetRotationEuler)
.Prop(_SC("EulerRotation"), &CObject::GetRotationEuler)
.Prop(_SC("ShotReport"), &CObject::GetShotReport, &CObject::SetShotReport)
.Prop(_SC("BumpReport"), &CObject::GetTouchedReport, &CObject::SetTouchedReport)
.Prop(_SC("TouchedReport"), &CObject::GetTouchedReport, &CObject::SetTouchedReport)
.Prop(_SC("PosX"), &CObject::GetPositionX, &CObject::SetPositionX)
.Prop(_SC("PosY"), &CObject::GetPositionY, &CObject::SetPositionY)
.Prop(_SC("PosZ"), &CObject::GetPositionZ, &CObject::SetPositionZ)
.Prop(_SC("RotX"), &CObject::GetRotationX)
.Prop(_SC("RotY"), &CObject::GetRotationY)
.Prop(_SC("RotZ"), &CObject::GetRotationZ)
.Prop(_SC("RotW"), &CObject::GetRotationW)
.Prop(_SC("EulerRotX"), &CObject::GetEulerRotationX)
.Prop(_SC("EulerRotY"), &CObject::GetEulerRotationY)
.Prop(_SC("EulerRotZ"), &CObject::GetEulerRotationZ)
.Prop(_SC("MoveToX"), &CObject::GetPositionX, &CObject::MoveToX)
.Prop(_SC("MoveToY"), &CObject::GetPositionY, &CObject::MoveToY)
.Prop(_SC("MoveToZ"), &CObject::GetPositionZ, &CObject::MoveToZ)
.Prop(_SC("MoveByX"), &CObject::GetPositionX, &CObject::MoveByX)
.Prop(_SC("MoveByY"), &CObject::GetPositionY, &CObject::MoveByY)
.Prop(_SC("MoveByZ"), &CObject::GetPositionZ, &CObject::MoveByZ)
.Prop(_SC("RotateToX"), &CObject::GetRotationX, &CObject::RotateToX)
.Prop(_SC("RotateToY"), &CObject::GetRotationY, &CObject::RotateToY)
.Prop(_SC("RotateToZ"), &CObject::GetRotationZ, &CObject::RotateToZ)
.Prop(_SC("RotateToW"), &CObject::GetRotationW, &CObject::RotateToW)
.Prop(_SC("RotateByX"), &CObject::GetRotationX, &CObject::RotateByX)
.Prop(_SC("RotateByY"), &CObject::GetRotationY, &CObject::RotateByY)
.Prop(_SC("RotateByZ"), &CObject::GetRotationZ, &CObject::RotateByZ)
.Prop(_SC("RotateByW"), &CObject::GetRotationW, &CObject::RotateByW)
.Prop(_SC("RotateToEulerX"), &CObject::GetEulerRotationX, &CObject::RotateToEulerX)
.Prop(_SC("RotateToEulerY"), &CObject::GetEulerRotationY, &CObject::RotateToEulerY)
.Prop(_SC("RotateToEulerZ"), &CObject::GetEulerRotationZ, &CObject::RotateToEulerZ)
.Prop(_SC("RotateByEulerX"), &CObject::GetEulerRotationX, &CObject::RotateByEulerX)
.Prop(_SC("RotateByEulerY"), &CObject::GetEulerRotationY, &CObject::RotateByEulerY)
.Prop(_SC("RotateByEulerZ"), &CObject::GetEulerRotationZ, &CObject::RotateByEulerZ)
// Member Methods
.Func(_SC("StreamedFor"), &CObject::IsStreamedFor)
.Func(_SC("SetAlpha"), &CObject::SetAlphaEx)
.Func(_SC("SetPosition"), &CObject::SetPositionEx)
// Member Overloads
.Overload< void (CObject::*)(const Vector3 &, Uint32) const >
(_SC("MoveTo"), &CObject::MoveTo)
.Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const >
(_SC("MoveTo"), &CObject::MoveToEx)
.Overload< void (CObject::*)(const Vector3 &, Uint32) const >
(_SC("MoveBy"), &CObject::MoveBy)
.Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const >
(_SC("MoveBy"), &CObject::MoveByEx)
.Overload< void (CObject::*)(const Quaternion &, Uint32) const >
(_SC("RotateTo"), &CObject::RotateTo)
.Overload< void (CObject::*)(Float32, Float32, Float32, Float32, Uint32) const >
(_SC("RotateTo"), &CObject::RotateToEx)
.Overload< void (CObject::*)(const Vector3 &, Uint32) const >
(_SC("RotateToEuler"), &CObject::RotateToEuler)
.Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const >
(_SC("RotateToEuler"), &CObject::RotateToEulerEx)
.Overload< void (CObject::*)(const Quaternion &, Uint32) const >
(_SC("RotateBy"), &CObject::RotateBy)
.Overload< void (CObject::*)(Float32, Float32, Float32, Float32, Uint32) const >
(_SC("RotateBy"), &CObject::RotateByEx)
.Overload< void (CObject::*)(const Vector3 &, Uint32) const >
(_SC("RotateByEuler"), &CObject::RotateByEuler)
.Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const >
(_SC("RotateByEuler"), &CObject::RotateByEulerEx)
// Static Overloads
.StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Int32) >
(_SC("CreateEx"), &Object_CreateEx)
.StaticOverload< LightObj & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Int32, LightObj &) >
(_SC("CreateEx"), &Object_CreateEx)
.StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Int32) >
(_SC("Create"), &Object_Create)
.StaticOverload< LightObj & (*)(Int32, Int32, const Vector3 &, Int32, Int32, LightObj &) >
(_SC("Create"), &Object_Create)
// Raw Squirrel Methods
.SquirrelFunc(_SC("NullInst"), &CObject::SqGetNull)
.SquirrelFunc(_SC("MakeTask"), &Tasks::MakeTask< CObject, ENT_OBJECT >)
.SquirrelFunc(_SC("DropTask"), &Tasks::DropTask< CObject, ENT_OBJECT >)
.SquirrelFunc(_SC("DoesTask"), &Tasks::DoesTask< CObject, ENT_OBJECT >)
.SquirrelFunc(_SC("FindTask"), &Tasks::FindTask< CObject, ENT_OBJECT >)
);
}
} // Namespace:: SqMod

511
module/Entity/Object.hpp Normal file
View File

@ -0,0 +1,511 @@
#ifndef _ENTITY_OBJECT_HPP_
#define _ENTITY_OBJECT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Circular locks employed by the object manager.
*/
enum ObjectCircularLocks
{
OBJECTCL_EMIT_OBJECT_WORLD = (1 << 0),
OBJECTCL_EMIT_OBJECT_ALPHA = (2 << 0),
OBJECTCL_EMIT_OBJECT_REPORT = (3 << 0)
};
/* ------------------------------------------------------------------------------------------------
* Manages a single object entity.
*/
class CObject
{
// --------------------------------------------------------------------------------------------
friend class Core;
private:
/* --------------------------------------------------------------------------------------------
* Identifier of the managed entity.
*/
Int32 m_ID;
/* --------------------------------------------------------------------------------------------
* User tag associated with this instance.
*/
String m_Tag;
/* --------------------------------------------------------------------------------------------
* User data associated with this instance.
*/
LightObj m_Data;
/* --------------------------------------------------------------------------------------------
* Prevent events from triggering themselves.
*/
Uint32 m_CircularLocks;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
CObject(Int32 id);
public:
/* --------------------------------------------------------------------------------------------
* The default duration to use when moving the object.
*/
Uint32 mMoveToDuration;
Uint32 mMoveByDuration;
/* --------------------------------------------------------------------------------------------
* The default duration to use when rotating the object to Quaternion.
*/
Uint32 mRotateToDuration;
Uint32 mRotateByDuration;
/* --------------------------------------------------------------------------------------------
* The default duration to use when rotating the object to Euler.
*/
Uint32 mRotateToEulerDuration;
Uint32 mRotateByEulerDuration;
/* --------------------------------------------------------------------------------------------
* Maximum possible number that could represent an identifier for this entity type.
*/
static const Int32 Max;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
CObject(const CObject &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
CObject(CObject &&) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CObject();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
CObject & operator = (const CObject &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
CObject & operator = (CObject &&) = delete;
/* --------------------------------------------------------------------------------------------
* See whether this instance manages a valid entity instance otherwise throw an exception.
*/
void Validate() const
{
if (INVALID_ENTITY(m_ID))
{
STHROWF("Invalid object reference [%s]", m_Tag.c_str());
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static SQInteger SqGetNull(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static LightObj & GetNull();
/* --------------------------------------------------------------------------------------------
* Retrieve the identifier of the entity managed by this instance.
*/
Int32 GetID() const
{
return m_ID;
}
/* --------------------------------------------------------------------------------------------
* Check whether this instance manages a valid entity.
*/
bool IsActive() const
{
return VALID_ENTITY(m_ID);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user tag.
*/
const String & GetTag() const;
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
void SetTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
CObject & ApplyTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user data.
*/
LightObj & GetData();
/* --------------------------------------------------------------------------------------------
* Modify the associated user data.
*/
void SetData(LightObj & data);
/* --------------------------------------------------------------------------------------------
* Destroy the managed object entity.
*/
bool Destroy()
{
return Destroy(0, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed object entity.
*/
bool Destroy(Int32 header)
{
return Destroy(header, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed object entity.
*/
bool Destroy(Int32 header, LightObj & payload);
/* --------------------------------------------------------------------------------------------
* Retrieve the events table of this entity.
*/
LightObj & GetEvents() const;
/* --------------------------------------------------------------------------------------------
* Emit a custom event for the managed entity
*/
void CustomEvent(Int32 header, LightObj & payload) const;
/* --------------------------------------------------------------------------------------------
* See if the managed object entity is streamed for the specified player.
*/
bool IsStreamedFor(CPlayer & player) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the model of the managed object entity.
*/
Int32 GetModel() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the world in which the managed object entity exists.
*/
Int32 GetWorld() const;
/* --------------------------------------------------------------------------------------------
* Modify the world in which the managed object entity exists.
*/
void SetWorld(Int32 world);
/* --------------------------------------------------------------------------------------------
* Retrieve the alpha of the managed object entity.
*/
Int32 GetAlpha() const;
/* --------------------------------------------------------------------------------------------
* Modify the alpha of the managed object entity.
*/
void SetAlpha(Int32 alpha);
/* --------------------------------------------------------------------------------------------
* Modify the alpha of the managed object entity over the specified time.
*/
void SetAlphaEx(Int32 alpha, Uint32 time);
/* --------------------------------------------------------------------------------------------
* Move the managed object entity to the specified position over the specified time.
*/
void MoveTo(const Vector3 & pos, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Move the managed object entity to the specified position over the specified time.
*/
void MoveToEx(Float32 x, Float32 y, Float32 z, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Move the managed object entity by the specified position over the specified time.
*/
void MoveBy(const Vector3 & pos, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Move the managed object entity by the specified position over the specified time.
*/
void MoveByEx(Float32 x, Float32 y, Float32 z, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position of the managed object entity.
*/
Vector3 GetPosition();
/* --------------------------------------------------------------------------------------------
* Modify the position of the managed object entity.
*/
void SetPosition(const Vector3 & pos) const;
/* --------------------------------------------------------------------------------------------
* Modify the position of the managed object entity.
*/
void SetPositionEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Rotate the managed object entity to the specified rotation over the specified time.
*/
void RotateTo(const Quaternion & rot, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Rotate the managed object entity to the specified rotation over the specified time.
*/
void RotateToEx(Float32 x, Float32 y, Float32 z, Float32 w, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Rotate the managed object entity to the specified Euler rotation over the specified time.
*/
void RotateToEuler(const Vector3 & rot, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Rotate the managed object entity to the specified Euler rotation over the specified time.
*/
void RotateToEulerEx(Float32 x, Float32 y, Float32 z, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Rotate the managed object entity by the specified rotation over the specified time.
*/
void RotateBy(const Quaternion & rot, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Rotate the managed object entity by the specified rotation over the specified time.
*/
void RotateByEx(Float32 x, Float32 y, Float32 z, Float32 w, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Rotate the managed object entity by the specified Euler rotation over the specified time.
*/
void RotateByEuler(const Vector3 & rot, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Rotate the managed object entity by the specified Euler rotation over the specified time.
*/
void RotateByEulerEx(Float32 x, Float32 y, Float32 z, Uint32 time) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation of the managed object entity.
*/
Quaternion GetRotation();
/* --------------------------------------------------------------------------------------------
* Retrieve the Euler rotation of the managed object entity.
*/
Vector3 GetRotationEuler();
/* --------------------------------------------------------------------------------------------
* See whether the managed object entity reports gunshots.
*/
bool GetShotReport() const;
/* --------------------------------------------------------------------------------------------
* Set whether the managed object entity reports gunshots.
*/
void SetShotReport(bool toggle);
/* --------------------------------------------------------------------------------------------
* See whether the managed object entity reports player bumps.
*/
bool GetTouchedReport() const;
/* --------------------------------------------------------------------------------------------
* Set whether the managed object entity reports player bumps.
*/
void SetTouchedReport(bool toggle);
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the x axis of the managed object entity.
*/
Float32 GetPositionX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the y axis of the managed object entity.
*/
Float32 GetPositionY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the z axis of the managed object entity.
*/
Float32 GetPositionZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the x axis of the managed object entity.
*/
void SetPositionX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the y axis of the managed object entity.
*/
void SetPositionY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the z axis of the managed object entity.
*/
void SetPositionZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation on the x axis of the managed object entity.
*/
Float32 GetRotationX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation on the y axis of the managed object entity.
*/
Float32 GetRotationY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation on the z axis of the managed object entity.
*/
Float32 GetRotationZ() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation amount of the managed object entity.
*/
Float32 GetRotationW() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the Euler rotation on the x axis of the managed object entity.
*/
Float32 GetEulerRotationX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the Euler rotation on the y axis of the managed object entity.
*/
Float32 GetEulerRotationY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the Euler rotation on the z axis of the managed object entity.
*/
Float32 GetEulerRotationZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the x axis of the managed object entity.
*/
void MoveToX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the y axis of the managed object entity.
*/
void MoveToY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the z axis of the managed object entity.
*/
void MoveToZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the x axis of the managed object entity.
*/
void MoveByX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the y axis of the managed object entity.
*/
void MoveByY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the z axis of the managed object entity.
*/
void MoveByZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the x axis of the managed object entity.
*/
void RotateToX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the y axis of the managed object entity.
*/
void RotateToY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the z axis of the managed object entity.
*/
void RotateToZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the w axis of the managed object entity.
*/
void RotateToW(Float32 w) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the x axis of the managed object entity.
*/
void RotateByX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the y axis of the managed object entity.
*/
void RotateByY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the z axis of the managed object entity.
*/
void RotateByZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the w axis of the managed object entity.
*/
void RotateByW(Float32 w) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the x axis of the managed object entity.
*/
void RotateToEulerX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the y axis of the managed object entity.
*/
void RotateToEulerY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the z axis of the managed object entity.
*/
void RotateToEulerZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the x axis of the managed object entity.
*/
void RotateByEulerX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the y axis of the managed object entity.
*/
void RotateByEulerY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the z axis of the managed object entity.
*/
void RotateByEulerZ(Float32 z) const;
};
} // Namespace:: SqMod
#endif // _ENTITY_OBJECT_HPP_

550
module/Entity/Pickup.cpp Normal file
View File

@ -0,0 +1,550 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Pickup.hpp"
#include "Entity/Player.hpp"
#include "Base/Vector3.hpp"
#include "Core.hpp"
#include "Misc/Tasks.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqPickup"))
// ------------------------------------------------------------------------------------------------
const Int32 CPickup::Max = SQMOD_PICKUP_POOL;
// ------------------------------------------------------------------------------------------------
SQInteger CPickup::SqGetNull(HSQUIRRELVM vm)
{
sq_pushobject(vm, Core::Get().GetNullPickup().GetObject());
return 1;
}
// ------------------------------------------------------------------------------------------------
LightObj & CPickup::GetNull()
{
return Core::Get().GetNullPickup();
}
// ------------------------------------------------------------------------------------------------
CPickup::CPickup(Int32 id)
: m_ID(VALID_ENTITYGETEX(id, SQMOD_PICKUP_POOL))
, m_Tag(ToStrF("%d", id)), m_Data(), m_CircularLocks(0)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
CPickup::~CPickup()
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
const String & CPickup::ToString() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
const String & CPickup::GetTag() const
{
return m_Tag;
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetTag(StackStrF & tag)
{
if (tag.mLen > 0)
{
m_Tag.assign(tag.mPtr, tag.mLen);
}
else
{
m_Tag.clear();
}
}
// ------------------------------------------------------------------------------------------------
CPickup & CPickup::ApplyTag(StackStrF & tag)
{
SetTag(tag);
return *this;
}
// ------------------------------------------------------------------------------------------------
LightObj & CPickup::GetData()
{
// Validate the managed identifier
Validate();
// Return the requested information
return m_Data;
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetData(LightObj & data)
{
// Validate the managed identifier
Validate();
// Apply the specified value
m_Data = data;
}
// ------------------------------------------------------------------------------------------------
bool CPickup::Destroy(Int32 header, LightObj & payload)
{
// Validate the managed identifier
Validate();
// Perform the requested operation
return Core::Get().DelPickup(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
LightObj & CPickup::GetEvents() const
{
// Validate the managed identifier
Validate();
// Return the associated event table
return Core::Get().GetPickup(m_ID).mEvents;
}
// ------------------------------------------------------------------------------------------------
void CPickup::CustomEvent(Int32 header, LightObj & payload) const
{
// Validate the managed identifier
Validate();
// Perfrom the requested action
Core::Get().EmitPickupCustom(m_ID, header, payload);
}
// ------------------------------------------------------------------------------------------------
bool CPickup::IsStreamedFor(CPlayer & player) const
{
// Is the specified player even valid?
if (!player.IsActive())
{
STHROWF("Invalid player argument: null");
}
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->IsPickupStreamedForPlayer(m_ID, player.GetID());
}
// ------------------------------------------------------------------------------------------------
bool CPickup::GetOption(Int32 option_id) const
{
// Attempt to obtain the current value of the specified option
const bool value = _Func->GetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id));
// Check for errors
if (_Func->GetLastError() == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: %d", option_id);
}
// Return the requested value
return value;
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetOption(Int32 option_id, bool toggle)
{
// Attempt to obtain the current value of the specified option
const bool value = _Func->GetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id));
// Attempt to modify the current value of the specified option
if (_Func->SetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id),
toggle) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: %d", option_id);
}
else if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_OPTION))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_OPTION);
// Now forward the event call
Core::Get().EmitPickupOption(m_ID, option_id, value, 0, NullLightObj());
}
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload)
{
// Attempt to obtain the current value of the specified option
const bool value = _Func->GetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id));
// Attempt to modify the current value of the specified option
if (_Func->SetPickupOption(m_ID, static_cast< vcmpPickupOption >(option_id),
toggle) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: %d", option_id);
}
else if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_OPTION))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_OPTION);
// Now forward the event call
Core::Get().EmitPickupOption(m_ID, option_id, value, header, payload);
}
}
// ------------------------------------------------------------------------------------------------
Int32 CPickup::GetWorld() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetPickupWorld(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetWorld(Int32 world)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const Int32 current = _Func->GetPickupWorld(m_ID);
// Don't even bother if it's the same value
if (current == world)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetPickupWorld(m_ID, world);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_WORLD))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_WORLD);
// Now forward the event call
Core::Get().EmitPickupWorld(m_ID, current, world);
}
}
// ------------------------------------------------------------------------------------------------
Int32 CPickup::GetAlpha() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetPickupAlpha(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetAlpha(Int32 alpha)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const Int32 current = _Func->GetPickupAlpha(m_ID);
// Don't even bother if it's the same value
if (current == alpha)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetPickupAlpha(m_ID, alpha);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_ALPHA))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_ALPHA);
// Now forward the event call
Core::Get().EmitPickupAlpha(m_ID, current, alpha);
}
}
// ------------------------------------------------------------------------------------------------
bool CPickup::GetAutomatic() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->IsPickupAutomatic(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetAutomatic(bool toggle)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const bool current = _Func->IsPickupAutomatic(m_ID);
// Don't even bother if it's the same value
if (current == toggle)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetPickupIsAutomatic(m_ID, toggle);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_AUTOMATIC))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_AUTOMATIC);
// Now forward the event call
Core::Get().EmitPickupAutomatic(m_ID, current, toggle);
}
}
// ------------------------------------------------------------------------------------------------
Int32 CPickup::GetAutoTimer() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetPickupAutoTimer(m_ID);
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetAutoTimer(Int32 timer)
{
// Validate the managed identifier
Validate();
// Grab the current value for this property
const Int32 current = _Func->GetPickupAutoTimer(m_ID);
// Don't even bother if it's the same value
if (current == timer)
{
return;
}
// Avoid property unwind from a recursive call
_Func->SetPickupAutoTimer(m_ID, timer);
// Avoid infinite recursive event loops
if (!(m_CircularLocks & PICKUPCL_EMIT_PICKUP_AUTOTIMER))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PICKUPCL_EMIT_PICKUP_AUTOTIMER);
// Now forward the event call
Core::Get().EmitPickupAutoTimer(m_ID, current, timer);
}
}
// ------------------------------------------------------------------------------------------------
void CPickup::Refresh() const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->RefreshPickup(m_ID);
}
// ------------------------------------------------------------------------------------------------
Vector3 CPickup::GetPosition()
{
// Validate the managed identifier
Validate();
// Create a default vector instance
Vector3 vec;
// Query the server for the position values
_Func->GetPickupPosition(m_ID, &vec.x, &vec.y, &vec.z);
// Return the requested information
return vec;
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetPosition(const Vector3 & pos) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetPickupPosition(m_ID, pos.x, pos.y, pos.z);
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetPositionEx(Float32 x, Float32 y, Float32 z) const
{
// Validate the managed identifier
Validate();
// Perform the requested operation
_Func->SetPickupPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
Int32 CPickup::GetModel() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetPickupModel(m_ID);
}
// ------------------------------------------------------------------------------------------------
Int32 CPickup::GetQuantity() const
{
// Validate the managed identifier
Validate();
// Return the requested information
return _Func->GetPickupQuantity(m_ID);
}
// ------------------------------------------------------------------------------------------------
Float32 CPickup::GetPositionX() const
{
// Validate the managed identifier
Validate();
// Clear previous position information, if any
Float32 x = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetPickupPosition(m_ID, &x, &dummy, &dummy);
// Return the requested information
return x;
}
// ------------------------------------------------------------------------------------------------
Float32 CPickup::GetPositionY() const
{
// Validate the managed identifier
Validate();
// Clear previous position information, if any
Float32 y = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetPickupPosition(m_ID, &dummy, &y, &dummy);
// Return the requested information
return y;
}
// ------------------------------------------------------------------------------------------------
Float32 CPickup::GetPositionZ() const
{
// Validate the managed identifier
Validate();
// Clear previous position information, if any
Float32 z = 0.0f, dummy;
// Query the server for the requested component value
_Func->GetPickupPosition(m_ID, &dummy, &dummy, &z);
// Return the requested information
return z;
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetPositionX(Float32 x) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 y, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetPickupPosition(m_ID, &dummy, &y, &z);
// Perform the requested operation
_Func->SetPickupPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetPositionY(Float32 y) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, z, dummy;
// Retrieve the current values for unchanged components
_Func->GetPickupPosition(m_ID, &x, &dummy, &z);
// Perform the requested operation
_Func->SetPickupPosition(m_ID, x, y, z);
}
// ------------------------------------------------------------------------------------------------
void CPickup::SetPositionZ(Float32 z) const
{
// Validate the managed identifier
Validate();
// Reserve some temporary floats to retrieve the missing components
Float32 x, y, dummy;
// Retrieve the current values for unchanged components
_Func->GetPickupPosition(m_ID, &x, &y, &dummy);
// Perform the requested operation
_Func->SetPickupPosition(m_ID, z, y, z);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity,
Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic)
{
return Core::Get().NewPickup(model, world, quantity, x, y, z, alpha, automatic,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity,
Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic,
Int32 header, LightObj & payload)
{
return Core::Get().NewPickup(model, world, quantity, x, y, z, alpha, automatic, header, payload);
}
// ------------------------------------------------------------------------------------------------
static LightObj & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos,
Int32 alpha, bool automatic)
{
return Core::Get().NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic,
SQMOD_CREATE_DEFAULT, NullLightObj());
}
static LightObj & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos,
Int32 alpha, bool automatic, Int32 header, LightObj & payload)
{
return Core::Get().NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic,
header, payload);
}
// ================================================================================================
void Register_CPickup(HSQUIRRELVM vm)
{
RootTable(vm).Bind(Typename::Str,
Class< CPickup, NoConstructor< CPickup > >(vm, Typename::Str)
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &CPickup::ToString)
// Static Values
.SetStaticValue(_SC("MaxID"), CPickup::Max)
// Core Properties
.Prop(_SC("On"), &CPickup::GetEvents)
.Prop(_SC("ID"), &CPickup::GetID)
.Prop(_SC("Tag"), &CPickup::GetTag, &CPickup::SetTag)
.Prop(_SC("Data"), &CPickup::GetData, &CPickup::SetData)
.Prop(_SC("Active"), &CPickup::IsActive)
// Core Methods
.FmtFunc(_SC("SetTag"), &CPickup::ApplyTag)
.Func(_SC("CustomEvent"), &CPickup::CustomEvent)
// Core Overloads
.Overload< bool (CPickup::*)(void) >(_SC("Destroy"), &CPickup::Destroy)
.Overload< bool (CPickup::*)(Int32) >(_SC("Destroy"), &CPickup::Destroy)
.Overload< bool (CPickup::*)(Int32, LightObj &) >(_SC("Destroy"), &CPickup::Destroy)
// Properties
.Prop(_SC("Model"), &CPickup::GetModel)
.Prop(_SC("World"), &CPickup::GetWorld, &CPickup::SetWorld)
.Prop(_SC("Alpha"), &CPickup::GetAlpha, &CPickup::SetAlpha)
.Prop(_SC("Auto"), &CPickup::GetAutomatic, &CPickup::SetAutomatic)
.Prop(_SC("Automatic"), &CPickup::GetAutomatic, &CPickup::SetAutomatic)
.Prop(_SC("Timer"), &CPickup::GetAutoTimer, &CPickup::SetAutoTimer)
.Prop(_SC("Autotimer"), &CPickup::GetAutoTimer, &CPickup::SetAutoTimer)
.Prop(_SC("Pos"), &CPickup::GetPosition, &CPickup::SetPosition)
.Prop(_SC("Position"), &CPickup::GetPosition, &CPickup::SetPosition)
.Prop(_SC("Quantity"), &CPickup::GetQuantity)
.Prop(_SC("PosX"), &CPickup::GetPositionX, &CPickup::SetPositionX)
.Prop(_SC("PosY"), &CPickup::GetPositionY, &CPickup::SetPositionY)
.Prop(_SC("PosZ"), &CPickup::GetPositionZ, &CPickup::SetPositionZ)
// Member Methods
.Func(_SC("StreamedFor"), &CPickup::IsStreamedFor)
.Func(_SC("GetOption"), &CPickup::GetOption)
.Func(_SC("SetOption"), &CPickup::SetOption)
.Func(_SC("SetOptionEx"), &CPickup::SetOptionEx)
.Func(_SC("Refresh"), &CPickup::Refresh)
.Func(_SC("SetPos"), &CPickup::SetPositionEx)
.Func(_SC("SetPosition"), &CPickup::SetPositionEx)
// Static Overloads
.StaticOverload< LightObj & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool) >
(_SC("CreateEx"), &Pickup_CreateEx)
.StaticOverload< LightObj & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool, Int32, LightObj &) >
(_SC("CreateEx"), &Pickup_CreateEx)
.StaticOverload< LightObj & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool) >
(_SC("Create"), &Pickup_Create)
.StaticOverload< LightObj & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool, Int32, LightObj &) >
(_SC("Create"), &Pickup_Create)
// Raw Squirrel Methods
.SquirrelFunc(_SC("NullInst"), &CPickup::SqGetNull)
.SquirrelFunc(_SC("MakeTask"), &Tasks::MakeTask< CPickup, ENT_PICKUP >)
.SquirrelFunc(_SC("DropTask"), &Tasks::DropTask< CPickup, ENT_PICKUP >)
.SquirrelFunc(_SC("DoesTask"), &Tasks::DoesTask< CPickup, ENT_PICKUP >)
.SquirrelFunc(_SC("FindTask"), &Tasks::FindTask< CPickup, ENT_PICKUP >)
);
}
} // Namespace:: SqMod

310
module/Entity/Pickup.hpp Normal file
View File

@ -0,0 +1,310 @@
#ifndef _ENTITY_PICKUP_HPP_
#define _ENTITY_PICKUP_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Circular locks employed by the pickup manager.
*/
enum PickupCircularLocks
{
PICKUPCL_EMIT_PICKUP_OPTION = (1 << 0),
PICKUPCL_EMIT_PICKUP_WORLD = (1 << 1),
PICKUPCL_EMIT_PICKUP_ALPHA = (1 << 2),
PICKUPCL_EMIT_PICKUP_AUTOMATIC = (1 << 3),
PICKUPCL_EMIT_PICKUP_AUTOTIMER = (1 << 4)
};
/* ------------------------------------------------------------------------------------------------
* Manages a single pickup entity.
*/
class CPickup
{
// --------------------------------------------------------------------------------------------
friend class Core;
private:
/* --------------------------------------------------------------------------------------------
* Identifier of the managed entity.
*/
Int32 m_ID;
/* --------------------------------------------------------------------------------------------
* User tag associated with this instance.
*/
String m_Tag;
/* --------------------------------------------------------------------------------------------
* User data associated with this instance.
*/
LightObj m_Data;
/* --------------------------------------------------------------------------------------------
* Prevent events from triggering themselves.
*/
Uint32 m_CircularLocks;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
CPickup(Int32 id);
public:
/* --------------------------------------------------------------------------------------------
* Maximum possible number that could represent an identifier for this entity type.
*/
static const Int32 Max;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
CPickup(const CPickup &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
CPickup(CPickup &&) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CPickup();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
CPickup & operator = (const CPickup &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
CPickup & operator = (CPickup &&) = delete;
/* --------------------------------------------------------------------------------------------
* See whether this instance manages a valid entity instance otherwise throw an exception.
*/
void Validate() const
{
if (INVALID_ENTITY(m_ID))
{
STHROWF("Invalid pickup reference [%s]", m_Tag.c_str());
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static SQInteger SqGetNull(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static LightObj & GetNull();
/* --------------------------------------------------------------------------------------------
* Retrieve the identifier of the entity managed by this instance.
*/
Int32 GetID() const
{
return m_ID;
}
/* --------------------------------------------------------------------------------------------
* Check whether this instance manages a valid entity.
*/
bool IsActive() const
{
return VALID_ENTITY(m_ID);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user tag.
*/
const String & GetTag() const;
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
void SetTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
CPickup & ApplyTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user data.
*/
LightObj & GetData();
/* --------------------------------------------------------------------------------------------
* Modify the associated user data.
*/
void SetData(LightObj & data);
/* --------------------------------------------------------------------------------------------
* Destroy the managed pickup entity.
*/
bool Destroy()
{
return Destroy(0, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed pickup entity.
*/
bool Destroy(Int32 header)
{
return Destroy(header, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed pickup entity.
*/
bool Destroy(Int32 header, LightObj & payload);
/* --------------------------------------------------------------------------------------------
* Retrieve the events table of this entity.
*/
LightObj & GetEvents() const;
/* --------------------------------------------------------------------------------------------
* Emit a custom event for the managed entity
*/
void CustomEvent(Int32 header, LightObj & payload) const;
/* --------------------------------------------------------------------------------------------
* See if the managed pickup entity is streamed for the specified player.
*/
bool IsStreamedFor(CPlayer & player) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the current option value of the managed pickup entity.
*/
bool GetOption(Int32 option_id) const;
/* --------------------------------------------------------------------------------------------
* Modify the current option value of the managed pickup entity.
*/
void SetOption(Int32 option_id, bool toggle);
/* --------------------------------------------------------------------------------------------
* Modify the current option value of the managed pickup entity.
*/
void SetOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload);
/* --------------------------------------------------------------------------------------------
* Retrieve the world in which the managed pickup entity exists.
*/
Int32 GetWorld() const;
/* --------------------------------------------------------------------------------------------
* Mpdify the world in which the managed pickup entity exists.
*/
void SetWorld(Int32 world);
/* --------------------------------------------------------------------------------------------
* Retrieve the alpha of the managed pickup entity.
*/
Int32 GetAlpha() const;
/* --------------------------------------------------------------------------------------------
* Mpdify the alpha of the managed pickup entity.
*/
void SetAlpha(Int32 alpha);
/* --------------------------------------------------------------------------------------------
* See whether the managed pickup entity is automatic.
*/
bool GetAutomatic() const;
/* --------------------------------------------------------------------------------------------
* Set whether the managed pickup entity is automatic.
*/
void SetAutomatic(bool toggle);
/* --------------------------------------------------------------------------------------------
* Retrieve the automatic timer of the managed pickup entity.
*/
Int32 GetAutoTimer() const;
/* --------------------------------------------------------------------------------------------
* Mpdify the automatic timer of the managed pickup entity.
*/
void SetAutoTimer(Int32 timer);
/* --------------------------------------------------------------------------------------------
* Refresh the managed pickup entity.
*/
void Refresh() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position of the managed pickup entity.
*/
Vector3 GetPosition();
/* --------------------------------------------------------------------------------------------
* Mpdify the position of the managed pickup entity.
*/
void SetPosition(const Vector3 & pos) const;
/* --------------------------------------------------------------------------------------------
* Mpdify the position of the managed pickup entity.
*/
void SetPositionEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the model of the managed pickup entity.
*/
Int32 GetModel() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the quantity of the managed pickup entity.
*/
Int32 GetQuantity() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the x axis of the managed pickup entity.
*/
Float32 GetPositionX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the y axis of the managed pickup entity.
*/
Float32 GetPositionY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the z axis of the managed pickup entity.
*/
Float32 GetPositionZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the x axis of the managed pickup entity.
*/
void SetPositionX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the y axis of the managed pickup entity.
*/
void SetPositionY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the z axis of the managed pickup entity.
*/
void SetPositionZ(Float32 z) const;
};
} // Namespace:: SqMod
#endif // _ENTITY_PICKUP_HPP_

2928
module/Entity/Player.cpp Normal file

File diff suppressed because it is too large Load Diff

1092
module/Entity/Player.hpp Normal file

File diff suppressed because it is too large Load Diff

2139
module/Entity/Vehicle.cpp Normal file

File diff suppressed because it is too large Load Diff

928
module/Entity/Vehicle.hpp Normal file
View File

@ -0,0 +1,928 @@
#ifndef _ENTITY_VEHICLE_HPP_
#define _ENTITY_VEHICLE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Circular locks employed by the vehicle manager.
*/
enum VehicleCircularLocks
{
VEHICLECL_EMIT_VEHICLE_OPTION = (1 << 0),
VEHICLECL_EMIT_VEHICLE_WORLD = (1 << 1),
VEHICLECL_EMIT_VEHICLE_IMMUNITY = (1 << 2),
VEHICLECL_EMIT_VEHICLE_PARTSTATUS = (1 << 3),
VEHICLECL_EMIT_VEHICLE_TYRESTATUS = (1 << 4),
VEHICLECL_EMIT_VEHICLE_DAMAGEDATA = (1 << 5),
VEHICLECL_EMIT_VEHICLE_RADIO = (1 << 6),
VEHICLECL_EMIT_VEHICLE_HANDLINGRULE = (1 << 7)
};
/* ------------------------------------------------------------------------------------------------
* Manages a single vehicle entity.
*/
class CVehicle
{
// --------------------------------------------------------------------------------------------
friend class Core;
private:
/* --------------------------------------------------------------------------------------------
* Identifier of the managed entity.
*/
Int32 m_ID;
/* --------------------------------------------------------------------------------------------
* User tag associated with this instance.
*/
String m_Tag;
/* --------------------------------------------------------------------------------------------
* User data associated with this instance.
*/
LightObj m_Data;
/* --------------------------------------------------------------------------------------------
* Prevent events from triggering themselves.
*/
Uint32 m_CircularLocks;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
CVehicle(Int32 id);
public:
/* --------------------------------------------------------------------------------------------
* Maximum possible number that could represent an identifier for this entity type.
*/
static const Int32 Max;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
CVehicle(const CVehicle &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
CVehicle(CVehicle &&) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CVehicle();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
CVehicle & operator = (const CVehicle &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
CVehicle & operator = (CVehicle &&) = delete;
/* --------------------------------------------------------------------------------------------
* See whether this instance manages a valid entity.
*/
void Validate() const
{
if (INVALID_ENTITY(m_ID))
{
STHROWF("Invalid vehicle reference [%s]", m_Tag.c_str());
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
const String & ToString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static SQInteger SqGetNull(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated null entity instance.
*/
static LightObj & GetNull();
/* --------------------------------------------------------------------------------------------
* Retrieve the identifier of the entity managed by this instance.
*/
Int32 GetID() const
{
return m_ID;
}
/* --------------------------------------------------------------------------------------------
* Check whether this instance manages a valid entity.
*/
bool IsActive() const
{
return VALID_ENTITY(m_ID);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user tag.
*/
const String & GetTag() const;
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
void SetTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Modify the associated user tag.
*/
CVehicle & ApplyTag(StackStrF & tag);
/* --------------------------------------------------------------------------------------------
* Retrieve the associated user data.
*/
LightObj & GetData();
/* --------------------------------------------------------------------------------------------
* Modify the associated user data.
*/
void SetData(LightObj & data);
/* --------------------------------------------------------------------------------------------
* Destroy the managed vehicle entity.
*/
bool Destroy()
{
return Destroy(0, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed vehicle entity.
*/
bool Destroy(Int32 header)
{
return Destroy(header, NullLightObj());
}
/* --------------------------------------------------------------------------------------------
* Destroy the managed vehicle entity.
*/
bool Destroy(Int32 header, LightObj & payload);
/* --------------------------------------------------------------------------------------------
* Retrieve the events table of this entity.
*/
LightObj & GetEvents() const;
/* --------------------------------------------------------------------------------------------
* Emit a custom event for the managed entity
*/
void CustomEvent(Int32 header, LightObj & payload) const;
/* --------------------------------------------------------------------------------------------
* See if the managed vehicle entity is streamed for the specified player.
*/
bool IsStreamedFor(CPlayer & player) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the current option value of the managed vehicle entity.
*/
bool GetOption(Int32 option_id) const;
/* --------------------------------------------------------------------------------------------
* Modify the current option value of the managed vehicle entity.
*/
void SetOption(Int32 option_id, bool toggle);
/* --------------------------------------------------------------------------------------------
* Modify the current option value of the managed vehicle entity.
*/
void SetOptionEx(Int32 option_id, bool toggle, Int32 header, LightObj & payload);
/* --------------------------------------------------------------------------------------------
* Retrieve the synchronization source of the managed vehicle entity.
*/
Int32 GetSyncSource() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the synchronization type of the managed vehicle entity.
*/
Int32 GetSyncType() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the world in which the managed vehicle entity exists.
*/
Int32 GetWorld() const;
/* --------------------------------------------------------------------------------------------
* Modify the world in which the managed vehicle entity exists.
*/
void SetWorld(Int32 world);
/* --------------------------------------------------------------------------------------------
* Retrieve the vehicle model of the managed vehicle entity.
*/
Int32 GetModel() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the slot occupant from the managed vehicle entity.
*/
LightObj & GetOccupant(Int32 slot) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the slot occupant identifier from the managed vehicle entity.
*/
Int32 GetOccupantID(Int32 slot) const;
/* --------------------------------------------------------------------------------------------
* See whether the managed vehicle entity has an occupant in a certain slot.
*/
bool HasOccupant(Int32 slot) const;
/* --------------------------------------------------------------------------------------------
* Respawn the managed vehicle entity.
*/
void Respawn() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the immunity flags of the managed vehicle entity.
*/
Int32 GetImmunity() const;
/* --------------------------------------------------------------------------------------------
* Modify the immunity flags of the managed vehicle entity.
*/
void SetImmunity(Int32 flags);
/* --------------------------------------------------------------------------------------------
* Explode the managed vehicle entity.
*/
void Explode() const;
/* --------------------------------------------------------------------------------------------
* See whether the managed vehicle entity is wrecked.
*/
bool IsWrecked() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position of the managed vehicle entity.
*/
Vector3 GetPosition() const;
/* --------------------------------------------------------------------------------------------
* Modify the position of the managed vehicle entity.
*/
void SetPosition(const Vector3 & pos) const;
/* --------------------------------------------------------------------------------------------
* Modify the position of the managed vehicle entity.
*/
void SetPositionEx(const Vector3 & pos, bool empty) const;
/* --------------------------------------------------------------------------------------------
* Modify the position of the managed vehicle entity.
*/
void SetPositionEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the position of the managed vehicle entity.
*/
void SetPositionEx(Float32 x, Float32 y, Float32 z, bool empty) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation of the managed vehicle entity.
*/
Quaternion GetRotation() const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation of the managed vehicle entity.
*/
void SetRotation(const Quaternion & rot) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation of the managed vehicle entity.
*/
void SetRotationEx(Float32 x, Float32 y, Float32 z, Float32 w) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the euler rotation of the managed vehicle entity.
*/
Vector3 GetRotationEuler() const;
/* --------------------------------------------------------------------------------------------
* Modify the euler rotation of the managed vehicle entity.
*/
void SetRotationEuler(const Vector3 & rot) const;
/* --------------------------------------------------------------------------------------------
* Modify the euler rotation of the managed vehicle entity.
*/
void SetRotationEulerEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the speed of the managed vehicle entity.
*/
Vector3 GetSpeed() const;
/* --------------------------------------------------------------------------------------------
* Modify the speed of the managed vehicle entity.
*/
void SetSpeed(const Vector3 & vel) const;
/* --------------------------------------------------------------------------------------------
* Modify the speed of the managed vehicle entity.
*/
void SetSpeedEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the speed of the managed vehicle entity.
*/
void AddSpeed(const Vector3 & vel) const;
/* --------------------------------------------------------------------------------------------
* Modify the speed of the managed vehicle entity.
*/
void AddSpeedEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the relative speed of the managed vehicle entity.
*/
Vector3 GetRelativeSpeed() const;
/* --------------------------------------------------------------------------------------------
* Modify the relative speed of the managed vehicle entity.
*/
void SetRelativeSpeed(const Vector3 & vel) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative speed of the managed vehicle entity.
*/
void SetRelativeSpeedEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative speed of the managed vehicle entity.
*/
void AddRelativeSpeed(const Vector3 & vel) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative speed of the managed vehicle entity.
*/
void AddRelativeSpeedEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the turn speed of the managed vehicle entity.
*/
Vector3 GetTurnSpeed() const;
/* --------------------------------------------------------------------------------------------
* Modify the turn speed of the managed vehicle entity.
*/
void SetTurnSpeed(const Vector3 & vel) const;
/* --------------------------------------------------------------------------------------------
* Modify the turn speed of the managed vehicle entity.
*/
void SetTurnSpeedEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the turn speed of the managed vehicle entity.
*/
void AddTurnSpeed(const Vector3 & vel) const;
/* --------------------------------------------------------------------------------------------
* Modify the turn speed of the managed vehicle entity.
*/
void AddTurnSpeedEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the relative turn speed of the managed vehicle entity.
*/
Vector3 GetRelativeTurnSpeed() const;
/* --------------------------------------------------------------------------------------------
* Modify the relative turn speed of the managed vehicle entity.
*/
void SetRelativeTurnSpeed(const Vector3 & vel) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative turn speed of the managed vehicle entity.
*/
void SetRelativeTurnSpeedEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative turn speed of the managed vehicle entity.
*/
void AddRelativeTurnSpeed(const Vector3 & vel) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative turn speed of the managed vehicle entity.
*/
void AddRelativeTurnSpeedEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the spawn position of the managed vehicle entity.
*/
Vector3 GetSpawnPosition() const;
/* --------------------------------------------------------------------------------------------
* Modify the spawn position of the managed vehicle entity.
*/
void SetSpawnPosition(const Vector3 & pos) const;
/* --------------------------------------------------------------------------------------------
* Modify the spawn position of the managed vehicle entity.
*/
void SetSpawnPositionEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the spawn rotation of the managed vehicle entity.
*/
Quaternion GetSpawnRotation() const;
/* --------------------------------------------------------------------------------------------
* Modify the spawn rotation of the managed vehicle entity.
*/
void SetSpawnRotation(const Quaternion & rot) const;
/* --------------------------------------------------------------------------------------------
* Modify the spawn rotation of the managed vehicle entity.
*/
void SetSpawnRotationEx(Float32 x, Float32 y, Float32 z, Float32 w) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the euler spawn rotation of the managed vehicle entity.
*/
Vector3 GetSpawnRotationEuler() const;
/* --------------------------------------------------------------------------------------------
* Modify the euler spawn rotation of the managed vehicle entity.
*/
void SetSpawnRotationEuler(const Vector3 & rot) const;
/* --------------------------------------------------------------------------------------------
* Modify the euler spawn rotation of the managed vehicle entity.
*/
void SetSpawnRotationEulerEx(Float32 x, Float32 y, Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the respawn timer of the managed vehicle entity.
*/
Uint32 GetIdleRespawnTimer() const;
/* --------------------------------------------------------------------------------------------
* Modify the respawn timer of the managed vehicle entity.
*/
void SetIdleRespawnTimer(Uint32 millis) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the health of the managed vehicle entity.
*/
Float32 GetHealth() const;
/* --------------------------------------------------------------------------------------------
* Modify the health of the managed vehicle entity.
*/
void SetHealth(Float32 amount) const;
/* --------------------------------------------------------------------------------------------
* Fix the damage and restore health for the managed vehicle entity.
*/
void Fix() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the primary color of the managed vehicle entity.
*/
Int32 GetPrimaryColor() const;
/* --------------------------------------------------------------------------------------------
* Modify the primary color of the managed vehicle entity.
*/
void SetPrimaryColor(Int32 col) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the secondary color of the managed vehicle entity.
*/
Int32 GetSecondaryColor() const;
/* --------------------------------------------------------------------------------------------
* Modify the secondary color of the managed vehicle entity.
*/
void SetSecondaryColor(Int32 col) const;
/* --------------------------------------------------------------------------------------------
* Modify the primary and secondary colors of the managed vehicle entity.
*/
void SetColors(Int32 primary, Int32 secondary) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the part status of the managed vehicle entity.
*/
Int32 GetPartStatus(Int32 part) const;
/* --------------------------------------------------------------------------------------------
* Modify the part status of the managed vehicle entity.
*/
void SetPartStatus(Int32 part, Int32 status);
/* --------------------------------------------------------------------------------------------
* Retrieve the tyre status of the managed vehicle entity.
*/
Int32 GetTyreStatus(Int32 tyre) const;
/* --------------------------------------------------------------------------------------------
* Modify the tyre status of the managed vehicle entity.
*/
void SetTyreStatus(Int32 tyre, Int32 status);
/* --------------------------------------------------------------------------------------------
* Retrieve the damage data of the managed vehicle entity.
*/
Uint32 GetDamageData() const;
/* --------------------------------------------------------------------------------------------
* Modify the damage data of the managed vehicle entity.
*/
void SetDamageData(Uint32 data);
/* --------------------------------------------------------------------------------------------
* Retrieve the radio of the managed vehicle entity.
*/
Int32 GetRadio() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the radio of the managed vehicle entity.
*/
void SetRadio(Int32 radio);
/* --------------------------------------------------------------------------------------------
* Retrieve the turret rotation of the managed vehicle entity.
*/
Vector2 GetTurretRotation() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the horizontal turret rotation of the managed vehicle entity.
*/
Float32 GetHorizontalTurretRotation() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the vertical turret rotation of the managed vehicle entity.
*/
Float32 GetVerticalTurretRotation() const;
/* --------------------------------------------------------------------------------------------
* See whether the specified handling ruleexists in the managed vehicle entity.
*/
bool ExistsHandlingRule(Int32 rule) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the handling data of the managed vehicle entity.
*/
Float32 GetHandlingRule(Int32 rule) const;
/* --------------------------------------------------------------------------------------------
* Modify the handling data of the managed vehicle entity.
*/
void SetHandlingRule(Int32 rule, Float32 data);
/* --------------------------------------------------------------------------------------------
* Reset the specified handling rule for the managed vehicle entity.
*/
void ResetHandlingRule(Int32 rule);
/* --------------------------------------------------------------------------------------------
* Reset all the handling rules for the managed vehicle entity.
*/
void ResetHandlings() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the lights data for the managed vehicle entity.
*/
Int32 GetLightsData() const;
/* --------------------------------------------------------------------------------------------
* Modify the lights data for the managed vehicle entity.
*/
void SetLightsData(Int32 data) const;
/* --------------------------------------------------------------------------------------------
* Embark the specified player entity into the managed vehicle entity.
*/
bool Embark(CPlayer & player) const;
/* --------------------------------------------------------------------------------------------
* Embark the specified player entity into the managed vehicle entity.
*/
bool Embark(CPlayer & player, Int32 slot, bool allocate, bool warp) const;
#if SQMOD_SDK_LEAST(2, 1)
/* --------------------------------------------------------------------------------------------
* Set whether the target player will see an objective arrow over a vehicle.
*/
void SetPlayer3DArrow(CPlayer & target, bool toggle) const;
/* --------------------------------------------------------------------------------------------
* See whether the target player sees an objective arrow over a vehicle.
*/
bool GetPlayer3DArrow(CPlayer & target) const;
/* --------------------------------------------------------------------------------------------
* Set whether the target player will see an objective arrow over a vehicle.
*/
void SetPlayer3DArrowID(SQInteger id, bool toggle) const;
/* --------------------------------------------------------------------------------------------
* See whether the target player sees an objective arrow over a vehicle.
*/
bool GetPlayer3DArrowID(SQInteger id) const;
#endif
/* --------------------------------------------------------------------------------------------
* See whether the managed vehicle entity collides with user defined areas.
*/
bool GetCollideAreas() const;
/* --------------------------------------------------------------------------------------------
* Set whether the managed vehicle entity can collide with user defined areas.
*/
void SetCollideAreas(bool toggle) const;
/* --------------------------------------------------------------------------------------------
* Set whether the managed vehicle entity can collide with user defined areas (with last test).
*/
void SetAreasCollide(bool toggle) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of tracked position changes for the managed vehicle entity.
*/
SQInteger GetTrackPosition() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of tracked position changes for the managed vehicle entity.
*/
void SetTrackPosition(SQInteger num) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of tracked rotation changes for the managed vehicle entity.
*/
SQInteger GetTrackRotation() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of tracked rotation changes for the managed vehicle entity.
*/
void SetTrackRotation(SQInteger num) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the last known primary color for the managed vehicle entity.
*/
Int32 GetLastPrimaryColor() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the last known secondary color for the managed vehicle entity.
*/
Int32 GetLastSecondaryColor() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the last known health for the managed vehicle entity.
*/
Float32 GetLastHealth() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the last known position for the managed player entity.
*/
const Vector3 & GetLastPosition() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the last known rotation for the managed player entity.
*/
const Quaternion & GetLastRotation() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the x axis of the managed vehicle entity.
*/
Float32 GetPositionX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the y axis of the managed vehicle entity.
*/
Float32 GetPositionY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the position on the z axis of the managed vehicle entity.
*/
Float32 GetPositionZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the x axis of the managed vehicle entity.
*/
void SetPositionX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the y axis of the managed vehicle entity.
*/
void SetPositionY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the position on the z axis of the managed vehicle entity.
*/
void SetPositionZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation on the x axis of the managed vehicle entity.
*/
Float32 GetRotationX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation on the y axis of the managed vehicle entity.
*/
Float32 GetRotationY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation on the z axis of the managed vehicle entity.
*/
Float32 GetRotationZ() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the rotation amount of the managed vehicle entity.
*/
Float32 GetRotationW() const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the x axis of the managed vehicle entity.
*/
void SetRotationX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the y axis of the managed vehicle entity.
*/
void SetRotationY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation on the z axis of the managed vehicle entity.
*/
void SetRotationZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Modify the rotation amount of the managed vehicle entity.
*/
void SetRotationW(Float32 w) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the euler rotation on the x axis of the managed vehicle entity.
*/
Float32 GetEulerRotationX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the euler rotation on the y axis of the managed vehicle entity.
*/
Float32 GetEulerRotationY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the euler rotation on the z axis of the managed vehicle entity.
*/
Float32 GetEulerRotationZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the euler rotation on the x axis of the managed vehicle entity.
*/
void SetEulerRotationX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the euler rotation on the y axis of the managed vehicle entity.
*/
void SetEulerRotationY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the euler rotation on the z axis of the managed vehicle entity.
*/
void SetEulerRotationZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the velocity on the x axis of the managed vehicle entity.
*/
Float32 GetSpeedX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the velocity on the y axis of the managed vehicle entity.
*/
Float32 GetSpeedY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the velocity on the z axis of the managed vehicle entity.
*/
Float32 GetSpeedZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the velocity on the x axis of the managed vehicle entity.
*/
void SetSpeedX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the velocity on the y axis of the managed vehicle entity.
*/
void SetSpeedY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the velocity on the z axis of the managed vehicle entity.
*/
void SetSpeedZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the relative velocity on the x axis of the managed vehicle entity.
*/
Float32 GetRelativeSpeedX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the relative velocity on the y axis of the managed vehicle entity.
*/
Float32 GetRelativeSpeedY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the relative velocity on the z axis of the managed vehicle entity.
*/
Float32 GetRelativeSpeedZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the relative velocity on the x axis of the managed vehicle entity.
*/
void SetRelativeSpeedX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative velocity on the y axis of the managed vehicle entity.
*/
void SetRelativeSpeedY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative velocity on the z axis of the managed vehicle entity.
*/
void SetRelativeSpeedZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the turn velocity on the x axis of the managed vehicle entity.
*/
Float32 GetTurnSpeedX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the turn velocity on the y axis of the managed vehicle entity.
*/
Float32 GetTurnSpeedY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the turn velocity on the z axis of the managed vehicle entity.
*/
Float32 GetTurnSpeedZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the turn velocity on the x axis of the managed vehicle entity.
*/
void SetTurnSpeedX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the turn velocity on the y axis of the managed vehicle entity.
*/
void SetTurnSpeedY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the turn velocity on the z axis of the managed vehicle entity.
*/
void SetTurnSpeedZ(Float32 z) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the relative turn velocity on the x axis of the managed vehicle entity.
*/
Float32 GetRelativeTurnSpeedX() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the relative turn velocity on the y axis of the managed vehicle entity.
*/
Float32 GetRelativeTurnSpeedY() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the relative turn velocity on the z axis of the managed vehicle entity.
*/
Float32 GetRelativeTurnSpeedZ() const;
/* --------------------------------------------------------------------------------------------
* Modify the relative turn velocity on the x axis of the managed vehicle entity.
*/
void SetRelativeTurnSpeedX(Float32 x) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative turn velocity on the y axis of the managed vehicle entity.
*/
void SetRelativeTurnSpeedY(Float32 y) const;
/* --------------------------------------------------------------------------------------------
* Modify the relative turn velocity on the z axis of the managed vehicle entity.
*/
void SetRelativeTurnSpeedZ(Float32 z) const;
};
} // Namespace:: SqMod
#endif // _ENTITY_VEHICLE_HPP_

309
module/Library/Chrono.cpp Normal file
View File

@ -0,0 +1,309 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono.hpp"
#include "Library/Chrono/Date.hpp"
#include "Library/Chrono/Datetime.hpp"
#include "Library/Chrono/Time.hpp"
#include "Library/Chrono/Timer.hpp"
#include "Library/Chrono/Timestamp.hpp"
#include "Library/Numeric/LongInt.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
#if defined(_SQ64) && (_WIN32_WINNT < 0x0600)
// We need this for the GetTickCount64() function
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif // _SQ64
#include <windows.h>
#else
#include <time.h>
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_ChronoDate(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoDatetime(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoTime(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoTimer(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoTimestamp(HSQUIRRELVM vm, Table & cns);
// ------------------------------------------------------------------------------------------------
const Uint8 Chrono::MonthLengths[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
/* ------------------------------------------------------------------------------------------------
* Used by GetCurrentSysTime to obtain the system frequency on initial call.
*/
inline LARGE_INTEGER GetFrequency()
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return frequency;
}
// ------------------------------------------------------------------------------------------------
Int64 Chrono::GetCurrentSysTime()
{
// Force the following code to run on first core
// (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx)
HANDLE current_thread = GetCurrentThread();
DWORD_PTR previous_mask = SetThreadAffinityMask(current_thread, 1);
// Get the frequency of the performance counter
// (it is constant across the program lifetime)
static const LARGE_INTEGER frequency = GetFrequency();
// Get the current time
LARGE_INTEGER time;
QueryPerformanceCounter(&time);
// Restore the thread affinity
SetThreadAffinityMask(current_thread, previous_mask);
// Return the current time as microseconds
return Int64(1000000LL * time.QuadPart / frequency.QuadPart);
}
// ------------------------------------------------------------------------------------------------
Int64 Chrono::GetEpochTimeMicro()
{
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
// Extract the nanoseconds from the resulted timestamp
Uint64 time = ft.dwHighDateTime;
time <<= 32;
time |= ft.dwLowDateTime;
time /= 10;
time -= 11644473600000000ULL;
// Return the resulted timestamp
return Int64(time);
}
// ------------------------------------------------------------------------------------------------
#ifndef _SQ64
Int64 GetTickCount64()
{
return static_cast< Int64 >(GetTickCount()); // Fall-back to 32 bit?
}
#endif // _SQ64
#else
// ------------------------------------------------------------------------------------------------
Int64 Chrono::GetCurrentSysTime()
{
// POSIX implementation
timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return Int64(Uint64(time.tv_sec) * 1000000 + time.tv_nsec / 1000);
}
// ------------------------------------------------------------------------------------------------
Int64 Chrono::GetEpochTimeMicro()
{
// POSIX implementation
timespec time;
clock_gettime(CLOCK_REALTIME, &time);
return Int64(Uint64(time.tv_sec) * 1000000 + time.tv_nsec / 1000);
}
// ------------------------------------------------------------------------------------------------
Uint32 GetTickCount()
{
// POSIX implementation
struct timespec time;
if (clock_gettime(CLOCK_MONOTONIC, &time))
{
return 0;
}
return time.tv_sec * 1000.0 + time.tv_nsec / 1000000.0;
}
// ------------------------------------------------------------------------------------------------
Int64 GetTickCount64()
{
struct timespec time;
if (clock_gettime(CLOCK_MONOTONIC, &time))
{
return 0;
}
return time.tv_sec * 1000.0 + time.tv_nsec / 1000000.0;
}
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
Int64 Chrono::GetEpochTimeMilli()
{
return (GetEpochTimeMicro() / 1000L);
}
// ------------------------------------------------------------------------------------------------
bool Chrono::ValidDate(Uint16 year, Uint8 month, Uint8 day)
{
// Is this a valid date?
if (year == 0 || month == 0 || day == 0)
{
return false;
}
// Is the month within range?
else if (month > 12)
{
return false;
}
// Return whether the day inside the month
return day <= DaysInMonth(year, month);
}
// ------------------------------------------------------------------------------------------------
Uint8 Chrono::DaysInMonth(Uint16 year, Uint8 month)
{
// Is the specified month within range?
if (month > 12)
{
STHROWF("Month value is out of range: %u > 12", month);
}
// Obtain the days in this month
Uint8 days = *(MonthLengths + month);
// Should we account for January?
if (month == 2 && IsLeapYear(year))
{
++days;
}
// Return the resulted days
return days;
}
// ------------------------------------------------------------------------------------------------
Uint16 Chrono::DayOfYear(Uint16 year, Uint8 month, Uint8 day)
{
// Start with 0 days
Uint16 doy = 0;
// Cumulate the days in months
for (Uint8 m = 1; m < month; ++month)
{
doy += DaysInMonth(year, m);
}
// Add the specified days
doy += day;
// Return the result
return doy;
}
// ------------------------------------------------------------------------------------------------
Date Chrono::ReverseDayOfyear(Uint16 year, Uint16 doy)
{
// The resulted month
Uint8 month = 1;
// Calculate the months till the specified day of year
for (; month < 12; ++month)
{
// Get the number of days in the current month
Uint32 days = DaysInMonth(year, month);
// Can this month fit in the remaining days?
if (days >= doy)
{
break; // The search is complete
}
// Subtract the month days from days of year
doy -= days;
}
// Return the resulted date
return Date(year, month, doy);
}
// ------------------------------------------------------------------------------------------------
Int64 Chrono::DateRangeToSeconds(Uint16 _year, Uint8 _month, Uint8 _day, Uint16 year_, Uint8 month_, Uint8 day_)
{
// Are we within the same year?
if (_year == year_)
{
return std::abs((DayOfYear(_year, _month, _day) - DayOfYear(year_, month_, day_)) * 86400LL);
}
// Is the start year greater than the end year?
else if (_year > year_)
{
std::swap(_year, year_);
std::swap(_month, month_);
std::swap(_day, day_);
}
// Calculate the remaining days from the first year
Int64 num = DaysInYear(_year) - DayOfYear(_year, _month, _day);
// Calculate the days withing the years range
while (++_year < year_)
{
num += DaysInYear(_year);
}
// Calculate the days up to the last day
num += DayOfYear(year_, month_, day_);
// Convert the obtained days in seconds
num *= 86400ULL;
// Return the result
return std::abs(num);
}
// ------------------------------------------------------------------------------------------------
static SLongInt SqGetEpochTimeMicro()
{
return SLongInt(Chrono::GetEpochTimeMicro());
}
// ------------------------------------------------------------------------------------------------
static SLongInt SqGetEpochTimeMilli()
{
return SLongInt(Chrono::GetEpochTimeMilli());
}
// ------------------------------------------------------------------------------------------------
static SLongInt SqGetCurrentSysTime()
{
return SLongInt(Chrono::GetCurrentSysTime());
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqGetTickCount()
{
return ConvTo< SQInteger >::From(GetTickCount());
}
// ------------------------------------------------------------------------------------------------
static SLongInt SqGetTickCount64()
{
return SLongInt(GetTickCount64());
}
// ================================================================================================
void Register_Chrono(HSQUIRRELVM vm)
{
Table cns(vm);
Register_ChronoDate(vm, cns);
Register_ChronoDatetime(vm, cns);
Register_ChronoTime(vm, cns);
Register_ChronoTimer(vm, cns);
Register_ChronoTimestamp(vm, cns);
cns
.Func(_SC("EpochMicro"), &SqGetEpochTimeMicro)
.Func(_SC("EpochMilli"), &SqGetEpochTimeMilli)
.Func(_SC("Current"), &SqGetCurrentSysTime)
.Func(_SC("TickCount"), &SqGetTickCount)
.Func(_SC("TickCount64"), &SqGetTickCount64)
.Func(_SC("IsLeapYear"), &Chrono::IsLeapYear)
.Func(_SC("IsDateValid"), &Chrono::ValidDate)
.Func(_SC("DaysInYear"), &Chrono::DaysInYear)
.Func(_SC("DaysInMonth"), &Chrono::DaysInMonth)
.Func(_SC("DayOfYear"), &Chrono::DayOfYear)
.Func(_SC("ReverseDayOfyear"), &Chrono::ReverseDayOfyear);
RootTable(vm).Bind(_SC("SqChrono"), cns);
}
} // Namespace:: SqMod

116
module/Library/Chrono.hpp Normal file
View File

@ -0,0 +1,116 @@
#ifndef _LIBRARY_CHRONO_HPP_
#define _LIBRARY_CHRONO_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
class Date;
class Time;
class Datetime;
class Timer;
class Timestamp;
/* ------------------------------------------------------------------------------------------------
* Class that offers helpers to work with time related information.
*/
class Chrono
{
public:
// ------------------------------------------------------------------------------------------------
static const Uint8 MonthLengths[12];
/* --------------------------------------------------------------------------------------------
* Default constructor. (disabled)
*/
Chrono() = delete;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Chrono(const Chrono & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
Chrono(Chrono && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor. (disabled)
*/
~Chrono() = delete;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Chrono & operator = (const Chrono & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
Chrono & operator = (Chrono && o) = delete;
/* --------------------------------------------------------------------------------------------
* Retrieve the current time as microseconds.
*/
static Int64 GetCurrentSysTime();
/* --------------------------------------------------------------------------------------------
* Retrieve the epoch time as microseconds.
*/
static Int64 GetEpochTimeMicro();
/* --------------------------------------------------------------------------------------------
* Retrieve the epoch time as milliseconds.
*/
static Int64 GetEpochTimeMilli();
/* --------------------------------------------------------------------------------------------
* See whether the specified date is valid.
*/
static bool ValidDate(Uint16 year, Uint8 month, Uint8 day);
/* --------------------------------------------------------------------------------------------
* See whether the specified year is a leap year.
*/
static bool IsLeapYear(Uint16 year)
{
return !(year % 400) || (!(year % 4) && (year % 100));
}
/* --------------------------------------------------------------------------------------------
* retrieve the number of days in the specified year.
*/
static Uint16 DaysInYear(Uint16 year)
{
return IsLeapYear(year) ? 366 : 365;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of days in the specified month.
*/
static Uint8 DaysInMonth(Uint16 year, Uint8 month);
/* --------------------------------------------------------------------------------------------
* Retrieve the number/position of the specified day in the specified year and month.
*/
static Uint16 DayOfYear(Uint16 year, Uint8 month, Uint8 day);
/* --------------------------------------------------------------------------------------------
* Convert just the year and day of year to full date.
*/
static Date ReverseDayOfyear(Uint16 year, Uint16 doy);
/* --------------------------------------------------------------------------------------------
* Calculate the number of days in the specified date range.
*/
static Int64 DateRangeToSeconds(Uint16 _year, Uint8 _month, Uint8 _day, Uint16 year_, Uint8 month_, Uint8 day_);
};
} // Namespace:: SqMod
#endif // _LIBRARY_CHRONO_HPP_

View File

@ -0,0 +1,414 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono/Date.hpp"
#include "Library/Chrono/Time.hpp"
#include "Library/Chrono/Datetime.hpp"
#include "Library/Chrono/Timestamp.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqDate"))
// ------------------------------------------------------------------------------------------------
SQChar Date::Delimiter = '-';
// ------------------------------------------------------------------------------------------------
Int32 Date::Compare(const Date & o) const
{
if (m_Year < o.m_Year)
{
return -1;
}
else if (m_Year > o.m_Year)
{
return 1;
}
else if (m_Month < o.m_Month)
{
return -1;
}
else if (m_Month > o.m_Month)
{
return 1;
}
else if (m_Day < o.m_Day)
{
return -1;
}
else if (m_Day > o.m_Day)
{
return 1;
}
// They're equal
return 0;
}
// ------------------------------------------------------------------------------------------------
Date Date::operator + (const Date & o) const
{
// Add the components individually
return Date(o);
}
// ------------------------------------------------------------------------------------------------
Date Date::operator - (const Date & o) const
{
return Date(o);
}
// ------------------------------------------------------------------------------------------------
Date Date::operator * (const Date & o) const
{
return Date(o);
}
// ------------------------------------------------------------------------------------------------
Date Date::operator / (const Date & o) const
{
return Date(o);
}
// ------------------------------------------------------------------------------------------------
CSStr Date::ToString() const
{
return ToStrF("%04u%c%02u%c%02u", m_Year, m_Delimiter, m_Month, m_Delimiter, m_Day);
}
// ------------------------------------------------------------------------------------------------
void Date::Set(Uint16 year, Uint8 month, Uint8 day)
{
if (!Chrono::ValidDate(year, month, day))
{
STHROWF("Invalid date: %04u%c%02u%c%02u" , m_Year, m_Delimiter, m_Month, m_Delimiter, m_Day);
}
// Assign the specified values
m_Year = year;
m_Month = month;
m_Day = day;
}
// ------------------------------------------------------------------------------------------------
void Date::SetStr(CSStr str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %u - %u - %u ");
// Is the specified string empty?
if (!str || *str == '\0')
{
// Clear the values
m_Year = 0;
m_Month = 0;
m_Day = 0;
// We're done here
return;
}
// Assign the specified delimiter
fs[4] = m_Delimiter;
fs[9] = m_Delimiter;
// The sscanf function requires at least 32 bit integers
Uint32 year = 0, month = 0, day = 0;
// Attempt to extract the component values from the specified string
sscanf(str, fs, &year, &month, &day);
// Clamp the extracted values to the boundaries of associated type and assign them
Set(ClampL< Uint32, Uint8 >(year),
ClampL< Uint32, Uint8 >(month),
ClampL< Uint32, Uint8 >(day)
);
}
// ------------------------------------------------------------------------------------------------
void Date::SetDayOfYear(Uint16 doy)
{
// Reverse the given day of year to a full date
Date d = Chrono::ReverseDayOfyear(m_Year, doy);
// Set the obtained month
SetMonth(d.m_Month);
// Set the obtained day
SetDay(d.m_Day);
}
// ------------------------------------------------------------------------------------------------
void Date::SetYear(Uint16 year)
{
// Make sure the year is valid
if (!year)
{
STHROWF("Invalid year: %u", year);
}
// Assign the value
m_Year = year;
// Make sure the new date is valid
if (!Chrono::ValidDate(m_Year, m_Month, m_Day))
{
m_Month = 1;
m_Day = 1;
}
}
// ------------------------------------------------------------------------------------------------
void Date::SetMonth(Uint8 month)
{
// Make sure the month is valid
if (month == 0 || month > 12)
{
STHROWF("Invalid month: %u", month);
}
// Assign the value
m_Month = month;
// Make sure the month days are in range
if (m_Day > Chrono::DaysInMonth(m_Year, m_Month))
{
m_Month = 1; // Fall back to the beginning of the month
}
}
// ------------------------------------------------------------------------------------------------
void Date::SetDay(Uint8 day)
{
// Grab the amount of days in the current month
const Uint8 dim = Chrono::DaysInMonth(m_Year, m_Month);
// Make sure the day is valid
if (day == 0)
{
STHROWF("Invalid day: %u", day);
}
else if (day > dim)
{
STHROWF("Day is out of range: %u > %u", day, dim);
}
// Assign the value
m_Day = day;
}
// ------------------------------------------------------------------------------------------------
Date & Date::AddYears(Int32 years)
{
// Do we have a valid amount of years?
if (years)
{
// Add the specified amount of years
SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Date & Date::AddMonths(Int32 months)
{
// Do we have a valid amount of months?
if (months)
{
// Extract the number of years
Int32 years = static_cast< Int32 >(months / 12);
// Extract the number of months
months = (months % 12) + m_Month;
// Do we have extra months?
if (months >= 12)
{
// Increase the years
++years;
// Subtract one year from months
months %= 12;
}
else if (months < 0)
{
// Decrease the years
--years;
// Add one year to months
months = 12 - months;
}
// Are there any years to add?
if (years)
{
SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
}
// Add the months
SetMonth(months);
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Date & Date::AddDays(Int32 days)
{
// Do we have a valid amount of days?
if (days)
{
// Whether the number of days is positive or negative
const Int32 dir = days > 0 ? 1 : -1;
// Grab current year
Int32 year = m_Year;
// Calculate the days in the current year
Int32 diy = Chrono::DaysInYear(year);
// Calculate the day of year
Int32 doy = GetDayOfYear() + days;
// Calculate the resulting years
while (doy > diy || doy < 0)
{
doy -= diy * dir;
year += dir;
diy = Chrono::DaysInYear(year);
}
// Set the obtained year
SetYear(year);
// Set the obtained day of year
SetDayOfYear(doy);
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Date Date::AndYears(Int32 years)
{
// Do we have a valid amount of years?
if (!years)
{
return Date(*this); // Return the date as is
}
// Replicate the current date
Date d(*this);
// Add the specified amount of years
d.SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
// Return the resulted date
return d;
}
// ------------------------------------------------------------------------------------------------
Date Date::AndMonths(Int32 months)
{
// Do we have a valid amount of months?
if (!months)
{
return Date(*this); // Return the date as is
}
// Extract the number of years
Int32 years = static_cast< Int32 >(months / 12);
// Extract the number of months
months = (months % 12) + m_Month;
// Do we have extra months?
if (months >= 12)
{
// Increase the years
++years;
// Subtract one year from months
months %= 12;
}
else if (months < 0)
{
// Decrease the years
--years;
// Add one year to months
months = 12 - months;
}
// Replicate the current date
Date d(*this);
// Are there any years to add?
if (years)
{
d.SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
}
// Add the months
d.SetMonth(months);
// Return the resulted date
return d;
}
// ------------------------------------------------------------------------------------------------
Date Date::AndDays(Int32 days)
{
// Do we have a valid amount of days?
if (!days)
{
return Date(*this); // Return the date as is
}
// Whether the number of days is positive or negative
const Int32 dir = days > 0 ? 1 : -1;
// Grab current year
Int32 year = m_Year;
// Calculate the days in the current year
Int32 diy = Chrono::DaysInYear(year);
// Calculate the day of year
Int32 doy = GetDayOfYear() + days;
// Calculate the resulting years
while (doy > diy || doy < 0)
{
doy -= diy * dir;
year += dir;
diy = Chrono::DaysInYear(year);
}
// Replicate the current date
Date d(*this);
// Set the obtained year
d.SetYear(year);
// Set the obtained day of year
d.SetDayOfYear(doy);
// Return the resulted date
return d;
}
// ------------------------------------------------------------------------------------------------
Timestamp Date::GetTimestamp() const
{
// Calculate the current day of the year
Int32 days = Chrono::DayOfYear(m_Year, m_Month, m_Day);
// Calculate all days till the current year
for (Int32 year = 0; year < m_Year; --year)
{
days += Chrono::DaysInYear(year);
}
// Return the resulted timestamp
return Timestamp(static_cast< Int64 >(days * 86400000000LL));
}
// ================================================================================================
void Register_ChronoDate(HSQUIRRELVM vm, Table & /*cns*/)
{
RootTable(vm).Bind(Typename::Str,
Class< Date >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Uint16 >()
.Ctor< Uint16, Uint8 >()
.Ctor< Uint16, Uint8, Uint8 >()
// Static Properties
.SetStaticValue(_SC("GlobalDelimiter"), &Date::Delimiter)
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Date::ToString)
.Func(_SC("cmp"), &Date::Cmp)
// Meta-methods
.Func< Date (Date::*)(const Date &) const >(_SC("_add"), &Date::operator +)
.Func< Date (Date::*)(const Date &) const >(_SC("_sub"), &Date::operator -)
.Func< Date (Date::*)(const Date &) const >(_SC("_mul"), &Date::operator *)
.Func< Date (Date::*)(const Date &) const >(_SC("_div"), &Date::operator /)
// Properties
.Prop(_SC("Delimiter"), &Date::GetDelimiter, &Date::SetDelimiter)
.Prop(_SC("Str"), &Date::GetStr, &Date::SetStr)
.Prop(_SC("DayOfYear"), &Date::GetDayOfYear, &Date::SetDayOfYear)
.Prop(_SC("Year"), &Date::GetYear, &Date::SetYear)
.Prop(_SC("Month"), &Date::GetMonth, &Date::SetMonth)
.Prop(_SC("Day"), &Date::GetDay, &Date::SetDay)
.Prop(_SC("LeapYear"), &Date::IsThisLeapYear)
.Prop(_SC("YearDays"), &Date::GetYearDays)
.Prop(_SC("MonthDays"), &Date::GetMonthDays)
.Prop(_SC("Timestamp"), &Date::GetTimestamp)
// Member Methods
.Func(_SC("AddYears"), &Date::AddYears)
.Func(_SC("AddMonths"), &Date::AddMonths)
.Func(_SC("AddDays"), &Date::AddDays)
.Func(_SC("AndYears"), &Date::AndYears)
.Func(_SC("AndMonths"), &Date::AndMonths)
.Func(_SC("AndDays"), &Date::AndDays)
// Overloaded Methods
.Overload< void (Date::*)(Uint16) >(_SC("Set"), &Date::Set)
.Overload< void (Date::*)(Uint16, Uint8) >(_SC("Set"), &Date::Set)
.Overload< void (Date::*)(Uint16, Uint8, Uint8) >(_SC("Set"), &Date::Set)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,357 @@
#ifndef _LIBRARY_CHRONO_DATE_HPP_
#define _LIBRARY_CHRONO_DATE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class used to represent a certain date.
*/
class Date
{
public:
// ------------------------------------------------------------------------------------------------
static SQChar Delimiter;
private:
// ------------------------------------------------------------------------------------------------
Uint16 m_Year; // Year
Uint8 m_Month; // Month
Uint8 m_Day; // Day
// ------------------------------------------------------------------------------------------------
SQChar m_Delimiter; // Component delimiter when generating strings.
protected:
/* ------------------------------------------------------------------------------------------------
* Compare the values of two instances.
*/
Int32 Compare(const Date & o) const;
public:
/* ------------------------------------------------------------------------------------------------
* Default constructor.
*/
Date()
: m_Year(1970)
, m_Month(1)
, m_Day(1)
, m_Delimiter(Delimiter)
{
/* ... */
}
/* ------------------------------------------------------------------------------------------------
* Speciffic year constructor.
*/
Date(Uint16 year)
: m_Delimiter(Delimiter)
{
Set(year, 1, 1);
}
/* ------------------------------------------------------------------------------------------------
* Speciffic year and month constructor.
*/
Date(Uint16 year, Uint8 month)
: m_Delimiter(Delimiter)
{
Set(year, month, 1);
}
/* ------------------------------------------------------------------------------------------------
* Speciffic date constructor.
*/
Date(Uint16 year, Uint8 month, Uint8 day)
: m_Delimiter(Delimiter)
{
Set(year, month, day);
}
/* ------------------------------------------------------------------------------------------------
* String constructor.
*/
Date(CSStr str)
: m_Delimiter(Delimiter)
{
SetStr(str);
}
/* ------------------------------------------------------------------------------------------------
* Copy constructor.
*/
Date(const Date & o) = default;
/* ------------------------------------------------------------------------------------------------
* Move constructor.
*/
Date(Date && o) = default;
/* ------------------------------------------------------------------------------------------------
* Destructor.
*/
~Date() = default;
/* ------------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Date & operator = (const Date & o) = default;
/* ------------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Date & operator = (Date && o) = default;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Date & o) const
{
return Compare(o) == 0;
}
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Date & o) const
{
return Compare(o) != 0;
}
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Date & o) const
{
return Compare(o) < 0;
}
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Date & o) const
{
return Compare(o) > 0;
}
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Date & o) const
{
return Compare(o) <= 0;
}
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Date & o) const
{
return Compare(o) >= 0;
}
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Date operator + (const Date & o) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Date operator - (const Date & o) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Date operator * (const Date & o) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Date operator / (const Date & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Date & o) const
{
return Compare(o);
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year)
{
Set(year, m_Month, m_Day);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year, Uint8 month)
{
Set(year, month, m_Day);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year, Uint8 month, Uint8 day);
/* ------------------------------------------------------------------------------------------------
* Retrieve the local delimiter character.
*/
SQChar GetDelimiter() const
{
return m_Delimiter;
}
/* ------------------------------------------------------------------------------------------------
* Modify the local delimiter character.
*/
void SetDelimiter(SQChar c)
{
m_Delimiter = c;
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the values as a string.
*/
CSStr GetStr() const
{
return ToString();
}
/* ------------------------------------------------------------------------------------------------
* Extract the values from a string.
*/
void SetStr(CSStr str);
/* ------------------------------------------------------------------------------------------------
* Retrieve the day component.
*/
Uint16 GetDayOfYear() const
{
return Chrono::DayOfYear(m_Year, m_Month, m_Day);
}
/* ------------------------------------------------------------------------------------------------
* Modify the day component.
*/
void SetDayOfYear(Uint16 doy);
/* ------------------------------------------------------------------------------------------------
* Retrieve the year component.
*/
Uint16 GetYear() const
{
return m_Year;
}
/* ------------------------------------------------------------------------------------------------
* Modify the year component.
*/
void SetYear(Uint16 year);
/* ------------------------------------------------------------------------------------------------
* Retrieve the month component.
*/
Uint8 GetMonth() const
{
return m_Month;
}
/* ------------------------------------------------------------------------------------------------
* Modify the month component.
*/
void SetMonth(Uint8 month);
/* ------------------------------------------------------------------------------------------------
* Retrieve the day component.
*/
Uint8 GetDay() const
{
return m_Day;
}
/* ------------------------------------------------------------------------------------------------
* Modify the day component.
*/
void SetDay(Uint8 day);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of years to the current date.
*/
Date & AddYears(Int32 years);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of months to the current date.
*/
Date & AddMonths(Int32 months);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of days to the current date.
*/
Date & AddDays(Int32 days);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of years to obtain a new date.
*/
Date AndYears(Int32 years);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of months to obtain a new date.
*/
Date AndMonths(Int32 months);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of days to obtain a new date.
*/
Date AndDays(Int32 days);
/* ------------------------------------------------------------------------------------------------
* See whether the associated year is a leap year.
*/
bool IsThisLeapYear() const
{
return Chrono::IsLeapYear(m_Year);
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the number of days in the associated year.
*/
Uint16 GetYearDays() const
{
return Chrono::DaysInYear(m_Year);
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the number of days in the associated month.
*/
Uint8 GetMonthDays() const
{
return Chrono::DaysInMonth(m_Year, m_Month);
}
/* ------------------------------------------------------------------------------------------------
* Convert this date instance to a time-stamp.
*/
Timestamp GetTimestamp() const;
};
} // Namespace:: SqMod
#endif // _LIBRARY_CHRONO_DATE_HPP_

View File

@ -0,0 +1,822 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono/Datetime.hpp"
#include "Library/Chrono/Date.hpp"
#include "Library/Chrono/Time.hpp"
#include "Library/Chrono/Timestamp.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqDatetime"))
// ------------------------------------------------------------------------------------------------
SQChar Datetime::Delimiter = ' ';
SQChar Datetime::DateDelim = '-';
SQChar Datetime::TimeDelim = ':';
// ------------------------------------------------------------------------------------------------
Int32 Datetime::Compare(const Datetime & o) const
{
if (m_Year < o.m_Year)
{
return -1;
}
else if (m_Year > o.m_Year)
{
return 1;
}
else if (m_Month < o.m_Month)
{
return -1;
}
else if (m_Month > o.m_Month)
{
return 1;
}
else if (m_Day < o.m_Day)
{
return -1;
}
else if (m_Day > o.m_Day)
{
return 1;
}
else if (m_Hour < o.m_Hour)
{
return -1;
}
else if (m_Hour > o.m_Hour)
{
return 1;
}
else if (m_Minute < o.m_Minute)
{
return -1;
}
else if (m_Minute > o.m_Minute)
{
return 1;
}
else if (m_Second < o.m_Second)
{
return -1;
}
else if (m_Second > o.m_Second)
{
return 1;
}
else if (m_Millisecond < o.m_Millisecond)
{
return -1;
}
else if (m_Millisecond == o.m_Millisecond)
{
return 0;
}
else
{
return 1;
}
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::operator + (const Datetime & o) const
{
// Add the components individually
return Datetime(o);
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::operator - (const Datetime & o) const
{
return Datetime(o);
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::operator * (const Datetime & o) const
{
return Datetime(o);
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::operator / (const Datetime & o) const
{
return Datetime(o);
}
// ------------------------------------------------------------------------------------------------
CSStr Datetime::ToString() const
{
return ToStrF("%04u%c%02u%c%02u%c%02u%c%02u%c%02u%c%u"
, m_Year, m_DateDelim, m_Month, m_DateDelim, m_Day
, m_Delimiter
, m_Hour, m_TimeDelim, m_Minute, m_TimeDelim, m_Second , m_TimeDelim, m_Millisecond
);
}
// ------------------------------------------------------------------------------------------------
void Datetime::Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond)
{
// Validate the specified date
if (!Chrono::ValidDate(year, month, day))
{
STHROWF("Invalid date: %04u%c%02u%c%02u%c%u"
, m_DateDelim, m_Year
, m_DateDelim, m_Month
, m_DateDelim, m_Day
);
}
// Is the specified hour within range?
else if (hour >= 24)
{
STHROWF("Hour value is out of range: %u >= 24", hour);
}
// Is the specified minute within range?
else if (minute >= 60)
{
STHROWF("Minute value is out of range: %u >= 60", minute);
}
// Is the specified second within range?
else if (second >= 60)
{
STHROWF("Second value is out of range: %u >= 60", second);
}
// Is the specified millisecond within range?
else if (millisecond >= 1000)
{
STHROWF("Millisecond value is out of range: %u >= 1000", millisecond);
}
// Assign the specified values
m_Year = year;
m_Month = month;
m_Day = day;
m_Hour = hour;
m_Minute = minute;
m_Second = second;
m_Millisecond = millisecond;
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetStr(CSStr str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %u - %u - %u %u : %u : %u : %u ");
// Is the specified string empty?
if (!str || *str == '\0')
{
// Clear the values
m_Year = 0;
m_Month = 0;
m_Day = 0;
m_Hour = 0;
m_Minute = 0;
m_Second = 0;
m_Millisecond = 0;
// We're done here
return;
}
// Assign the specified delimiter
fs[4] = m_DateDelim;
fs[9] = m_DateDelim;
fs[14] = m_Delimiter;
fs[19] = m_TimeDelim;
fs[24] = m_TimeDelim;
fs[29] = m_TimeDelim;
// The sscanf function requires at least 32 bit integers
Uint32 year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, milli = 0;
// Attempt to extract the component values from the specified string
sscanf(str, fs, &year, &month, &day, &hour, &minute, &second, &milli);
// Clamp the extracted values to the boundaries of associated type and assign them
Set(ClampL< Uint32, Uint8 >(year),
ClampL< Uint32, Uint8 >(month),
ClampL< Uint32, Uint8 >(day),
ClampL< Uint32, Uint8 >(hour),
ClampL< Uint32, Uint8 >(minute),
ClampL< Uint32, Uint8 >(second),
ClampL< Uint32, Uint16 >(milli)
);
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetDayOfYear(Uint16 doy)
{
// Reverse the given day of year to a full date
Date d = Chrono::ReverseDayOfyear(m_Year, doy);
// Set the obtained month
SetMonth(d.GetMonth());
// Set the obtained day
SetDay(d.GetDay());
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetYear(Uint16 year)
{
// Make sure the year is valid
if (!year)
{
STHROWF("Invalid year: %u", year);
}
// Assign the value
m_Year = year;
// Make sure the new date is valid
if (!Chrono::ValidDate(m_Year, m_Month, m_Day))
{
m_Month = 1;
m_Day = 1;
}
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetMonth(Uint8 month)
{
// Make sure the month is valid
if (month == 0 || month > 12)
{
STHROWF("Invalid month: %u", month);
}
// Assign the value
m_Month = month;
// Make sure the month days are in range
if (m_Day > Chrono::DaysInMonth(m_Year, m_Month))
{
m_Month = 1; // Fall back to the beginning of the month
}
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetDay(Uint8 day)
{
// Grab the amount of days in the current month
const Uint8 dim = Chrono::DaysInMonth(m_Year, m_Month);
// Make sure the day is valid
if (day == 0)
{
STHROWF("Invalid day: %u", day);
}
else if (day > dim)
{
STHROWF("Day is out of range: %u > %u", day, dim);
}
// Assign the value
m_Day = day;
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetHour(Uint8 hour)
{
// Is the specified hour within range?
if (hour >= 24)
{
STHROWF("Hour value is out of range: %u >= 24", hour);
}
// Now it's safe to assign the value
m_Hour = hour;
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetMinute(Uint8 minute)
{
// Is the specified minute within range?
if (minute >= 60)
{
STHROWF("Minute value is out of range: %u >= 60", minute);
}
// Now it's safe to assign the value
m_Minute = minute;
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetSecond(Uint8 second)
{
// Is the specified second within range?
if (second >= 60)
{
STHROWF("Second value is out of range: %u >= 60", second);
}
// Now it's safe to assign the value
m_Second = second;
}
// ------------------------------------------------------------------------------------------------
void Datetime::SetMillisecond(Uint16 millisecond)
{
// Is the specified millisecond within range?
if (millisecond >= 1000)
{
STHROWF("Millisecond value is out of range: %u >= 1000", millisecond);
}
// Now it's safe to assign the value
m_Millisecond = millisecond;
}
// ------------------------------------------------------------------------------------------------
Datetime & Datetime::AddYears(Int32 years)
{
// Do we have a valid amount of years?
if (years)
{
// Add the specified amount of years
SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Datetime & Datetime::AddMonths(Int32 months)
{
// Do we have a valid amount of months?
if (months)
{
// Extract the number of years
Int32 years = static_cast< Int32 >(months / 12);
// Extract the number of months
months = (months % 12) + m_Month;
// Do we have extra months?
if (months >= 12)
{
// Increase the years
++years;
// Subtract one year from months
months %= 12;
}
else if (months < 0)
{
// Decrease the years
--years;
// Add one year to months
months = 12 - months;
}
// Are there any years to add?
if (years)
{
SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
}
// Add the months
SetMonth(months);
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Datetime & Datetime::AddDays(Int32 days)
{
// Do we have a valid amount of days?
if (days)
{
// Whether the number of days is positive or negative
const Int32 dir = days > 0 ? 1 : -1;
// Grab current year
Int32 year = m_Year;
// Calculate the days in the current year
Int32 diy = Chrono::DaysInYear(year);
// Calculate the day of year
Int32 doy = GetDayOfYear() + days;
// Calculate the resulting years
while (doy > diy || doy < 0)
{
doy -= diy * dir;
year += dir;
diy = Chrono::DaysInYear(year);
}
// Set the obtained year
SetYear(year);
// Set the obtained day of year
SetDayOfYear(doy);
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Datetime & Datetime::AddHours(Int32 hours)
{
// Did we even add any hours?
if (hours)
{
// Extract the number of days
Int32 days = static_cast< Int32 >(hours / 24);
// Extract the number of hours
m_Hour += (hours % 24);
// Are the hours overlapping with the next day?
if (m_Hour >= 24)
{
// Increase the days
++days;
// Subtract one day from hours
m_Hour %= 24;
}
// Should we add any days?
if (days)
{
AddDays(days);
}
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Datetime & Datetime::AddMinutes(Int32 minutes)
{
// Did we even add any minutes?
if (minutes)
{
// Extract the number of hours
Int32 hours = static_cast< Int32 >(minutes / 60);
// Extract the number of minutes
m_Minute += (minutes % 60);
// Are the minutes overlapping with the next hour?
if (m_Minute >= 60)
{
// Increase the hours
++hours;
// Subtract one hour from minutes
m_Minute %= 60;
}
// Should we add any hours?
if (hours)
{
AddHours(hours);
}
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Datetime & Datetime::AddSeconds(Int32 seconds)
{
// Did we even add any seconds?
if (seconds)
{
// Extract the number of minutes
Int32 minutes = static_cast< Int32 >(seconds / 60);
// Extract the number of seconds
m_Second += (seconds % 60);
// Are the seconds overlapping with the next minute?
if (m_Second >= 60)
{
// Increase the minutes
++minutes;
// Subtract one minute from seconds
m_Second %= 60;
}
// Should we add any minutes?
if (minutes)
{
AddMinutes(minutes);
}
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Datetime & Datetime::AddMilliseconds(Int32 milliseconds)
{
// Did we even add any milliseconds?
if (milliseconds)
{
// Extract the number of seconds
Int32 seconds = static_cast< Int32 >(milliseconds / 1000);
// Extract the number of milliseconds
m_Millisecond += (milliseconds / 1000);
// Are the milliseconds overlapping with the next second?
if (m_Millisecond >= 1000)
{
// Increase the seconds
++seconds;
// Subtract one second from milliseconds
m_Millisecond %= 1000;
}
// Should we add any seconds?
if (seconds)
{
AddSeconds(seconds);
}
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::AndYears(Int32 years)
{
// Do we have a valid amount of years?
if (!years)
{
return Datetime(*this); // Return the date-time as is
}
// Replicate the current date
Datetime dt(*this);
// Add the specified amount of years
dt.SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
// Return the resulted date
return dt;
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::AndMonths(Int32 months)
{
// Do we have a valid amount of months?
if (!months)
{
return Datetime(*this); // Return the date-time as is
}
// Extract the number of years
Int32 years = static_cast< Int32 >(months / 12);
// Extract the number of months
months = (months % 12) + m_Month;
// Do we have extra months?
if (months >= 12)
{
// Increase the years
++years;
// Subtract one year from months
months %= 12;
}
else if (months < 0)
{
// Decrease the years
--years;
// Add one year to months
months = 12 - months;
}
// Replicate the current date
Datetime dt(*this);
// Are there any years to add?
if (years)
{
dt.SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
}
// Add the months
dt.SetMonth(months);
// Return the resulted date
return dt;
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::AndDays(Int32 days)
{
// Do we have a valid amount of days?
if (!days)
{
return Datetime(*this); // Return the date-time as is
}
// Whether the number of days is positive or negative
const Int32 dir = days > 0 ? 1 : -1;
// Grab current year
Int32 year = m_Year;
// Calculate the days in the current year
Int32 diy = Chrono::DaysInYear(year);
// Calculate the day of year
Int32 doy = GetDayOfYear() + days;
// Calculate the resulting years
while (doy > diy || doy < 0)
{
doy -= diy * dir;
year += dir;
diy = Chrono::DaysInYear(year);
}
// Replicate the current date
Datetime dt(*this);
// Set the obtained year
dt.SetYear(year);
// Set the obtained day of year
dt.SetDayOfYear(doy);
// Return the resulted date
return dt;
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::AndHours(Int32 hours)
{
// Did we even add any hours?
if (!hours)
{
return Datetime(*this); // Return the date-time as is
}
// Extract the number of days
Int32 days = static_cast< Int32 >(hours / 24);
// Extract the number of hours
hours = m_Hour + (hours % 24);
// Are the hours overlapping with the next day?
if (hours >= 24)
{
++days; // Increase the days
}
// Replicate the current time
Datetime dt(*this);
// Should we add any days?
if (days)
{
dt.AddDays(days);
}
// Assign the resulted hours
dt.m_Hour = (hours % 24);
// Return the result
return dt;
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::AndMinutes(Int32 minutes)
{
// Did we even added any minutes?
if (!minutes)
{
return Datetime(*this); // Return the date-time as is
}
// Extract the number of hours
Int32 hours = static_cast< Int32 >(minutes / 60);
// Extract the number of minutes
minutes = m_Minute + (minutes % 60);
// Are the minutes overlapping with the next hour?
if (minutes >= 60)
{
++hours; // Increase hours
}
// Replicate the current time
Datetime dt(*this);
// Should we add any hours?
if (hours)
{
dt.AddHours(hours);
}
// Assign the resulted minutes
dt.m_Minute = (minutes % 60);
// Return the result
return dt;
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::AndSeconds(Int32 seconds)
{
// Did we even added any seconds?
if (!seconds)
{
return Datetime(*this); // Return the date-time as is
}
// Extract the number of minutes
Int32 minutes = static_cast< Int32 >(seconds / 60);
// Extract the number of seconds
seconds = m_Second + (seconds % 60);
// Are the seconds overlapping with the next minute?
if (seconds >= 60)
{
++minutes; // Increase minutes
}
// Replicate the current time
Datetime dt(*this);
// Should we add any minutes?
if (minutes)
{
dt.AddMinutes(minutes);
}
// Assign the resulted seconds
dt.m_Second = (seconds % 60);
// Return the result
return dt;
}
// ------------------------------------------------------------------------------------------------
Datetime Datetime::AndMilliseconds(Int32 milliseconds)
{
// Did we even added any milliseconds?
if (!milliseconds)
{
return Datetime(*this); // Return the date-time as is
}
// Extract the number of seconds
Int32 seconds = static_cast< Int32 >(milliseconds / 1000);
// Extract the number of milliseconds
milliseconds = m_Millisecond + (milliseconds % 1000);
// Are the milliseconds overlapping with the next second?
if (milliseconds >= 1000)
{
++seconds; // Increase seconds
}
// Replicate the current time
Datetime dt(*this);
// Should we add any seconds?
if (seconds)
{
dt.AddSeconds(seconds);
}
// Assign the resulted milliseconds
dt.m_Millisecond = (milliseconds % 1000);
// Return the result
return dt;
}
// ------------------------------------------------------------------------------------------------
Date Datetime::GetDate() const
{
return Date(m_Year, m_Month, m_Day);
}
// ------------------------------------------------------------------------------------------------
Time Datetime::GetTime() const
{
return Time(m_Hour, m_Minute, m_Second, m_Millisecond);
}
// ------------------------------------------------------------------------------------------------
Timestamp Datetime::GetTimestamp() const
{
// Calculate the current day of the year
Int32 days = Chrono::DayOfYear(m_Year, m_Month, m_Day);
// Calculate all days till the current year
for (Int32 year = 0; year < m_Year; --year)
{
days += Chrono::DaysInYear(year);
}
// Calculate the microseconds in the resulted days
Int64 ms = static_cast< Int64 >(days * 86400000000LL);
// Calculate the microseconds in the current time
ms += static_cast< Int64 >(m_Hour * 3600000000LL);
ms += static_cast< Int64 >(m_Minute * 60000000L);
ms += static_cast< Int64 >(m_Second * 1000000L);
ms += static_cast< Int64 >(m_Millisecond * 1000L);
// Return the resulted timestamp
return Timestamp(ms);
}
// ================================================================================================
void Register_ChronoDatetime(HSQUIRRELVM vm, Table & /*cns*/)
{
RootTable(vm).Bind(Typename::Str,
Class< Datetime >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Uint16 >()
.Ctor< Uint16, Uint8 >()
.Ctor< Uint16, Uint8, Uint8 >()
.Ctor< Uint16, Uint8, Uint8, Uint8 >()
.Ctor< Uint16, Uint8, Uint8, Uint8, Uint8 >()
.Ctor< Uint16, Uint8, Uint8, Uint8, Uint8, Uint8 >()
.Ctor< Uint16, Uint8, Uint8, Uint8, Uint8, Uint8, Uint16 >()
// Static Properties
.SetStaticValue(_SC("GlobalDelimiter"), &Datetime::Delimiter)
.SetStaticValue(_SC("GlobalDateDelim"), &Datetime::DateDelim)
.SetStaticValue(_SC("GlobalTimeDelim"), &Datetime::TimeDelim)
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Datetime::ToString)
.Func(_SC("cmp"), &Datetime::Cmp)
// Meta-methods
.Func< Datetime (Datetime::*)(const Datetime &) const >(_SC("_add"), &Datetime::operator +)
.Func< Datetime (Datetime::*)(const Datetime &) const >(_SC("_sub"), &Datetime::operator -)
.Func< Datetime (Datetime::*)(const Datetime &) const >(_SC("_mul"), &Datetime::operator *)
.Func< Datetime (Datetime::*)(const Datetime &) const >(_SC("_div"), &Datetime::operator /)
// Properties
.Prop(_SC("Delimiter"), &Datetime::GetDelimiter, &Datetime::SetDelimiter)
.Prop(_SC("DateDelim"), &Datetime::GetDateDelim, &Datetime::SetDateDelim)
.Prop(_SC("TimeDelim"), &Datetime::GetTimeDelim, &Datetime::SetTimeDelim)
.Prop(_SC("Str"), &Datetime::GetStr, &Datetime::SetStr)
.Prop(_SC("DayOfYear"), &Datetime::GetDayOfYear, &Datetime::SetDayOfYear)
.Prop(_SC("Year"), &Datetime::GetYear, &Datetime::SetYear)
.Prop(_SC("Month"), &Datetime::GetMonth, &Datetime::SetMonth)
.Prop(_SC("Day"), &Datetime::GetDay, &Datetime::SetDay)
.Prop(_SC("Hour"), &Datetime::GetHour, &Datetime::SetHour)
.Prop(_SC("Minute"), &Datetime::GetMinute, &Datetime::SetMinute)
.Prop(_SC("Second"), &Datetime::GetSecond, &Datetime::SetSecond)
.Prop(_SC("Millisecond"), &Datetime::GetMillisecond, &Datetime::SetMillisecond)
.Prop(_SC("LeapYear"), &Datetime::IsThisLeapYear)
.Prop(_SC("YearDays"), &Datetime::GetYearDays)
.Prop(_SC("MonthDays"), &Datetime::GetMonthDays)
.Prop(_SC("Date"), &Datetime::GetDate)
.Prop(_SC("Time"), &Datetime::GetTime)
.Prop(_SC("Timestamp"), &Datetime::GetTimestamp)
// Member Methods
.Func(_SC("AddYears"), &Datetime::AddYears)
.Func(_SC("AddMonths"), &Datetime::AddMonths)
.Func(_SC("AddDays"), &Datetime::AddDays)
.Func(_SC("AddHours"), &Datetime::AddHours)
.Func(_SC("AddMinutes"), &Datetime::AddMinutes)
.Func(_SC("AddSeconds"), &Datetime::AddSeconds)
.Func(_SC("AddMillis"), &Datetime::AddMilliseconds)
.Func(_SC("AddMilliseconds"), &Datetime::AddMilliseconds)
.Func(_SC("AndYears"), &Datetime::AndYears)
.Func(_SC("AndMonths"), &Datetime::AndMonths)
.Func(_SC("AndDays"), &Datetime::AndDays)
.Func(_SC("AndHours"), &Datetime::AndHours)
.Func(_SC("AndMinutes"), &Datetime::AndMinutes)
.Func(_SC("AndSeconds"), &Datetime::AndSeconds)
.Func(_SC("AndMillis"), &Datetime::AndMilliseconds)
.Func(_SC("AndMilliseconds"), &Datetime::AndMilliseconds)
// Overloaded Methods
.Overload< void (Datetime::*)(Uint16) >(_SC("Set"), &Datetime::Set)
.Overload< void (Datetime::*)(Uint16, Uint8) >(_SC("Set"), &Datetime::Set)
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8) >(_SC("Set"), &Datetime::Set)
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8, Uint8) >(_SC("Set"), &Datetime::Set)
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8, Uint8, Uint8) >(_SC("Set"), &Datetime::Set)
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8, Uint8, Uint8, Uint8) >(_SC("Set"), &Datetime::Set)
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8, Uint8, Uint8, Uint8, Uint16) >(_SC("Set"), &Datetime::Set)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,580 @@
#ifndef _LIBRARY_CHRONO_DATETIME_HPP_
#define _LIBRARY_CHRONO_DATETIME_HPP_
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class used to represent a certain date and time.
*/
class Datetime
{
public:
// ------------------------------------------------------------------------------------------------
static SQChar Delimiter;
static SQChar DateDelim;
static SQChar TimeDelim;
private:
// ------------------------------------------------------------------------------------------------
Uint16 m_Year; // Year
Uint8 m_Month; // Month
Uint8 m_Day; // Day
// ------------------------------------------------------------------------------------------------
Uint8 m_Hour; // Hour
Uint8 m_Minute; // Minute
Uint8 m_Second; // Second
Uint16 m_Millisecond; // Millisecond
// ------------------------------------------------------------------------------------------------
SQChar m_Delimiter; // Date and time delimiter when generating strings.
SQChar m_DateDelim; // Date component delimiter when generating strings.
SQChar m_TimeDelim; // Time component delimiter when generating strings.
protected:
/* ------------------------------------------------------------------------------------------------
* Compare the values of two instances.
*/
Int32 Compare(const Datetime & o) const;
public:
/* ------------------------------------------------------------------------------------------------
* Default constructor.
*/
Datetime()
: m_Year(1970)
, m_Month(1)
, m_Day(1)
, m_Hour(0)
, m_Minute(0)
, m_Second(0)
, m_Millisecond(0)
, m_Delimiter(Delimiter)
, m_DateDelim(DateDelim)
, m_TimeDelim(TimeDelim)
{
/* ... */
}
/* ------------------------------------------------------------------------------------------------
* Speciffic year constructor.
*/
Datetime(Uint16 year)
: m_Delimiter(Delimiter)
, m_DateDelim(DateDelim)
, m_TimeDelim(TimeDelim)
{
Set(year, 1, 1, 0, 0, 0, 0);
}
/* ------------------------------------------------------------------------------------------------
* Speciffic year and month constructor.
*/
Datetime(Uint16 year, Uint8 month)
: m_Delimiter(Delimiter)
, m_DateDelim(DateDelim)
, m_TimeDelim(TimeDelim)
{
Set(year, month, 1, 0, 0, 0, 0);
}
/* ------------------------------------------------------------------------------------------------
* Speciffic date constructor.
*/
Datetime(Uint16 year, Uint8 month, Uint8 day)
: m_Delimiter(Delimiter)
, m_DateDelim(DateDelim)
, m_TimeDelim(TimeDelim)
{
Set(year, month, day, 0, 0, 0, 0);
}
/* ------------------------------------------------------------------------------------------------
* Speciffic date and hour constructor.
*/
Datetime(Uint16 year, Uint8 month, Uint8 day, Uint8 hour)
: m_Delimiter(Delimiter)
, m_DateDelim(DateDelim)
, m_TimeDelim(TimeDelim)
{
Set(year, month, day, hour, 0, 0, 0);
}
/* ------------------------------------------------------------------------------------------------
* Speciffic date, hour and minute constructor.
*/
Datetime(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute)
: m_Delimiter(Delimiter)
, m_DateDelim(DateDelim)
, m_TimeDelim(TimeDelim)
{
Set(year, month, day, hour, minute, 0, 0);
}
/* ------------------------------------------------------------------------------------------------
* Speciffic date and time constructor.
*/
Datetime(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second)
: m_Delimiter(Delimiter)
, m_DateDelim(DateDelim)
, m_TimeDelim(TimeDelim)
{
Set(year, month, day, hour, minute, second, 0);
}
/* ------------------------------------------------------------------------------------------------
* Speciffic date and precise time constructor.
*/
Datetime(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond)
: m_Delimiter(Delimiter)
, m_DateDelim(DateDelim)
, m_TimeDelim(TimeDelim)
{
Set(year, month, day, hour, minute, second, millisecond);
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Datetime(const Datetime & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
Datetime(Datetime && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Datetime() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Datetime & operator = (const Datetime & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Datetime & operator = (Datetime && o) = default;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Datetime & o) const
{
return Compare(o) == 0;
}
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Datetime & o) const
{
return Compare(o) != 0;
}
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Datetime & o) const
{
return Compare(o) < 0;
}
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Datetime & o) const
{
return Compare(o) > 0;
}
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Datetime & o) const
{
return Compare(o) <= 0;
}
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Datetime & o) const
{
return Compare(o) >= 0;
}
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Datetime operator + (const Datetime & o) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Datetime operator - (const Datetime & o) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Datetime operator * (const Datetime & o) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Datetime operator / (const Datetime & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Datetime & o) const
{
return Compare(o);
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year)
{
Set(year, m_Month, m_Day, m_Hour, m_Minute, m_Second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year, Uint8 month)
{
Set(year, month, m_Day, m_Hour, m_Minute, m_Second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year, Uint8 month, Uint8 day)
{
Set(year, month, day, m_Hour, m_Minute, m_Second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour)
{
Set(year, month, day, hour, m_Minute, m_Second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute)
{
Set(year, month, day, hour, minute, m_Second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second)
{
Set(year, month, day, hour, minute, second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond);
/* ------------------------------------------------------------------------------------------------
* Retrieve the local delimiter character.
*/
SQChar GetDelimiter() const
{
return m_Delimiter;
}
/* ------------------------------------------------------------------------------------------------
* Modify the local delimiter character.
*/
void SetDelimiter(SQChar c)
{
m_Delimiter = c;
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the local date delimiter character.
*/
SQChar GetDateDelim() const
{
return m_DateDelim;
}
/* ------------------------------------------------------------------------------------------------
* Modify the local date delimiter character.
*/
void SetDateDelim(SQChar c)
{
m_DateDelim = c;
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the local time delimiter character.
*/
SQChar GetTimeDelim() const
{
return m_TimeDelim;
}
/* ------------------------------------------------------------------------------------------------
* Modify the local time delimiter character.
*/
void SetTimeDelim(SQChar c)
{
m_TimeDelim = c;
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the values as a string.
*/
CSStr GetStr() const
{
return ToString();
}
/* ------------------------------------------------------------------------------------------------
* Extract the values from a string.
*/
void SetStr(CSStr str);
/* ------------------------------------------------------------------------------------------------
* Retrieve the day component.
*/
Uint16 GetDayOfYear() const
{
return Chrono::DayOfYear(m_Year, m_Month, m_Day);
}
/* ------------------------------------------------------------------------------------------------
* Modify the day component.
*/
void SetDayOfYear(Uint16 doy);
/* ------------------------------------------------------------------------------------------------
* Retrieve the year component.
*/
Uint16 GetYear() const
{
return m_Year;
}
/* ------------------------------------------------------------------------------------------------
* Modify the year component.
*/
void SetYear(Uint16 year);
/* ------------------------------------------------------------------------------------------------
* Retrieve the month component.
*/
Uint8 GetMonth() const
{
return m_Month;
}
/* ------------------------------------------------------------------------------------------------
* Modify the month component.
*/
void SetMonth(Uint8 month);
/* ------------------------------------------------------------------------------------------------
* Retrieve the day component.
*/
Uint8 GetDay() const
{
return m_Day;
}
/* ------------------------------------------------------------------------------------------------
* Modify the day component.
*/
void SetDay(Uint8 day);
/* ------------------------------------------------------------------------------------------------
* Retrieve the hour component.
*/
Uint8 GetHour() const
{
return m_Hour;
}
/* ------------------------------------------------------------------------------------------------
* Modify the hour component.
*/
void SetHour(Uint8 hour);
/* ------------------------------------------------------------------------------------------------
* Retrieve the minute component.
*/
Uint8 GetMinute() const
{
return m_Minute;
}
/* ------------------------------------------------------------------------------------------------
* Modify the minute component.
*/
void SetMinute(Uint8 minute);
/* ------------------------------------------------------------------------------------------------
* Retrieve the second component.
*/
Uint8 GetSecond() const
{
return m_Second;
}
/* ------------------------------------------------------------------------------------------------
* Modify the second component.
*/
void SetSecond(Uint8 second);
/* ------------------------------------------------------------------------------------------------
* Retrieve the millisecond component.
*/
Uint16 GetMillisecond() const
{
return m_Millisecond;
}
/* ------------------------------------------------------------------------------------------------
* Modify the millisecond component.
*/
void SetMillisecond(Uint16 millisecond);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of years to the current date.
*/
Datetime & AddYears(Int32 years);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of months to the current date.
*/
Datetime & AddMonths(Int32 months);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of days to the current date.
*/
Datetime & AddDays(Int32 days);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of hours to the current time.
*/
Datetime & AddHours(Int32 hours);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of minutes to the current time.
*/
Datetime & AddMinutes(Int32 minutes);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of seconds to the current time.
*/
Datetime & AddSeconds(Int32 seconds);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of milliseconds to the current time.
*/
Datetime & AddMilliseconds(Int32 milliseconds);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of years to obtain a new date.
*/
Datetime AndYears(Int32 years);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of months to obtain a new date.
*/
Datetime AndMonths(Int32 months);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of days to obtain a new date.
*/
Datetime AndDays(Int32 days);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of hours to obtain a new time.
*/
Datetime AndHours(Int32 hours);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of minutes to obtain a new time.
*/
Datetime AndMinutes(Int32 minutes);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of seconds to obtain a new time.
*/
Datetime AndSeconds(Int32 seconds);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of milliseconds to obtain a new time.
*/
Datetime AndMilliseconds(Int32 milliseconds);
/* ------------------------------------------------------------------------------------------------
* See whether the associated year is a leap year.
*/
bool IsThisLeapYear() const
{
return Chrono::IsLeapYear(m_Year);
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the number of days in the associated year.
*/
Uint16 GetYearDays() const
{
return Chrono::DaysInYear(m_Year);
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the number of days in the associated month.
*/
Uint8 GetMonthDays() const
{
return Chrono::DaysInMonth(m_Year, m_Month);
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the date from this date-time instance.
*/
Date GetDate() const;
/* ------------------------------------------------------------------------------------------------
* Retrieve the time from this date-time instance.
*/
Time GetTime() const;
/* ------------------------------------------------------------------------------------------------
* Convert this date-time instance to a time-stamp.
*/
Timestamp GetTimestamp() const;
};
} // Namespace:: SqMod
#endif // _LIBRARY_CHRONO_DATETIME_HPP_

View File

@ -0,0 +1,464 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono/Time.hpp"
#include "Library/Chrono/Date.hpp"
#include "Library/Chrono/Datetime.hpp"
#include "Library/Chrono/Timestamp.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqTime"))
// ------------------------------------------------------------------------------------------------
SQChar Time::Delimiter = ':';
// ------------------------------------------------------------------------------------------------
Int32 Time::Compare(const Time & o) const
{
if (m_Hour < o.m_Hour)
{
return -1;
}
else if (m_Hour > o.m_Hour)
{
return 1;
}
else if (m_Minute < o.m_Minute)
{
return -1;
}
else if (m_Minute > o.m_Minute)
{
return 1;
}
else if (m_Second < o.m_Second)
{
return -1;
}
else if (m_Second > o.m_Second)
{
return 1;
}
else if (m_Millisecond < o.m_Millisecond)
{
return -1;
}
else if (m_Millisecond == o.m_Millisecond)
{
return 0;
}
else
{
return 1;
}
}
// ------------------------------------------------------------------------------------------------
Time Time::operator + (const Time & o) const
{
return Time(o);
}
// ------------------------------------------------------------------------------------------------
Time Time::operator - (const Time & o) const
{
return Time(o);
}
// ------------------------------------------------------------------------------------------------
Time Time::operator * (const Time & o) const
{
return Time(o);
}
// ------------------------------------------------------------------------------------------------
Time Time::operator / (const Time & o) const
{
return Time(o);
}
// ------------------------------------------------------------------------------------------------
CSStr Time::ToString() const
{
return ToStrF("%02u%c%02u%c%02u%c%u",
m_Hour, m_Delimiter,
m_Minute, m_Delimiter,
m_Second, m_Delimiter,
m_Millisecond);
}
// ------------------------------------------------------------------------------------------------
void Time::Set(Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond)
{
// Is the specified hour within range?
if (hour >= 24)
{
STHROWF("Hour value is out of range: %u >= 24", hour);
}
// Is the specified minute within range?
else if (minute >= 60)
{
STHROWF("Minute value is out of range: %u >= 60", minute);
}
// Is the specified second within range?
else if (second >= 60)
{
STHROWF("Second value is out of range: %u >= 60", second);
}
// Is the specified millisecond within range?
else if (millisecond >= 1000)
{
STHROWF("Millisecond value is out of range: %u >= 1000", millisecond);
}
// Now it's safe to assign the values
m_Hour = hour;
m_Minute = minute;
m_Second = second;
m_Millisecond = millisecond;
}
// ------------------------------------------------------------------------------------------------
void Time::SetStr(CSStr str)
{
// The format specifications that will be used to scan the string
static SQChar fs[] = _SC(" %u : %u : %u : %u ");
// Is the specified string empty?
if (!str || *str == '\0')
{
// Clear the values
m_Hour = 0;
m_Minute = 0;
m_Second = 0;
m_Millisecond = 0;
// We're done here
return;
}
// Assign the specified delimiter
fs[4] = m_Delimiter;
fs[9] = m_Delimiter;
fs[14] = m_Delimiter;
// The sscanf function requires at least 32 bit integers
Uint32 hour = 0, minute = 0, second = 0, milli = 0;
// Attempt to extract the component values from the specified string
sscanf(str, fs, &hour, &minute, &second, &milli);
// Clamp the extracted values to the boundaries of associated type and assign them
Set(ClampL< Uint32, Uint8 >(hour),
ClampL< Uint32, Uint8 >(minute),
ClampL< Uint32, Uint8 >(second),
ClampL< Uint32, Uint16 >(milli)
);
}
// ------------------------------------------------------------------------------------------------
void Time::SetHour(Uint8 hour)
{
// Is the specified hour within range?
if (hour >= 24)
{
STHROWF("Hour value is out of range: %u >= 24", hour);
}
// Now it's safe to assign the value
m_Hour = hour;
}
// ------------------------------------------------------------------------------------------------
void Time::SetMinute(Uint8 minute)
{
// Is the specified minute within range?
if (minute >= 60)
{
STHROWF("Minute value is out of range: %u >= 60", minute);
}
// Now it's safe to assign the value
m_Minute = minute;
}
// ------------------------------------------------------------------------------------------------
void Time::SetSecond(Uint8 second)
{
// Is the specified second within range?
if (second >= 60)
{
STHROWF("Second value is out of range: %u >= 60", second);
}
// Now it's safe to assign the value
m_Second = second;
}
// ------------------------------------------------------------------------------------------------
void Time::SetMillisecond(Uint16 millisecond)
{
// Is the specified millisecond within range?
if (millisecond >= 1000)
{
STHROWF("Millisecond value is out of range: %u >= 1000", millisecond);
}
// Now it's safe to assign the value
m_Millisecond = millisecond;
}
// ------------------------------------------------------------------------------------------------
Time & Time::AddHours(Int32 hours)
{
// Did we even add any hours?
if (hours)
{
// Add the specified amount of hours
m_Hour += (hours % 24);
// Make sure the value is within range
m_Hour %= 24;
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Time & Time::AddMinutes(Int32 minutes)
{
// Did we even add any minutes?
if (minutes)
{
// Extract the number of hours
Int32 hours = static_cast< Int32 >(minutes / 60);
// Extract the number of minutes
m_Minute += (minutes % 60);
// Are the minutes overlapping with the next hour?
if (m_Minute >= 60)
{
// Increase the hours
++hours;
// Subtract one hour from minutes
m_Minute %= 60;
}
// Should we add any hours?
if (hours)
{
AddHours(hours);
}
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Time & Time::AddSeconds(Int32 seconds)
{
// Did we even add any seconds?
if (seconds)
{
// Extract the number of minutes
Int32 minutes = static_cast< Int32 >(seconds / 60);
// Extract the number of seconds
m_Second += (seconds % 60);
// Are the seconds overlapping with the next minute?
if (m_Second >= 60)
{
// Increase the minutes
++minutes;
// Subtract one minute from seconds
m_Second %= 60;
}
// Should we add any minutes?
if (minutes)
{
AddMinutes(minutes);
}
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Time & Time::AddMilliseconds(Int32 milliseconds)
{
// Did we even add any milliseconds?
if (milliseconds)
{
// Extract the number of seconds
Int32 seconds = static_cast< Int32 >(milliseconds / 1000);
// Extract the number of milliseconds
m_Millisecond += (milliseconds / 1000);
// Are the milliseconds overlapping with the next second?
if (m_Millisecond >= 1000)
{
// Increase the seconds
++seconds;
// Subtract one second from milliseconds
m_Millisecond %= 1000;
}
// Should we add any seconds?
if (seconds)
{
AddSeconds(seconds);
}
}
// Allow chaining operations
return *this;
}
// ------------------------------------------------------------------------------------------------
Time Time::AndHours(Int32 hours)
{
// Did we even add any hours?
if (hours)
{
return Time((m_Hour + (hours % 24)) % 24, m_Minute, m_Second, m_Millisecond);
}
// Return the time as is
return Time(*this);
}
// ------------------------------------------------------------------------------------------------
Time Time::AndMinutes(Int32 minutes)
{
// Did we even added any minutes?
if (!minutes)
{
return Time(*this); // Return the time as is
}
// Extract the number of hours
Int32 hours = static_cast< Int32 >(minutes / 60);
// Extract the number of minutes
minutes = m_Minute + (minutes % 60);
// Are the minutes overlapping with the next hour?
if (minutes >= 60)
{
++hours; // Increase hours
}
// Replicate the current time
Time t(*this);
// Should we add any hours?
if (hours)
{
t.AddHours(hours);
}
// Assign the resulted minutes
t.m_Minute = (minutes % 60);
// Return the result
return t;
}
// ------------------------------------------------------------------------------------------------
Time Time::AndSeconds(Int32 seconds)
{
// Did we even added any seconds?
if (!seconds)
{
return Time(*this); // Return the time as is
}
// Extract the number of minutes
Int32 minutes = static_cast< Int32 >(seconds / 60);
// Extract the number of seconds
seconds = m_Second + (seconds % 60);
// Are the seconds overlapping with the next minute?
if (seconds >= 60)
{
++minutes; // Increase minutes
}
// Replicate the current time
Time t(*this);
// Should we add any minutes?
if (minutes)
{
t.AddMinutes(minutes);
}
// Assign the resulted seconds
t.m_Second = (seconds % 60);
// Return the result
return t;
}
// ------------------------------------------------------------------------------------------------
Time Time::AndMilliseconds(Int32 milliseconds)
{
// Did we even added any milliseconds?
if (!milliseconds)
{
return Time(*this); // Return the time as is
}
// Extract the number of seconds
Int32 seconds = static_cast< Int32 >(milliseconds / 1000);
// Extract the number of milliseconds
milliseconds = m_Millisecond + (milliseconds % 1000);
// Are the milliseconds overlapping with the next second?
if (milliseconds >= 1000)
{
++seconds; // Increase seconds
}
// Replicate the current time
Time t(*this);
// Should we add any seconds?
if (seconds)
{
t.AddSeconds(seconds);
}
// Assign the resulted milliseconds
t.m_Millisecond = (milliseconds % 1000);
// Return the result
return t;
}
// ------------------------------------------------------------------------------------------------
Timestamp Time::GetTimestamp() const
{
// Calculate the microseconds in the current time
Int64 ms = static_cast< Int64 >(m_Hour * 3600000000LL);
ms += static_cast< Int64 >(m_Minute * 60000000L);
ms += static_cast< Int64 >(m_Second * 1000000L);
ms += static_cast< Int64 >(m_Millisecond * 1000L);
// Return the resulted timestamp
return Timestamp(ms);
}
// ================================================================================================
void Register_ChronoTime(HSQUIRRELVM vm, Table & /*cns*/)
{
RootTable(vm).Bind(Typename::Str,
Class< Time >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< Uint8 >()
.Ctor< Uint8, Uint8 >()
.Ctor< Uint8, Uint8, Uint8 >()
.Ctor< Uint8, Uint8, Uint8, Uint16 >()
// Static Properties
.SetStaticValue(_SC("GlobalDelimiter"), &Time::Delimiter)
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Time::ToString)
.Func(_SC("cmp"), &Time::Cmp)
// Meta-methods
.Func< Time (Time::*)(const Time &) const >(_SC("_add"), &Time::operator +)
.Func< Time (Time::*)(const Time &) const >(_SC("_sub"), &Time::operator -)
.Func< Time (Time::*)(const Time &) const >(_SC("_mul"), &Time::operator *)
.Func< Time (Time::*)(const Time &) const >(_SC("_div"), &Time::operator /)
// Properties
.Prop(_SC("Delimiter"), &Time::GetDelimiter, &Time::SetDelimiter)
.Prop(_SC("Str"), &Time::GetStr, &Time::SetStr)
.Prop(_SC("Hour"), &Time::GetHour, &Time::SetHour)
.Prop(_SC("Minute"), &Time::GetMinute, &Time::SetMinute)
.Prop(_SC("Second"), &Time::GetSecond, &Time::SetSecond)
.Prop(_SC("Millisecond"), &Time::GetMillisecond, &Time::SetMillisecond)
.Prop(_SC("Timestamp"), &Time::GetTimestamp)
// Member Methods
.Func(_SC("AddHours"), &Time::AddHours)
.Func(_SC("AddMinutes"), &Time::AddMinutes)
.Func(_SC("AddSeconds"), &Time::AddSeconds)
.Func(_SC("AddMillis"), &Time::AddMilliseconds)
.Func(_SC("AddMilliseconds"), &Time::AddMilliseconds)
.Func(_SC("AndHours"), &Time::AndHours)
.Func(_SC("AndMinutes"), &Time::AndMinutes)
.Func(_SC("AndSeconds"), &Time::AndSeconds)
.Func(_SC("AndMillis"), &Time::AndMilliseconds)
.Func(_SC("AndMilliseconds"), &Time::AndMilliseconds)
// Overloaded Methods
.Overload< void (Time::*)(Uint8) >(_SC("Set"), &Time::Set)
.Overload< void (Time::*)(Uint8, Uint8) >(_SC("Set"), &Time::Set)
.Overload< void (Time::*)(Uint8, Uint8, Uint8) >(_SC("Set"), &Time::Set)
.Overload< void (Time::*)(Uint8, Uint8, Uint8, Uint16) >(_SC("Set"), &Time::Set)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,362 @@
#ifndef _LIBRARY_CHRONO_TIME_HPP_
#define _LIBRARY_CHRONO_TIME_HPP_
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper class used to represent a certain time.
*/
class Time
{
public:
// ------------------------------------------------------------------------------------------------
static SQChar Delimiter;
protected:
/* ------------------------------------------------------------------------------------------------
* Compare the values of two instances.
*/
Int32 Compare(const Time & o) const;
private:
// ------------------------------------------------------------------------------------------------
Uint8 m_Hour; // Hour
Uint8 m_Minute; // Minute
Uint8 m_Second; // Second
Uint16 m_Millisecond; // Millisecond
// ------------------------------------------------------------------------------------------------
SQChar m_Delimiter; // Component delimiter when generating strings.
public:
/* ------------------------------------------------------------------------------------------------
* Default constructor.
*/
Time()
: m_Hour(0)
, m_Minute(0)
, m_Second(0)
, m_Millisecond(0)
, m_Delimiter(Delimiter)
{
/* ... */
}
/* ------------------------------------------------------------------------------------------------
* Base constructor.
*/
Time(Uint8 hour)
: m_Delimiter(Delimiter)
{
Set(hour, 0, 0, 0);
}
/* ------------------------------------------------------------------------------------------------
* Base constructor.
*/
Time(Uint8 hour, Uint8 minute)
: m_Delimiter(Delimiter)
{
Set(hour, minute, 0, 0);
}
/* ------------------------------------------------------------------------------------------------
* Base constructor.
*/
Time(Uint8 hour, Uint8 minute, Uint8 second)
: m_Delimiter(Delimiter)
{
Set(hour, minute, second, 0);
}
/* ------------------------------------------------------------------------------------------------
* Base constructor.
*/
Time(Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond)
: m_Delimiter(Delimiter)
{
Set(hour, minute, second, millisecond);
}
/* ------------------------------------------------------------------------------------------------
* String constructor.
*/
Time(CSStr str)
: m_Delimiter(Delimiter)
{
SetStr(str);
}
/* ------------------------------------------------------------------------------------------------
* Copy constructor.
*/
Time(const Time & o) = default;
/* ------------------------------------------------------------------------------------------------
* Move constructor.
*/
Time(Time && o) = default;
/* ------------------------------------------------------------------------------------------------
* Destructor.
*/
~Time() = default;
/* ------------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Time & operator = (const Time & o) = default;
/* ------------------------------------------------------------------------------------------------
* Move assignment operator.
*/
Time & operator = (Time && o) = default;
/* --------------------------------------------------------------------------------------------
* Equality comparison operator.
*/
bool operator == (const Time & o) const
{
return Compare(o) == 0;
}
/* --------------------------------------------------------------------------------------------
* Inequality comparison operator.
*/
bool operator != (const Time & o) const
{
return Compare(o) != 0;
}
/* --------------------------------------------------------------------------------------------
* Less than comparison operator.
*/
bool operator < (const Time & o) const
{
return Compare(o) < 0;
}
/* --------------------------------------------------------------------------------------------
* Greater than comparison operator.
*/
bool operator > (const Time & o) const
{
return Compare(o) > 0;
}
/* --------------------------------------------------------------------------------------------
* Less than or equal comparison operator.
*/
bool operator <= (const Time & o) const
{
return Compare(o) <= 0;
}
/* --------------------------------------------------------------------------------------------
* Greater than or equal comparison operator.
*/
bool operator >= (const Time & o) const
{
return Compare(o) >= 0;
}
/* --------------------------------------------------------------------------------------------
* Addition operator.
*/
Time operator + (const Time & o) const;
/* --------------------------------------------------------------------------------------------
* Subtraction operator.
*/
Time operator - (const Time & o) const;
/* --------------------------------------------------------------------------------------------
* Multiplication operator.
*/
Time operator * (const Time & o) const;
/* --------------------------------------------------------------------------------------------
* Division operator.
*/
Time operator / (const Time & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Time & o) const
{
return Compare(o);
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint8 hour)
{
Set(hour, m_Minute, m_Second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint8 hour, Uint8 minute)
{
Set(hour, minute, m_Second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint8 hour, Uint8 minute, Uint8 second)
{
Set(hour, minute, second, m_Millisecond);
}
/* ------------------------------------------------------------------------------------------------
* Assign the specified values.
*/
void Set(Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond);
/* ------------------------------------------------------------------------------------------------
* Retrieve the local delimiter character.
*/
SQChar GetDelimiter() const
{
return m_Delimiter;
}
/* ------------------------------------------------------------------------------------------------
* Modify the local delimiter character.
*/
void SetDelimiter(SQChar c)
{
m_Delimiter = c;
}
/* ------------------------------------------------------------------------------------------------
* Retrieve the values as a string.
*/
CSStr GetStr() const
{
return ToString();
}
/* ------------------------------------------------------------------------------------------------
* Extract the values from a string.
*/
void SetStr(CSStr str);
/* ------------------------------------------------------------------------------------------------
* Retrieve the hour component.
*/
Uint8 GetHour() const
{
return m_Hour;
}
/* ------------------------------------------------------------------------------------------------
* Modify the hour component.
*/
void SetHour(Uint8 hour);
/* ------------------------------------------------------------------------------------------------
* Retrieve the minute component.
*/
Uint8 GetMinute() const
{
return m_Minute;
}
/* ------------------------------------------------------------------------------------------------
* Modify the minute component.
*/
void SetMinute(Uint8 minute);
/* ------------------------------------------------------------------------------------------------
* Retrieve the second component.
*/
Uint8 GetSecond() const
{
return m_Second;
}
/* ------------------------------------------------------------------------------------------------
* Modify the second component.
*/
void SetSecond(Uint8 second);
/* ------------------------------------------------------------------------------------------------
* Retrieve the millisecond component.
*/
Uint16 GetMillisecond() const
{
return m_Millisecond;
}
/* ------------------------------------------------------------------------------------------------
* Modify the millisecond component.
*/
void SetMillisecond(Uint16 millisecond);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of hours to the current time.
*/
Time & AddHours(Int32 hours);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of minutes to the current time.
*/
Time & AddMinutes(Int32 minutes);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of seconds to the current time.
*/
Time & AddSeconds(Int32 seconds);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of milliseconds to the current time.
*/
Time & AddMilliseconds(Int32 milliseconds);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of hours to obtain a new time.
*/
Time AndHours(Int32 hours);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of minutes to obtain a new time.
*/
Time AndMinutes(Int32 minutes);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of seconds to obtain a new time.
*/
Time AndSeconds(Int32 seconds);
/* ------------------------------------------------------------------------------------------------
* Add the specified amount of milliseconds to obtain a new time.
*/
Time AndMilliseconds(Int32 milliseconds);
/* ------------------------------------------------------------------------------------------------
* Convert this time instance to a time-stamp.
*/
Timestamp GetTimestamp() const;
};
} // Namespace:: SqMod
#endif // _LIBRARY_CHRONO_TIME_HPP_

View File

@ -0,0 +1,92 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono/Timer.hpp"
#include "Library/Chrono/Timestamp.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqTimer"))
// ------------------------------------------------------------------------------------------------
Timer::Timer()
: m_Timestamp(Chrono::GetCurrentSysTime())
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Int32 Timer::Cmp(const Timer & o) const
{
if (m_Timestamp == o.m_Timestamp)
return 0;
else if (m_Timestamp > o.m_Timestamp)
return 1;
else
return -1;
}
// ------------------------------------------------------------------------------------------------
CSStr Timer::ToString() const
{
return ToStrF("%lld", m_Timestamp);
}
// ------------------------------------------------------------------------------------------------
void Timer::Reset()
{
m_Timestamp = Chrono::GetCurrentSysTime();
}
// ------------------------------------------------------------------------------------------------
Timestamp Timer::Restart()
{
const Int64 now = Chrono::GetCurrentSysTime(), elapsed = now - m_Timestamp;
m_Timestamp = now;
return Timestamp(elapsed);
}
// ------------------------------------------------------------------------------------------------
Int64 Timer::RestartRaw()
{
const Int64 now = Chrono::GetCurrentSysTime(), elapsed = now - m_Timestamp;
m_Timestamp = now;
return elapsed;
}
// ------------------------------------------------------------------------------------------------
Timestamp Timer::GetElapsedTime() const
{
return Timestamp(Chrono::GetCurrentSysTime() - m_Timestamp);
}
// ------------------------------------------------------------------------------------------------
Int64 Timer::GetElapsedTimeRaw() const
{
return (Chrono::GetCurrentSysTime() - m_Timestamp);
}
// ================================================================================================
void Register_ChronoTimer(HSQUIRRELVM vm, Table & /*cns*/)
{
RootTable(vm).Bind(Typename::Str,
Class< Timer >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< const Timer & >()
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Timer::ToString)
.Func(_SC("cmp"), &Timer::Cmp)
// Properties
.Prop(_SC("Elapsed"), &Timer::GetElapsedTime)
.Prop(_SC("ElapsedRaw"), &Timer::GetElapsedTimeRaw)
// Functions
.Func(_SC("Reset"), &Timer::Reset)
.Func(_SC("Restart"), &Timer::Restart)
.Func(_SC("RestartRaw"), &Timer::RestartRaw)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,100 @@
#ifndef _LIBRARY_CHRONO_TIMER_HPP_
#define _LIBRARY_CHRONO_TIMER_HPP_
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
*
*/
class Timer
{
/* --------------------------------------------------------------------------------------------
*
*/
Timer(Int64 t)
: m_Timestamp(t)
{
/* ... */
}
public:
/* --------------------------------------------------------------------------------------------
*
*/
Timer();
/* --------------------------------------------------------------------------------------------
*
*/
Timer(const Timer & o)
: m_Timestamp(o.m_Timestamp)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
*
*/
~Timer()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
*
*/
Timer & operator = (const Timer o)
{
m_Timestamp = o.m_Timestamp;
return *this;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Int32 Cmp(const Timer & b) const;
/* --------------------------------------------------------------------------------------------
* ...
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
*
*/
void Reset();
/* --------------------------------------------------------------------------------------------
*
*/
Timestamp Restart();
/* --------------------------------------------------------------------------------------------
*
*/
Int64 RestartRaw();
/* --------------------------------------------------------------------------------------------
*
*/
Timestamp GetElapsedTime() const;
/* --------------------------------------------------------------------------------------------
*
*/
Int64 GetElapsedTimeRaw() const;
private:
// --------------------------------------------------------------------------------------------
Int64 m_Timestamp;
};
} // Namespace:: SqMod
#endif // _LIBRARY_CHRONO_TIMER_HPP_

View File

@ -0,0 +1,180 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono/Timestamp.hpp"
#include "Library/Chrono/Timer.hpp"
#include "Library/Chrono/Date.hpp"
#include "Library/Chrono/Time.hpp"
#include "Library/Chrono/Datetime.hpp"
#include "Library/Numeric/LongInt.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqTimestamp"))
// ------------------------------------------------------------------------------------------------
Timestamp::Timestamp(const SLongInt & t)
: m_Timestamp(t.GetNum())
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Int32 Timestamp::Cmp(const Timestamp & o) const
{
if (m_Timestamp == o.m_Timestamp)
{
return 0;
}
else if (m_Timestamp > o.m_Timestamp)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Timestamp::ToString() const
{
return ToStrF("%lld", m_Timestamp);
}
// ------------------------------------------------------------------------------------------------
void Timestamp::SetNow()
{
m_Timestamp = Chrono::GetCurrentSysTime();
}
// ------------------------------------------------------------------------------------------------
SLongInt Timestamp::GetMicroseconds() const
{
return SLongInt(m_Timestamp);
}
// ------------------------------------------------------------------------------------------------
void Timestamp::SetMicroseconds(const SLongInt & ammount)
{
m_Timestamp = ammount.GetNum();
}
// ------------------------------------------------------------------------------------------------
SLongInt Timestamp::GetMilliseconds() const
{
return SLongInt(m_Timestamp / 1000L);
}
// ------------------------------------------------------------------------------------------------
void Timestamp::SetMilliseconds(const SLongInt & ammount)
{
m_Timestamp = (ammount.GetNum() * 1000L);
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetEpochTimeNow()
{
return Timestamp(Chrono::GetEpochTimeMicro());
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetMicrosecondsRaw(Int64 ammount)
{
return Timestamp(ammount);
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetMicroseconds(const SLongInt & ammount)
{
return Timestamp(ammount);
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetMilliseconds(SQInteger ammount)
{
return Timestamp(Int64(Int64(ammount) * 1000L));
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetSeconds(SQFloat ammount)
{
return Timestamp(Int64(Float64(ammount) * 1000000L));
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetMinutes(SQFloat ammount)
{
return Timestamp(Int64((Float64(ammount) * 60000000L)));
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetHours(SQFloat ammount)
{
return Timestamp(Int64(Float64(ammount) * 3600000000LL));
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetDays(SQFloat ammount)
{
return Timestamp(Int64(Float64(ammount) * 86400000000LL));
}
// ------------------------------------------------------------------------------------------------
static Timestamp SqGetYears(SQFloat ammount)
{
return Timestamp(Int64(Float64(ammount) * 31557600000000LL));
}
// ================================================================================================
void Register_ChronoTimestamp(HSQUIRRELVM vm, Table & /*cns*/)
{
RootTable(vm).Bind(Typename::Str,
Class< Timestamp >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< const Timestamp & >()
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &Timestamp::ToString)
.Func(_SC("cmp"), &Timestamp::Cmp)
// Meta-methods
.Func< Timestamp (Timestamp::*)(const Timestamp &) const >(_SC("_add"), &Timestamp::operator +)
.Func< Timestamp (Timestamp::*)(const Timestamp &) const >(_SC("_sub"), &Timestamp::operator -)
.Func< Timestamp (Timestamp::*)(const Timestamp &) const >(_SC("_mul"), &Timestamp::operator *)
.Func< Timestamp (Timestamp::*)(const Timestamp &) const >(_SC("_div"), &Timestamp::operator /)
// Properties
.Prop(_SC("Microseconds"), &Timestamp::GetMicroseconds, &Timestamp::SetMicroseconds)
.Prop(_SC("MicrosecondsRaw"), &Timestamp::GetMicrosecondsRaw, &Timestamp::SetMicrosecondsRaw)
.Prop(_SC("Milliseconds"), &Timestamp::GetMilliseconds, &Timestamp::SetMilliseconds)
.Prop(_SC("MillisecondsRaw"), &Timestamp::GetMillisecondsRaw, &Timestamp::SetMillisecondsRaw)
.Prop(_SC("SecondsF"), &Timestamp::GetSecondsF, &Timestamp::SetSecondsF)
.Prop(_SC("SecondsI"), &Timestamp::GetSecondsI, &Timestamp::SetSecondsI)
.Prop(_SC("MinutesF"), &Timestamp::GetMinutesF, &Timestamp::SetMinutesF)
.Prop(_SC("MinutesI"), &Timestamp::GetMinutesI, &Timestamp::SetMinutesI)
.Prop(_SC("HoursF"), &Timestamp::GetHoursF, &Timestamp::SetHoursF)
.Prop(_SC("HoursI"), &Timestamp::GetHoursI, &Timestamp::SetHoursI)
.Prop(_SC("DaysF"), &Timestamp::GetDaysF, &Timestamp::SetDaysF)
.Prop(_SC("DaysI"), &Timestamp::GetDaysI, &Timestamp::SetDaysI)
.Prop(_SC("YearsF"), &Timestamp::GetYearsF, &Timestamp::SetYearsF)
.Prop(_SC("YearsI"), &Timestamp::GetYearsI, &Timestamp::SetYearsI)
// Member Methods
.Func(_SC("SetNow"), &Timestamp::SetNow)
// Static Functions
.StaticFunc(_SC("GetNow"), &SqGetEpochTimeNow)
.StaticFunc(_SC("GetMicrosRaw"), &SqGetMicrosecondsRaw)
.StaticFunc(_SC("GetMicrosecondsRaw"), &SqGetMicrosecondsRaw)
.StaticFunc(_SC("GetMicros"), &SqGetMicroseconds)
.StaticFunc(_SC("GetMicroseconds"), &SqGetMicroseconds)
.StaticFunc(_SC("GetMillis"), &SqGetMilliseconds)
.StaticFunc(_SC("GetMilliseconds"), &SqGetMilliseconds)
.StaticFunc(_SC("GetSeconds"), &SqGetSeconds)
.StaticFunc(_SC("GetMinutes"), &SqGetMinutes)
.StaticFunc(_SC("GetHours"), &SqGetHours)
.StaticFunc(_SC("GetDays"), &SqGetDays)
.StaticFunc(_SC("GetYears"), &SqGetYears)
);
;
}
} // Namespace:: SqMod

View File

@ -0,0 +1,347 @@
#ifndef _LIBRARY_CHRONO_TIMESTAMP_HPP_
#define _LIBRARY_CHRONO_TIMESTAMP_HPP_
// ------------------------------------------------------------------------------------------------
#include "Library/Chrono.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
class Timer;
/* ------------------------------------------------------------------------------------------------
*
*/
class Timestamp
{
// --------------------------------------------------------------------------------------------
friend class Timer;
public:
/* --------------------------------------------------------------------------------------------
*
*/
Timestamp()
: m_Timestamp(0)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
*
*/
Timestamp(Int64 t)
: m_Timestamp(t)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
*
*/
explicit Timestamp(const SLongInt & t);
/* --------------------------------------------------------------------------------------------
*
*/
Timestamp(const Timestamp & o)
: m_Timestamp(o.m_Timestamp)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
*
*/
~Timestamp()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
*
*/
Timestamp & operator = (const Timestamp o)
{
m_Timestamp = o.m_Timestamp;
return *this;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Timestamp operator + (const Timestamp & o) const
{
return Timestamp(m_Timestamp + o.m_Timestamp);
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Timestamp operator - (const Timestamp & o) const
{
return Timestamp(m_Timestamp - o.m_Timestamp);
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Timestamp operator * (const Timestamp & o) const
{
return Timestamp(m_Timestamp * o.m_Timestamp);
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Timestamp operator / (const Timestamp & o) const
{
return Timestamp(m_Timestamp / o.m_Timestamp);
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Int32 Cmp(const Timestamp & b) const;
/* --------------------------------------------------------------------------------------------
* ...
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* ...
*/
void SetNow();
/* --------------------------------------------------------------------------------------------
*
*/
Int64 GetNum() const
{
return m_Timestamp;
}
/* --------------------------------------------------------------------------------------------
*
*/
SLongInt GetMicroseconds() const;
/* --------------------------------------------------------------------------------------------
*
*/
void SetMicroseconds(const SLongInt & ammount);
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger GetMicrosecondsRaw() const
{
return SQInteger(m_Timestamp);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetMicrosecondsRaw(SQInteger ammount)
{
m_Timestamp = ammount;
}
/* --------------------------------------------------------------------------------------------
*
*/
SLongInt GetMilliseconds() const;
/* --------------------------------------------------------------------------------------------
*
*/
void SetMilliseconds(const SLongInt & ammount);
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger GetMillisecondsRaw() const
{
return SQInteger(m_Timestamp / 1000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetMillisecondsRaw(SQInteger ammount)
{
m_Timestamp = Int64(Int64(ammount) * 1000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQFloat GetSecondsF() const
{
return SQFloat(m_Timestamp / 1000000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetSecondsF(SQFloat ammount)
{
m_Timestamp = Int64(Float64(ammount) * 1000000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger GetSecondsI() const
{
return SQInteger(m_Timestamp / 1000000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetSecondsI(SQInteger ammount)
{
m_Timestamp = Int64(Int64(ammount) * 1000000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQFloat GetMinutesF() const
{
return SQFloat(m_Timestamp / 60000000.0f);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetMinutesF(SQFloat ammount)
{
m_Timestamp = Int64(Float64(ammount) * 60000000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger GetMinutesI() const
{
return SQInteger(m_Timestamp / 60000000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetMinutesI(SQInteger ammount)
{
m_Timestamp = Int64(Int64(ammount) * 60000000L);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQFloat GetHoursF() const
{
return SQFloat(m_Timestamp / 3600000000.0d);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetHoursF(SQFloat ammount)
{
m_Timestamp = Int64(Float64(ammount) * 3600000000LL);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger GetHoursI() const
{
return SQInteger(m_Timestamp / 3600000000LL);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetHoursI(SQInteger ammount)
{
m_Timestamp = Int64(Float64(ammount) * 3600000000LL);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQFloat GetDaysF() const
{
return SQFloat(m_Timestamp / 86400000000.0d);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetDaysF(SQFloat ammount)
{
m_Timestamp = Int64(Float64(ammount) * 86400000000LL);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger GetDaysI() const
{
return SQInteger(m_Timestamp / 86400000000LL);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetDaysI(SQInteger ammount)
{
m_Timestamp = Int64(Float64(ammount) * 86400000000LL);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQFloat GetYearsF() const
{
return SQFloat(m_Timestamp / 31557600000000.0d);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetYearsF(SQFloat ammount)
{
m_Timestamp = Int64(Float64(ammount) * 31557600000000LL);
}
/* --------------------------------------------------------------------------------------------
*
*/
SQInteger GetYearsI() const
{
return SQInteger(m_Timestamp / 31557600000000LL);
}
/* --------------------------------------------------------------------------------------------
*
*/
void SetYearsI(SQInteger ammount)
{
m_Timestamp = Int64(Float64(ammount) * 31557600000000LL);
}
private:
// --------------------------------------------------------------------------------------------
Int64 m_Timestamp;
};
} // Namespace:: SqMod
#endif // _LIBRARY_CHRONO_TIMESTAMP_HPP_

23
module/Library/Crypt.cpp Normal file
View File

@ -0,0 +1,23 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Crypt.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_Hash(HSQUIRRELVM vm);
extern void Register_AES(HSQUIRRELVM vm);
// ================================================================================================
void Register_Crypt(HSQUIRRELVM vm)
{
Register_Hash(vm);
Register_AES(vm);
}
} // Namespace:: SqMod

14
module/Library/Crypt.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef _LIBRARY_CRYPT_HPP_
#define _LIBRARY_CRYPT_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod
#endif // _LIBRARY_CRYPT_HPP_

View File

@ -0,0 +1,155 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Crypt/AES.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqAES256"))
// ------------------------------------------------------------------------------------------------
AES256::AES256()
: m_Context(), m_Buffer()
{
aes256_done(&m_Context);
}
// ------------------------------------------------------------------------------------------------
AES256::AES256(CSStr key)
: m_Context(), m_Buffer()
{
Init(key);
}
// ------------------------------------------------------------------------------------------------
Int32 AES256::Cmp(const AES256 & o) const
{
return std::memcmp(m_Buffer, o.m_Buffer, sizeof(m_Buffer));
}
// ------------------------------------------------------------------------------------------------
CSStr AES256::ToString() const
{
return ToStrF("%s", m_Buffer);
}
// ------------------------------------------------------------------------------------------------
CSStr AES256::GetKey() const
{
return reinterpret_cast< CSStr >(m_Buffer);
}
// ------------------------------------------------------------------------------------------------
bool AES256::Init(CSStr key)
{
// Clear current key, if any
aes256_done(&m_Context);
// Is the specified key empty?
if (!key || *key == '\0')
{
return false; // Leave the context with an empty key
}
// Obtain the specified key size
const Uint32 size = (std::strlen(key) * sizeof(SQChar));
// See if the key size is accepted
if (size > sizeof(m_Buffer))
{
STHROWF("The specified key is out of bounds: %u > %u", size, sizeof(m_Buffer));
}
// Initialize the key buffer to 0
std::memset(m_Buffer, 0, sizeof(m_Buffer));
// Copy the key into the key buffer
std::memcpy(m_Buffer, key, size);
// Initialize the context with the specified key
aes256_init(&m_Context, m_Buffer);
// This context was successfully initialized
return true;
}
// ------------------------------------------------------------------------------------------------
void AES256::Done()
{
aes256_done(&m_Context);
}
// ------------------------------------------------------------------------------------------------
String AES256::Encrypt(CSStr data)
{
// Is there any data to encrypt?
if (!data || *data == 0)
{
return String();
}
// Copy the data into an editable string
String str(data);
// Make sure that we have a size with a multiple of 16
if ((str.size() % 16) != 0)
{
str.resize(str.size() - (str.size() % 16) + 16);
}
// Encrypt in chunks of 16 characters
for (Uint32 n = 0; n < str.size(); n += 16)
{
aes256_encrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n]));
}
// Return ownership of the encrypted string
return std::move(str);
}
// ------------------------------------------------------------------------------------------------
String AES256::Decrypt(CSStr data)
{
// Is there any data to decrypt?
if (!data || *data == 0)
{
return String();
}
// Copy the data into an editable string
String str(data);
// Make sure that we have a size with a multiple of 16
if ((str.size() % 16) != 0)
{
str.resize(str.size() - (str.size() % 16) + 16);
}
// Decrypt inc chunks of 16 characters
for (Uint32 n = 0; n < str.size(); n += 16)
{
aes256_decrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n]));
}
// Remove null characters in case the string was not a multiple of 16 when encrypted
while (!str.empty() && str.back() == 0)
{
str.pop_back();
}
// Return ownership of the encrypted string
return std::move(str);
}
// ================================================================================================
void Register_AES(HSQUIRRELVM vm)
{
RootTable(vm).Bind(Typename::Str,
Class< AES256 >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< CSStr >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
.Func(_SC("_tostring"), &AES256::ToString)
.Func(_SC("cmp"), &AES256::Cmp)
/* Properties */
.Prop(_SC("Key"), &AES256::GetKey)
/* Functions */
.Func(_SC("Init"), &AES256::Init)
.Func(_SC("Done"), &AES256::Done)
.Func(_SC("Encrypt"), &AES256::Encrypt)
.Func(_SC("Decrypt"), &AES256::Decrypt)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,105 @@
#ifndef _LIBRARY_CRYPT_AES_HPP_
#define _LIBRARY_CRYPT_AES_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
#include <aes256.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Simple wrapper around a the AES encryption context.
*/
class AES256
{
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
AES256();
/* --------------------------------------------------------------------------------------------
* Construct with an explicit key.
*/
AES256(CSStr key);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
AES256(const AES256 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
AES256(AES256 && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~AES256() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
AES256 & operator = (const AES256 & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
AES256 & operator = (AES256 && o) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const AES256 & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the associated key.
*/
CSStr GetKey() const;
/* --------------------------------------------------------------------------------------------
* Initialize the context key.
*/
bool Init(CSStr key);
/* --------------------------------------------------------------------------------------------
* Reset the associated context.
*/
void Done();
/* --------------------------------------------------------------------------------------------
* Encrypt the specified string.
*/
String Encrypt(CSStr data);
/* --------------------------------------------------------------------------------------------
* Decrypt the specified string.
*/
String Decrypt(CSStr data);
private:
/* --------------------------------------------------------------------------------------------
* The managed encryption context.
*/
aes256_context m_Context;
/* --------------------------------------------------------------------------------------------
* The key used to encrypt data.
*/
Uint8 m_Buffer[32]{0};
};
} // Namespace:: SqMod
#endif // _LIBRARY_CRYPT_AES_HPP_

View File

@ -0,0 +1,192 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Crypt/Hash.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#include <crc32.h>
#include <keccak.h>
#include <md5.h>
#include <sha1.h>
#include <sha256.h>
#include <sha3.h>
#include <b64.h>
#include <whirlpool.h>
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Utility to avoid creating encoder instances for each call.
*/
template < class T > struct BaseHash
{
static T Algo;
};
// ------------------------------------------------------------------------------------------------
template < class T > T BaseHash< T >::Algo;
/* ------------------------------------------------------------------------------------------------
* Hash the specified value or the result of a formatted string.
*/
template < class T > static SQInteger HashF(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Forward the call to the actual implementation and store the string
String str(BaseHash< T >::Algo(val.mPtr));
// Push the string on the stack
sq_pushstring(vm, str.data(), str.size());
// At this point we have a valid string on the stack
return 1;
}
/* ------------------------------------------------------------------------------------------------
* Hash the specified value or the result of a formatted string with whirlpool algorithm.
*/
static SQInteger WhirlpoolF(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Prepare a whirlpool hashing context
whirlpool_ctx ctx;
// Initialize the hashing context
rhash_whirlpool_init(&ctx);
// Update the context with the given string
rhash_whirlpool_update(&ctx, reinterpret_cast< const unsigned char * >(val.mPtr),
val.mLen < 0 ? 0 : static_cast< size_t >(val.mLen));
// Reserve space for the result in binary form
unsigned char raw_hash[whirlpool_block_size];
// Finalize hashing and obtain the result
rhash_whirlpool_final(&ctx, raw_hash);
// Reserve space for the hexadecimal string
char hex_hash[whirlpool_block_size * 2];
// Convert from binary form to hex string
for (int i = 0, p = 0; i < whirlpool_block_size; ++i)
{
static const char dec2hex[16+1] = "0123456789abcdef";
hex_hash[p++] = dec2hex[(raw_hash[i] >> 4) & 15];
hex_hash[p++] = dec2hex[ raw_hash[i] & 15];
}
// Push the string on the stack
sq_pushstring(vm, hex_hash, whirlpool_block_size * 2);
// At this point we have a valid string on the stack
return 1;
}
/* ------------------------------------------------------------------------------------------------
* Encode the specified value or the result of a formatted string with base64 algorithm.
*/
static SQInteger EncodeBase64F(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Size of the encoded string
size_t enclen = 0;
// Attempt to encode the resulted string
char * result = b64_encode_ex(reinterpret_cast< const unsigned char * >(val.mPtr),
val.mLen < 0 ? 0 : static_cast< size_t >(val.mLen), &enclen);
// Did we fail to allocate memory for it?
if (!result)
{
return sq_throwerror(vm, _SC("Unable to allocate memory for output"));
}
// Push the string on the stack
sq_pushstring(vm, result, ConvTo< SQInteger >::From(enclen));
// At this point we have a valid string on the stack
return 1;
}
/* ------------------------------------------------------------------------------------------------
* Decode the specified value or the result of a formatted string with base64 algorithm.
*/
static SQInteger DecodeBase64F(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Size of the decoded string
size_t declen = 0;
// Attempt to decode the resulted string
unsigned char * result = b64_decode_ex(val.mPtr, val.mLen < 0 ? 0 : static_cast< size_t >(val.mLen), &declen);
// Did we fail to allocate memory for it?
if (!result)
{
return sq_throwerror(vm, _SC("Unable to allocate memory for output"));
}
// Push the string on the stack
sq_pushstring(vm, reinterpret_cast< CSStr >(result), ConvTo< SQInteger >::From(declen));
// At this point we have a valid string on the stack
return 1;
}
// ================================================================================================
template < class T > static void RegisterWrapper(Table & hashns, CCStr cname)
{
typedef HashWrapper< T > Hash;
hashns.Bind(cname,
Class< Hash >(hashns.GetVM(), cname)
// Constructors
.Ctor()
// Meta-methods
.Func(_SC("_tostring"), &Hash::ToString)
// Properties
.Prop(_SC("Hash"), &Hash::GetHash)
// Functions
.Func(_SC("Reset"), &Hash::Reset)
.Func(_SC("Compute"), &Hash::Compute)
.Func(_SC("GetHash"), &Hash::GetHash)
.Func(_SC("Add"), &Hash::AddStr)
.Func(_SC("AddStr"), &Hash::AddStr)
);
}
// ================================================================================================
void Register_Hash(HSQUIRRELVM vm)
{
Table hashns(vm);
RegisterWrapper< CRC32 >(hashns, _SC("CRC32"));
RegisterWrapper< Keccak >(hashns, _SC("Keccak"));
RegisterWrapper< MD5 >(hashns, _SC("MD5"));
RegisterWrapper< SHA1 >(hashns, _SC("SHA1"));
RegisterWrapper< SHA256 >(hashns, _SC("SHA256"));
RegisterWrapper< SHA3 >(hashns, _SC("SHA3"));
hashns.SquirrelFunc(_SC("GetCRC32"), &HashF< CRC32 >);
hashns.SquirrelFunc(_SC("GetKeccak"), &HashF< Keccak >);
hashns.SquirrelFunc(_SC("GetMD5"), &HashF< MD5 >);
hashns.SquirrelFunc(_SC("GetSHA1"), &HashF< SHA1 >);
hashns.SquirrelFunc(_SC("GetSHA256"), &HashF< SHA256 >);
hashns.SquirrelFunc(_SC("GetSHA3"), &HashF< SHA3 >);
hashns.SquirrelFunc(_SC("GetWhirlpool"), &WhirlpoolF);
hashns.SquirrelFunc(_SC("EncodeBase64"), &EncodeBase64F);
hashns.SquirrelFunc(_SC("DecodeBase64"), &DecodeBase64F);
RootTable(vm).Bind(_SC("SqHash"), hashns);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,102 @@
#ifndef _LIBRARY_CRYPT_HASH_HPP_
#define _LIBRARY_CRYPT_HASH_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Simple class to maintain the state of an encoder.
*/
template < class T > class HashWrapper
{
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
HashWrapper()
: m_Encoder()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy operator.
*/
HashWrapper(const HashWrapper & o)
: m_Encoder(o.m_Encoder)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~HashWrapper()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
HashWrapper & operator = (const HashWrapper & o)
{
m_Encoder = o.m_Encoder;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
String ToString()
{
return m_Encoder.getHash();
}
/* --------------------------------------------------------------------------------------------
* Reset the encoder state.
*/
void Reset()
{
m_Encoder.reset();
}
/* --------------------------------------------------------------------------------------------
* Compute the hash of the specified string.
*/
String Compute(const String & str)
{
return m_Encoder(str);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the hash value of the data hashed so far.
*/
String GetHash()
{
return m_Encoder.getHash();
}
/* --------------------------------------------------------------------------------------------
* Add a string value to be hashed.
*/
void AddStr(const String & str)
{
m_Encoder.add(str.data(), str.length() * sizeof(String::value_type));
}
private:
/* --------------------------------------------------------------------------------------------
* The managed encoder state.
*/
T m_Encoder;
};
} // Namespace:: SqMod
#endif // _LIBRARY_CRYPT_HASH_HPP_

16
module/Library/IO.cpp Normal file
View File

@ -0,0 +1,16 @@
// ------------------------------------------------------------------------------------------------
#include "Library/IO.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_INI(HSQUIRRELVM vm);
// ================================================================================================
void Register_IO(HSQUIRRELVM vm)
{
Register_INI(vm);
}
} // Namespace:: SqMod

14
module/Library/IO.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef _LIBRARY_IO_HPP_
#define _LIBRARY_IO_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod
#endif // _LIBRARY_IO_HPP_

View File

View File

479
module/Library/IO/INI.cpp Normal file
View File

@ -0,0 +1,479 @@
// ------------------------------------------------------------------------------------------------
#include "Library/IO/INI.hpp"
// ------------------------------------------------------------------------------------------------
#include <cerrno>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(ResultTypename, _SC("SqIniResult"))
SQMODE_DECL_TYPENAME(EntriesTypename, _SC("SqIniEntries"))
SQMODE_DECL_TYPENAME(DocumentTypename, _SC("SqIniDocument"))
// ------------------------------------------------------------------------------------------------
void IniResult::Check() const
{
// Identify the error type
switch (m_Result)
{
case SI_FAIL:
STHROWF("Unable to %s. Probably invalid", m_Action.c_str());
break;
case SI_NOMEM:
STHROWF("Unable to %s. Ran out of memory", m_Action.c_str());
break;
case SI_FILE:
STHROWF("Unable to %s. %s", strerror(errno));
break;
case SI_OK:
case SI_UPDATED:
case SI_INSERTED:
break; /* These are not error messahes. */
default:
STHROWF("Unable to %s for some unforeseen reason", m_Action.c_str());
}
}
// ------------------------------------------------------------------------------------------------
void DocumentRef::Validate() const
{
// Is the document handle valid?
if (!m_Ptr)
{
STHROWF("Invalid INI document reference");
}
}
// ------------------------------------------------------------------------------------------------
Int32 Entries::Cmp(const Entries & o) const
{
if (m_Elem == o.m_Elem)
{
return 0;
}
else if (m_List.size() > o.m_List.size())
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Next()
{
// Are there any other elements ahead?
if (!m_List.empty() && m_Elem != m_List.end())
{
++m_Elem; // Go ahead one element
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Prev()
{
// Are there any other elements behind?
if (!m_List.empty() && m_Elem != m_List.begin())
{
--m_Elem; // Go back one element
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Advance(Int32 n)
{
// Are there any other elements ahead?
if (m_List.empty() || m_Elem == m_List.end())
{
return;
}
// Jump as many elements as possible within the specified distance
while ((--n >= 0) && m_Elem != m_List.end())
{
++m_Elem;
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Retreat(Int32 n)
{
// Are there any other elements behind?
if (m_List.empty() || m_Elem == m_List.begin())
{
return;
}
// Jump as many elements as possible within the specified distance
while ((--n >= 0) && m_Elem != m_List.begin())
{
--m_Elem;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Entries::GetItem() const
{
// is the current element valid?
if (m_List.empty() || m_Elem == m_List.end())
{
STHROWF("Invalid INI entry [item]");
}
// Return the requested information
return m_Elem->pItem;
}
// ------------------------------------------------------------------------------------------------
CSStr Entries::GetComment() const
{
// is the current element valid?
if (m_List.empty() || m_Elem == m_List.end())
{
STHROWF("Invalid INI entry [comment]");
}
// Return the requested information
return m_Elem->pComment;
}
// ------------------------------------------------------------------------------------------------
Int32 Entries::GetOrder() const
{
// is the current element valid?
if (m_List.empty() || m_Elem == m_List.end())
{
STHROWF("Invalid INI entry [order]");
}
// Return the requested information
return m_Elem->nOrder;
}
// ------------------------------------------------------------------------------------------------
Int32 Document::Cmp(const Document & o) const
{
if (m_Doc == o.m_Doc)
{
return 0;
}
else if (m_Doc.m_Ptr > o.m_Doc.m_Ptr)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadFile(CSStr filepath)
{
// Validate the handle
m_Doc.Validate();
// Attempt to load the file from disk and return the result
return IniResult("load INI file", m_Doc->LoadFile(filepath));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadData(CSStr source, Int32 size)
{
// Validate the handle
m_Doc.Validate();
// Attempt to load the file from memory and return the result
return IniResult("load INI file", m_Doc->LoadData(source, size < 0 ? strlen(source) : size));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SaveFile(CSStr filepath, bool signature)
{
// Validate the handle
m_Doc.Validate();
// Attempt to save the file to disk and return the result
return IniResult("save INI file", m_Doc->SaveFile(filepath, signature));
}
// ------------------------------------------------------------------------------------------------
Object Document::SaveData(bool signature)
{
// Validate the handle
m_Doc.Validate();
// The string where the content will be saved
String source;
// Attempt to save the data to string
if (m_Doc->Save(source, signature) < 0)
{
STHROWF("Unable to save INI document");
}
// Obtain the initial stack size
const StackGuard sg(DefaultVM::Get());
// Transform it into a script object
sq_pushstring(DefaultVM::Get(), source.c_str(), source.size());
// Get the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllSections() const
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllSections(entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllKeys(CSStr section) const
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllKeys(section, entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllValues(CSStr section, CSStr key) const
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllValues(section, key, entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Int32 Document::GetSectionSize(CSStr section) const
{
// Validate the handle
m_Doc.Validate();
// Return the requested information
return m_Doc->GetSectionSize(section);
}
// ------------------------------------------------------------------------------------------------
bool Document::HasMultipleKeys(CSStr section, CSStr key) const
{
// Validate the handle
m_Doc.Validate();
// Where to retrive whether the key has multiple instances
bool multiple = false;
// Attempt to query the information
if (m_Doc->GetValue(section, key, nullptr, &multiple) == nullptr)
{
return true; // Doesn't exist
}
// Return the result
return multiple;
}
// ------------------------------------------------------------------------------------------------
CCStr Document::GetValue(CSStr section, CSStr key, CSStr def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return m_Doc->GetValue(section, key, def, nullptr);
}
// ------------------------------------------------------------------------------------------------
SQInteger Document::GetInteger(CSStr section, CSStr key, SQInteger def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return static_cast< SQInteger >(m_Doc->GetLongValue(section, key, def, nullptr));
}
// ------------------------------------------------------------------------------------------------
SQFloat Document::GetFloat(CSStr section, CSStr key, SQFloat def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return static_cast< SQFloat >(m_Doc->GetDoubleValue(section, key, def, nullptr));
}
// ------------------------------------------------------------------------------------------------
bool Document::GetBoolean(CSStr section, CSStr key, bool def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return m_Doc->GetBoolValue(section, key, def, nullptr);
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI value", m_Doc->SetValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI integer", m_Doc->SetLongValue(section, key, value, comment, hex, force));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI float", m_Doc->SetDoubleValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information
return IniResult("set INI boolean", m_Doc->SetBoolValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
bool Document::DeleteValue(CSStr section, CSStr key, CSStr value, bool empty)
{
// Validate the handle
m_Doc.Validate();
// Attempt to remove the specified value and return the result
return m_Doc->DeleteValue(section, key, value, empty);
}
// ================================================================================================
void Register_INI(HSQUIRRELVM vm)
{
Table inins(vm);
inins.Bind(_SC("Result"),
Class< IniResult >(vm, ResultTypename::Str)
// Constructors
.Ctor()
.Ctor< CSStr, SQInteger >()
.Ctor< const IniResult & >()
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &ResultTypename::Fn)
.Func(_SC("_tostring"), &IniResult::ToString)
.Func(_SC("cmp"), &IniResult::Cmp)
// Properties
.Prop(_SC("Valid"), &IniResult::IsValid)
.Prop(_SC("Action"), &IniResult::GetAction)
.Prop(_SC("Result"), &IniResult::GetResult)
// Member Methods
.Func(_SC("Check"), &IniResult::Check)
);
inins.Bind(_SC("Entries"),
Class< Entries >(vm, EntriesTypename::Str)
// Constructors
.Ctor()
.Ctor< const Entries & >()
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &EntriesTypename::Fn)
.Func(_SC("_tostring"), &Entries::ToString)
.Func(_SC("cmp"), &Entries::Cmp)
// Properties
.Prop(_SC("Valid"), &Entries::IsValid)
.Prop(_SC("Empty"), &Entries::IsEmpty)
.Prop(_SC("References"), &Entries::GetRefCount)
.Prop(_SC("Size"), &Entries::GetSize)
.Prop(_SC("Item"), &Entries::GetItem)
.Prop(_SC("Comment"), &Entries::GetComment)
.Prop(_SC("Order"), &Entries::GetOrder)
// Member Methods
.Func(_SC("Reset"), &Entries::Reset)
.Func(_SC("Next"), &Entries::Next)
.Func(_SC("Prev"), &Entries::Prev)
.Func(_SC("Advance"), &Entries::Advance)
.Func(_SC("Retreat"), &Entries::Retreat)
.Func(_SC("Sort"), &Entries::Sort)
.Func(_SC("SortByKeyOrder"), &Entries::SortByKeyOrder)
.Func(_SC("SortByLoadOrder"), &Entries::SortByLoadOrder)
);
inins.Bind(_SC("Document"),
Class< Document, NoCopy< Document > >(vm, DocumentTypename::Str)
// Constructors
.Ctor()
.Ctor< bool >()
.Ctor< bool, bool >()
.Ctor< bool, bool, bool >()
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &DocumentTypename::Fn)
.Func(_SC("_tostring"), &Document::ToString)
.Func(_SC("cmp"), &Document::Cmp)
// Properties
.Prop(_SC("Valid"), &Document::IsValid)
.Prop(_SC("Empty"), &Document::IsEmpty)
.Prop(_SC("References"), &Document::GetRefCount)
.Prop(_SC("Unicode"), &Document::GetUnicode, &Document::SetUnicode)
.Prop(_SC("MultiKey"), &Document::GetMultiKey, &Document::SetMultiKey)
.Prop(_SC("MultiLine"), &Document::GetMultiLine, &Document::SetMultiLine)
.Prop(_SC("Spaces"), &Document::GetSpaces, &Document::SetSpaces)
// Member Methods
.Func(_SC("Reset"), &Document::Reset)
.Func(_SC("LoadFile"), &Document::LoadFile)
.Overload< IniResult (Document::*)(CSStr) >(_SC("LoadString"), &Document::LoadData)
.Overload< IniResult (Document::*)(CSStr, Int32) >(_SC("LoadString"), &Document::LoadData)
.Overload< IniResult (Document::*)(CSStr) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< IniResult (Document::*)(CSStr, bool) >(_SC("SaveFile"), &Document::SaveFile)
.Func(_SC("SaveData"), &Document::SaveData)
.Func(_SC("GetSections"), &Document::GetAllSections)
.Func(_SC("GetKeys"), &Document::GetAllKeys)
.Func(_SC("GetValues"), &Document::GetAllValues)
.Func(_SC("GetSectionSize"), &Document::GetSectionSize)
.Func(_SC("HasMultipleKeys"), &Document::HasMultipleKeys)
.Func(_SC("GetValue"), &Document::GetValue)
.Func(_SC("GetInteger"), &Document::GetInteger)
.Func(_SC("GetFloat"), &Document::GetFloat)
.Func(_SC("GetBoolean"), &Document::GetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr, bool) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr, bool, CSStr) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool, bool) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool, bool, CSStr) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat, bool) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat, bool, CSStr) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool, bool) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool, bool, CSStr) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< bool (Document::*)(CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr, CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr, CSStr, bool) >(_SC("DeleteValue"), &Document::DeleteValue)
);
RootTable(vm).Bind(_SC("SqIni"), inins);
ConstTable(vm).Enum(_SC("SqIniError"), Enumeration(vm)
.Const(_SC("Ok"), Int32(SI_OK))
.Const(_SC("Updated"), Int32(SI_UPDATED))
.Const(_SC("Inserted"), Int32(SI_INSERTED))
.Const(_SC("Fail"), Int32(SI_FAIL))
.Const(_SC("NoMem"), Int32(SI_NOMEM))
.Const(_SC("File"), Int32(SI_FILE))
);
}
} // Namespace:: SqMod

981
module/Library/IO/INI.hpp Normal file
View File

@ -0,0 +1,981 @@
#ifndef _LIBRARY_IO_INI_HPP_
#define _LIBRARY_IO_INI_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#include <SimpleIni.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Allows the user to inspect the result of certain operations and act accordingly.
*/
class IniResult
{
private:
// --------------------------------------------------------------------------------------------
String m_Action; // The action that was performed.
SQInteger m_Result; // The internal result code.
public:
/* --------------------------------------------------------------------------------------------
* Construct with no specific action or result.
*/
IniResult()
: m_Action("unknown action"), m_Result(SI_OK)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with no specific result.
*/
explicit IniResult(CSStr action)
: m_Action(!action ? _SC("") : action), m_Result(SI_OK)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with no specific action.
*/
explicit IniResult(SQInteger result)
: m_Action("unknown action"), m_Result(result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with specific action and result.
*/
IniResult(CSStr action, SQInteger result)
: m_Action(!action ? _SC("") : action), m_Result(result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
IniResult(const IniResult & o)
: m_Action(o.m_Action), m_Result(o.m_Result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~IniResult()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
IniResult & operator = (const IniResult & o)
{
m_Action = o.m_Action;
m_Result = o.m_Result;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two results.
*/
bool operator == (const IniResult & o) const
{
return (m_Result == o.m_Result);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two results.
*/
bool operator != (const IniResult & o) const
{
return (m_Result != o.m_Result);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return (m_Result >= 0);
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const IniResult & o) const
{
if (m_Result == o.m_Result)
{
return 0;
}
else if (m_Result > o.m_Result)
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Action.c_str();
}
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI result.
*/
bool IsValid() const
{
return (m_Result >= 0);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated action.
*/
CSStr GetAction() const
{
return m_Action.c_str();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the resulted code.
*/
SQInteger GetResult() const
{
return m_Result;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the resulted code.
*/
void Check() const;
};
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted INI document instance.
*/
class DocumentRef
{
// --------------------------------------------------------------------------------------------
friend class Document;
public:
// --------------------------------------------------------------------------------------------
typedef CSimpleIniA Type; // The managed type.
// --------------------------------------------------------------------------------------------
typedef Type* Pointer; // Pointer to the managed type.
typedef const Type* ConstPtr; // Constant pointer to the managed type.
// --------------------------------------------------------------------------------------------
typedef Type& Reference; // Reference to the managed type.
typedef const Type& ConstRef; // Constant reference to the managed type.
// --------------------------------------------------------------------------------------------
typedef unsigned int Counter; // Reference counter type.
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
void Validate() const;
private:
// --------------------------------------------------------------------------------------------
Pointer m_Ptr; // The document reader, writer and manager instance.
Counter* m_Ref; // Reference count to the managed instance.
/* --------------------------------------------------------------------------------------------
* Grab a strong reference to a document instance.
*/
void Grab()
{
if (m_Ptr)
{
++(*m_Ref);
}
}
/* --------------------------------------------------------------------------------------------
* Drop a strong reference to a document instance.
*/
void Drop()
{
if (m_Ptr && --(*m_Ref) == 0)
{
delete m_Ptr;
delete m_Ref;
m_Ptr = NULL;
m_Ref = NULL;
}
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
DocumentRef(bool utf8, bool multikey, bool multiline)
: m_Ptr(new Type(utf8, multikey, multiline)), m_Ref(new Counter(1))
{
/* ... */
}
public:
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
DocumentRef()
: m_Ptr(NULL), m_Ref(NULL)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
DocumentRef(const DocumentRef & o)
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
{
Grab();
}
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
DocumentRef(DocumentRef && o)
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
{
o.m_Ptr = NULL;
o.m_Ref = NULL;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~DocumentRef()
{
Drop();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
DocumentRef & operator = (const DocumentRef & o)
{
if (m_Ptr != o.m_Ptr)
{
Drop();
m_Ptr = o.m_Ptr;
m_Ref = o.m_Ref;
Grab();
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
DocumentRef & operator = (DocumentRef && o)
{
if (m_Ptr != o.m_Ptr)
{
m_Ptr = o.m_Ptr;
m_Ref = o.m_Ref;
o.m_Ptr = NULL;
o.m_Ref = NULL;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two document instances.
*/
bool operator == (const DocumentRef & o) const
{
return (m_Ptr == o.m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two document instances.
*/
bool operator != (const DocumentRef & o) const
{
return (m_Ptr != o.m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance pointer.
*/
operator Pointer ()
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance pointer.
*/
operator ConstPtr () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance reference.
*/
operator Reference ()
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance reference.
*/
operator ConstRef () const
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Member operator for dereferencing the managed pointer.
*/
Pointer operator -> () const
{
assert(m_Ptr);
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator for obtaining a reference of the managed pointer.
*/
Reference operator * () const
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of active references to the managed instance.
*/
Counter Count() const
{
return (m_Ptr && m_Ref) ? (*m_Ref) : 0;
}
};
/* ------------------------------------------------------------------------------------------------
* Class that can access and iterate a series of entries in the INI document.
*/
class Entries
{
// --------------------------------------------------------------------------------------------
friend class Document;
protected:
// --------------------------------------------------------------------------------------------
typedef DocumentRef::Type::TNamesDepend Container;
// --------------------------------------------------------------------------------------------
typedef Container::iterator Iterator;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Entries(const DocumentRef & ini, Container & list)
: m_Doc(ini), m_List(), m_Elem()
{
m_List.swap(list);
Reset();
}
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The document that contains the elements.
Container m_List; // The list of elements to iterate.
Iterator m_Elem; // The currently processed element.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
Entries()
: m_Doc(), m_List(), m_Elem(m_List.end())
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Entries(const Entries & o)
: m_Doc(o.m_Doc), m_List(o.m_List), m_Elem()
{
Reset();
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Entries()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Entries & operator = (const Entries & o)
{
m_Doc = o.m_Doc;
m_List = o.m_List;
Reset();
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Entries & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return GetItem();
}
/* --------------------------------------------------------------------------------------------
* Return whether the current element is valid and can be accessed.
*/
bool IsValid() const
{
return !(m_List.empty() || m_Elem == m_List.end());
}
/* --------------------------------------------------------------------------------------------
* Return whether the entry list is empty.
*/
bool IsEmpty() const
{
return m_List.empty();
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* Return the total entries in the list.
*/
Int32 GetSize() const
{
return static_cast< Int32 >(m_List.size());
}
/* --------------------------------------------------------------------------------------------
* Reset the internal iterator to the first element.
*/
void Reset()
{
if (m_List.empty())
{
m_Elem = m_List.end();
}
else
{
m_Elem = m_List.begin();
}
}
/* --------------------------------------------------------------------------------------------
* Go to the next element.
*/
void Next();
/* --------------------------------------------------------------------------------------------
* Go to the previous element.
*/
void Prev();
/* --------------------------------------------------------------------------------------------
* Advance a certain number of elements.
*/
void Advance(Int32 n);
/* --------------------------------------------------------------------------------------------
* Retreat a certain number of elements.
*/
void Retreat(Int32 n);
/* --------------------------------------------------------------------------------------------
* Sort the entries using the default options.
*/
void Sort()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::KeyOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Sort the entries by name of key only.
*/
void SortByKeyOrder()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::KeyOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Sort the entries by their load order and then name of key.
*/
void SortByLoadOrder()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::LoadOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Retrieve the string value of the current element item.
*/
CSStr GetItem() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the string value of the current element comment.
*/
CSStr GetComment() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the order of the current element.
*/
Int32 GetOrder() const;
};
/* ------------------------------------------------------------------------------------------------
* Class that can read/write and alter the contents of INI files.
*/
class Document
{
protected:
// --------------------------------------------------------------------------------------------
typedef DocumentRef::Type::TNamesDepend Container;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Document(const Document & o);
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Document & operator = (const Document & o);
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The main INI document instance.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Document()
: m_Doc(false, false, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8)
: m_Doc(utf8, false, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8, bool multikey)
: m_Doc(utf8, multikey, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8, bool multikey, bool multiline)
: m_Doc(utf8, multikey, multiline)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Document()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Document & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return _SC("");
}
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* See whether any data has been loaded into this document.
*/
bool IsEmpty() const
{
return m_Doc->IsEmpty();
}
/* --------------------------------------------------------------------------------------------
* Deallocate all memory stored by this document.
*/
void Reset() const
{
m_Doc->Reset();
}
/* --------------------------------------------------------------------------------------------
* See whether the INI data is treated as unicode.
*/
bool GetUnicode() const
{
return m_Doc->IsUnicode();
}
/* --------------------------------------------------------------------------------------------
* Set whether the INI data should be treated as unicode.
*/
void SetUnicode(bool toggle)
{
m_Doc->SetUnicode(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether multiple identical keys be permitted in the file.
*/
bool GetMultiKey() const
{
return m_Doc->IsMultiKey();
}
/* --------------------------------------------------------------------------------------------
* Set whether multiple identical keys be permitted in the file.
*/
void SetMultiKey(bool toggle)
{
m_Doc->SetMultiKey(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether data values are permitted to span multiple lines in the file.
*/
bool GetMultiLine() const
{
return m_Doc->IsMultiLine();
}
/* --------------------------------------------------------------------------------------------
* Set whether data values are permitted to span multiple lines in the file.
*/
void SetMultiLine(bool toggle)
{
m_Doc->SetMultiLine(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether spaces are added around the equals sign when writing key/value pairs out.
*/
bool GetSpaces() const
{
return m_Doc->UsingSpaces();
}
/* --------------------------------------------------------------------------------------------
* Set whether spaces are added around the equals sign when writing key/value pairs out.
*/
void SetSpaces(bool toggle)
{
m_Doc->SetSpaces(toggle);
}
/* --------------------------------------------------------------------------------------------
* Load an INI file from disk into memory.
*/
IniResult LoadFile(CSStr filepath);
/* --------------------------------------------------------------------------------------------
* Load INI file data direct from a string. (LoadString collides with the windows api)
*/
IniResult LoadData(CSStr source)
{
return LoadData(source, -1);
}
/* --------------------------------------------------------------------------------------------
* Load INI file data direct from a string. (LoadString collides with the windows api)
*/
IniResult LoadData(CSStr source, Int32 size);
/* --------------------------------------------------------------------------------------------
* Save an INI file from memory to disk.
*/
IniResult SaveFile(CSStr filepath)
{
return SaveFile(filepath, true);
}
/* --------------------------------------------------------------------------------------------
* Save an INI file from memory to disk.
*/
IniResult SaveFile(CSStr filepath, bool signature);
/* --------------------------------------------------------------------------------------------
* Save the INI data to a string.
*/
Object SaveData(bool signature);
/* --------------------------------------------------------------------------------------------
* Retrieve all section names.
*/
Entries GetAllSections() const;
/* --------------------------------------------------------------------------------------------
* Retrieve all unique key names in a section.
*/
Entries GetAllKeys(CSStr section) const;
/* --------------------------------------------------------------------------------------------
* Retrieve all values for a specific key.
*/
Entries GetAllValues(CSStr section, CSStr key) const;
/* --------------------------------------------------------------------------------------------
* Query the number of keys in a specific section.
*/
Int32 GetSectionSize(CSStr section) const;
/* --------------------------------------------------------------------------------------------
* See whether a certain key has multiple instances.
*/
bool HasMultipleKeys(CSStr section, CSStr key) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value for a specific key.
*/
CCStr GetValue(CSStr section, CSStr key, CSStr def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a numeric value for a specific key.
*/
SQInteger GetInteger(CSStr section, CSStr key, SQInteger def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a numeric value for a specific key.
*/
SQFloat GetFloat(CSStr section, CSStr key, SQFloat def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a boolean value for a specific key.
*/
bool GetBoolean(CSStr section, CSStr key, bool def) const;
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value)
{
return SetValue(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force)
{
return SetValue(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value)
{
return SetInteger(section, key, value, false, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex)
{
return SetInteger(section, key, value, hex, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force)
{
return SetInteger(section, key, value, hex, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value)
{
return SetFloat(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force)
{
return SetFloat(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value)
{
return SetBoolean(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force)
{
return SetBoolean(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a boolean value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section)
{
return DeleteValue(section, nullptr, nullptr, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key)
{
return DeleteValue(section, key, nullptr, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key, CSStr value)
{
return DeleteValue(section, key, value, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key, CSStr value, bool empty);
};
} // Namespace:: SqMod
#endif // _LIBRARY_IO_INI_HPP_

View File

@ -0,0 +1,20 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Numeric.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_LongInt(HSQUIRRELVM vm);
extern void Register_Math(HSQUIRRELVM vm);
extern void Register_Random(HSQUIRRELVM vm);
// ================================================================================================
void Register_Numeric(HSQUIRRELVM vm)
{
Register_LongInt(vm);
Register_Math(vm);
Register_Random(vm);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,14 @@
#ifndef _LIBRARY_NUMERIC_HPP_
#define _LIBRARY_NUMERIC_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod
#endif // _LIBRARY_NUMERIC_HPP_

View File

@ -0,0 +1,197 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Numeric/LongInt.hpp"
#include "Library/Numeric/Random.hpp"
#include "Base/Shared.hpp"
#include "Base/DynArg.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cerrno>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(TypenameS, _SC("SLongInt"))
SQMODE_DECL_TYPENAME(TypenameU, _SC("ULongInt"))
// ------------------------------------------------------------------------------------------------
LongInt< Int64 >::LongInt(CSStr text)
: m_Data(0), m_Text()
{
m_Data = std::strtoll(text, nullptr, 10);
}
// ------------------------------------------------------------------------------------------------
LongInt< Int64 >::LongInt(CSStr text, Uint32 base)
: m_Data(0), m_Text()
{
m_Data = std::strtoll(text, nullptr, base);
}
// ------------------------------------------------------------------------------------------------
LongInt< Int64 > & LongInt< Int64 >::operator = (CSStr text)
{
m_Data = std::strtoll(text, nullptr, 10);
return *this;
}
// ------------------------------------------------------------------------------------------------
CSStr LongInt< Int64 >::ToString()
{
if (std::snprintf(m_Text, sizeof(m_Text), "%llu", m_Data) < 0)
{
m_Text[0] = 0;
}
return m_Text;
}
// ------------------------------------------------------------------------------------------------
void LongInt< Int64 >::Random()
{
m_Data = GetRandomInt64();
}
// ------------------------------------------------------------------------------------------------
void LongInt< Int64 >::Random(Type n)
{
m_Data = GetRandomInt64(n);
}
// ------------------------------------------------------------------------------------------------
void LongInt< Int64 >::Random(Type m, Type n)
{
m_Data = GetRandomInt64(m, n);
}
// ------------------------------------------------------------------------------------------------
LongInt< Uint64 >::LongInt(CSStr text)
: m_Data(0), m_Text()
{
m_Data = std::strtoull(text, nullptr, 10);
}
// ------------------------------------------------------------------------------------------------
LongInt< Uint64 >::LongInt(CSStr text, Uint32 base)
: m_Data(0), m_Text()
{
m_Data = std::strtoull(text, nullptr, base);
}
// ------------------------------------------------------------------------------------------------
LongInt< Uint64 > & LongInt< Uint64 >::operator = (CSStr text)
{
m_Data = std::strtoull(text, nullptr, 10);
return *this;
}
// ------------------------------------------------------------------------------------------------
CSStr LongInt< Uint64 >::ToString()
{
if (std::snprintf(m_Text, sizeof(m_Text), "%llu", m_Data) < 0)
{
m_Text[0] = 0;
}
return m_Text;
}
// ------------------------------------------------------------------------------------------------
void LongInt< Uint64 >::Random()
{
m_Data = GetRandomUint64();
}
// ------------------------------------------------------------------------------------------------
void LongInt< Uint64 >::Random(Type n)
{
m_Data = GetRandomUint64(n);
}
// ------------------------------------------------------------------------------------------------
void LongInt< Uint64 >::Random(Type m, Type n)
{
m_Data = GetRandomUint64(m, n);
}
// ================================================================================================
void Register_LongInt(HSQUIRRELVM vm)
{
RootTable(vm).Bind(TypenameS::Str,
Class< SLongInt >(vm, TypenameS::Str)
// Constructors
.Ctor()
.Ctor< SLongInt::Type >()
.template Ctor< CCStr, SQInteger >()
// Properties
.Prop(_SC("Str"), &SLongInt::GetCStr, &SLongInt::SetStr)
.Prop(_SC("Num"), &SLongInt::GetSNum, &SLongInt::SetNum)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
.SquirrelFunc(_SC("_typename"), &TypenameS::Fn)
.Func(_SC("_tostring"), &SLongInt::ToString)
// Core Functions
.Func(_SC("tointeger"), &SLongInt::ToSqInteger)
.Func(_SC("tofloat"), &SLongInt::ToSqFloat)
.Func(_SC("tostring"), &SLongInt::ToSqString)
.Func(_SC("tobool"), &SLongInt::ToSqBool)
.Func(_SC("tochar"), &SLongInt::ToSqChar)
// Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
.SquirrelFunc(_SC("_mul"), &SqDynArgFwd< SqDynArgMulFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
.Func< SLongInt (SLongInt::*)(void) const >(_SC("_unm"), &SLongInt::operator -)
// Functions
.Func(_SC("GetStr"), &SLongInt::GetCStr)
.Func(_SC("SetStr"), &SLongInt::SetStr)
.Func(_SC("GetNum"), &SLongInt::GetSNum)
.Func(_SC("SetNum"), &SLongInt::SetNum)
// Overloads
.Overload< void (SLongInt::*)(void) >(_SC("Random"), &SLongInt::Random)
.Overload< void (SLongInt::*)(SLongInt::Type) >(_SC("Random"), &SLongInt::Random)
.Overload< void (SLongInt::*)(SLongInt::Type, SLongInt::Type) >(_SC("Random"), &SLongInt::Random)
);
RootTable(vm).Bind(TypenameU::Str,
Class< ULongInt >(vm, TypenameU::Str)
// Constructors
.Ctor()
.Ctor< ULongInt::Type >()
.Ctor< CCStr, SQInteger >()
// Properties
.Prop(_SC("Str"), &ULongInt::GetCStr, &ULongInt::SetStr)
.Prop(_SC("Num"), &ULongInt::GetSNum, &ULongInt::SetNum)
// Core Meta-methods
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
.SquirrelFunc(_SC("_typename"), &TypenameU::Fn)
.Func(_SC("_tostring"), &ULongInt::ToString)
// Core Functions
.Func(_SC("tointeger"), &ULongInt::ToSqInteger)
.Func(_SC("tofloat"), &ULongInt::ToSqFloat)
.Func(_SC("tostring"), &ULongInt::ToSqString)
.Func(_SC("tobool"), &ULongInt::ToSqBool)
.Func(_SC("tochar"), &ULongInt::ToSqChar)
// Meta-methods
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
.SquirrelFunc(_SC("_mul"), &SqDynArgFwd< SqDynArgMulFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
.Func< ULongInt (ULongInt::*)(void) const >(_SC("_unm"), &ULongInt::operator -)
// Functions
.Func(_SC("GetStr"), &ULongInt::GetCStr)
.Func(_SC("SetStr"), &ULongInt::SetStr)
.Func(_SC("GetNum"), &ULongInt::GetSNum)
.Func(_SC("SetNum"), &ULongInt::SetNum)
// Overloads
.Overload< void (ULongInt::*)(void) >(_SC("Random"), &ULongInt::Random)
.Overload< void (ULongInt::*)(ULongInt::Type) >(_SC("Random"), &ULongInt::Random)
.Overload< void (ULongInt::*)(ULongInt::Type, ULongInt::Type) >(_SC("Random"), &ULongInt::Random)
);
}
} // Namespace:: SqMod

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
#ifndef _LIBRARY_NUMERIC_MATH_HPP_
#define _LIBRARY_NUMERIC_MATH_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod
#endif // _LIBRARY_NUMERIC_MATH_HPP_

View File

@ -0,0 +1,444 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Numeric/Random.hpp"
#include "Base/Shared.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
#include <ctime>
#include <memory>
#include <random>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
#include <process.h>
#else
#include <sys/types.h>
#include <unistd.h>
#endif
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
static std::unique_ptr< std::mt19937 > RG32_MT19937 =
std::unique_ptr< std::mt19937 >(new std::mt19937(GenerateSeed()));
static std::unique_ptr< std::mt19937_64 > RG64_MT19937 =
std::unique_ptr< std::mt19937_64 >(new std::mt19937_64(GenerateSeed()));
// ------------------------------------------------------------------------------------------------
static std::uniform_int_distribution< Int8 > Int8_Dist(std::numeric_limits< Int8 >::min(),
std::numeric_limits< Int8 >::max());
static std::uniform_int_distribution< Uint8 > Uint8_Dist(std::numeric_limits< Uint8 >::min(),
std::numeric_limits< Uint8 >::max());
static std::uniform_int_distribution< Int16 > Int16_Dist(std::numeric_limits< Int16 >::min(),
std::numeric_limits< Int16 >::max());
static std::uniform_int_distribution< Uint16 > Uint16_Dist(std::numeric_limits< Uint16 >::min(),
std::numeric_limits< Uint16 >::max());
static std::uniform_int_distribution< Int32 > Int32_Dist(std::numeric_limits< Int32 >::min(),
std::numeric_limits< Int32 >::max());
static std::uniform_int_distribution< Uint32 > Uint32_Dist(std::numeric_limits< Uint32 >::min(),
std::numeric_limits< Uint32 >::max());
static std::uniform_int_distribution< Int64 > Int64_Dist(std::numeric_limits< Int64 >::min(),
std::numeric_limits< Int64 >::max());
static std::uniform_int_distribution< Uint64 > Uint64_Dist(std::numeric_limits< Uint64 >::min(),
std::numeric_limits< Uint64 >::max());
static std::uniform_real_distribution<Float32> Float32_Dist(std::numeric_limits< Float32 >::min(),
std::numeric_limits< Float32 >::max());
static std::uniform_real_distribution<Float64> Float64_Dist(std::numeric_limits< Float64 >::min(),
std::numeric_limits< Float64 >::max());
// ------------------------------------------------------------------------------------------------
static std::uniform_int_distribution< String::value_type >
String_Dist(std::numeric_limits< String::value_type >::min(),
std::numeric_limits< String::value_type >::max());
// ------------------------------------------------------------------------------------------------
SizeT GenerateSeed()
{
Ulong a = clock();
Ulong b = time(NULL);
#ifdef SQMOD_OS_WINDOWS
Ulong c = _getpid();
#else
Ulong c = getpid();
#endif
// Mangle
a=a-b; a=a-c; a=a^(c >> 13);
b=b-c; b=b-a; b=b^(a << 8);
c=c-a; c=c-b; c=c^(b >> 13);
a=a-b; a=a-c; a=a^(c >> 12);
b=b-c; b=b-a; b=b^(a << 16);
c=c-a; c=c-b; c=c^(b >> 5);
a=a-b; a=a-c; a=a^(c >> 3);
b=b-c; b=b-a; b=b^(a << 10);
c=c-a; c=c-b; c=c^(b >> 15);
// Return result
return c;
}
// ------------------------------------------------------------------------------------------------
SizeT GenerateSeed2()
{
struct {
std::clock_t c;
std::time_t t;
#ifdef SQMOD_OS_WINDOWS
int p;
#else
pid_t p;
#endif
} data;
data.c = std::clock();
data.t = std::time(nullptr);
#ifdef SQMOD_OS_WINDOWS
data.p = _getpid();
#else
data.p = getpid();
#endif
// Mangle and return result
return FnvHash(reinterpret_cast< const uint8_t * >(&data), sizeof(data));
}
// ------------------------------------------------------------------------------------------------
void ReseedRandom()
{
RG32_MT19937.reset(new std::mt19937(GenerateSeed()));
RG64_MT19937.reset(new std::mt19937_64(GenerateSeed()));
}
void ReseedRandom(Uint32 n)
{
RG32_MT19937.reset(new std::mt19937(n));
RG64_MT19937.reset(new std::mt19937_64(n));
}
// ------------------------------------------------------------------------------------------------
void ReseedRandom32()
{
RG32_MT19937.reset(new std::mt19937(GenerateSeed()));
}
void ReseedRandom32(Uint32 n)
{
RG32_MT19937.reset(new std::mt19937(n));
}
// ------------------------------------------------------------------------------------------------
void ReseedRandom64()
{
RG64_MT19937.reset(new std::mt19937_64(GenerateSeed()));
}
void ReseedRandom64(Uint32 n)
{
RG64_MT19937.reset(new std::mt19937_64(n));
}
// ------------------------------------------------------------------------------------------------
Int8 GetRandomInt8()
{
return Int8_Dist(*RG32_MT19937);
}
Int8 GetRandomInt8(Int8 n)
{
return std::uniform_int_distribution< Int8 >(0, n)(*RG32_MT19937);
}
Int8 GetRandomInt8(Int8 m, Int8 n)
{
return std::uniform_int_distribution< Int8 >(m, n)(*RG32_MT19937);
}
// ------------------------------------------------------------------------------------------------
Uint8 GetRandomUint8()
{
return Uint8_Dist(*RG32_MT19937);
}
Uint8 GetRandomUint8(Uint8 n)
{
return std::uniform_int_distribution< Uint8 >(0, n)(*RG32_MT19937);
}
Uint8 GetRandomUint8(Uint8 m, Uint8 n)
{
return std::uniform_int_distribution< Uint8 >(m, n)(*RG32_MT19937);
}
// ------------------------------------------------------------------------------------------------
Int16 GetRandomInt16()
{
return Int16_Dist(*RG32_MT19937);
}
Int16 GetRandomInt16(Int16 n)
{
return std::uniform_int_distribution< Int16 >(0, n)(*RG32_MT19937);
}
Int16 GetRandomInt16(Int16 m, Int16 n)
{
return std::uniform_int_distribution< Int16 >(m, n)(*RG32_MT19937);
}
// ------------------------------------------------------------------------------------------------
Uint16 GetRandomUint16()
{
return Uint16_Dist(*RG32_MT19937);
}
Uint16 GetRandomUint16(Uint16 n)
{
return std::uniform_int_distribution< Uint16 >(0, n)(*RG32_MT19937);
}
Uint16 GetRandomUint16(Uint16 m, Uint16 n)
{
return std::uniform_int_distribution< Uint16 >(m, n)(*RG32_MT19937);
}
// ------------------------------------------------------------------------------------------------
Int32 GetRandomInt32()
{
return Int32_Dist(*RG32_MT19937);
}
Int32 GetRandomInt32(Int32 n)
{
return std::uniform_int_distribution< Int32 >(0, n)(*RG32_MT19937);
}
Int32 GetRandomInt32(Int32 m, Int32 n)
{
return std::uniform_int_distribution< Int32 >(m, n)(*RG32_MT19937);
}
// ------------------------------------------------------------------------------------------------
Uint32 GetRandomUint32()
{
return Int32_Dist(*RG32_MT19937);
}
Uint32 GetRandomUint32(Uint32 n)
{
return std::uniform_int_distribution< Int32 >(0, n)(*RG32_MT19937);
}
Uint32 GetRandomUint32(Uint32 m, Uint32 n)
{
return std::uniform_int_distribution< Int32 >(m, n)(*RG32_MT19937);
}
// ------------------------------------------------------------------------------------------------
Int64 GetRandomInt64()
{
return Int64_Dist(*RG64_MT19937);
}
Int64 GetRandomInt64(Int64 n)
{
return std::uniform_int_distribution< Int64 >(0, n)(*RG64_MT19937);
}
Int64 GetRandomInt64(Int64 m, Int64 n)
{
return std::uniform_int_distribution< Int64 >(m, n)(*RG64_MT19937);
}
// ------------------------------------------------------------------------------------------------
Uint64 GetRandomUint64()
{
return Uint64_Dist(*RG64_MT19937);
}
Uint64 GetRandomUint64(Uint64 n)
{
return std::uniform_int_distribution< Uint64 >(0, n)(*RG64_MT19937);
}
Uint64 GetRandomUint64(Uint64 m, Uint64 n)
{
return std::uniform_int_distribution< Uint64 >(m, n)(*RG64_MT19937);
}
// ------------------------------------------------------------------------------------------------
Float32 GetRandomFloat32()
{
return Float32_Dist(*RG32_MT19937);
}
Float32 GetRandomFloat32(Float32 n)
{
return std::uniform_real_distribution< Float32 >(0, n)(*RG32_MT19937);
}
Float32 GetRandomFloat32(Float32 m, Float32 n)
{
return std::uniform_real_distribution< Float32 >(m, n)(*RG32_MT19937);
}
// ------------------------------------------------------------------------------------------------
Float64 GetRandomFloat64()
{
return Float64_Dist(*RG64_MT19937);
}
Float64 GetRandomFloat64(Float64 n)
{
return std::uniform_real_distribution< Float64 >(0, n)(*RG64_MT19937);
}
Float64 GetRandomFloat64(Float64 m, Float64 n)
{
return std::uniform_real_distribution< Float64 >(m, n)(*RG64_MT19937);
}
// ------------------------------------------------------------------------------------------------
void GetRandomString(String & str, String::size_type len)
{
// Reserve the requested size + the null terminator
str.reserve(len+1);
// Resize to the requested size and fill with 0
str.resize(len);
// Generate the requested amount of characters
for (auto & c : str)
c = String_Dist(*RG32_MT19937);
// Append the null terminator
str.push_back(0);
}
void GetRandomString(String & str, String::size_type len, String::value_type n)
{
// Reserve the requested size + the null terminator
str.reserve(len+1);
// Resize to the requested size and fill with 0
str.resize(len);
// Create the custom distribution
std::uniform_int_distribution< String::value_type > dist(1, n);
// Generate the requested amount of characters
for (auto & c : str)
c = dist(*RG32_MT19937);
// Append the null terminator
str.push_back(0);
}
void GetRandomString(String & str, String::size_type len, String::value_type m, String::value_type n)
{
// Reserve the requested size + the null terminator
str.reserve(len+1);
// Resize to the requested size and fill with 0
str.resize(len);
// Create the custom distribution
std::uniform_int_distribution< String::value_type > dist(m, n);
// Generate the requested amount of characters
for (auto & c : str)
c = dist(*RG32_MT19937);
// Append the null terminator
str.push_back(0);
}
// ------------------------------------------------------------------------------------------------
bool GetRandomBool()
{
return std::bernoulli_distribution()(*RG32_MT19937);
}
bool GetRandomBool(SQFloat p)
{
return std::bernoulli_distribution(p)(*RG32_MT19937);
}
// ------------------------------------------------------------------------------------------------
static String RandomString(Int32 len)
{
// Is there anything to generate?
if (len <= 0)
return _SC("");
// Prepare the string buffer
String str;
// Request the random fill
GetRandomString(str, len);
// Return ownership of the string
return std::move(str);
}
// ------------------------------------------------------------------------------------------------
static String RandomString(Int32 len, SQChar n)
{
// Is there anything to generate?
if (len <= 0)
return _SC("");
// Prepare the string buffer
String str;
// Request the random fill
GetRandomString(str, len, n);
// Return ownership of the string
return std::move(str);
}
// ------------------------------------------------------------------------------------------------
static String RandomString(Int32 len, SQChar m, SQChar n)
{
// Is there anything to generate?
if (len <= 0)
return _SC("");
// Prepare the string buffer
String str;
// Request the random fill
GetRandomString(str, len, m, n);
// Return ownership of the string
return std::move(str);
}
// ------------------------------------------------------------------------------------------------
void Register_Random(HSQUIRRELVM vm)
{
RootTable(vm).Bind(_SC("SqRand"), Table(vm)
.Func(_SC("GenSeed"), &GenerateSeed)
.Func(_SC("GenSeed2"), &GenerateSeed2)
.Overload< void (*)(void) >(_SC("Reseed"), &ReseedRandom)
.Overload< void (*)(Uint32) >(_SC("Reseed"), &ReseedRandom)
.Overload< void (*)(void) >(_SC("Reseed32"), &ReseedRandom32)
.Overload< void (*)(Uint32) >(_SC("Reseed32"), &ReseedRandom32)
.Overload< void (*)(void) >(_SC("Reseed64"), &ReseedRandom64)
.Overload< void (*)(Uint32) >(_SC("Reseed64"), &ReseedRandom64)
#ifdef _SQ64
.Overload< SQInteger (*)(void) >(_SC("Integer"), &GetRandomInt64)
.Overload< SQInteger (*)(SQInteger) >(_SC("Integer"), &GetRandomInt64)
.Overload< SQInteger (*)(SQInteger, SQInteger) >(_SC("Integer"), &GetRandomInt64)
#else
.Overload< SQInteger (*)(void) >(_SC("Integer"), &GetRandomInt32)
.Overload< SQInteger (*)(SQInteger) >(_SC("Integer"), &GetRandomInt32)
.Overload< SQInteger (*)(SQInteger, SQInteger) >(_SC("Integer"), &GetRandomInt32)
#endif // _SQ64
#ifdef SQUSEDOUBLE
.Overload< SQFloat (*)(void) >(_SC("Float"), &GetRandomFloat64)
.Overload< SQFloat (*)(SQFloat) >(_SC("Float"), &GetRandomFloat64)
.Overload< SQFloat (*)(SQFloat, SQFloat) >(_SC("Float"), &GetRandomFloat64)
#else
.Overload< SQFloat (*)(void) >(_SC("Float"), &GetRandomFloat32)
.Overload< SQFloat (*)(SQFloat) >(_SC("Float"), &GetRandomFloat32)
.Overload< SQFloat (*)(SQFloat, SQFloat) >(_SC("Float"), &GetRandomFloat32)
#endif // SQUSEDOUBLE
.Overload< String (*)(Int32) >(_SC("String"), &RandomString)
.Overload< String (*)(Int32, SQChar) >(_SC("String"), &RandomString)
.Overload< String (*)(Int32, SQChar, SQChar) >(_SC("String"), &RandomString)
.Overload< bool (*)(void) >(_SC("Bool"), &GetRandomBool)
.Overload< bool (*)(SQFloat) >(_SC("Bool"), &GetRandomBool)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,164 @@
#ifndef _LIBRARY_NUMERIC_RANDOM_HPP_
#define _LIBRARY_NUMERIC_RANDOM_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Attempt to generate a moderately unique number to be used as a seed for random numbers.
*/
Uint32 GenerateSeed();
// ------------------------------------------------------------------------------------------------
void ReseedRandom();
void ReseedRandom(Uint32 n);
// ------------------------------------------------------------------------------------------------
Int8 GetRandomInt8();
Int8 GetRandomInt8(Int8 n);
Int8 GetRandomInt8(Int8 m, Int8 n);
// ------------------------------------------------------------------------------------------------
Uint8 GetRandomUint8();
Uint8 GetRandomUint8(Uint8 n);
Uint8 GetRandomUint8(Uint8 m, Uint8 n);
// ------------------------------------------------------------------------------------------------
Int16 GetRandomInt16();
Int16 GetRandomInt16(Int16 n);
Int16 GetRandomInt16(Int16 m, Int16 n);
// ------------------------------------------------------------------------------------------------
Uint16 GetRandomUint16();
Uint16 GetRandomUint16(Uint16 n);
Uint16 GetRandomUint16(Uint16 m, Uint16 n);
// ------------------------------------------------------------------------------------------------
Int32 GetRandomInt32();
Int32 GetRandomInt32(Int32 n);
Int32 GetRandomInt32(Int32 m, Int32 n);
// ------------------------------------------------------------------------------------------------
Uint32 GetRandomUint32();
Uint32 GetRandomUint32(Uint32 n);
Uint32 GetRandomUint32(Uint32 m, Uint32 n);
// ------------------------------------------------------------------------------------------------
Int64 GetRandomInt64();
Int64 GetRandomInt64(Int64 n);
Int64 GetRandomInt64(Int64 m, Int64 n);
// ------------------------------------------------------------------------------------------------
Uint64 GetRandomUint64();
Uint64 GetRandomUint64(Uint64 n);
Uint64 GetRandomUint64(Uint64 m, Uint64 n);
// ------------------------------------------------------------------------------------------------
Float32 GetRandomFloat32();
Float32 GetRandomFloat32(Float32 n);
Float32 GetRandomFloat32(Float32 m, Float32 n);
// ------------------------------------------------------------------------------------------------
Float64 GetRandomFloat64();
Float64 GetRandomFloat64(Float64 n);
Float64 GetRandomFloat64(Float64 m, Float64 n);
// ------------------------------------------------------------------------------------------------
void GetRandomString(String & str, String::size_type len);
void GetRandomString(String & str, String::size_type len, String::value_type n);
void GetRandomString(String & str, String::size_type len, String::value_type m, String::value_type n);
// ------------------------------------------------------------------------------------------------
bool GetRandomBool();
// ------------------------------------------------------------------------------------------------
template <typename T> struct RandomVal
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template <> struct RandomVal< Int8 >
{
static inline Int8 Get() { return GetRandomInt8(); }
static inline Int8 Get(Int8 n) { return GetRandomInt8(n); }
static inline Int8 Get(Int8 m, Int8 n) { return GetRandomInt8(m, n); }
};
template <> struct RandomVal< Uint8 >
{
static inline Uint8 Get() { return GetRandomUint8(); }
static inline Uint8 Get(Uint8 n) { return GetRandomUint8(n); }
static inline Uint8 Get(Uint8 m, Uint8 n) { return GetRandomUint8(m, n); }
};
// ------------------------------------------------------------------------------------------------
template <> struct RandomVal< Int16 >
{
static inline Int16 Get() { return GetRandomInt16(); }
static inline Int16 Get(Int16 n) { return GetRandomInt16(n); }
static inline Int16 Get(Int16 m, Int16 n) { return GetRandomInt16(m, n); }
};
template <> struct RandomVal< Uint16 >
{
static inline Uint16 Get() { return GetRandomUint16(); }
static inline Uint16 Get(Uint16 n) { return GetRandomUint16(n); }
static inline Uint16 Get(Uint16 m, Uint16 n) { return GetRandomUint16(m, n); }
};
// ------------------------------------------------------------------------------------------------
template <> struct RandomVal< Int32 >
{
static inline Int32 Get() { return GetRandomInt32(); }
static inline Int32 Get(Int32 n) { return GetRandomInt32(n); }
static inline Int32 Get(Int32 m, Int32 n) { return GetRandomInt32(m, n); }
};
template <> struct RandomVal< Uint32 >
{
static inline Uint32 Get() { return GetRandomUint32(); }
static inline Uint32 Get(Uint32 n) { return GetRandomUint32(n); }
static inline Uint32 Get(Uint32 m, Uint32 n) { return GetRandomUint32(m, n); }
};
// ------------------------------------------------------------------------------------------------
template <> struct RandomVal< Int64 >
{
static inline Int64 Get() { return GetRandomInt64(); }
static inline Int64 Get(Int64 n) { return GetRandomInt64(n); }
static inline Int64 Get(Int64 m, Int64 n) { return GetRandomInt64(m, n); }
};
template <> struct RandomVal< Uint64 >
{
static inline Uint64 Get() { return GetRandomUint64(); }
static inline Uint64 Get(Uint64 n) { return GetRandomUint64(n); }
static inline Uint64 Get(Uint64 m, Uint64 n) { return GetRandomUint64(m, n); }
};
// ------------------------------------------------------------------------------------------------
template <> struct RandomVal< Float32 >
{
static inline Float32 Get() { return GetRandomFloat32(); }
static inline Float32 Get(Float32 n) { return GetRandomFloat32(n); }
static inline Float32 Get(Float32 m, Float32 n) { return GetRandomFloat32(m, n); }
};
template <> struct RandomVal< Float64 >
{
static inline Float64 Get() { return GetRandomFloat64(); }
static inline Float64 Get(Float64 n) { return GetRandomFloat64(n); }
static inline Float64 Get(Float64 m, Float64 n) { return GetRandomFloat64(m, n); }
};
// ------------------------------------------------------------------------------------------------
template <> struct RandomVal< bool >
{
static inline bool Get() { return GetRandomBool(); }
};
} // Namespace:: SqMod
#endif // _LIBRARY_NUMERIC_RANDOM_HPP_

973
module/Library/String.cpp Normal file
View File

@ -0,0 +1,973 @@
// ------------------------------------------------------------------------------------------------
#include "Library/String.hpp"
#include "Base/Shared.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
// ------------------------------------------------------------------------------------------------
#include <algorithm>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
static LightObj SqLeftStr(SQChar f, Uint32 w, StackStrF & s)
{
// Is the specified width valid?
if (!w)
{
return _SC(""); // Default to an empty string!
}
// Allocate a buffer with the requested width
Buffer b(w + 1); // + null terminator
// Is the specified string valid?
if (!s.mLen)
{
std::memset(b.Data(), f, w); // Insert only the fill character
}
else
{
// Insert only the fill character first
std::memset(b.Data(), f, w);
// Overwrite with the specified string
std::strncpy(b.Data(), s.mPtr, s.mLen);
}
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// Push the string onto the stack
sq_pushstring(s.mVM, b.Data(), w);
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
// ------------------------------------------------------------------------------------------------
static LightObj SqLeftOffsetStr(SQChar f, Uint32 w, Uint32 o, StackStrF & s)
{
// Is the specified width valid?
if (!w)
{
return _SC(""); // Default to an empty string!
}
// Is the specified offset within width range?
else if (o > w)
{
STHROWF("Offset is out of bounds");
}
// Allocate a buffer with the requested width
Buffer b(w + 1); // + null terminator
// Is the specified string valid?
if (!s.mLen)
{
std::memset(b.Data(), f, w); // Insert only the fill character
}
else
{
// Calculate the string length
const Uint32 n = ConvTo< Uint32 >::From(s.mLen);
// Insert the fill character first
std::memset(b.Data(), f, w);
// Overwrite with the specified string
if (n > (w - o))
{
std::strncpy(b.Data() + o, s.mPtr, n);
}
else
{
std::memcpy(b.Data() + o, s.mPtr, n * sizeof(SQChar));
}
}
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// Push the string onto the stack
sq_pushstring(s.mVM, b.Data(), w);
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
// ------------------------------------------------------------------------------------------------
static LightObj SqRightStr(SQChar f, Uint32 w, StackStrF & s)
{
// Is the specified width valid?
if (!w)
{
return _SC(""); // Default to an empty string!
}
// Allocate a buffer with the requested width
Buffer b(w + 1); // + null terminator
// Is the specified string valid?
if (!s.mLen)
{
std::memset(b.Data(), f, w); // Insert only the fill character
}
else
{
// Calculate the string length
const Uint32 n = ConvTo< Uint32 >::From(s.mLen);
// Insert the fill character first
std::memset(b.Data(), f, w);
// Overwrite with the specified string
if (n >= w)
{
std::strncpy(b.Data(), s.mPtr, w);
}
else
{
std::strncpy(b.Data() + (w - n), s.mPtr, n);
}
}
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// Push the string onto the stack
sq_pushstring(s.mVM, b.Data(), w);
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
// ------------------------------------------------------------------------------------------------
static LightObj SqRightOffsetStr(SQChar f, Uint32 w, Uint32 o, StackStrF & s)
{
// Is the specified width valid?
if (!w)
{
return _SC(""); // Default to an empty string!
}
// Is the specified offset within width range?
else if (o > w)
{
STHROWF("Offset is out of bounds");
}
// Allocate a buffer with the requested width
Buffer b(w + 1); // + null terminator
// Is the specified string valid?
if (!s.mLen)
{
std::memset(b.Data(), f, w); // Insert only the fill character
}
else
{
// Calculate the string length
const Uint32 n = ConvTo< Uint32 >::From(s.mLen);
// Insert the fill character first
std::memset(b.Data(), f, w);
// Overwrite with the specified string
if (n >= w || (n + o) >= w)
{
std::strncpy(b.Data(), s.mPtr, w - o);
}
else
{
std::strncpy(b.Data() + ((w - n) - o), s.mPtr, n);
}
}
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// Push the string onto the stack
sq_pushstring(s.mVM, b.Data(), w);
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
// ------------------------------------------------------------------------------------------------
static LightObj SqCenterStr(SQChar f, Uint32 w, StackStrF & s)
{
// Is the specified width valid?
if (!w)
{
return _SC(""); // Default to an empty string!
}
// Allocate a buffer with the requested width
Buffer b(w + 1); // + null terminator
// Is the specified string valid?
if (!s.mLen)
{
std::memset(b.Data(), f, w); // Insert only the fill character
}
else
{
// Calculate the insert position
const Int32 p = ((w/2) - (s.mLen/2));
// Insert only the fill character first
std::memset(b.Data(), f, w);
// Overwrite with the specified string
std::strncpy(b.Data() + (p < 0 ? 0 : p), s.mPtr, s.mLen);
}
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// Push the string onto the stack
sq_pushstring(s.mVM, b.Data(), w);
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
// ------------------------------------------------------------------------------------------------
static Buffer StrJustAlphaNumImpl(CSStr str, Uint32 len)
{
// See if we actually have something to search for
if(!len)
{
return Buffer(); // Default to an empty buffer!
}
// Obtain a temporary buffer
Buffer b(len + 1); // + null terminator
// Resulted string size
Uint32 n = 0;
// Currently processed character
SQChar c = 0;
// Process characters
while ((c = *(str++)) != '\0')
{
// Is this an alpha-numeric character?
if (std::isalnum(c) != 0)
{
// Save it and move to the next one
b.At(n++) = c;
}
}
// End the resulted string
b.At(n) = '\0';
// Move the cursor to the end
b.Move(n);
// Return ownership of the buffer
return std::move(b);
}
// ------------------------------------------------------------------------------------------------
Buffer StrJustAlphaNumB(CSStr str)
{
// See if we actually have something to search for
if(!str || *str == '\0')
{
return Buffer(); // Default to an empty string!
}
// Attempt to convert and return the result
return StrJustAlphaNumImpl(str, std::strlen(str));
}
// ------------------------------------------------------------------------------------------------
CSStr StrJustAlphaNum(CSStr str)
{
// See if we actually have something to search for
if(!str || *str == '\0')
{
return _SC(""); // Default to an empty string!
}
// Attempt to convert and return the result
return StrJustAlphaNumImpl(str, std::strlen(str)).Get< SQChar >();
}
// ------------------------------------------------------------------------------------------------
static LightObj SqJustAlphaNum(StackStrF & s)
{
const Buffer b(StrJustAlphaNumImpl(s.mPtr, s.mLen));
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// Push the string onto the stack
sq_pushstring(s.mVM, b.Data(), b.Position());
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
// ------------------------------------------------------------------------------------------------
static Buffer StrToLowercaseImpl(CSStr str, Uint32 len)
{
// See if we actually have something to search for
if(!len)
{
return Buffer(); // Default to an empty buffer!
}
// Obtain a temporary buffer
Buffer b(len + 1); // + null terminator
// Resulted string size
Uint32 n = 0;
// Process characters
while (*str != '\0')
{
// Convert it and move to the next one
b.At(n++) = std::tolower(*(str++));
}
// End the resulted string
b.At(n) = '\0';
// Move the cursor to the end
b.Move(n);
// Return ownership of the buffer
return std::move(b);
}
// ------------------------------------------------------------------------------------------------
Buffer StrToLowercaseB(CSStr str)
{
// See if we actually have something to search for
if(!str || *str == '\0')
{
return Buffer(); // Default to an empty string!
}
// Attempt to convert and return the result
return StrToLowercaseImpl(str, std::strlen(str));
}
// ------------------------------------------------------------------------------------------------
CSStr StrToLowercase(CSStr str)
{
// See if we actually have something to search for
if(!str || *str == '\0')
{
return _SC(""); // Default to an empty string!
}
// Attempt to convert and return the result
return StrToLowercaseImpl(str, std::strlen(str)).Get< SQChar >();
}
// ------------------------------------------------------------------------------------------------
static LightObj SqToLowercase(StackStrF & s)
{
const Buffer b(StrToLowercaseImpl(s.mPtr, s.mLen));
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// Push the string onto the stack
sq_pushstring(s.mVM, b.Data(), b.Position());
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
// ------------------------------------------------------------------------------------------------
static Buffer StrToUppercaseImpl(CSStr str, Uint32 len)
{
// See if we actually have something to search for
if(!len)
{
return Buffer(); // Default to an empty buffer!
}
// Obtain a temporary buffer
Buffer b(len + 1); // + null terminator
// Resulted string size
Uint32 n = 0;
// Process characters
while (*str != '\0')
{
// Convert it and move to the next one
b.At(n++) = std::toupper(*(str++));
}
// End the resulted string
b.At(n) = '\0';
// Move the cursor to the end
b.Move(n);
// Return ownership of the buffer
return std::move(b);
}
// ------------------------------------------------------------------------------------------------
Buffer StrToUppercaseB(CSStr str)
{
// See if we actually have something to search for
if(!str || *str == '\0')
{
return Buffer(); // Default to an empty string!
}
// Attempt to convert and return the result
return StrToUppercaseImpl(str, std::strlen(str));
}
// ------------------------------------------------------------------------------------------------
CSStr StrToUppercase(CSStr str)
{
// See if we actually have something to search for
if(!str || *str == '\0')
{
return _SC(""); // Default to an empty string!
}
// Attempt to convert and return the result
return StrToUppercaseImpl(str, std::strlen(str)).Get< SQChar >();
}
// ------------------------------------------------------------------------------------------------
static LightObj SqToUppercase(StackStrF & s)
{
const Buffer b(StrToUppercaseImpl(s.mPtr, s.mLen));
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// Push the string onto the stack
sq_pushstring(s.mVM, b.Data(), b.Position());
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
/* ------------------------------------------------------------------------------------------------
* Checks if all the characters in the specified string are of the specified class or not.
*/
template < int (*Fn)(int) > static bool SqAllChars(StackStrF & s)
{
// See if we actually have something to search for
if (!s.mLen)
{
// Since there are no other different character then
// we count this as all characters being of this type
return true;
}
// Start iterating characters and find the first that doesn't match
for (CSStr itr = s.mPtr; *itr != '\0'; ++itr)
{
// Call the predicate with the current character
if (Fn(*itr) == 0)
{
return false; // This character did not pass the test
}
}
// All characters passed the test
return true;
}
/* ------------------------------------------------------------------------------------------------
* Find the position of the first character that matches the specified class.
*/
template < int (*Fn)(int), bool Neg > static LightObj SqFirstChar(StackStrF & s)
{
// See if we actually have something to search for
if (s.mLen)
{
// Start iterating characters and find the first that doesn't match
for (CSStr itr = s.mPtr; *itr != '\0'; ++itr)
{
// Call the predicate with the current character
if ((Fn(*itr) == 0) == Neg)
{
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// This character passed our test, push it's position
sq_pushinteger(s.mVM, itr - s.mPtr);
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
}
}
// Since there are no other different character then
// we count this as all characters being of this type
return LightObj();
}
/* ------------------------------------------------------------------------------------------------
* Find the position of the last character that matches the specified class.
*/
template < int (*Fn)(int), bool Neg > static LightObj SqLastChar(StackStrF & s)
{
// See if we actually have something to search for
if (s.mLen)
{
// Start iterating characters and find the first that doesn't match
for (CSStr itr = (s.mPtr + s.mLen) - 1; itr >= s.mPtr; --itr)
{
// Call the predicate with the current character
if ((Fn(*itr) == 0) == Neg)
{
// Obtain the initial stack size
const StackGuard sg(s.mVM);
// This character passed our test, push it's position
sq_pushinteger(s.mVM, itr - s.mPtr);
// Obtain the object from the stack and return it
return std::move(Var< LightObj >(s.mVM, -1).value);
}
}
}
// Since there are no other different character then
// we count this as all characters being of this type
return LightObj();
}
/* ------------------------------------------------------------------------------------------------
* Split the string into chunks wherever a character matches or not the specified class.
*/
static SQInteger SplitWhereCharImpl(HSQUIRRELVM vm, int(*fn)(int), bool neg)
{
static const SQInteger top = sq_gettop(vm);
// Is there a value to process?
if (top <= 1)
{
return sq_throwerror(vm, "Missing string or value");
}
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Create a new array on the stack
sq_newarray(vm, 0);
// See if we actually have something to search for
if (!(val.mPtr) || *(val.mPtr) == '\0')
{
return 1; // Return an empty array
}
// Remember the position of the last found match
CSStr last = val.mPtr;
// Start iterating characters and slice where a match is found
for (CSStr itr = val.mPtr; *itr != '\0'; ++itr)
{
// Call the predicate with the current character
if ((fn(*itr) == 0) == neg)
{
// Are there any characters before this match?
if ((itr - last) > 0 && (*last != '\0'))
{
// Push this chunk of string on the stack
sq_pushstring(vm, last, itr - last);
// Insert this element into the array on the stack
const SQRESULT r = sq_arrayappend(vm, -2);
// Did we fail to append the element?
if (SQ_FAILED(r))
{
return r; // We're done here
}
}
// Push this character as an integer on the stack
sq_pushinteger(vm, *itr);
// Insert this element into the array on the stack
const SQRESULT r = sq_arrayappend(vm, -2);
// Did we fail to append the element?
if (SQ_FAILED(r))
{
return r; // We're done here
}
// Update the position of the last found match
last = (itr + 1);
}
}
// Push the remaining chunk, if any
if (*last != '\0')
{
// Push this chunk of string on the stack
sq_pushstring(vm, last, -1);
// Insert this element into the array on the stack
const SQRESULT r = sq_arrayappend(vm, -2);
// Did we fail to append the element?
if (SQ_FAILED(r))
{
return r; // We're done here
}
}
// We have a value to return on the stack
return 1;
}
/* ------------------------------------------------------------------------------------------------
* Simple forwarder to minimize templated functions with large body and reduce executable size.
*/
template < int (*Fn)(int), bool Neg > static SQInteger SplitWhereCharProxy(HSQUIRRELVM vm)
{
return SplitWhereCharImpl(vm, Fn, Neg);
}
/* ------------------------------------------------------------------------------------------------
* Checks if the specified character is of the specified class.
*/
template < int (*Fn)(int) > static bool IsCharOfType(int c)
{
return (Fn(c) != 0);
}
// ------------------------------------------------------------------------------------------------
static bool OnlyDelimiter(CSStr str, SQChar chr)
{
while (*str != '\0')
{
// Is this different from the delimiter?
if (*(str++) != chr)
{
// Another character was found
return false;
}
}
// No other character was found
return true;
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqStrExplode(HSQUIRRELVM vm)
{
const Int32 top = sq_gettop(vm);
// Was the delimiter character specified?
if (top <= 1)
{
return sq_throwerror(vm, _SC("Missing delimiter character"));
}
// Was the boolean empty specified?
else if (top <= 2)
{
return sq_throwerror(vm, _SC("Missing boolean empty"));
}
// Was the string value specified?
else if (top <= 3)
{
return sq_throwerror(vm, _SC("Missing string value"));
}
// Attempt to generate the string value
StackStrF val(vm, 4);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// The delimiter character and boolean empty
SQChar delim = 0;
bool empty = 0;
// Attempt to retrieve the remaining arguments from the stack
try
{
delim = Var< SQChar >(vm, 2).value;
empty = Var< bool >(vm, 3).value;
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
catch (...)
{
return sq_throwerror(vm, _SC("Unable to retrieve arguments"));
}
// Grab the string value to a shorter name
CSStr str = val.mPtr;
// Create an empty array on the stack
sq_newarray(vm, 0);
// See if we actually have something to explode
if(!str || *str == '\0')
{
// Specify that we have an argument on the stack
return 1;
}
// Don't modify the specified string pointer
CSStr itr = str, last = str;
// The number of delimiter occurrences
Uint32 num = 0;
// Pre-count how many delimiters of this type exist
while (*itr != '\0')
{
// Is this our delimiter?
if (*(itr++) == delim)
{
// Are we allowed to include empty elements?
if (empty || (itr - last) > 1)
{
// Increase the count
++num;
}
// Update the last delimiter position
last = itr;
}
}
// Were there no delimiters found and can we include empty elements?
if (num == 0 && !empty && (str[1] == '\0' || OnlyDelimiter(str, delim)))
{
// Specify that we have an argument on the stack
return 1;
}
// Have we found any delimiters?
else if (num == 0)
{
// Test against strings with only delimiters
if (str[1] == '\0' || OnlyDelimiter(str, delim))
{
sq_pushstring(vm, _SC(""), 0); // Add an empty string
}
else
{
sq_pushstring(vm, val.mPtr, val.mLen); // Add the whole string
}
// Append the string on the stack to the array
const SQRESULT r = sq_arrayappend(vm, -2);
// Check the result
if (SQ_FAILED(r))
{
return r; // Propagate the error
}
// Specify that we have an argument on the stack
return 1;
}
// Is there anything after the last delimiter?
if (itr != last && *last != delim)
{
++num; // Add it to the counter
}
SQRESULT r = SQ_OK;
// Pre-allocate an array with the number of found delimiters
r = sq_arrayresize(vm, -1, num);
// Check the result
if (SQ_FAILED(r))
{
return r; // Propagate the error
}
// Don't modify the specified string pointer
itr = str, last = str;
// Reset the counter and use it as the element index
num = 0;
// Process the string again, this time slicing the actual elements
while (*itr != '\0')
{
// Is this our delimiter?
if (*itr++ == delim)
{
// Are we allowed to include empty elements?
if (empty || (itr - last) > 1)
{
// Push the element index on the stack and advance to the next one
sq_pushinteger(vm, num++);
// Push the string portion on the stack
sq_pushstring(vm, last, itr - last - 1);
// Assign the string onto the
r = sq_set(vm, -3);
// Check the result
if (SQ_FAILED(r))
{
return r; // Propagate the error
}
}
// Update the last delimiter position
last = itr;
}
}
// Is there anything after the last delimiter?
if (itr != last && *last != delim)
{
// Push the element index on the stack
sq_pushinteger(vm, num);
// Add the remaining string as an element
sq_pushstring(vm, last, itr - last);
// Assign the string onto the
r = sq_set(vm, -3);
// Check the result
if (SQ_FAILED(r))
{
return r; // Propagate the error
}
}
// Specify that we have an argument on the stack
return 1;
}
// ------------------------------------------------------------------------------------------------
static CSStr StrImplode(SQChar chr, Array & arr)
{
// Determine array size
const Int32 length = static_cast< Int32 >(arr.Length());
// Is there anything to implode?
if (length <= 0)
{
return _SC(""); // Default to an empty string
}
// Obtain a temporary buffer
Buffer b(length * 32);
// Process array elements
for (SQInteger i = 0; i < length; ++i)
{
// Retrieve the element value as string
SharedPtr< String > str = arr.GetValue< String >(i);
// Was there any value retrieved?
if (!!str)
{
// Append the value to the buffer
b.AppendS(str->data(), str->size());
}
// Append the delimiter
b.Push(chr);
}
// Move the cursor back one element
b.Retreat(1);
// Set that as the null character
b.Cursor() = '\0';
// Return the string
return b.Get< SQChar >();
}
// ------------------------------------------------------------------------------------------------
static CSStr FromArray(Array & arr)
{
// Determine array size
const Int32 length = ConvTo< Int32 >::From(arr.Length());
// Obtain a temporary buffer
Buffer b(length * sizeof(Int32));
// Get array elements as integers
arr.GetArray< Int32 >(b.Get< Int32 >(), length);
// Overwrite integers with characters
for (Int32 n = 0; n < length; ++n)
{
b.At(n) = ConvTo< SQChar >::From(b.At< Int32 >(n * sizeof(Int32)));
}
// Terminate the resulted string
b.At(length) = '\0';
// Return the string
return b.Get< SQChar >();
}
// ------------------------------------------------------------------------------------------------
static SQInteger StdPrintF(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Send the resulted string to console as a user message
LogUsr("%s", val.mPtr);
// This function doesn't return anything
return 0;
}
// ------------------------------------------------------------------------------------------------
static String StrCharacterSwap(SQInteger a, SQInteger b, StackStrF & val)
{
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
STHROWLASTF("Invalid string");
}
// Is the string empty?
else if (!val.mLen)
{
return String();
}
// Turn it into a string that we can edit
String str(val.mPtr, val.mLen);
// Replace all occurences of the specified character
std::replace(str.begin(), str.end(),
static_cast< String::value_type >(a), static_cast< String::value_type >(b));
// Return the new string
return str;
}
// ================================================================================================
void Register_String(HSQUIRRELVM vm)
{
Table strns(vm);
strns.Func(_SC("FromArray"), &FromArray)
.SquirrelFunc(_SC("Explode"), &SqStrExplode)
.Func(_SC("Implode"), &StrImplode)
.FmtFunc(_SC("Center"), &SqCenterStr)
.FmtFunc(_SC("Left"), &SqLeftStr)
.FmtFunc(_SC("Right"), &SqRightStr)
.FmtFunc(_SC("LeftEx"), &SqLeftOffsetStr)
.FmtFunc(_SC("RightEx"), &SqRightOffsetStr)
.FmtFunc(_SC("ToLower"), &SqToLowercase)
.FmtFunc(_SC("ToUpper"), &SqToUppercase)
.FmtFunc(_SC("CharSwap"), &StrCharacterSwap)
.FmtFunc(_SC("Lowercase"), &SqToLowercase)
.FmtFunc(_SC("Uppercase"), &SqToUppercase)
.FmtFunc(_SC("JustAlnum"), &SqJustAlphaNum)
.FmtFunc(_SC("AreAllSpace"), &SqAllChars< std::isspace >)
.FmtFunc(_SC("AreAllPrint"), &SqAllChars< std::isprint >)
.FmtFunc(_SC("AreAllCntrl"), &SqAllChars< std::iscntrl >)
.FmtFunc(_SC("AreAllUpper"), &SqAllChars< std::isupper >)
.FmtFunc(_SC("AreAllLower"), &SqAllChars< std::islower >)
.FmtFunc(_SC("AreAllAlpha"), &SqAllChars< std::isalpha >)
.FmtFunc(_SC("AreAllDigit"), &SqAllChars< std::isdigit >)
.FmtFunc(_SC("AreAllPunct"), &SqAllChars< std::ispunct >)
.FmtFunc(_SC("AreAllXdigit"), &SqAllChars< std::isxdigit >)
.FmtFunc(_SC("AreAllAlnum"), &SqAllChars< std::isalnum >)
.FmtFunc(_SC("AreAllGraph"), &SqAllChars< std::isgraph >)
.FmtFunc(_SC("AreAllBlank"), &SqAllChars< std::isblank >)
.FmtFunc(_SC("FirstSpace"), &SqFirstChar< std::isspace, false >)
.FmtFunc(_SC("FirstPrint"), &SqFirstChar< std::isprint, false >)
.FmtFunc(_SC("FirstCntrl"), &SqFirstChar< std::iscntrl, false >)
.FmtFunc(_SC("FirstUpper"), &SqFirstChar< std::isupper, false >)
.FmtFunc(_SC("FirstLower"), &SqFirstChar< std::islower, false >)
.FmtFunc(_SC("FirstAlpha"), &SqFirstChar< std::isalpha, false >)
.FmtFunc(_SC("FirstDigit"), &SqFirstChar< std::isdigit, false >)
.FmtFunc(_SC("FirstPunct"), &SqFirstChar< std::ispunct, false >)
.FmtFunc(_SC("FirstXdigit"), &SqFirstChar< std::isxdigit, false >)
.FmtFunc(_SC("FirstAlnum"), &SqFirstChar< std::isalnum, false >)
.FmtFunc(_SC("FirstGraph"), &SqFirstChar< std::isgraph, false >)
.FmtFunc(_SC("FirstBlank"), &SqFirstChar< std::isblank, false >)
.FmtFunc(_SC("FirstNotSpace"), &SqFirstChar< std::isspace, true >)
.FmtFunc(_SC("FirstNotPrint"), &SqFirstChar< std::isprint, true >)
.FmtFunc(_SC("FirstNotCntrl"), &SqFirstChar< std::iscntrl, true >)
.FmtFunc(_SC("FirstNotUpper"), &SqFirstChar< std::isupper, true >)
.FmtFunc(_SC("FirstNotLower"), &SqFirstChar< std::islower, true >)
.FmtFunc(_SC("FirstNotAlpha"), &SqFirstChar< std::isalpha, true >)
.FmtFunc(_SC("FirstNotDigit"), &SqFirstChar< std::isdigit, true >)
.FmtFunc(_SC("FirstNotPunct"), &SqFirstChar< std::ispunct, true >)
.FmtFunc(_SC("FirstNotXdigit"), &SqFirstChar< std::isxdigit, true >)
.FmtFunc(_SC("FirstNotAlnum"), &SqFirstChar< std::isalnum, true >)
.FmtFunc(_SC("FirstNotGraph"), &SqFirstChar< std::isgraph, true >)
.FmtFunc(_SC("FirstNotBlank"), &SqFirstChar< std::isblank, true >)
.FmtFunc(_SC("LastSpace"), &SqLastChar< std::isspace, false >)
.FmtFunc(_SC("LastPrint"), &SqLastChar< std::isprint, false >)
.FmtFunc(_SC("LastCntrl"), &SqLastChar< std::iscntrl, false >)
.FmtFunc(_SC("LastUpper"), &SqLastChar< std::isupper, false >)
.FmtFunc(_SC("LastLower"), &SqLastChar< std::islower, false >)
.FmtFunc(_SC("LastAlpha"), &SqLastChar< std::isalpha, false >)
.FmtFunc(_SC("LastDigit"), &SqLastChar< std::isdigit, false >)
.FmtFunc(_SC("LastPunct"), &SqLastChar< std::ispunct, false >)
.FmtFunc(_SC("LastXdigit"), &SqLastChar< std::isxdigit, false >)
.FmtFunc(_SC("LastAlnum"), &SqLastChar< std::isalnum, false >)
.FmtFunc(_SC("LastGraph"), &SqLastChar< std::isgraph, false >)
.FmtFunc(_SC("LastBlank"), &SqLastChar< std::isblank, false >)
.FmtFunc(_SC("LastNotSpace"), &SqLastChar< std::isspace, true >)
.FmtFunc(_SC("LastNotPrint"), &SqLastChar< std::isprint, true >)
.FmtFunc(_SC("LastNotCntrl"), &SqLastChar< std::iscntrl, true >)
.FmtFunc(_SC("LastNotUpper"), &SqLastChar< std::isupper, true >)
.FmtFunc(_SC("LastNotLower"), &SqLastChar< std::islower, true >)
.FmtFunc(_SC("LastNotAlpha"), &SqLastChar< std::isalpha, true >)
.FmtFunc(_SC("LastNotDigit"), &SqLastChar< std::isdigit, true >)
.FmtFunc(_SC("LastNotPunct"), &SqLastChar< std::ispunct, true >)
.FmtFunc(_SC("LastNotXdigit"), &SqLastChar< std::isxdigit, true >)
.FmtFunc(_SC("LastNotAlnum"), &SqLastChar< std::isalnum, true >)
.FmtFunc(_SC("LastNotGraph"), &SqLastChar< std::isgraph, true >)
.FmtFunc(_SC("LastNotBlank"), &SqLastChar< std::isblank, true >)
.SquirrelFunc(_SC("SplitWhereSpace"), &SplitWhereCharProxy< std::isspace, false >)
.SquirrelFunc(_SC("SplitWherePrint"), &SplitWhereCharProxy< std::isprint, false >)
.SquirrelFunc(_SC("SplitWhereCntrl"), &SplitWhereCharProxy< std::iscntrl, false >)
.SquirrelFunc(_SC("SplitWhereUpper"), &SplitWhereCharProxy< std::isupper, false >)
.SquirrelFunc(_SC("SplitWhereLower"), &SplitWhereCharProxy< std::islower, false >)
.SquirrelFunc(_SC("SplitWhereAlpha"), &SplitWhereCharProxy< std::isalpha, false >)
.SquirrelFunc(_SC("SplitWhereDigit"), &SplitWhereCharProxy< std::isdigit, false >)
.SquirrelFunc(_SC("SplitWherePunct"), &SplitWhereCharProxy< std::ispunct, false >)
.SquirrelFunc(_SC("SplitWhereXdigit"), &SplitWhereCharProxy< std::isxdigit, false >)
.SquirrelFunc(_SC("SplitWhereAlnum"), &SplitWhereCharProxy< std::isalnum, false >)
.SquirrelFunc(_SC("SplitWhereGraph"), &SplitWhereCharProxy< std::isgraph, false >)
.SquirrelFunc(_SC("SplitWhereBlank"), &SplitWhereCharProxy< std::isblank, false >)
.SquirrelFunc(_SC("SplitWhereNotSpace"), &SplitWhereCharProxy< std::isspace, true >)
.SquirrelFunc(_SC("SplitWhereNotPrint"), &SplitWhereCharProxy< std::isprint, true >)
.SquirrelFunc(_SC("SplitWhereNotCntrl"), &SplitWhereCharProxy< std::iscntrl, true >)
.SquirrelFunc(_SC("SplitWhereNotUpper"), &SplitWhereCharProxy< std::isupper, true >)
.SquirrelFunc(_SC("SplitWhereNotLower"), &SplitWhereCharProxy< std::islower, true >)
.SquirrelFunc(_SC("SplitWhereNotAlpha"), &SplitWhereCharProxy< std::isalpha, true >)
.SquirrelFunc(_SC("SplitWhereNotDigit"), &SplitWhereCharProxy< std::isdigit, true >)
.SquirrelFunc(_SC("SplitWhereNotPunct"), &SplitWhereCharProxy< std::ispunct, true >)
.SquirrelFunc(_SC("SplitWhereNotXdigit"), &SplitWhereCharProxy< std::isxdigit, true >)
.SquirrelFunc(_SC("SplitWhereNotAlnum"), &SplitWhereCharProxy< std::isalnum, true >)
.SquirrelFunc(_SC("SplitWhereNotGraph"), &SplitWhereCharProxy< std::isgraph, true >)
.SquirrelFunc(_SC("SplitWhereNotBlank"), &SplitWhereCharProxy< std::isblank, true >);
RootTable(vm).Bind(_SC("SqStr"), strns);
RootTable(vm).SquirrelFunc(_SC("printf"), &StdPrintF);
RootTable(vm)
.Func(_SC("IsSpace"), &IsCharOfType< std::isspace >)
.Func(_SC("IsPrint"), &IsCharOfType< std::isprint >)
.Func(_SC("IsCntrl"), &IsCharOfType< std::iscntrl >)
.Func(_SC("IsUpper"), &IsCharOfType< std::isupper >)
.Func(_SC("IsLower"), &IsCharOfType< std::islower >)
.Func(_SC("IsAlpha"), &IsCharOfType< std::isalpha >)
.Func(_SC("IsDigit"), &IsCharOfType< std::isdigit >)
.Func(_SC("IsPunct"), &IsCharOfType< std::ispunct >)
.Func(_SC("IsXdigit"), &IsCharOfType< std::isxdigit >)
.Func(_SC("IsAlnum"), &IsCharOfType< std::isalnum >)
.Func(_SC("IsGraph"), &IsCharOfType< std::isgraph >)
.Func(_SC("IsBlank"), &IsCharOfType< std::isblank >)
.Func(_SC("ToLower"), &tolower)
.Func(_SC("ToUpper"), &toupper);
}
} // Namespace:: SqMod

30
module/Library/String.hpp Normal file
View File

@ -0,0 +1,30 @@
#ifndef _LIBRARY_STRING_HPP_
#define _LIBRARY_STRING_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Get a new string with only the alpha numeric characters from the specified string.
*/
CSStr StrJustAlphaNum(CSStr str);
Buffer StrJustAlphaNumB(CSStr str);
/* ------------------------------------------------------------------------------------------------
* Convert the specified string to lowercase.
*/
CSStr StrToLowercase(CSStr str);
Buffer StrToLowercaseB(CSStr str);
/* ------------------------------------------------------------------------------------------------
* Convert the specified string to uppercase.
*/
CSStr StrToUppercase(CSStr str);
Buffer StrToUppercaseB(CSStr str);
} // Namespace:: SqMod
#endif // _LIBRARY_STRING_HPP_

109
module/Library/System.cpp Normal file
View File

@ -0,0 +1,109 @@
// ------------------------------------------------------------------------------------------------
#include "Library/System.hpp"
#include "Base/Shared.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_SysDir(HSQUIRRELVM vm);
extern void Register_SysEnv(HSQUIRRELVM vm);
extern void Register_SysPath(HSQUIRRELVM vm);
// ------------------------------------------------------------------------------------------------
static SQInteger SqSysExec(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Allocate a temp buffer to retrieve chunks from output
char buffer[128];
// Allocate a buffer which will contain the final output
Buffer b(128);
// Attempt to open the specified process
FILE * pipe = popen(val.mPtr, "r");
// The process return status
Int32 status = -1;
// Did we fail to open the process?
if (!pipe)
{
return sq_throwerror(vm, ToStrF("Unable to open process [%s]", val.mPtr));
}
// Attempt to read process output
try
{
while (!std::feof(pipe))
{
if (std::fgets(buffer, 128, pipe) != NULL)
{
b.AppendS(buffer);
}
}
}
catch (...)
{
// Close the process
status = pclose(pipe);
// Now throw the error
return sq_throwerror(vm, ToStrF("Unable read process output [%d]", status));
}
// Close the process and obtain the exit status
status = pclose(pipe);
// Remember the top of the stack
const Int32 top = sq_gettop(vm);
// Create a new table on the stack
sq_newtable(vm);
// Push the element name
sq_pushstring(vm, _SC("Status"), -1);
// Push the element value
sq_pushinteger(vm, status);
// Create the element in the table
SQRESULT res = sq_rawset(vm, -3);
// Check the result
if (SQ_FAILED(res))
{
// Clean the stack
sq_settop(vm, top);
// Return the error
return res;
}
// Push the element name
sq_pushstring(vm, _SC("Output"), -1);
// Push the element value
sq_pushstring(vm, b.Get< SQChar >(), b.Position());
// Create the element in the table
res = sq_rawset(vm, -3);
// Check the result
if (SQ_FAILED(res))
{
// Clean the stack
sq_settop(vm, top);
// Return the error
return res;
}
// Specify that we want to return the table we created
return 1;
}
// ================================================================================================
void Register_System(HSQUIRRELVM vm)
{
Register_SysDir(vm);
Register_SysEnv(vm);
Register_SysPath(vm);
RootTable(vm).SquirrelFunc(_SC("SysExec"), &SqSysExec);
}
} // Namespace:: SqMod

14
module/Library/System.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef _LIBRARY_SYSTEM_HPP_
#define _LIBRARY_SYSTEM_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod
#endif // _LIBRARY_SYSTEM_HPP_

View File

@ -0,0 +1,126 @@
// ------------------------------------------------------------------------------------------------
#include "Library/System/Dir.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(TypenameD, _SC("SqSysDir"))
SQMODE_DECL_TYPENAME(TypenameF, _SC("SqSysFile"))
// ------------------------------------------------------------------------------------------------
LightObj SysDir::ReadFile() const
{
Validate("read current file");
// Create a file instance
std::unique_ptr< SysFile > mem = std::make_unique< SysFile >();
// Turn it into a script object
LightObj obj(mem.get());
// Will hold the raw object pointer
SysFile * ptr = nullptr;
// Release it if it was taken over by the script engine
if (obj.IsNull())
{
STHROWF("Failed to create a SqSysFile object.");
}
else
{
ptr = mem.release();
}
// The file handle where it will be opened
tinydir_file * handle = ptr->GetOrMake();
// Attempt to read the current file
if (tinydir_readfile(mHandle.get(), handle) == -1)
{
STHROWF("Failed to read current file.");
}
// Return the resulted object
return obj;
}
// ------------------------------------------------------------------------------------------------
LightObj SysDir::ReadFileAt(SQInteger i) const
{
Validate("read scanned file");
// Make sure the specified directory index is valid
if (i < 0)
{
STHROWF("File index (" PRINT_INT_FMT " < 0) our of bounds.", i);
}
if (static_cast< size_t >(i) >= mHandle->n_files)
{
STHROWF("File index (" PRINT_INT_FMT " >= " PRINT_SZ_FMT ") our of bounds.", i, mHandle->n_files);
}
// Create a file instance
std::unique_ptr< SysFile > mem = std::make_unique< SysFile >();
// Turn it into a script object
LightObj obj(mem.get());
// Will hold the raw object pointer
SysFile * ptr = nullptr;
// Release it if it was taken over by the script engine
if (obj.IsNull())
{
STHROWF("Failed to create a SqSysFile object.");
}
else
{
ptr = mem.release();
}
// The file handle where it will be opened
tinydir_file * handle = ptr->GetOrMake();
// Attempt to read the current file
if (tinydir_readfile_n(mHandle.get(), handle, i) == -1)
{
STHROWF("Failed to read file at index (" PRINT_INT_FMT ")", i);
}
// Return the resulted object
return obj;
}
// ================================================================================================
void Register_SysDir(HSQUIRRELVM vm)
{
RootTable(vm).Bind(TypenameD::Str,
Class< SysDir, NoCopy< SysDir > >(vm, TypenameD::Str)
// Constructors
.Ctor()
.Ctor< StackStrF & >()
.Ctor< bool, StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &TypenameD::Fn)
.Func(_SC("_tostring"), &SysDir::ToString)
// Member Properties
.Prop(_SC("IsValid"), &SysDir::IsValid)
.Prop(_SC("Path"), &SysDir::GetPath)
.Prop(_SC("HasNext"), &SysDir::HasNext)
.Prop(_SC("FileCount"), &SysDir::FileCount)
// Member Methods
.FmtFunc(_SC("Open"), &SysDir::Open)
.FmtFunc(_SC("OpenSorted"), &SysDir::OpenSorted)
.Func(_SC("OpenSubDir"), &SysDir::OpenSubDir)
.Func(_SC("Next"), &SysDir::Next)
.Func(_SC("Close"), &SysDir::Close)
.Func(_SC("ReadFile"), &SysDir::ReadFile)
.Func(_SC("ReadFileAt"), &SysDir::ReadFileAt)
);
RootTable(vm).Bind(TypenameF::Str,
Class< SysFile, NoCopy< SysFile > >(vm, TypenameF::Str)
// Constructors
.Ctor()
.Ctor< StackStrF & >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &TypenameF::Fn)
.Func(_SC("_tostring"), &SysFile::ToString)
// Member Properties
.Prop(_SC("IsValid"), &SysFile::IsValid)
.Prop(_SC("IsDir"), &SysFile::IsDir)
.Prop(_SC("IsReg"), &SysFile::IsReg)
.Prop(_SC("Path"), &SysFile::GetPath)
.Prop(_SC("Name"), &SysFile::GetName)
.Prop(_SC("Extension"), &SysFile::GetExtension)
// Member Methods
.FmtFunc(_SC("Open"), &SysFile::Open)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,587 @@
#ifndef _LIBRARY_SYSDIR_HPP_
#define _LIBRARY_SYSDIR_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#include <memory>
// ------------------------------------------------------------------------------------------------
#include <tinydir.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
typedef std::unique_ptr< tinydir_dir > TinyDir;
typedef std::unique_ptr< tinydir_file > TinyFile;
/* ------------------------------------------------------------------------------------------------
* This class represents file-system directories in a platform-independent manner.
*/
class SysDir
{
// --------------------------------------------------------------------------------------------
TinyDir mHandle; /* Handle to the managed directory. */
public:
/* --------------------------------------------------------------------------------------------
* Make sure a valid handle is being managed before attempting to use it.
*/
void Validate() const
{
if (!mHandle)
{
STHROWF("Invalid directory handle. Please open a directory first.");
}
}
/* --------------------------------------------------------------------------------------------
* Make sure a valid handle is being managed before attempting to use it.
*/
void Validate(CSStr action) const
{
if (!mHandle)
{
STHROWF("Cannot %s. Invalid directory handle.", action);
}
}
/* --------------------------------------------------------------------------------------------
* Defaults to a null handle.
*/
SysDir()
: mHandle()
{
/*...*/
}
/* --------------------------------------------------------------------------------------------
* Opens the directory at the specified path.
*/
SysDir(StackStrF & path)
: SysDir(false, path)
{
/*...*/
}
/* --------------------------------------------------------------------------------------------
* Construct from an existing file handle.
*/
explicit SysDir(tinydir_dir * handle)
: mHandle(handle)
{
/*...*/
}
/* --------------------------------------------------------------------------------------------
* Opens the directory at the specified path.
*/
SysDir(bool sorted, StackStrF & path)
: SysDir()
{
// Should we open this in sorted mode?
if (sorted)
{
OpenSorted(path);
}
else
{
Open(path);
}
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
SysDir(const SysDir &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
SysDir(SysDir && o)
: mHandle(std::forward< TinyDir >(o.mHandle))
{
/*...*/
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~SysDir()
{
// Is there handle being managed?
if (mHandle)
{
tinydir_close(mHandle.get()); // Close it!
}
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
SysDir & operator = (const SysDir &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
SysDir & operator = (SysDir && o)
{
// Avoid self assignment
if (this != &o)
{
// Is there handle being managed?
if (mHandle)
{
tinydir_close(mHandle.get()); // Close it!
}
// Take ownership of the new handle
mHandle = std::move(o.mHandle);
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw managed handle.
*/
tinydir_dir * Get() const
{
return mHandle.get();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw managed handle and make one if it doesn't exist already.
*/
tinydir_dir * GetOrMake()
{
// Do we have a handle already?
if (!mHandle)
{
mHandle = std::make_unique< tinydir_dir >(); // Make one
}
// Return it like we promised
return mHandle.get();
}
/* --------------------------------------------------------------------------------------------
* Take ownership of the managed handle.
*/
tinydir_dir * Release()
{
return mHandle.release();
}
/* --------------------------------------------------------------------------------------------
* Release the managed handle.
*/
void Reset()
{
mHandle.reset();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return mHandle ? mHandle->path : _SC("");
}
/* --------------------------------------------------------------------------------------------
* Check for the presence of a handle.
*/
bool IsValid() const
{
return !!mHandle;
}
/* --------------------------------------------------------------------------------------------
* Open a handle to the directory at the specified path.
*/
void Open(StackStrF & path)
{
// Get the string from the script
if ((SQ_FAILED(path.Proc(true))))
{
STHROWF("Unable to extract the specified path.");
}
// Allocate handle memory, if necessary
if (!mHandle)
{
mHandle = std::make_unique< tinydir_dir >();
}
// If there was a handle open, we close it
// If we just allocated one, we initialize it (win, either way)
tinydir_close(mHandle.get());
// Attempt to open the specified directory
if (tinydir_open(mHandle.get(), path.mPtr) == -1)
{
// Don't keep a bad handle
mHandle.reset();
// Now we can throw the exception
STHROWLASTF("Failed to open directory: %s", path.mPtr);
}
}
/* --------------------------------------------------------------------------------------------
* Open a handle to the directory at the specified path.
*/
void OpenSorted(StackStrF & path)
{
// Get the string from the script
if ((SQ_FAILED(path.Proc(true))))
{
STHROWF("Unable to extract the specified path.");
}
// Allocate handle memory, if necessary
if (!mHandle)
{
mHandle = std::make_unique< tinydir_dir >();
}
// If there was a handle open, we close it
// If we just allocated one, we initialize it (win, either way)
tinydir_close(mHandle.get());
// Attempt to open the specified directory
if (tinydir_open_sorted(mHandle.get(), path.mPtr) == -1)
{
// Don't keep a bad handle
mHandle.reset();
// Now we can throw the exception
STHROWLASTF("Failed to open directory: %s", path.mPtr);
}
}
/* --------------------------------------------------------------------------------------------
* Open a handle to the directory at the specified path.
*/
SysDir & OpenSubDir(SQInteger i)
{
Validate("open sub directory");
// Discard current error number
errno = 0;
// Make sure the specified directory index is valid
if (i < 0)
{
STHROWF("Directory index (" PRINT_INT_FMT " < 0) our of bounds.", i);
}
if (static_cast< size_t >(i) >= mHandle->n_files)
{
STHROWF("Directory index (" PRINT_INT_FMT " >= " PRINT_SZ_FMT ") our of bounds.", i, mHandle->n_files);
}
// Make sure there is a directory at the specified index
else if (!mHandle->_files[i].is_dir)
{
STHROWF("The specified index (" PRINT_INT_FMT ") is not a directory.", i);
}
// Attempt to open the specified sub-directory
if (tinydir_open_subdir_n(mHandle.get(), static_cast< size_t >(i)) == -1)
{
// Don't keep a bad handle
mHandle.reset();
// Now we can throw the exception
STHROWLASTF("Failed to open sub directory (" PRINT_INT_FMT ").", i);
}
// Return self to allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* Advance to the next element in the opened directory.
*/
void Next()
{
Validate("advance to next element");
// See if there is a next element
if (!mHandle->has_next)
{
STHROWF("Nothing left to advance to.");
}
// Discard current error number
errno = 0;
// Perform the requested action
if (tinydir_next(mHandle.get()) == -1)
{
// This particular error number means the directory was closed
if (errno == EIO) mHandle.reset();
// Now the exception can be thrown
STHROWLASTF("Failed to advance to the next element");
}
}
/* --------------------------------------------------------------------------------------------
* Close the currently associated directory handle.
*/
void Close()
{
Validate("close directory");
// Perform the requested action
tinydir_close(mHandle.get());
// Release any associated memory
mHandle.reset();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the opened path.
*/
CSStr GetPath() const
{
Validate("obtain path");
// Return the requested information
return mHandle->path;
}
/* --------------------------------------------------------------------------------------------
* See if there's a next element in the opened directory.
*/
bool HasNext() const
{
Validate("check for next");
// Return the requested information
return static_cast< bool >(mHandle->has_next);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of files in the opened directory (only when opened in sorted mode).
*/
SQInteger FileCount() const
{
Validate("obtain file count");
// Return the requested information
return static_cast< SQInteger >(mHandle->n_files);
}
/* --------------------------------------------------------------------------------------------
* Open current file from the specified directory.
*/
LightObj ReadFile() const;
/* --------------------------------------------------------------------------------------------
* Open current file from the specified directory.
*/
LightObj ReadFileAt(SQInteger i) const;
};
/* ------------------------------------------------------------------------------------------------
* This class represents file-system files in a platform-independent manner.
*/
class SysFile
{
// --------------------------------------------------------------------------------------------
TinyFile mHandle; /* Handle to the managed file. */
public:
/* --------------------------------------------------------------------------------------------
* Make sure a valid handle is being managed before attempting to use it.
*/
void Validate() const
{
if (!mHandle)
{
STHROWF("Invalid file handle. Please open a file first.");
}
}
/* --------------------------------------------------------------------------------------------
* Make sure a valid handle is being managed before attempting to use it.
*/
void Validate(CSStr action) const
{
if (!mHandle)
{
STHROWF("Cannot %s. Invalid file handle.", action);
}
}
/* --------------------------------------------------------------------------------------------
* Defaults to a null handle.
*/
SysFile()
: mHandle()
{
/*...*/
}
/* --------------------------------------------------------------------------------------------
* Opens the file at the specified path.
*/
SysFile(StackStrF & path)
: SysFile()
{
Open(path);
}
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
SysFile(const SysFile &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
SysFile(SysFile && o)
: mHandle(std::forward< TinyFile >(o.mHandle))
{
/*...*/
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
SysFile & operator = (const SysFile &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
SysFile & operator = (SysFile && o)
{
// Avoid self assignment
if (this != &o)
{
// Take ownership of the new handle
mHandle = std::move(o.mHandle);
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw managed handle.
*/
tinydir_file * Get() const
{
return mHandle.get();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the raw managed handle and make one if it doesn't exist already.
*/
tinydir_file * GetOrMake()
{
// Do we have a handle already?
if (!mHandle)
{
mHandle = std::make_unique< tinydir_file >(); // Make one
}
// Return it like we promised
return mHandle.get();
}
/* --------------------------------------------------------------------------------------------
* Take ownership of the managed handle.
*/
tinydir_file * Release()
{
return mHandle.release();
}
/* --------------------------------------------------------------------------------------------
* Release the managed handle.
*/
void Reset()
{
mHandle.reset();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return mHandle ? mHandle->path : _SC("");
}
/* --------------------------------------------------------------------------------------------
* Check for the presence of a handle.
*/
bool IsValid() const
{
return !!mHandle;
}
/* --------------------------------------------------------------------------------------------
* Open a handle to the file at the specified path.
*/
void Open(StackStrF & path)
{
// Get the string from the script
if ((SQ_FAILED(path.Proc(true))))
{
STHROWF("Unable to extract the specified path.");
}
// Allocate the handle memory
mHandle = std::make_unique< tinydir_file >();
// Discard current error number
errno = 0;
// Attempt to open the specified file
if (tinydir_file_open(mHandle.get(), path.mPtr) == -1)
{
// Don't keep a bad handle
mHandle.reset();
// Now we can throw the exception
if (errno != 0)
{
STHROWF("Failed to open file: %s [%s]", path.mPtr, strerror(errno));
}
else
{
STHROWLASTF("Failed to open file: %s", path.mPtr);
}
}
}
/* --------------------------------------------------------------------------------------------
* Check if the opened element is a directory.
*/
bool IsDir() const
{
Validate("check type");
// Return the requested information
return static_cast< bool >(mHandle->is_dir);
}
/* --------------------------------------------------------------------------------------------
* Check if the opened element is a regular file.
*/
bool IsReg() const
{
Validate("check type");
// Return the requested information
return static_cast< bool >(mHandle->is_reg);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the path of the opened file.
*/
CSStr GetPath() const
{
Validate("retrieve path");
// Return the requested information
return mHandle->path;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the name of the opened file.
*/
CSStr GetName() const
{
Validate("retrieve name");
// Return the requested information
return mHandle->name;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the extension of the opened file.
*/
CSStr GetExtension() const
{
Validate("retrieve extension");
// Return the requested information
return mHandle->extension != nullptr ? mHandle->extension : _SC("");
}
};
} // Namespace:: SqMod
#endif // _LIBRARY_SYSDIR_HPP_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
#ifndef _LIBRARY_SYSENV_HPP_
#define _LIBRARY_SYSENV_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* This class provides access to environment variables and some general system information.
*/
struct SysEnv
{
/* --------------------------------------------------------------------------------------------
* Default constructor. (disabled)
*/
SysEnv() = delete;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
SysEnv(const SysEnv &) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
SysEnv(SysEnv &&) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor. (disabled)
*/
~SysEnv() = delete;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
SysEnv & operator = (const SysEnv &) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
SysEnv & operator = (SysEnv &&) = delete;
public:
/* --------------------------------------------------------------------------------------------
* Returns true if an environment variable with the given name is defined.
*/
static bool Has(CCStr name);
/* --------------------------------------------------------------------------------------------
* Returns true if an environment variable with the given name is defined.
*/
static bool Has(const String & name);
/* --------------------------------------------------------------------------------------------
* Returns the value of the environment variable with the given name.
* If the environment variable is undefined, returns fallback value instead.
*/
static void Get(Buffer & b, CCStr name, CCStr fallback);
/* --------------------------------------------------------------------------------------------
* Returns the value of the environment variable with the given name.
*/
static Buffer Get(CCStr name)
{
return Get(name, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Returns the value of the environment variable with the given name.
*/
static Buffer Get(const String & name)
{
return Get(name.c_str(), nullptr);
}
/* --------------------------------------------------------------------------------------------
* Returns the value of the environment variable with the given name.
* If the environment variable is undefined, returns fallback value instead.
*/
static Buffer Get(CCStr name, CCStr fallback);
/* --------------------------------------------------------------------------------------------
* Returns the value of the environment variable with the given name.
* If the environment variable is undefined, returns fallback value instead.
*/
static Buffer Get(CCStr name, const String & fallback)
{
return Get(name, fallback.c_str());
}
/* --------------------------------------------------------------------------------------------
* Returns the value of the environment variable with the given name.
* If the environment variable is undefined, returns fallback value instead.
*/
static Buffer Get(const String & name, CCStr fallback)
{
return Get(name.c_str(), fallback);
}
/* --------------------------------------------------------------------------------------------
* Returns the value of the environment variable with the given name.
* If the environment variable is undefined, returns fallback value instead.
*/
static Buffer Get(const String & name, const String & fallback)
{
return Get(name.c_str(), fallback.c_str());
}
/* --------------------------------------------------------------------------------------------
* Sets the environment variable with the given name to the given value.
*/
static bool Set(CCStr name, CCStr value);
/* --------------------------------------------------------------------------------------------
* Sets the environment variable with the given name to the given value.
*/
static bool Set(const String & name, const String & value);
/* --------------------------------------------------------------------------------------------
* Returns the operating system name.
*/
static String OSName();
/* --------------------------------------------------------------------------------------------
* Returns the operating system name in a more "user-friendly" way. This only affects Windows.
*/
static String OSDisplayName();
/* --------------------------------------------------------------------------------------------
* Returns the operating system version.
*/
static String OSVersion();
/* --------------------------------------------------------------------------------------------
* Returns the operating system architecture.
*/
static String OSArchitecture();
/* --------------------------------------------------------------------------------------------
* Returns the node (or host) name.
*/
static String NodeName();
/* --------------------------------------------------------------------------------------------
* Returns the number of processors installed in the system. If the number of processors
* cannot be determined, returns 1.
*/
static Uint32 ProcessorCount();
protected:
/* --------------------------------------------------------------------------------------------
* Make sure that the path in the specified buffer contains a trailing slash.
*/
static void TerminatePath(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the string.
*/
static void ExpandVars(Buffer & b, CCStr pos, CCStr end);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the path. Uses the Unix variable style.
*/
static void ExpandPath(Buffer & b, CCStr pos, CCStr end);
public:
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the string.
*/
static void ExpandVars(Buffer & b, CCStr str);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the string.
*/
static void ExpandVars(Buffer & b, const String & str);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the string.
*/
static Buffer ExpandVars(CCStr str);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the string.
*/
static Buffer ExpandVars(const String & str);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the path. Uses the Unix variable style.
*/
static void ExpandPath(Buffer & b, CCStr path);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the path. Uses the Unix variable style.
*/
static void ExpandPath(Buffer & b, const String & path);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the path. Uses the Unix variable style.
*/
static Buffer ExpandPath(CCStr path);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the path. Uses the Unix variable style.
*/
static Buffer ExpandPath(const String & path);
/* --------------------------------------------------------------------------------------------
* Obtain the current working directory within the specified buffer.
*/
static void WorkingDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the current working directory within a buffer and return it.
*/
static Buffer WorkingDir();
/* --------------------------------------------------------------------------------------------
* Obtain the user's home directory within the specified buffer.
*/
static void HomeDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the user's home directory within a buffer and return it.
*/
static Buffer HomeDir();
/* --------------------------------------------------------------------------------------------
* Obtain the user's config directory within the specified buffer.
*/
static void ConfigHomeDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the user's config directory within a buffer and return it.
*/
static Buffer ConfigHomeDir();
/* --------------------------------------------------------------------------------------------
* Obtain the user's data directory within the specified buffer.
*/
static void DataHomeDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the user's data directory within a buffer and return it.
*/
static Buffer DataHomeDir();
/* --------------------------------------------------------------------------------------------
* Obtain the user's temporary directory within the specified buffer.
*/
static void TempHomeDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the user's temporary directory within a buffer and return it.
*/
static Buffer TempHomeDir();
/* --------------------------------------------------------------------------------------------
* Obtain the user's cache directory within the specified buffer.
*/
static void CacheHomeDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the user's cache directory within a buffer and return it.
*/
static Buffer CacheHomeDir();
/* --------------------------------------------------------------------------------------------
* Obtain the temporary directory within the specified buffer.
*/
static void TempDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the temporary directory within a buffer and return it.
*/
static Buffer TempDir();
/* --------------------------------------------------------------------------------------------
* Obtain the systemwide config directory within the specified buffer.
*/
static void ConfigDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the systemwide config directory within a buffer and return it.
*/
static Buffer ConfigDir();
/* --------------------------------------------------------------------------------------------
* Obtain the system directory within the specified buffer.
*/
static void SystemDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the system directory within a buffer and return it.
*/
static Buffer SystemDir();
/* --------------------------------------------------------------------------------------------
* Obtain the null directory within the specified buffer.
*/
static void NullDir(Buffer & b);
/* --------------------------------------------------------------------------------------------
* Obtain the null directory within a buffer and return it.
*/
static Buffer NullDir();
};
} // Namespace:: SqMod
#endif // _LIBRARY_SYSENV_HPP_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,763 @@
#ifndef _LIBRARY_SYSPATH_HPP_
#define _LIBRARY_SYSPATH_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#include <vector>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Retrieve the full path of file.
*/
Buffer GetRealFilePath(CSStr path);
/* ------------------------------------------------------------------------------------------------
* This class represents filesystem paths in a platform-independent manner.
*/
class SysPath
{
public:
// --------------------------------------------------------------------------------------------
typedef std::vector< String > StrVec; // Directory list.
/* --------------------------------------------------------------------------------------------
* Styles of directories to expect when parsing or to export.
*/
enum struct Style
{
Unix = 0,
Windows,
Native,
Guess,
Dynamic
};
/* --------------------------------------------------------------------------------------------
* Creates an empty relative path.
*/
SysPath();
/* --------------------------------------------------------------------------------------------
* Creates an empty absolute or relative path.
*/
SysPath(bool absolute);
/* --------------------------------------------------------------------------------------------
* Creates a path in native format from a string.
*/
SysPath(CSStr path);
/* --------------------------------------------------------------------------------------------
* Creates a path from a string.
*/
SysPath(CSStr path, Int32 style);
/* --------------------------------------------------------------------------------------------
* Creates a path from a string.
*/
SysPath(CSStr path, Style style);
/* --------------------------------------------------------------------------------------------
* Creates a path in native format from a string.
*/
SysPath(const Buffer & path, Int32 size = -1);
/* --------------------------------------------------------------------------------------------
* Creates a path from a string.
*/
SysPath(const Buffer & path, Style style, Int32 size = -1);
/* --------------------------------------------------------------------------------------------
* Creates a path in native format from a string.
*/
SysPath(const String & path);
/* --------------------------------------------------------------------------------------------
* Creates a path from a string.
*/
SysPath(const String & path, Style style);
/* --------------------------------------------------------------------------------------------
* Creates a path from a parent path and a file name. The parent path is expected to reference
* a directory.
*/
SysPath(const SysPath & parent, CSStr name);
/* --------------------------------------------------------------------------------------------
* Creates a path from a parent path and a file name. The parent path is expected to reference
* a directory.
*/
SysPath(const SysPath & parent, const String & name);
/* --------------------------------------------------------------------------------------------
* Creates a path from a parent path and a relative path. The parent path is expected
* to reference a directory. The relative path is appended to the parent path.
*/
SysPath(const SysPath & parent, const SysPath & relative);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
SysPath(const SysPath & o);
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
SysPath(SysPath && o);
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~SysPath();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
SysPath & operator = (const SysPath & o);
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
SysPath & operator = (SysPath && o);
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path in native format.
*/
SysPath & operator = (CSStr path);
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path in native format.
*/
SysPath & operator = (const String & path);
/* --------------------------------------------------------------------------------------------
* Equality comparison.
*/
bool operator == (const SysPath & o) const;
/* --------------------------------------------------------------------------------------------
* Inequality comparison.
*/
bool operator != (const SysPath & o) const;
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean operator.
*/
operator bool () const;
/* --------------------------------------------------------------------------------------------
* Returns the n'th directory in the directory list. If n == depth(), returns the file name.
*/
const String & operator [] (Uint32 n) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const SysPath & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
Object ToString() const;
/* --------------------------------------------------------------------------------------------
* Swaps the path with another one.
*/
void Swap(SysPath & path);
/* --------------------------------------------------------------------------------------------
* Clears all components.
*/
void Clear();
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path in native format.
*/
SysPath & Assign(CSStr path);
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path.
*/
SysPath & Assign(CSStr path, Int32 style);
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path.
*/
SysPath & Assign(CSStr path, Style style);
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path in native format.
*/
SysPath & Assign(const Buffer & path, Int32 size = -1);
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path.
*/
SysPath & Assign(const Buffer & path, Style style, Int32 size = -1);
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path in native format.
*/
SysPath & Assign(const String & path);
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path.
*/
SysPath & Assign(const String & path, Style style);
/* --------------------------------------------------------------------------------------------
* Creates a path from a parent path and a file name. The parent path is expected to reference
* a directory.
*/
SysPath & Assign(const SysPath & parent, CSStr name);
/* --------------------------------------------------------------------------------------------
* Creates a path from a parent path and a file name. The parent path is expected to reference
* a directory.
*/
SysPath & Assign(const SysPath & parent, const String & name);
/* --------------------------------------------------------------------------------------------
* Creates a path from a parent path and a relative path. The parent path is expected
* to reference a directory. The relative path is appended to the parent path.
*/
SysPath & Assign(const SysPath & parent, const SysPath & relative);
/* --------------------------------------------------------------------------------------------
* Copy the components from another path.
*/
SysPath & Assign(const SysPath & path);
/* --------------------------------------------------------------------------------------------
* Move the components of another path into this instance.
*/
SysPath & Assign(SysPath && path);
/* --------------------------------------------------------------------------------------------
* The resulting path always refers to a directory and the filename part is empty.
*/
SysPath & AssignDir(CSStr path);
/* --------------------------------------------------------------------------------------------
* The resulting path always refers to a directory and the filename part is empty.
*/
SysPath & AssignDir(CSStr path, Int32 style);
/* --------------------------------------------------------------------------------------------
* The resulting path always refers to a directory and the filename part is empty.
*/
SysPath & AssignDir(CSStr path, Style style);
/* --------------------------------------------------------------------------------------------
* The resulting path always refers to a directory and the filename part is empty.
*/
SysPath & AssignDir(const Buffer & path, Int32 size = -1);
/* --------------------------------------------------------------------------------------------
* The resulting path always refers to a directory and the filename part is empty.
*/
SysPath & AssignDir(const Buffer & path, Style style, Int32 size = -1);
/* --------------------------------------------------------------------------------------------
* The resulting path always refers to a directory and the filename part is empty.
*/
SysPath & AssignDir(const String & path);
/* --------------------------------------------------------------------------------------------
* The resulting path always refers to a directory and the filename part is empty.
*/
SysPath & AssignDir(const String & path, Style style);
/* --------------------------------------------------------------------------------------------
* Returns a string containing the path in native format.
*/
Buffer ToBuffer() const;
/* --------------------------------------------------------------------------------------------
* Returns a string containing the path in the given format.
*/
Buffer ToBuffer(Style style) const;
/* --------------------------------------------------------------------------------------------
* Returns a string containing the path in the given format.
*/
Object ToStr(Int32 style) const;
/* --------------------------------------------------------------------------------------------
* Assigns a string containing a path.
*/
void FromString(CSStr path);
/* --------------------------------------------------------------------------------------------
* See whether the path is absolute.
*/
bool IsAbsolute() const
{
return m_Absolute;
}
/* --------------------------------------------------------------------------------------------
* See whether the path is relative.
*/
bool IsRelative() const
{
return !m_Absolute;
}
/* --------------------------------------------------------------------------------------------
* See whether the path references a directory.
*/
bool IsDirectory() const
{
return m_Name.empty();
}
/* --------------------------------------------------------------------------------------------
* See whether the path references a file.
*/
bool IsFile() const
{
return !m_Name.empty();
}
/* --------------------------------------------------------------------------------------------
* See whether the path Does not contain a drive, directories or file name.
*/
bool Empty() const
{
return (m_Dirs.empty() && m_Name.empty() && m_Drive == 0);
}
/* --------------------------------------------------------------------------------------------
* If the path contains a file name, the file name is appended to the directory list and cleared.
*/
SysPath & MakeDirectory();
/* --------------------------------------------------------------------------------------------
* If the path contains no file name, the last directory becomes the file name.
*/
SysPath & MakeFile();
/* --------------------------------------------------------------------------------------------
* Makes the path refer to its parent.
*/
SysPath & MakeParent();
/* --------------------------------------------------------------------------------------------
* Makes the path absolute if it is relative. The current working directory is taken
* as base directory.
*/
SysPath & MakeAbsolute();
/* --------------------------------------------------------------------------------------------
* Makes the path absolute if it is relative. The given path is taken as base.
*/
SysPath & MakeAbsolute(const SysPath & base);
/* --------------------------------------------------------------------------------------------
* Makes the path absolute if it is relative. The given path is taken as base.
*/
SysPath & MakeAbsolute(SysPath && base);
/* --------------------------------------------------------------------------------------------
* Appends the given path.
*/
SysPath & Append(const SysPath & path);
/* --------------------------------------------------------------------------------------------
* Appends the given path.
*/
SysPath & Append(SysPath && path);
/* --------------------------------------------------------------------------------------------
* Parse the given string and append the resulted path.
*/
SysPath & Append(CSStr path);
/* --------------------------------------------------------------------------------------------
* Parse the given string and append the resulted path.
*/
SysPath & Append(CSStr path, Int32 style);
/* --------------------------------------------------------------------------------------------
* Parse the given string and append the resulted path.
*/
SysPath & Append(CSStr path, Style style);
/* --------------------------------------------------------------------------------------------
* Parse the given string and append the resulted path.
*/
SysPath & Append(const Buffer & path, Int32 size = -1);
/* --------------------------------------------------------------------------------------------
* Parse the given string and append the resulted path.
*/
SysPath & Append(const Buffer & path, Style style, Int32 size = -1);
/* --------------------------------------------------------------------------------------------
* Parse the given string and append the resulted path.
*/
SysPath & Append(const String & path);
/* --------------------------------------------------------------------------------------------
* Parse the given string and append the resulted path.
*/
SysPath & Append(const String & path, Style style);
/* --------------------------------------------------------------------------------------------
* Returns the drive letter.
*/
CharT GetDrive() const
{
return m_Drive;
}
/* --------------------------------------------------------------------------------------------
* Modifies the drive letter.
*/
void SetDrive(CharT drive)
{
m_Drive = drive;
}
/* --------------------------------------------------------------------------------------------
* Returns the number of directories in the directory list.
*/
Uint32 Depth() const
{
return m_Dirs.size();
}
/* --------------------------------------------------------------------------------------------
* Returns the n'th directory in the directory list. If n == depth(), returns the file name.
*/
const String & Directory(Uint32 n) const;
/* --------------------------------------------------------------------------------------------
* Adds a directory to the directory list.
*/
SysPath & Push(CSStr dir);
/* --------------------------------------------------------------------------------------------
* Adds a directory to the directory list.
*/
SysPath & Push(const String & dir);
/* --------------------------------------------------------------------------------------------
* Adds a directory to the directory list.
*/
SysPath & Push(String && dir);
/* --------------------------------------------------------------------------------------------
* Removes the last directory from the directory list.
*/
SysPath & PopBack();
/* --------------------------------------------------------------------------------------------
* Removes the first directory from the directory list.
*/
SysPath & PopFront();
/* --------------------------------------------------------------------------------------------
* Set the specified file name.
*/
SysPath & SetFilename(CSStr name);
/* --------------------------------------------------------------------------------------------
* Set the specified file name.
*/
SysPath & SetFilename(const String & name);
/* --------------------------------------------------------------------------------------------
* Set the specified file name.
*/
SysPath & SetFilename(String && name);
/* --------------------------------------------------------------------------------------------
* Retrieves the file name.
*/
const String & GetFilename() const
{
return m_Name;
}
/* --------------------------------------------------------------------------------------------
* Set the specified file name.
*/
void SqSetFilename(CSStr name)
{
SetFilename(name);
}
/* --------------------------------------------------------------------------------------------
* Sets the basename part of the file name and does not change the extension.
*/
SysPath & SetBasename(CSStr name);
/* --------------------------------------------------------------------------------------------
* Sets the basename part of the file name and does not change the extension.
*/
SysPath & SetBasename(const String & name);
/* --------------------------------------------------------------------------------------------
* Sets the basename part of the file name and does not change the extension.
*/
SysPath & SetBasename(String && name);
/* --------------------------------------------------------------------------------------------
* Returns the basename (the file name without extension) of the path.
*/
String GetBasename() const;
/* --------------------------------------------------------------------------------------------
* Sets the basename part of the file name and does not change the extension.
*/
void SqSetBasename(CSStr name)
{
SetBasename(name);
}
/* --------------------------------------------------------------------------------------------
* Sets the file name extension.
*/
SysPath & SetExtension(CSStr ext);
/* --------------------------------------------------------------------------------------------
* Sets the file name extension.
*/
SysPath & SetExtension(const String & ext);
/* --------------------------------------------------------------------------------------------
* Returns the file name extension.
*/
String GetExtension() const;
/* --------------------------------------------------------------------------------------------
* Sets the file name extension.
*/
void SqSetExtension(CSStr ext)
{
SetExtension(ext);
}
/* --------------------------------------------------------------------------------------------
* Returns a pointer to the internal name string where the extension starts.
*/
CSStr GetExtensionC() const;
/* --------------------------------------------------------------------------------------------
* Returns a path referring to the path's directory.
*/
SysPath Parent() const;
/* --------------------------------------------------------------------------------------------
* Resolves the given path against the current one. If the given path is absolute, it replaces
* the current one. Otherwise, the relative path is appended to the current path.
*/
SysPath & Resolve(const SysPath & path);
protected:
/* --------------------------------------------------------------------------------------------
* Parse a path using the unix standards.
*/
void ParseUnix(CSStr pos, CSStr end);
/* --------------------------------------------------------------------------------------------
* Parse a path using the windows standards.
*/
void ParseWindows(CSStr pos, CSStr end);
/* --------------------------------------------------------------------------------------------
* Parse a path and expect combined windows and unix styles.
*/
void ParseDynamic(CSStr pos, CSStr end);
/* --------------------------------------------------------------------------------------------
* Parse a path and try to detect it's type automatically.
*/
void ParseGuess(CSStr pos, CSStr end);
/* --------------------------------------------------------------------------------------------
* Build a path string using the Unix conventions.
*/
Buffer BuildUnix() const;
/* --------------------------------------------------------------------------------------------
* Build a path string using the Windows conventions.
*/
Buffer BuildWindows() const;
private:
// --------------------------------------------------------------------------------------------
StrVec m_Dirs; /* The list of directories that form the path. */
String m_Name; /* The file name if one was specified. */
CharT m_Drive; /* The drive letter if one was specified. */
bool m_Absolute; /* Whether this path is an absolute path. */
public:
/* --------------------------------------------------------------------------------------------
* Returns the platform's path name separator, which separates the components (names) in a path.
*/
static CharT Separator()
{
#ifdef GMOD_OS_WINDOWS
return '\\';
#else
return '/';
#endif // GMOD_OS_WINDOWS
}
/* --------------------------------------------------------------------------------------------
* Returns the platform's path separator, which separates single paths in a list of paths.
*/
static CharT PathSeparator()
{
#ifdef GMOD_OS_WINDOWS
return ';';
#else
return ':';
#endif // GMOD_OS_WINDOWS
}
/* --------------------------------------------------------------------------------------------
* Creates a path referring to a directory.
*/
static SysPath ForDirectory(CSStr path);
/* --------------------------------------------------------------------------------------------
* Creates a path referring to a directory.
*/
static SysPath ForDirectory(CSStr path, Int32 style);
/* --------------------------------------------------------------------------------------------
* Creates a path referring to a directory.
*/
static SysPath ForDirectory(CSStr path, Style style);
/* --------------------------------------------------------------------------------------------
* Creates a path referring to a directory.
*/
static SysPath ForDirectory(const String & path);
/* --------------------------------------------------------------------------------------------
* Creates a path referring to a directory.
*/
static SysPath ForDirectory(const String & path, Style style);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the path. On Unix, a tilde as first character
* in the path is replaced with the path to user's home directory.
*/
static SysPath Expand(CSStr path);
/* --------------------------------------------------------------------------------------------
* Expands all environment variables contained in the path.
*/
static SysPath Expand(const String & path)
{
return Expand(path.c_str());
}
/* --------------------------------------------------------------------------------------------
* Returns the user's home directory.
*/
static SysPath Home();
/* --------------------------------------------------------------------------------------------
* Returns the user's config directory.
*/
static SysPath ConfigHome();
/* --------------------------------------------------------------------------------------------
* Returns the user's data directory.
*/
static SysPath DataHome();
/* --------------------------------------------------------------------------------------------
* Returns the user's temp directory.
*/
static SysPath TempHome();
/* --------------------------------------------------------------------------------------------
* Returns the user's temp directory.
*/
static SysPath CacheHome();
/* --------------------------------------------------------------------------------------------
* Returns the current working directory.
*/
static SysPath Working();
/* --------------------------------------------------------------------------------------------
* Returns the temporary directory.
*/
static SysPath Temp();
/* --------------------------------------------------------------------------------------------
* Returns the systemwide config directory.
*/
static SysPath Config();
/* --------------------------------------------------------------------------------------------
* Returns the system directory.
*/
static SysPath System();
/* --------------------------------------------------------------------------------------------
* Returns the name of the null device.
*/
static SysPath Null();
/* --------------------------------------------------------------------------------------------
* Returns the real path to the specified file or directory.
*/
static SysPath Real(CSStr path);
/* --------------------------------------------------------------------------------------------
* Creates a path from a parent path and a file name. The parent path is expected to reference
* a directory.
*/
static SysPath With(const SysPath & parent, CSStr name);
/* --------------------------------------------------------------------------------------------
* Creates a path in unix format from a string.
*/
static SysPath MakeUnix(CSStr path);
/* --------------------------------------------------------------------------------------------
* Creates a path in windows format from a string.
*/
static SysPath MakeWindows(CSStr path);
/* --------------------------------------------------------------------------------------------
* Creates a path in native format from a string.
*/
static SysPath MakeNative(CSStr path);
/* --------------------------------------------------------------------------------------------
* Creates a path in and guess the format from a string.
*/
static SysPath MakeGuess(CSStr path);
/* --------------------------------------------------------------------------------------------
* Creates a path in dynamic format from a string.
*/
static SysPath MakeDynamic(CSStr path);
/* --------------------------------------------------------------------------------------------
* Makes sure all separators from a path are the same.
*/
static String NormalizePath(SQInteger s, StackStrF & val);
};
} // Namespace:: SqMod
#endif // _LIBRARY_SYSPATH_HPP_

98
module/Library/Utils.cpp Normal file
View File

@ -0,0 +1,98 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Utils.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_Buffer(HSQUIRRELVM vm);
/* ------------------------------------------------------------------------------------------------
* Probably not the best implementation but should cover all sorts of weird cases.
*/
static SQInteger SqExtractIPv4(HSQUIRRELVM vm)
{
// Was the IP address specified?
if (sq_gettop(vm) <= 1)
{
return sq_throwerror(vm, "Missing IP address string");
}
// Attempt to generate the string value
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Cleansed IP address buffer
SQChar address[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// Counting variables used by loops
Uint32 i = 0, j = 0, k = 0;
// Replicate the necessary characters from the resulted string
for (; (i < static_cast< Uint32 >(val.mLen)) && (j < 16) && (k < 4); ++i)
{
// Is this a digit?
if (std::isdigit(val.mPtr[i]) != 0)
{
address[j++] = val.mPtr[i]; // Just replicate it
}
// Is this a delimiter?
else if (val.mPtr[i] == '.')
{
// Add a dummy component if one was not specified
if (j == 0 || address[j-1] == '.')
{
address[j++] = '0';
}
// Add the actual delimiter
address[j++] = '.';
// Increase the block counter
++k;
}
}
// Complete the address if it wasn't (also count the last block)
while (++k < 4)
{
address[j++] = '0';
address[j++] = '.';
}
// Components of the IP address
Uint32 blocks[4] = {0, 0, 0, 0};
// Attempt to extract the components of the IP address
std::sscanf(address, "%u.%u.%u.%u", &blocks[0], &blocks[1], &blocks[2], &blocks[3]);
// Create a new array on the stack to hold the extracted components
sq_newarray(vm, 4);
// Push the elements into the array
for (i = 0; i < 4; ++i)
{
// Push the element index
sq_pushinteger(vm, i);
// Push the element value
sq_pushinteger(vm, Clamp(blocks[i], 0U, 255U));
// Assign the element
const SQRESULT res = sq_set(vm, -3);
// See if the assignment failed
if (SQ_FAILED(res))
{
return res;
}
}
// Specify that we have a result on the stack
return 1;
}
// ================================================================================================
void Register_Utils(HSQUIRRELVM vm)
{
RootTable(vm).Bind(_SC("SqUtils"), Table(vm)
.SquirrelFunc(_SC("ExtractIPv4"), &SqExtractIPv4)
);
Register_Buffer(vm);
}
} // Namespace:: SqMod

14
module/Library/Utils.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef _LIBRARY_UTILS_HPP_
#define _LIBRARY_UTILS_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod
#endif // _LIBRARY_UTILS_HPP_

View File

@ -0,0 +1,477 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Utils/Buffer.hpp"
#include "Library/Numeric/LongInt.hpp"
#include "Base/AABB.hpp"
#include "Base/Circle.hpp"
#include "Base/Color3.hpp"
#include "Base/Color4.hpp"
#include "Base/Quaternion.hpp"
#include "Base/Sphere.hpp"
#include "Base/Vector2.hpp"
#include "Base/Vector2i.hpp"
#include "Base/Vector3.hpp"
#include "Base/Vector4.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstring>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMODE_DECL_TYPENAME(Typename, _SC("SqBuffer"))
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteInt64(const SLongInt & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Int64 >(val.GetNum());
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteUint64(const ULongInt & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Uint64 >(val.GetNum());
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteString(CSStr val)
{
// Validate the managed buffer reference
Validate();
// Is the given string value even valid?
if (!val)
{
STHROWF("Invalid string argument: null");
}
// Calculate the string length
Uint16 length = ConvTo< Uint16 >::From(std::strlen(val));
// Change the size endianness to big endian
Uint16 size = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8);
// Write the size and then the string contents
m_Buffer->Push< Uint16 >(size);
m_Buffer->AppendS(val, length);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteRawString(CSStr val)
{
// Validate the managed buffer reference
Validate();
// Is the given string value even valid?
if (!val)
{
STHROWF("Invalid string argument: null");
}
// Calculate the string length
Uint16 length = ConvTo< Uint16 >::From(std::strlen(val));
// Write the the string contents
m_Buffer->AppendS(val, length);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteAABB(const AABB & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< AABB >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteCircle(const Circle & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Circle >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteColor3(const Color3 & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Color3 >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteColor4(const Color4 & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Color4 >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteQuaternion(const Quaternion & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Quaternion >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteSphere(const Sphere &val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Sphere >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteVector2(const Vector2 & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Vector2 >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteVector2i(const Vector2i & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Vector2i >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteVector3(const Vector3 & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Vector3 >(val);
}
// ------------------------------------------------------------------------------------------------
void SqBuffer::WriteVector4(const Vector4 & val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Vector4 >(val);
}
// ------------------------------------------------------------------------------------------------
SLongInt SqBuffer::ReadInt64()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Int64 value = m_Buffer->Cursor< Int64 >();
// Advance the buffer cursor
m_Buffer->Advance< Int64 >(1);
// Return the requested information
return SLongInt(value);
}
// ------------------------------------------------------------------------------------------------
ULongInt SqBuffer::ReadUint64()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Uint64 value = m_Buffer->Cursor< Uint64 >();
// Advance the buffer cursor
m_Buffer->Advance< Uint64 >(1);
// Return the requested information
return ULongInt(value);
}
// ------------------------------------------------------------------------------------------------
Object SqBuffer::ReadString()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
Uint16 length = m_Buffer->Cursor< Uint16 >();
// Convert the length to little endian
length = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8);
// Validate the obtained length
if ((m_Buffer->Position() + sizeof(Uint16) + length) > m_Buffer->Capacity())
{
STHROWF("String of size (%u) starting at (%u) is out of buffer capacity (%u)",
length, m_Buffer->Position() + sizeof(Uint16), m_Buffer->Capacity());
}
// Advance the buffer to the actual string
m_Buffer->Advance< Uint16 >(1);
// Remember the current stack size
const StackGuard sg;
// Attempt to create the string as an object
sq_pushstring(DefaultVM::Get(), &m_Buffer->Cursor(), length);
// Advance the cursor after the string
m_Buffer->Advance(length);
// Return the resulted object
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Object SqBuffer::ReadRawString(SQInteger length)
{
// Validate the managed buffer reference
ValidateDeeper();
// Start with a length of zero
Uint32 len = 0;
// Should we Identify the string length ourselves?
if (length < 0)
{
// Grab the buffer range to search for
CCStr ptr = &m_Buffer->Cursor(), itr = ptr, end = m_Buffer->End();
// Attempt to look for a string terminator
while (itr != end && *itr != '\0')
{
++itr;
}
// If nothing was found, consider the remaining buffer part of the requested string
len = static_cast< Uint32 >(ptr - itr);
}
else
{
len = ConvTo< Uint32 >::From(length);
}
// Validate the obtained length
if ((m_Buffer->Position() + len) > m_Buffer->Capacity())
{
STHROWF("String of size (%u) starting at (%u) is out of buffer capacity (%u)",
len, m_Buffer->Position(), m_Buffer->Capacity());
}
// Remember the current stack size
const StackGuard sg;
// Attempt to create the string as an object
sq_pushstring(DefaultVM::Get(), &m_Buffer->Cursor(), len);
// Advance the cursor after the string
m_Buffer->Advance(len);
// Return the resulted object
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
AABB SqBuffer::ReadAABB()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const AABB & value = m_Buffer->Cursor< AABB >();
// Advance the buffer cursor
m_Buffer->Advance< AABB >(1);
// Return the requested information
return AABB(value);
}
// ------------------------------------------------------------------------------------------------
Circle SqBuffer::ReadCircle()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Circle & value = m_Buffer->Cursor< Circle >();
// Advance the buffer cursor
m_Buffer->Advance< Circle >(1);
// Return the requested information
return Circle(value);
}
// ------------------------------------------------------------------------------------------------
Color3 SqBuffer::ReadColor3()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Color3 & value = m_Buffer->Cursor< Color3 >();
// Advance the buffer cursor
m_Buffer->Advance< Color3 >(1);
// Return the requested information
return Color3(value);
}
// ------------------------------------------------------------------------------------------------
Color4 SqBuffer::ReadColor4()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Color4 & value = m_Buffer->Cursor< Color4 >();
// Advance the buffer cursor
m_Buffer->Advance< Color4 >(1);
// Return the requested information
return Color4(value);
}
// ------------------------------------------------------------------------------------------------
Quaternion SqBuffer::ReadQuaternion()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Quaternion & value = m_Buffer->Cursor< Quaternion >();
// Advance the buffer cursor
m_Buffer->Advance< Quaternion >(1);
// Return the requested information
return Quaternion(value);
}
// ------------------------------------------------------------------------------------------------
Sphere SqBuffer::ReadSphere()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Sphere & value = m_Buffer->Cursor< Sphere >();
// Advance the buffer cursor
m_Buffer->Advance< Sphere >(1);
// Return the requested information
return Sphere(value);
}
// ------------------------------------------------------------------------------------------------
Vector2 SqBuffer::ReadVector2()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Vector2 & value = m_Buffer->Cursor< Vector2 >();
// Advance the buffer cursor
m_Buffer->Advance< Vector2 >(1);
// Return the requested information
return Vector2(value);
}
// ------------------------------------------------------------------------------------------------
Vector2i SqBuffer::ReadVector2i()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Vector2i & value = m_Buffer->Cursor< Vector2i >();
// Advance the buffer cursor
m_Buffer->Advance< Vector2i >(1);
// Return the requested information
return Vector2i(value);
}
// ------------------------------------------------------------------------------------------------
Vector3 SqBuffer::ReadVector3()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Vector3 & value = m_Buffer->Cursor< Vector3 >();
// Advance the buffer cursor
m_Buffer->Advance< Vector3 >(1);
// Return the requested information
return Vector3(value);
}
// ------------------------------------------------------------------------------------------------
Vector4 SqBuffer::ReadVector4()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Vector4 & value = m_Buffer->Cursor< Vector4 >();
// Advance the buffer cursor
m_Buffer->Advance< Vector4 >(1);
// Return the requested information
return Vector4(value);
}
// ================================================================================================
void Register_Buffer(HSQUIRRELVM vm)
{
RootTable(vm).Bind(Typename::Str,
Class< SqBuffer >(vm, Typename::Str)
// Constructors
.Ctor()
.Ctor< SQInteger >()
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
// Properties
.Prop(_SC("Front"), &SqBuffer::GetFront, &SqBuffer::SetFront)
.Prop(_SC("Next"), &SqBuffer::GetNext, &SqBuffer::SetNext)
.Prop(_SC("Back"), &SqBuffer::GetBack, &SqBuffer::SetBack)
.Prop(_SC("Prev"), &SqBuffer::GetPrev, &SqBuffer::SetPrev)
.Prop(_SC("Cursor"), &SqBuffer::GetCursor, &SqBuffer::SetCursor)
.Prop(_SC("Before"), &SqBuffer::GetBefore, &SqBuffer::SetBefore)
.Prop(_SC("After"), &SqBuffer::GetAfter, &SqBuffer::SetAfter)
.Prop(_SC("Max"), &SqBuffer::GetMax)
.Prop(_SC("Size"), &SqBuffer::GetSize, &SqBuffer::Adjust)
.Prop(_SC("Capacity"), &SqBuffer::GetCapacity, &SqBuffer::Adjust)
.Prop(_SC("Position"), &SqBuffer::GetPosition, &SqBuffer::Move)
.Prop(_SC("Remaining"), &SqBuffer::GetRemaining)
// Member Methods
.Func(_SC("Get"), &SqBuffer::Get)
.Func(_SC("Set"), &SqBuffer::Set)
.Func(_SC("Move"), &SqBuffer::Move)
.Func(_SC("Advance"), &SqBuffer::Advance)
.Func(_SC("Retreat"), &SqBuffer::Retreat)
.Func(_SC("Push"), &SqBuffer::Push)
.Func(_SC("Grow"), &SqBuffer::Grow)
.Func(_SC("Adjust"), &SqBuffer::Adjust)
.Func(_SC("WriteByte"), &SqBuffer::WriteUint8)
.Func(_SC("WriteShort"), &SqBuffer::WriteInt16)
.Func(_SC("WriteInt"), &SqBuffer::WriteInt32)
.Func(_SC("WriteFloat"), &SqBuffer::WriteFloat32)
.Func(_SC("WriteInt8"), &SqBuffer::WriteInt8)
.Func(_SC("WriteUint8"), &SqBuffer::WriteUint8)
.Func(_SC("WriteInt16"), &SqBuffer::WriteInt16)
.Func(_SC("WriteUint16"), &SqBuffer::WriteUint16)
.Func(_SC("WriteInt32"), &SqBuffer::WriteInt32)
.Func(_SC("WriteUint32"), &SqBuffer::WriteUint32)
.Func(_SC("WriteInt64"), &SqBuffer::WriteInt64)
.Func(_SC("WriteUint64"), &SqBuffer::WriteUint64)
.Func(_SC("WriteFloat32"), &SqBuffer::WriteFloat32)
.Func(_SC("WriteFloat64"), &SqBuffer::WriteFloat64)
.Func(_SC("WriteString"), &SqBuffer::WriteString)
.Func(_SC("WriteRawString"), &SqBuffer::WriteRawString)
.Func(_SC("WriteAABB"), &SqBuffer::WriteAABB)
.Func(_SC("WriteCircle"), &SqBuffer::WriteCircle)
.Func(_SC("WriteColor3"), &SqBuffer::WriteColor3)
.Func(_SC("WriteColor4"), &SqBuffer::WriteColor4)
.Func(_SC("WriteQuaternion"), &SqBuffer::WriteQuaternion)
.Func(_SC("WriteSphere"), &SqBuffer::WriteSphere)
.Func(_SC("WriteVector2"), &SqBuffer::WriteVector2)
.Func(_SC("WriteVector2i"), &SqBuffer::WriteVector2i)
.Func(_SC("WriteVector3"), &SqBuffer::WriteVector3)
.Func(_SC("WriteVector4"), &SqBuffer::WriteVector4)
.Func(_SC("ReadByte"), &SqBuffer::ReadUint8)
.Func(_SC("ReadShort"), &SqBuffer::ReadInt16)
.Func(_SC("ReadInt"), &SqBuffer::ReadInt32)
.Func(_SC("ReadFloat"), &SqBuffer::ReadFloat32)
.Func(_SC("ReadInt8"), &SqBuffer::ReadInt8)
.Func(_SC("ReadUint8"), &SqBuffer::ReadUint8)
.Func(_SC("ReadInt16"), &SqBuffer::ReadInt16)
.Func(_SC("ReadUint16"), &SqBuffer::ReadUint16)
.Func(_SC("ReadInt32"), &SqBuffer::ReadInt32)
.Func(_SC("ReadUint32"), &SqBuffer::ReadUint32)
.Func(_SC("ReadInt64"), &SqBuffer::ReadInt64)
.Func(_SC("ReadUint64"), &SqBuffer::ReadUint64)
.Func(_SC("ReadFloat32"), &SqBuffer::ReadFloat32)
.Func(_SC("ReadFloat64"), &SqBuffer::ReadFloat64)
.Func(_SC("ReadString"), &SqBuffer::ReadString)
.Func(_SC("ReadRawString"), &SqBuffer::ReadRawString)
.Func(_SC("ReadAABB"), &SqBuffer::ReadAABB)
.Func(_SC("ReadCircle"), &SqBuffer::ReadCircle)
.Func(_SC("ReadColor3"), &SqBuffer::ReadColor3)
.Func(_SC("ReadColor4"), &SqBuffer::ReadColor4)
.Func(_SC("ReadQuaternion"), &SqBuffer::ReadQuaternion)
.Func(_SC("ReadSphere"), &SqBuffer::ReadSphere)
.Func(_SC("ReadVector2"), &SqBuffer::ReadVector2)
.Func(_SC("ReadVector2i"), &SqBuffer::ReadVector2i)
.Func(_SC("ReadVector3"), &SqBuffer::ReadVector3)
.Func(_SC("ReadVector4"), &SqBuffer::ReadVector4)
);
}
} // Namespace:: SqMod

View File

@ -0,0 +1,837 @@
#ifndef _LIBRARY_UTILS_BUFFER_HPP_
#define _LIBRARY_UTILS_BUFFER_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Squirrel wrapper for the shared buffer class.
*/
class SqBuffer
{
private:
// --------------------------------------------------------------------------------------------
typedef SharedPtr< Buffer > SRef; // Strong reference type to the managed memory buffer.
typedef WeakPtr< Buffer > WRef; // Weak reference type to the managed memory buffer.
// --------------------------------------------------------------------------------------------
SRef m_Buffer; // The managed memory buffer.
public:
// --------------------------------------------------------------------------------------------
typedef Buffer::Value Value; // The type of value used to represent a byte.
// --------------------------------------------------------------------------------------------
typedef Value & Reference; // A reference to the stored value type.
typedef const Value & ConstRef; // A const reference to the stored value type.
// --------------------------------------------------------------------------------------------
typedef Value * Pointer; // A pointer to the stored value type.
typedef const Value * ConstPtr; // A const pointer to the stored value type.
// --------------------------------------------------------------------------------------------
typedef Buffer::SzType SzType; // The type used to represent size in general.
public:
/* --------------------------------------------------------------------------------------------
* Create a memory buffer with the requested size.
*/
static Object Create(SzType n);
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
SqBuffer()
: m_Buffer(new Buffer())
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Allocate constructor.
*/
SqBuffer(SQInteger n)
: m_Buffer(new Buffer(ConvTo< SzType >::From(n)))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Allocate constructor.
*/
SqBuffer(SQInteger n, SQInteger c)
: m_Buffer(new Buffer(ConvTo< SzType >::From(n), ConvTo< SzType >::From(c)))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
SqBuffer(ConstPtr p, SQInteger n)
: m_Buffer(new Buffer(p, ConvTo< SzType >::From(n)))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
SqBuffer(ConstPtr p, SQInteger n, SQInteger c)
: m_Buffer(new Buffer(p, ConvTo< SzType >::From(n), ConvTo< SzType >::From(c)))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Reference constructor.
*/
SqBuffer(const SRef & ref)
: m_Buffer(ref)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Buffer constructor.
*/
SqBuffer(const Buffer & b)
: m_Buffer(new Buffer(b))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Buffer constructor.
*/
SqBuffer(Buffer && b)
: m_Buffer(new Buffer(std::move(b)))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
SqBuffer(const SqBuffer & o) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
SqBuffer(SqBuffer && o) = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~SqBuffer() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
SqBuffer & operator = (const SqBuffer & o) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
SqBuffer & operator = (SqBuffer && o) = default;
/* --------------------------------------------------------------------------------------------
* Retrieve a reference to the managed memory buffer.
*/
const SRef & GetRef() const
{
return m_Buffer;
}
/* --------------------------------------------------------------------------------------------
* Validate the managed memory buffer reference.
*/
void Validate() const
{
// Do we even point to a valid buffer?
if (!m_Buffer)
{
STHROWF("Invalid memory buffer reference");
}
}
/* --------------------------------------------------------------------------------------------
* Validate the managed memory buffer reference and the buffer itself.
*/
void ValidateDeeper() const
{
// Do we even point to a valid buffer?
if (!m_Buffer)
{
STHROWF("Invalid memory buffer reference");
}
// Validate the buffer itself
else if (!(*m_Buffer))
{
STHROWF("Invalid memory buffer");
}
}
/* --------------------------------------------------------------------------------------------
* Retrieve a certain element type at the specified position.
*/
Value Get(SQInteger n) const
{
// Validate the managed buffer reference
Validate();
// Return the requested element
return m_Buffer->At(ConvTo< SzType >::From(n));
}
/* --------------------------------------------------------------------------------------------
* Modify a certain element type at the specified position.
*/
void Set(SQInteger n, SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Return the requested element
m_Buffer->At(ConvTo< SzType >::From(n)) = ConvTo< Value >::From(v);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the front of the buffer.
*/
Value GetFront() const
{
// Validate the managed buffer reference
Validate();
// Return the requested element
return m_Buffer->Front();
}
/* --------------------------------------------------------------------------------------------
* Modify the element at the front of the buffer.
*/
void SetFront(SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Return the requested element
m_Buffer->Front() = ConvTo< Value >::From(v);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element after the first element in the buffer.
*/
Value GetNext() const
{
// Validate the managed buffer reference
Validate();
// Return the requested element
return m_Buffer->Next();
}
/* --------------------------------------------------------------------------------------------
* Modify the element after the first element in the buffer.
*/
void SetNext(SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Return the requested element
m_Buffer->Next() = ConvTo< Value >::From(v);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the back of the buffer.
*/
Value GetBack() const
{
// Validate the managed buffer reference
Validate();
// Return the requested element
return m_Buffer->Back();
}
/* --------------------------------------------------------------------------------------------
* Modify the element at the back of the buffer.
*/
void SetBack(SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Return the requested element
m_Buffer->Back() = ConvTo< Value >::From(v);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element before the last element in the buffer.
*/
Value GetPrev() const
{
// Validate the managed buffer reference
Validate();
// Return the requested element
return m_Buffer->Prev();
}
/* --------------------------------------------------------------------------------------------
* Modify the element before the last element in the buffer.
*/
void SetPrev(SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Return the requested element
m_Buffer->Prev() = ConvTo< Value >::From(v);
}
/* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to the specified number of elements ahead.
*/
void Advance(SQInteger n)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Advance(ConvTo< SzType >::From(n));
}
/* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to the specified number of elements behind.
*/
void Retreat(SQInteger n)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Retreat(ConvTo< SzType >::From(n));
}
/* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to a fixed position within the buffer.
*/
void Move(SQInteger n)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Move(ConvTo< SzType >::From(n));
}
/* --------------------------------------------------------------------------------------------
* Append a value to the current cursor location and advance the cursor.
*/
void Push(SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push(ConvTo< Value >::From(v));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the cursor position.
*/
Value GetCursor() const
{
// Validate the managed buffer reference
Validate();
// Return the requested element
return m_Buffer->Cursor();
}
/* --------------------------------------------------------------------------------------------
* Modify the element at the cursor position.
*/
void SetCursor(SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Return the requested element
m_Buffer->Cursor() = ConvTo< Value >::From(v);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element before the cursor position.
*/
Value GetBefore() const
{
// Validate the managed buffer reference
Validate();
// Return the requested element
return m_Buffer->Before();
}
/* --------------------------------------------------------------------------------------------
* Modify the element before the cursor position.
*/
void SetBefore(SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Return the requested element
m_Buffer->Before() = ConvTo< Value >::From(v);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element after the cursor position.
*/
Value GetAfter() const
{
// Validate the managed buffer reference
Validate();
// Return the requested element
return m_Buffer->After();
}
/* --------------------------------------------------------------------------------------------
* Modify the element after the cursor position.
*/
void SetAfter(SQInteger v)
{
// Validate the managed buffer reference
Validate();
// Return the requested element
m_Buffer->After() = ConvTo< Value >::From(v);
}
/* --------------------------------------------------------------------------------------------
* Retrieve maximum elements it can hold for a certain type.
*/
SzType GetMax() const
{
return Buffer::Max();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the current buffer capacity in element count.
*/
SzType GetSize() const
{
// Validate the managed buffer reference
Validate();
// Return the requested information
return m_Buffer->CapacityAs< Value >();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the current buffer capacity in byte count.
*/
SzType GetCapacity() const
{
// Validate the managed buffer reference
Validate();
// Return the requested information
return m_Buffer->Capacity();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the current position of the cursor in the buffer.
*/
SzType GetPosition() const
{
// Validate the managed buffer reference
Validate();
// Return the requested information
return m_Buffer->Position();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of unused buffer after the edit cursor.
*/
SzType GetRemaining() const
{
// Validate the managed buffer reference
Validate();
// Return the requested information
return m_Buffer->Remaining();
}
/* --------------------------------------------------------------------------------------------
* Grow the size of the internal buffer by the specified amount of bytes.
*/
void Grow(SQInteger n)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
return m_Buffer->Grow(ConvTo< SzType >::From(n) * sizeof(Value));
}
/* --------------------------------------------------------------------------------------------
* Makes sure there is enough capacity to hold the specified element count.
*/
void Adjust(SQInteger n)
{
// Validate the managed buffer reference
Validate();
// Attempt to perform the requested operation
try
{
Buffer bkp(m_Buffer->Adjust(ConvTo< SzType >::From(n) * sizeof(Value)));
// Copy the data into the new buffer
m_Buffer->Write(0, bkp.Data(), bkp.Capacity());
m_Buffer->Move(bkp.Position());
}
catch (const std::exception & e)
{
STHROWF("%s", e.what()); // Re-package
}
}
/* --------------------------------------------------------------------------------------------
* Write a signed 8 bit integer to the buffer.
*/
void WriteInt8(SQInteger val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Int8 >(ConvTo< Int8 >::From(val));
}
/* --------------------------------------------------------------------------------------------
* Write an unsigned 8 bit integer to the buffer.
*/
void WriteUint8(SQInteger val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Uint8 >(ConvTo< Uint8 >::From(val));
}
/* --------------------------------------------------------------------------------------------
* Write a signed 16 bit integer to the buffer.
*/
void WriteInt16(SQInteger val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Int16 >(ConvTo< Int16 >::From(val));
}
/* --------------------------------------------------------------------------------------------
* Write an unsigned 16 bit integer to the buffer.
*/
void WriteUint16(SQInteger val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Uint16 >(ConvTo< Uint16 >::From(val));
}
/* --------------------------------------------------------------------------------------------
* Write a signed 32 bit integer to the buffer.
*/
void WriteInt32(SQInteger val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Int32 >(ConvTo< Int32 >::From(val));
}
/* --------------------------------------------------------------------------------------------
* Write an unsigned 32 bit integer to the buffer.
*/
void WriteUint32(SQInteger val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Uint32 >(ConvTo< Uint32 >::From(val));
}
/* --------------------------------------------------------------------------------------------
* Write a signed 64 bit integer to the buffer.
*/
void WriteInt64(const SLongInt & val);
/* --------------------------------------------------------------------------------------------
* Write an unsigned 64 bit integer to the buffer.
*/
void WriteUint64(const ULongInt & val);
/* --------------------------------------------------------------------------------------------
* Write a 32 bit float to the buffer.
*/
void WriteFloat32(SQFloat val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Float32 >(ConvTo< Float32 >::From(val));
}
/* --------------------------------------------------------------------------------------------
* Write a 64 bit float to the buffer.
*/
void WriteFloat64(SQFloat val)
{
// Validate the managed buffer reference
Validate();
// Perform the requested operation
m_Buffer->Push< Float64 >(ConvTo< Float64 >::From(val));
}
/* --------------------------------------------------------------------------------------------
* Write a string to the buffer.
*/
void WriteString(CSStr val);
/* --------------------------------------------------------------------------------------------
* Write a raw string to the buffer.
*/
void WriteRawString(CSStr val);
/* --------------------------------------------------------------------------------------------
* Write a AABB to the buffer.
*/
void WriteAABB(const AABB & val);
/* --------------------------------------------------------------------------------------------
* Write a Circle to the buffer.
*/
void WriteCircle(const Circle & val);
/* --------------------------------------------------------------------------------------------
* Write a Color3 to the buffer.
*/
void WriteColor3(const Color3 & val);
/* --------------------------------------------------------------------------------------------
* Write a Color4 to the buffer.
*/
void WriteColor4(const Color4 & val);
/* --------------------------------------------------------------------------------------------
* Write a Quaternion to the buffer.
*/
void WriteQuaternion(const Quaternion & val);
/* --------------------------------------------------------------------------------------------
* Write a Sphere to the buffer.
*/
void WriteSphere(const Sphere &val);
/* --------------------------------------------------------------------------------------------
* Write a Vector2 to the buffer.
*/
void WriteVector2(const Vector2 & val);
/* --------------------------------------------------------------------------------------------
* Write a Vector2i to the buffer.
*/
void WriteVector2i(const Vector2i & val);
/* --------------------------------------------------------------------------------------------
* Write a Vector3 to the buffer.
*/
void WriteVector3(const Vector3 & val);
/* --------------------------------------------------------------------------------------------
* Write a Vector4 to the buffer.
*/
void WriteVector4(const Vector4 & val);
/* --------------------------------------------------------------------------------------------
* Write a signed 8 bit integer from the buffer.
*/
SQInteger ReadInt8()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Int8 value = m_Buffer->Cursor< Int8 >();
// Advance the buffer cursor
m_Buffer->Advance< Int8 >(1);
// Return the requested information
return ConvTo< SQInteger >::From(value);
}
/* --------------------------------------------------------------------------------------------
* Read an unsigned 8 bit integer from the buffer.
*/
SQInteger ReadUint8()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Uint8 value = m_Buffer->Cursor< Uint8 >();
// Advance the buffer cursor
m_Buffer->Advance< Uint8 >(1);
// Return the requested information
return ConvTo< SQInteger >::From(value);
}
/* --------------------------------------------------------------------------------------------
* Read a signed 16 bit integer from the buffer.
*/
SQInteger ReadInt16()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Int16 value = m_Buffer->Cursor< Int16 >();
// Advance the buffer cursor
m_Buffer->Advance< Int16 >(1);
// Return the requested information
return ConvTo< SQInteger >::From(value);
}
/* --------------------------------------------------------------------------------------------
* Read an unsigned 16 bit integer from the buffer.
*/
SQInteger ReadUint16()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Uint16 value = m_Buffer->Cursor< Uint16 >();
// Advance the buffer cursor
m_Buffer->Advance< Uint16 >(1);
// Return the requested information
return ConvTo< SQInteger >::From(value);
}
/* --------------------------------------------------------------------------------------------
* Read a signed 32 bit integer from the buffer.
*/
SQInteger ReadInt32()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Int32 value = m_Buffer->Cursor< Int32 >();
// Advance the buffer cursor
m_Buffer->Advance< Int32 >(1);
// Return the requested information
return ConvTo< SQInteger >::From(value);
}
/* --------------------------------------------------------------------------------------------
* Read an unsigned 32 bit integer from the buffer.
*/
SQInteger ReadUint32()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Uint32 value = m_Buffer->Cursor< Uint32 >();
// Advance the buffer cursor
m_Buffer->Advance< Uint32 >(1);
// Return the requested information
return ConvTo< SQInteger >::From(value);
}
/* --------------------------------------------------------------------------------------------
* Read a signed 64 bit integer from the buffer.
*/
SLongInt ReadInt64();
/* --------------------------------------------------------------------------------------------
* Read an unsigned 64 bit integer from the buffer.
*/
ULongInt ReadUint64();
/* --------------------------------------------------------------------------------------------
* Read a 32 bit float from the buffer.
*/
SQFloat ReadFloat32()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Float32 value = m_Buffer->Cursor< Float32 >();
// Advance the buffer cursor
m_Buffer->Advance< Float32 >(1);
// Return the requested information
return ConvTo< SQFloat >::From(value);
}
/* --------------------------------------------------------------------------------------------
* Read a 64 bit float from the buffer.
*/
SQFloat ReadFloat64()
{
// Validate the managed buffer reference
ValidateDeeper();
// Read one element from the buffer
const Float64 value = m_Buffer->Cursor< Float64 >();
// Advance the buffer cursor
m_Buffer->Advance< Float64 >(1);
// Return the requested information
return ConvTo< SQFloat >::From(value);
}
/* --------------------------------------------------------------------------------------------
* Read a string from the buffer.
*/
Object ReadString();
/* --------------------------------------------------------------------------------------------
* Read a raw string from the buffer.
*/
Object ReadRawString(SQInteger length);
/* --------------------------------------------------------------------------------------------
* Read a AABB from the buffer.
*/
AABB ReadAABB();
/* --------------------------------------------------------------------------------------------
* Read a Circle from the buffer.
*/
Circle ReadCircle();
/* --------------------------------------------------------------------------------------------
* Read a Color3 from the buffer.
*/
Color3 ReadColor3();
/* --------------------------------------------------------------------------------------------
* Read a Color4 from the buffer.
*/
Color4 ReadColor4();
/* --------------------------------------------------------------------------------------------
* Read a Quaternion from the buffer.
*/
Quaternion ReadQuaternion();
/* --------------------------------------------------------------------------------------------
* Read a Sphere from the buffer.
*/
Sphere ReadSphere();
/* --------------------------------------------------------------------------------------------
* Read a Vector2 from the buffer.
*/
Vector2 ReadVector2();
/* --------------------------------------------------------------------------------------------
* Read a Vector2i from the buffer.
*/
Vector2i ReadVector2i();
/* --------------------------------------------------------------------------------------------
* Read a Vector3 from the buffer.
*/
Vector3 ReadVector3();
/* --------------------------------------------------------------------------------------------
* Read a Vector4 from the buffer.
*/
Vector4 ReadVector4();
};
} // Namespace:: SqMod
#endif // _LIBRARY_UTILS_BUFFER_HPP_

920
module/Logger.cpp Normal file
View File

@ -0,0 +1,920 @@
// ------------------------------------------------------------------------------------------------
#include "Logger.hpp"
#include "Core.hpp"
#include "Base/Utility.hpp"
// ------------------------------------------------------------------------------------------------
#include <ctime>
#include <cerrno>
#include <cstring>
#include <cstdarg>
// ------------------------------------------------------------------------------------------------
#include <sqrat.h>
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
#include <Windows.h>
// ------------------------------------------------------------------------------------------------
namespace {
/* ------------------------------------------------------------------------------------------------
* Common windows colors.
*/
enum
{
LC_NORMAL = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
LC_WHITE = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
LC_GRAY = FOREGROUND_INTENSITY,
LC_LIGHT_BLUE = FOREGROUND_INTENSITY | FOREGROUND_BLUE,
LC_DARK_BLUE = FOREGROUND_BLUE,
LC_LIGHT_GREEN = FOREGROUND_INTENSITY | FOREGROUND_GREEN,
LC_DARK_GREEN = FOREGROUND_GREEN,
LC_LIGHT_CYAN = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE,
LC_DARK_CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE,
LC_LIGHT_YELLOW = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN,
LC_DARK_YELLOW = FOREGROUND_RED | FOREGROUND_GREEN,
LC_LIGHT_RED = FOREGROUND_INTENSITY | FOREGROUND_RED,
LC_DARK_RED = FOREGROUND_RED,
LC_LIGHT_MAGENTA = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE,
LC_DARK_MAGENTA = FOREGROUND_RED | FOREGROUND_BLUE
};
/* ------------------------------------------------------------------------------------------------
* Logging colors.
*/
enum
{
LC_DBG = LC_LIGHT_BLUE,
LC_USR = LC_GRAY,
LC_SCS = LC_LIGHT_GREEN,
LC_INF = LC_LIGHT_CYAN,
LC_WRN = LC_LIGHT_YELLOW,
LC_ERR = LC_LIGHT_RED,
LC_FTL = LC_LIGHT_MAGENTA
};
/* ------------------------------------------------------------------------------------------------
* Identify the associated message color.
*/
inline WORD GetLevelColor(BYTE level)
{
switch (level)
{
case SqMod::LOGL_DBG: return LC_DBG;
case SqMod::LOGL_USR: return LC_USR;
case SqMod::LOGL_SCS: return LC_SCS;
case SqMod::LOGL_INF: return LC_INF;
case SqMod::LOGL_WRN: return LC_WRN;
case SqMod::LOGL_ERR: return LC_ERR;
case SqMod::LOGL_FTL: return LC_FTL;
default: return LC_NORMAL;
}
}
} // Namespace::
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Identify the message prefix.
*/
static inline CCStr GetLevelTag(Uint8 level)
{
switch (level)
{
case LOGL_DBG: return "[DBG]";
case LOGL_USR: return "[USR]";
case LOGL_SCS: return "[SCS]";
case LOGL_INF: return "[INF]";
case LOGL_WRN: return "[WRN]";
case LOGL_ERR: return "[ERR]";
case LOGL_FTL: return "[FTL]";
default: return "[UNK]";
}
}
/* ------------------------------------------------------------------------------------------------
* Logging level to callback index.
*/
static inline Uint8 GetLevelIdx(Uint8 level)
{
switch (level)
{
case LOGL_DBG: return 0;
case LOGL_USR: return 1;
case LOGL_SCS: return 2;
case LOGL_INF: return 3;
case LOGL_WRN: return 4;
case LOGL_ERR: return 5;
case LOGL_FTL: return 6;
default: return 0xFF;
}
}
#ifndef SQMOD_OS_WINDOWS
/* ------------------------------------------------------------------------------------------------
* Identify the message prefix and color.
*/
static inline CCStr GetColoredLevelTag(Uint8 level)
{
switch (level)
{
case LOGL_DBG: return "\033[21;94m[DBG]\033[0m";
case LOGL_USR: return "\033[21;37m[USR]\033[0m";
case LOGL_SCS: return "\033[21;92m[SCS]\033[0m";
case LOGL_INF: return "\033[21;96m[INF]\033[0m";
case LOGL_WRN: return "\033[21;93m[WRN]\033[0m";
case LOGL_ERR: return "\033[21;91m[ERR]\033[0m";
case LOGL_FTL: return "\033[21;95m[FTL]\033[0m";
default: return "\033[21;0m[UNK]\033[0m";
}
}
/* ------------------------------------------------------------------------------------------------
* Identify the message prefix and color.
*/
static inline CCStr GetColoredLevelTagDim(Uint8 level)
{
switch (level)
{
case LOGL_DBG: return "\033[21;94m[DBG]\033[2m";
case LOGL_USR: return "\033[21;37m[USR]\033[2m";
case LOGL_SCS: return "\033[21;92m[SCS]\033[2m";
case LOGL_INF: return "\033[21;96m[INF]\033[2m";
case LOGL_WRN: return "\033[21;93m[WRN]\033[2m";
case LOGL_ERR: return "\033[21;91m[ERR]\033[2m";
case LOGL_FTL: return "\033[21;95m[FTL]\033[2m";
default: return "\033[21;0m[UNK]\033[0m";
}
}
#endif // SQMOD_OS_WINDOWS
/* ------------------------------------------------------------------------------------------------
* Output a logging message to the console window.
*/
static inline void OutputConsoleMessage(Uint8 level, bool sub, CCStr tms, CCStr msg)
{
#ifdef SQMOD_OS_WINDOWS
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csb_state;
GetConsoleScreenBufferInfo(hstdout, &csb_state);
SetConsoleTextAttribute(hstdout, GetLevelColor(level));
if (tms)
{
std::printf("%s %s ", GetLevelTag(level), tms);
}
else
{
std::printf("%s ", GetLevelTag(level));
}
SetConsoleTextAttribute(hstdout, sub ? LC_NORMAL : LC_WHITE);
std::printf("%s\n", msg);
SetConsoleTextAttribute(hstdout, csb_state.wAttributes);
#else
if (tms)
{
std::printf("%s %s %s\033[0m\n",
sub ? GetColoredLevelTagDim(level) : GetColoredLevelTag(level), tms, msg);
}
else
{
std::printf("%s %s\033[0m\n",
sub ? GetColoredLevelTagDim(level) : GetColoredLevelTag(level), msg);
}
#endif // SQMOD_OS_WINDOWS
}
/* ------------------------------------------------------------------------------------------------
* Identify the associated message color.
*/
static inline CCStr GetTimeStampStr()
{
static CharT tmbuff[80];
std::time_t t = std::time(nullptr);
std::strftime(tmbuff, sizeof(tmbuff), "%Y-%m-%d %H:%M:%S", std::localtime(&t));
// Return the resulted buffer
return tmbuff;
}
// ------------------------------------------------------------------------------------------------
Logger Logger::s_Inst;
// ------------------------------------------------------------------------------------------------
Logger::Logger()
: m_Buffer()
, m_ConsoleLevels(LOGL_ANY)
, m_LogFileLevels(~LOGL_DBG)
, m_ConsoleTime(false)
, m_LogFileTime(true)
, m_CyclicLock(false)
, m_StringTruncate(32)
, m_File(nullptr)
, m_Filename()
, m_LogCb{}
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
Logger::~Logger()
{
Close();
}
// ------------------------------------------------------------------------------------------------
void Logger::Close()
{
// Is there a file handle to close?
if (m_File)
{
// Flush buffered data
std::fflush(m_File);
// Close the file handle
std::fclose(m_File);
// Prevent further use of this file handle
m_File = nullptr;
}
}
// ------------------------------------------------------------------------------------------------
void Logger::SetLogFilename(CCStr filename)
{
// Close the current logging file, if any
Close();
// Clear the current name
m_Filename.clear();
// Was there a name specified?
if (!filename || *filename == '\0')
{
return; // We're done here!
}
// Make sure the internal buffer has some memory
m_Buffer.Adjust(1024);
// Obtain the current time for generating the filename
const std::time_t t = std::time(nullptr);
// Generate the filename using the current time-stamp
if (std::strftime(m_Buffer.Data(), m_Buffer.Size(), filename, std::localtime(&t)) > 0)
{
m_Filename.assign(m_Buffer.Data());
}
else
{
return; // We're done here!
}
// Attempt to open the file for writing
m_File = std::fopen(m_Filename.c_str(), "w");
// See if the file could be opened
if (!m_File)
{
OutputError("Unable to open the log file (%s) : %s", m_Filename.c_str(), std::strerror(errno));
}
}
// ------------------------------------------------------------------------------------------------
void Logger::BindCb(Uint8 level, Object & env, Function & func)
{
// Get the index of this log level
const Uint8 idx = GetLevelIdx(level);
// Is the log level valid?
if (idx > 6)
{
STHROWF("Out of range log level index: %d > 4", int(idx));
}
// Obtain the function instance called for this log level
Function & cb = m_LogCb[idx];
// Is the specified callback function null?
if (func.IsNull())
{
cb.ReleaseGently(); // Then release the current callback
}
// Does this function need a custom environment?
else if (env.IsNull())
{
// Use the root table instead
RootTable root(DefaultVM::Get_());
// Bind the root table with the function
cb = Function(env.GetVM(), root, func.GetFunc());
}
// Assign the specified environment and function
else
{
cb = Function(env.GetVM(), env, func.GetFunc());
}
}
// ------------------------------------------------------------------------------------------------
void Logger::Initialize(CCStr filename)
{
// Close the logging file
Close();
// Allocate some memory in the buffer
m_Buffer.Adjust(1024);
// Set the log file name and open the file if necessary
SetLogFilename(filename);
}
// ------------------------------------------------------------------------------------------------
void Logger::Terminate()
{
// Release all the buffer resources and references
m_Buffer.ResetAll();
}
// ------------------------------------------------------------------------------------------------
void Logger::Release()
{
for (Uint8 i = 0; i < 7; ++i)
{
m_LogCb[i].ReleaseGently();
}
}
// ------------------------------------------------------------------------------------------------
SQBool Logger::ProcessCb(Uint8 level, bool sub)
{
// Get the index of this log level
const Uint8 idx = GetLevelIdx(level);
// Is the log level valid and is there a callback associated?
if (idx > 6 || m_LogCb[idx].IsNull())
{
return SQFalse;
}
// Grab the associated function
Function & fn = m_LogCb[idx];
// Grab the default VM
HSQUIRRELVM vm = DefaultVM::Get_();
// Gram the top of the stack
SQInteger top = sq_gettop(vm);
// Push the function followed by the environment
sq_pushobject(vm, fn.GetFunc());
sq_pushobject(vm, fn.GetEnv());
// Push the log message
sq_pushstring(vm, m_Buffer.Get< SQChar >(), -1);
// Specify whether this is a sub message
sq_pushbool(vm, static_cast< SQBool >(sub));
// Make the function call and store the result
SQRESULT res = sq_call(vm, 3, true, ErrorHandling::IsEnabled());
// Default to non greedy callback
SQBool ret = SQFalse;
// Did the function succeeded and is the returned value not null?
if (SQ_SUCCEEDED(res) && sq_gettype(vm, -1) != OT_NULL) {
// Obtain the returned value
sq_tobool(vm, -1, &ret);
}
// Pop the callback object and return value from the stack
sq_settop(vm, top);
// Return the outcome of this callback
return ret;
}
// ------------------------------------------------------------------------------------------------
void Logger::Proccess(Uint8 level, bool sub)
{
// Is there a cyclic lock on the logger?
if (!m_CyclicLock)
{
// Lock the logger to prevent a cyclic dependency
m_CyclicLock = true;
// Attempt to process the script callback first
const bool greedy = ProcessCb(level, sub);
// Unlock the logger after the callback was invoked
m_CyclicLock = false;
// Is the callback for this level greedy?
if (greedy)
{
return;
}
}
// Obtain the time-stamp if necessary
CCStr tms = (m_ConsoleTime || m_LogFileTime) ? GetTimeStampStr() : nullptr;
// Are we allowed to send this message level to console?
if (m_ConsoleLevels & level)
{
OutputConsoleMessage(level, sub, (m_ConsoleTime ? tms : nullptr), m_Buffer.Get());
}
// Are we allowed to write it to a file?
if (m_File && (m_LogFileLevels & level))
{
// Write the level tag
std::fputs(GetLevelTag(level), m_File);
std::fputc(' ', m_File);
// Should we include the time-stamp?
if (m_LogFileTime && tms)
{
std::fputs(tms, m_File);
std::fputc(' ', m_File);
}
// Write the message
std::fputs(m_Buffer.Get(), m_File);
// Append a new line
std::fputc('\n', m_File);
}
}
// ------------------------------------------------------------------------------------------------
void Logger::Send(Uint8 level, bool sub, CCStr fmt, va_list args)
{
// Is this level even allowed?
if ((m_ConsoleLevels & level) || (m_LogFileLevels & level))
{
// Generate the message in the buffer
m_Buffer.WriteF(0, fmt, args);
// Process the message in the buffer
Proccess(level, sub);
}
}
// ------------------------------------------------------------------------------------------------
void Logger::Write(Uint8 level, bool sub, CCStr fmt, ...)
{
if ((m_ConsoleLevels & level) || (m_LogFileLevels & level))
{
// Initialize the variable argument list
va_list args;
va_start(args, fmt);
// Generate the message in the buffer
m_Buffer.WriteF(0, fmt, args);
// Finalize the variable argument list
va_end(args);
// Process the message in the buffer
Proccess(level, sub);
}
}
// ------------------------------------------------------------------------------------------------
void Logger::Debug(CCStr fmt, ...)
{
// Initialize the variable argument list
va_list args;
va_start(args, fmt);
// Forward the call to the actual debug function
Debug(fmt, args);
// Finalize the variable argument list
va_end(args);
}
void Logger::Debug(CCStr fmt, va_list args)
{
using namespace Sqrat;
// Retrieve the default Squirrel VM
HSQUIRRELVM vm = DefaultVM::Get();
// Used to acquire
SQStackInfos si;
// Write the message to the buffer
Int32 ret = m_Buffer.WriteF(0, fmt, args);
// Obtain information about the current stack level
if (SQ_SUCCEEDED(sq_stackinfos(vm, 1, &si)))
{
// Whether we should fall back to normal message
bool fall_back = true;
// Should (can) we include a snippet of code in the traceback?
if (Core::Get().IsDebugging() && si.source && (si.line > 0)) {
// Grab the associated line of code
String code = Core::Get().FetchCodeLine(si.source, si.line-1, true);
// Valid line of code?
if (!code.empty())
{
m_Buffer.WriteF(ret, "\n[\n=>Location: %s\n=>Line: %d\n=>Function: %s\n=>Code: %s\n]"
, si.source, si.line, si.funcname ? si.funcname : _SC("unknown"), code.c_str());
fall_back = false; // No need to fall back to normal message!
}
}
// Should the regular message be shown instead?
if (fall_back)
{
m_Buffer.WriteF(ret, "\n[\n=>Location: %s\n=>Line: %d\n=>Function: %s\n]"
, si.source ? si.source : _SC("unknown")
, si.line
, si.funcname ? si.funcname : _SC("unknown"));
}
}
else
{
m_Buffer.WriteF(ret, "\n[\n=>Location: unknown\n=>Line: unknown\n=>Function: unknown\n]");
}
// Process the message in the buffer
Proccess(LOGL_ERR, true);
// Begin the traceback process
ret = m_Buffer.WriteF(0, "Traceback:\n[\n");
// Traceback the function call
for (Int32 level = 1; SQ_SUCCEEDED(sq_stackinfos(vm, level, &si)); ++level)
{
ret += m_Buffer.WriteF(ret, "=> [%d] %s (%d) [%s]\n", level
, si.source ? si.source : _SC("unknown")
, si.line
, si.funcname ? si.funcname : _SC("unknown"));
}
// End the function call traceback
m_Buffer.WriteF(ret, "]");
// Process the message in the buffer
Proccess(LOGL_INF, true);
// Temporary variables to retrieve stack information
CSStr s_ = 0, name = 0;
SQInteger i_, seq = 0;
SQFloat f_;
SQUserPointer p_;
StackStrF ssf_;
// Begin the local variables information
ret = m_Buffer.WriteF(0, "Locals:\n[\n");
// Process each stack level
for (Int32 level = 0; level < 10; level++)
{
seq = 0;
// Display all locals in the current stack level
while((name = sq_getlocal(vm, level, seq)))
{
++seq;
switch(sq_gettype(vm, -1))
{
case OT_NULL:
ret += m_Buffer.WriteF(ret, "=> [%d] NULL [%s]\n", level, name);
break;
case OT_INTEGER:
sq_getinteger(vm, -1, &i_);
ret += m_Buffer.WriteF(ret, "=> [%d] INTEGER [%s] with value: %" PRINT_INT_FMT "\n", level, name, i_);
break;
case OT_FLOAT:
sq_getfloat(vm, -1, &f_);
ret += m_Buffer.WriteF(ret, "=> [%d] FLOAT [%s] with value: %f\n", level, name, f_);
break;
case OT_USERPOINTER:
sq_getuserpointer(vm, -1, &p_);
ret += m_Buffer.WriteF(ret, "=> [%d] USERPOINTER [%s] pointing at: %p\n", level, name, p_);
break;
case OT_STRING:
sq_getstringandsize(vm, -1, &s_, &i_);
if (i_ > 0) {
ret += m_Buffer.WriteF(ret, "=> [%d] STRING [%s] of %" PRINT_INT_FMT " characters: %.*s\n", level, name, i_, m_StringTruncate, s_);
} else {
ret += m_Buffer.WriteF(ret, "=> [%d] STRING [%s] empty\n", level, name);
}
break;
case OT_TABLE:
i_ = sq_getsize(vm, -1);
ret += m_Buffer.WriteF(ret, "=> [%d] TABLE [%s] with %" PRINT_INT_FMT " elements\n", level, name, i_);
break;
case OT_ARRAY:
i_ = sq_getsize(vm, -1);
ret += m_Buffer.WriteF(ret, "=> [%d] ARRAY [%s] with %" PRINT_INT_FMT " elements\n", level, name, i_);
break;
case OT_CLOSURE:
s_ = _SC("@anonymous");
if (SQ_SUCCEEDED(sq_getclosurename(vm, -1))) {
if (sq_gettype(vm, -1) != OT_NULL && SQ_SUCCEEDED(ssf_.Release(vm).Proc())) {
s_ = ssf_.mPtr;
}
sq_poptop(vm);
}
ret += m_Buffer.WriteF(ret, "=> [%d] CLOSURE [%s] with name: %s\n", level, name, s_);
break;
case OT_NATIVECLOSURE:
s_ = _SC("@unknown");
if (SQ_SUCCEEDED(sq_getclosurename(vm, -1))) {
if (sq_gettype(vm, -1) != OT_NULL && SQ_SUCCEEDED(ssf_.Release(vm).Proc())) {
s_ = ssf_.mPtr;
}
sq_poptop(vm);
}
ret += m_Buffer.WriteF(ret, "=> [%d] NATIVECLOSURE [%s] with name: %s\n", level, name, s_);
break;
case OT_GENERATOR:
ret += m_Buffer.WriteF(ret, "=> [%d] GENERATOR [%s]\n", level, name);
break;
case OT_USERDATA:
ret += m_Buffer.WriteF(ret, "=> [%d] USERDATA [%s]\n", level, name);
break;
case OT_THREAD:
ret += m_Buffer.WriteF(ret, "=> [%d] THREAD [%s]\n", level, name);
break;
case OT_CLASS:
// Brute force our way into getting the name of this class without blowing up
s_ = _SC("@unknown");
// Create a dummy, non-constructed instance and hope `_typeof` doesn't rely on member variables
if (SQ_SUCCEEDED(sq_createinstance(vm, -1))) {
// Attempt a `_typeof` on that instance
if (SQ_SUCCEEDED(sq_typeof(vm, -1))) {
if (SQ_SUCCEEDED(ssf_.Release(vm).Proc())) {
s_ = ssf_.mPtr;
}
// Pop the name object
sq_poptop(vm);
}
// Pop the dummy instance
sq_poptop(vm);
}
ret += m_Buffer.WriteF(ret, "=> [%d] CLASS [%s] of type: %s\n", level, name, s_);
break;
case OT_INSTANCE:
s_ = _SC("@unknown");
if (SQ_SUCCEEDED(sq_typeof(vm, -1))) {
if (SQ_SUCCEEDED(ssf_.Release(vm).Proc())) {
s_ = ssf_.mPtr;
}
sq_poptop(vm);
}
ret += m_Buffer.WriteF(ret, "=> [%d] INSTANCE [%s] of type: %s\n", level, name, s_);
break;
case OT_WEAKREF:
s_ = _SC("@unknown");
// Attempt to grab the value pointed by the weak reference
if (SQ_SUCCEEDED(sq_getweakrefval(vm, -1))) {
// Attempt a `_typeof` on that instance
if (SQ_SUCCEEDED(sq_typeof(vm, -1))) {
if (SQ_SUCCEEDED(ssf_.Release(vm).Proc())) {
s_ = ssf_.mPtr;
}
// Pop the name object
sq_poptop(vm);
}
// Pop the referenced value
sq_poptop(vm);
}
ret += m_Buffer.WriteF(ret, "=> [%d] WEAKREF [%s] of type: %s\n", level, name, s_);
break;
case OT_BOOL:
sq_getinteger(vm, -1, &i_);
ret += m_Buffer.WriteF(ret, "=> [%d] BOOL [%s] with value: %s\n", level, name, i_ ? _SC("true") : _SC("false"));
break;
default:
ret += m_Buffer.WriteF(ret, "=> [%d] UNKNOWN [%s]\n", level, name);
break;
}
sq_pop(vm, 1);
}
}
// End the variables information
m_Buffer.WriteF(ret, "]");
// Process the message in the buffer
Proccess(LOGL_INF, true);
}
// ------------------------------------------------------------------------------------------------
#define SQMOD_LOG(N_, L_, S_) /*
*/ void N_(CCStr fmt, ...) /*
*/ { /*
*/ va_list args; /*
*/ va_start(args, fmt); /*
*/ Logger::Get().Send(L_, S_, fmt, args); /*
*/ va_end(args); /*
*/ } /*
*/
// ------------------------------------------------------------------------------------------------
SQMOD_LOG(LogDbg, LOGL_DBG, false)
SQMOD_LOG(LogUsr, LOGL_USR, false)
SQMOD_LOG(LogScs, LOGL_SCS, false)
SQMOD_LOG(LogInf, LOGL_INF, false)
SQMOD_LOG(LogWrn, LOGL_WRN, false)
SQMOD_LOG(LogErr, LOGL_ERR, false)
SQMOD_LOG(LogFtl, LOGL_FTL, false)
// ------------------------------------------------------------------------------------------------
SQMOD_LOG(LogSDbg, LOGL_DBG, true)
SQMOD_LOG(LogSUsr, LOGL_USR, true)
SQMOD_LOG(LogSScs, LOGL_SCS, true)
SQMOD_LOG(LogSInf, LOGL_INF, true)
SQMOD_LOG(LogSWrn, LOGL_WRN, true)
SQMOD_LOG(LogSErr, LOGL_ERR, true)
SQMOD_LOG(LogSFtl, LOGL_FTL, true)
// ------------------------------------------------------------------------------------------------
#define SQMOD_CLOG(N_, L_, S_) /*
*/bool N_(bool c, CCStr fmt, ...) /*
*/ { /*
*/ if (!c) /*
*/ { /*
*/ return c; /*
*/ } /*
*/ va_list args; /*
*/ va_start(args, fmt); /*
*/ Logger::Get().Send(L_, S_, fmt, args); /*
*/ va_end(args); /*
*/ return c; /*
*/ } /*
*/
// ------------------------------------------------------------------------------------------------
SQMOD_CLOG(cLogDbg, LOGL_DBG, false)
SQMOD_CLOG(cLogUsr, LOGL_USR, false)
SQMOD_CLOG(cLogScs, LOGL_SCS, false)
SQMOD_CLOG(cLogInf, LOGL_INF, false)
SQMOD_CLOG(cLogWrn, LOGL_WRN, false)
SQMOD_CLOG(cLogErr, LOGL_ERR, false)
SQMOD_CLOG(cLogFtl, LOGL_FTL, false)
// ------------------------------------------------------------------------------------------------
SQMOD_CLOG(cLogSDbg, LOGL_DBG, true)
SQMOD_CLOG(cLogSUsr, LOGL_USR, true)
SQMOD_CLOG(cLogSScs, LOGL_SCS, true)
SQMOD_CLOG(cLogSInf, LOGL_INF, true)
SQMOD_CLOG(cLogSWrn, LOGL_WRN, true)
SQMOD_CLOG(cLogSErr, LOGL_ERR, true)
SQMOD_CLOG(cLogSFtl, LOGL_FTL, true)
// ------------------------------------------------------------------------------------------------
template < Uint8 L, bool S > static SQInteger LogBasicMessage(HSQUIRRELVM vm)
{
const Int32 top = sq_gettop(vm);
// Was the message value specified?
if (top <= 1)
{
return sq_throwerror(vm, "Missing message value");
}
// Attempt to generate the string value
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.Proc(true)))
{
return val.mRes; // Propagate the error!
}
// Forward the resulted string value to the logger
Logger::Get().Write(L, S, "%s", val.mPtr);
// This function does not return a value
return 0;
}
// ------------------------------------------------------------------------------------------------
template < Uint8 L > static void BindLogCallback(Object & env, Function & func)
{
Logger::Get().BindCb(L, env, func);
}
// ------------------------------------------------------------------------------------------------
static void SqLogClose()
{
Logger::Get().Close();
}
// ------------------------------------------------------------------------------------------------
static void SqLogInitialize(CSStr filename)
{
Logger::Get().Initialize(filename);
}
// ------------------------------------------------------------------------------------------------
static void SqLogToggleConsoleTime(bool toggle)
{
Logger::Get().ToggleConsoleTime(toggle);
}
// ------------------------------------------------------------------------------------------------
static bool SqLogConsoleHasTime()
{
return Logger::Get().ConsoleHasTime();
}
// ------------------------------------------------------------------------------------------------
static void SqLogToggleLogFileTime(bool toggle)
{
Logger::Get().ToggleLogFileTime(toggle);
}
// ------------------------------------------------------------------------------------------------
static bool SqLogLogFileHasTime()
{
return Logger::Get().LogFileHasTime();
}
// ------------------------------------------------------------------------------------------------
static void SqLogSetConsoleLevels(SQInteger level)
{
Logger::Get().SetConsoleLevels(ConvTo< Uint8 >::From(level));
}
// ------------------------------------------------------------------------------------------------
static bool SqLogGetConsoleLevels()
{
return Logger::Get().GetConsoleLevels();
}
// ------------------------------------------------------------------------------------------------
static void SqLogSetLogFileLevels(SQInteger level)
{
Logger::Get().SetLogFileLevels(ConvTo< Uint8 >::From(level));
}
// ------------------------------------------------------------------------------------------------
static bool SqLogGetLogFileLevels()
{
return Logger::Get().GetLogFileLevels();
}
// ------------------------------------------------------------------------------------------------
static void SqLogEnableConsoleLevel(SQInteger level)
{
Logger::Get().EnableConsoleLevel(ConvTo< Uint8 >::From(level));
}
// ------------------------------------------------------------------------------------------------
static void SqLogDisableConsoleLevel(SQInteger level)
{
Logger::Get().DisableConsoleLevel(ConvTo< Uint8 >::From(level));
}
// ------------------------------------------------------------------------------------------------
static void SqLogToggleConsoleLevel(SQInteger level, bool toggle)
{
Logger::Get().ToggleConsoleLevel(ConvTo< Uint8 >::From(level), toggle);
}
// ------------------------------------------------------------------------------------------------
static void SqLogEnableLogFileLevel(SQInteger level)
{
Logger::Get().EnableLogFileLevel(ConvTo< Uint8 >::From(level));
}
// ------------------------------------------------------------------------------------------------
static void SqLogDisableLogFileLevel(SQInteger level)
{
Logger::Get().DisableLogFileLevel(ConvTo< Uint8 >::From(level));
}
// ------------------------------------------------------------------------------------------------
static void SqLogToggleLogFileLevel(SQInteger level, bool toggle)
{
Logger::Get().ToggleLogFileLevel(ConvTo< Uint8 >::From(level), toggle);
}
// ------------------------------------------------------------------------------------------------
static const String & SqLogGetLogFilename()
{
return Logger::Get().GetLogFilename();
}
// ------------------------------------------------------------------------------------------------
static void SqLogSetLogFilename(CSStr filename)
{
Logger::Get().SetLogFilename(filename);
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqLogGetStringTruncate()
{
return static_cast< SQInteger >(Logger::Get().GetStringTruncate());
}
// ------------------------------------------------------------------------------------------------
static void SqLogSetStringTruncate(SQInteger nc)
{
Logger::Get().SetStringTruncate(ConvTo< Uint32 >::From(nc));
}
// ================================================================================================
void Register_Log(HSQUIRRELVM vm)
{
RootTable(vm)
.Bind(_SC("SqLog"), Table(vm)
.SquirrelFunc(_SC("Dbg"), &LogBasicMessage< LOGL_DBG, false >)
.SquirrelFunc(_SC("Usr"), &LogBasicMessage< LOGL_USR, false >)
.SquirrelFunc(_SC("Scs"), &LogBasicMessage< LOGL_SCS, false >)
.SquirrelFunc(_SC("Inf"), &LogBasicMessage< LOGL_INF, false >)
.SquirrelFunc(_SC("Wrn"), &LogBasicMessage< LOGL_WRN, false >)
.SquirrelFunc(_SC("Err"), &LogBasicMessage< LOGL_ERR, false >)
.SquirrelFunc(_SC("Ftl"), &LogBasicMessage< LOGL_FTL, false >)
.SquirrelFunc(_SC("SDbg"), &LogBasicMessage< LOGL_DBG, true >)
.SquirrelFunc(_SC("SUsr"), &LogBasicMessage< LOGL_USR, true >)
.SquirrelFunc(_SC("SScs"), &LogBasicMessage< LOGL_SCS, true >)
.SquirrelFunc(_SC("SInf"), &LogBasicMessage< LOGL_INF, true >)
.SquirrelFunc(_SC("SWrn"), &LogBasicMessage< LOGL_WRN, true >)
.SquirrelFunc(_SC("SErr"), &LogBasicMessage< LOGL_ERR, true >)
.SquirrelFunc(_SC("SFtl"), &LogBasicMessage< LOGL_FTL, true >)
.Func(_SC("BindDbg"), &BindLogCallback< LOGL_DBG >)
.Func(_SC("BindUsr"), &BindLogCallback< LOGL_USR >)
.Func(_SC("BindScs"), &BindLogCallback< LOGL_SCS >)
.Func(_SC("BindInf"), &BindLogCallback< LOGL_INF >)
.Func(_SC("BindWrn"), &BindLogCallback< LOGL_WRN >)
.Func(_SC("BindErr"), &BindLogCallback< LOGL_ERR >)
.Func(_SC("BindFtl"), &BindLogCallback< LOGL_FTL >)
.Func(_SC("Close"), &SqLogClose)
.Func(_SC("Initialize"), &SqLogInitialize)
.Func(_SC("ToggleConsoleTime"), &SqLogToggleConsoleTime)
.Func(_SC("ConsoleHasTime"), &SqLogConsoleHasTime)
.Func(_SC("ToggleLogFileTime"), &SqLogToggleLogFileTime)
.Func(_SC("LogFileHasTime"), &SqLogLogFileHasTime)
.Func(_SC("SetConsoleLevels"), &SqLogSetConsoleLevels)
.Func(_SC("GetConsoleLevels"), &SqLogGetConsoleLevels)
.Func(_SC("SetLogFileLevels"), &SqLogSetLogFileLevels)
.Func(_SC("GetLogFileLevels"), &SqLogGetLogFileLevels)
.Func(_SC("EnableConsoleLevel"), &SqLogEnableConsoleLevel)
.Func(_SC("DisableConsoleLevel"), &SqLogDisableConsoleLevel)
.Func(_SC("ToggleConsoleLevel"), &SqLogToggleConsoleLevel)
.Func(_SC("EnableLogFileLevel"), &SqLogEnableLogFileLevel)
.Func(_SC("DisableLogFileLevel"), &SqLogDisableLogFileLevel)
.Func(_SC("ToggleLogFileLevel"), &SqLogToggleLogFileLevel)
.Func(_SC("GetLogFilename"), &SqLogGetLogFilename)
.Func(_SC("SetLogFilename"), &SqLogSetLogFilename)
.Func(_SC("GetStringTruncate"), &SqLogGetStringTruncate)
.Func(_SC("SetStringTruncate"), &SqLogSetStringTruncate)
);
}
} // Namespace:: SqMod

344
module/Logger.hpp Normal file
View File

@ -0,0 +1,344 @@
#ifndef _LOGGER_HPP_
#define _LOGGER_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqBase.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <string>
// ------------------------------------------------------------------------------------------------
#include <sqrat/sqratFunction.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Supported levels of logging.
*/
enum LogLvl
{
LOGL_NIL = (1 << 0),
LOGL_DBG = (1 << 1),
LOGL_USR = (1 << 2),
LOGL_SCS = (1 << 3),
LOGL_INF = (1 << 4),
LOGL_WRN = (1 << 5),
LOGL_ERR = (1 << 6),
LOGL_FTL = (1 << 7),
LOGL_ANY = 0xFF
};
/* ------------------------------------------------------------------------------------------------
* Class responsible for logging output.
*/
class Logger
{
private:
// --------------------------------------------------------------------------------------------
static Logger s_Inst; // Logger instance.
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Logger();
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Logger(const Logger & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
Logger(Logger && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Logger();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Logger & operator = (const Logger & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
Logger & operator = (Logger && o) = delete;
private:
// --------------------------------------------------------------------------------------------
Buffer m_Buffer; // Common buffer where the message is written.
// --------------------------------------------------------------------------------------------
Uint8 m_ConsoleLevels; // The levels allowed to be outputted to console.
Uint8 m_LogFileLevels; // The levels allowed to be outputted to log file.
// --------------------------------------------------------------------------------------------
bool m_ConsoleTime; // Whether console messages should be timestamped.
bool m_LogFileTime; // Whether log file messages should be timestamped.
bool m_CyclicLock; // Prevent the script callback from entering a loop.
// --------------------------------------------------------------------------------------------
Uint32 m_StringTruncate; // The length at which to trincate strings in debug.
// --------------------------------------------------------------------------------------------
std::FILE* m_File; // Handle to the file where the logs should be saved.
std::string m_Filename; // The name of the file where the logs are saved.
// --------------------------------------------------------------------------------------------
Function m_LogCb[7]; //Callback to receive debug information instead of console.
protected:
/* --------------------------------------------------------------------------------------------
* Process the message in the internal buffer.
*/
void Proccess(Uint8 level, bool sub);
public:
/* --------------------------------------------------------------------------------------------
* Retrieve the logger instance.
*/
static Logger & Get()
{
return s_Inst;
}
/* --------------------------------------------------------------------------------------------
* Flush buffered data and close the logging file.
*/
void Close();
/* --------------------------------------------------------------------------------------------
* Initialize the logging utility.
*/
void Initialize(CCStr filename);
/* --------------------------------------------------------------------------------------------
* Terminate the logging utility.
*/
void Terminate();
/* --------------------------------------------------------------------------------------------
* Release the script associated resources.
*/
void Release();
/* --------------------------------------------------------------------------------------------
* Enable or disable console message time stamping.
*/
void ToggleConsoleTime(bool enabled)
{
m_ConsoleTime = enabled;
}
/* --------------------------------------------------------------------------------------------
* See whether console message time stamping is enabled.
*/
bool ConsoleHasTime() const
{
return m_ConsoleTime;
}
/* --------------------------------------------------------------------------------------------
* Enable or disable log file message time stamping.
*/
void ToggleLogFileTime(bool enabled)
{
m_LogFileTime = enabled;
}
/* --------------------------------------------------------------------------------------------
* See whether log file message time stamping is enabled.
*/
bool LogFileHasTime() const
{
return m_LogFileTime;
}
/* --------------------------------------------------------------------------------------------
* Set the console level flags.
*/
void SetConsoleLevels(Uint8 levels)
{
m_ConsoleLevels = levels;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the console level flags.
*/
Uint8 GetConsoleLevels() const
{
return m_ConsoleLevels;
}
/* --------------------------------------------------------------------------------------------
* Set the log file level flags.
*/
void SetLogFileLevels(Uint8 levels)
{
m_LogFileLevels = levels;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the log file level flags.
*/
Uint8 GetLogFileLevels() const
{
return m_LogFileLevels;
}
/* --------------------------------------------------------------------------------------------
* Enable a certain console logging level.
*/
void EnableConsoleLevel(Uint8 level)
{
m_ConsoleLevels |= level;
}
/* --------------------------------------------------------------------------------------------
* Disable a certain console logging level.
*/
void DisableConsoleLevel(Uint8 level)
{
if (m_ConsoleLevels & level)
{
m_ConsoleLevels ^= level;
}
}
/* --------------------------------------------------------------------------------------------
* Toggle a certain console logging level.
*/
void ToggleConsoleLevel(Uint8 level, bool toggle)
{
if (toggle)
{
EnableConsoleLevel(level);
}
else
{
DisableConsoleLevel(level);
}
}
/* --------------------------------------------------------------------------------------------
* Enable a certain log file logging level.
*/
void EnableLogFileLevel(Uint8 level)
{
m_LogFileLevels |= level;
}
/* --------------------------------------------------------------------------------------------
* Disable a certain log file logging level.
*/
void DisableLogFileLevel(Uint8 level)
{
m_LogFileLevels |= level;
m_LogFileLevels ^= level;
}
/* --------------------------------------------------------------------------------------------
* Toggle a certain log file logging level.
*/
void ToggleLogFileLevel(Uint8 level, bool toggle)
{
if (toggle)
{
EnableLogFileLevel(level);
}
else
{
DisableLogFileLevel(level);
}
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of characters that strings will be truncated in debug output.
*/
Uint32 GetStringTruncate() const
{
return m_StringTruncate;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of characters that strings will be truncated in debug output.
*/
void SetStringTruncate(Uint32 nc)
{
m_StringTruncate = nc;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the log file name.
*/
const std::string & GetLogFilename() const
{
return m_Filename;
}
/* --------------------------------------------------------------------------------------------
* Modify the log file name.
*/
void SetLogFilename(CCStr filename);
/* --------------------------------------------------------------------------------------------
* Bind a script callback to a log level.
*/
void BindCb(Uint8 level, Object & env, Function & func);
/* --------------------------------------------------------------------------------------------
* Send a log message.
*/
void Send(Uint8 level, bool sub, CCStr fmt, va_list args);
/* --------------------------------------------------------------------------------------------
* Write a log message.
*/
void Write(Uint8 level, bool sub, CCStr fmt, ...);
/* --------------------------------------------------------------------------------------------
* Generate a debug message.
*/
void Debug(CCStr fmt, ...);
/* --------------------------------------------------------------------------------------------
* Generate a debug message.
*/
void Debug(CCStr fmt, va_list args);
private:
/* --------------------------------------------------------------------------------------------
* Forward the log message to a callback.
*/
SQBool ProcessCb(Uint8 level, bool sub);
};
/* ------------------------------------------------------------------------------------------------
* Raw console message output.
*/
void OutputDebug(CCStr msg, ...);
/* ------------------------------------------------------------------------------------------------
* Raw console message output.
*/
void OutputMessage(CCStr msg, ...);
/* ------------------------------------------------------------------------------------------------
* Raw console message output.
*/
void OutputError(CCStr msg, ...);
} // Namespace:: SqMod
#endif // _LOGGER_HPP_

1048
module/Main.cpp Normal file

File diff suppressed because it is too large Load Diff

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