1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00

Implement formatting on math types.

Just a helper method to help you generate strings from math types more easilly. A bit risky if you're dumb and don't know how format specifiers work in C because it provides direct access to those.
This commit is contained in:
Sandu Liviu Catalin 2020-09-03 20:33:51 +03:00
parent db6cf1cdde
commit b18d0a129a
22 changed files with 397 additions and 0 deletions

View File

@ -3,6 +3,7 @@
#include "Base/Sphere.hpp" #include "Base/Sphere.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
@ -733,6 +734,33 @@ Int32 AABB::IsSphereInsideFastEx(Value x, Value y, Value z, Value r) const
return IsSphereInsideFast(Sphere(x, y, z, r)); return IsSphereInsideFast(Sphere(x, y, z, r));
} }
// ------------------------------------------------------------------------------------------------
LightObj AABB::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 6, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), min.x, min.y, min.z, max.x, max.y, max.z);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const AABB & AABB::Get(StackStrF & str) const AABB & AABB::Get(StackStrF & str)
{ {
@ -810,6 +838,7 @@ void Register_AABB(HSQUIRRELVM vm)
// Member Methods // Member Methods
.FmtFunc(_SC("SetStr"), &AABB::SetStr) .FmtFunc(_SC("SetStr"), &AABB::SetStr)
.Func(_SC("Clear"), &AABB::Clear) .Func(_SC("Clear"), &AABB::Clear)
.FmtFunc(_SC("Format"), &AABB::Format)
.Func(_SC("DefineScalar"), &AABB::DefineScalar) .Func(_SC("DefineScalar"), &AABB::DefineScalar)
.Func(_SC("DefineVector3"), &AABB::DefineVector3) .Func(_SC("DefineVector3"), &AABB::DefineVector3)
.Func(_SC("DefineVector3Ex"), &AABB::DefineVector3Ex) .Func(_SC("DefineVector3Ex"), &AABB::DefineVector3Ex)

View File

@ -466,6 +466,11 @@ struct AABB
*/ */
Int32 IsSphereInsideFastEx(Value x, Value y, Value z, Value r) const; Int32 IsSphereInsideFastEx(Value x, Value y, Value z, Value r) const;
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the AABB type from a string. * Extract the values for components of the AABB type from a string.
*/ */

View File

@ -2,6 +2,7 @@
#include "Base/Circle.hpp" #include "Base/Circle.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -494,6 +495,33 @@ Array Circle::ToPointsArray(SQInteger num_segments) const
return arr; return arr;
} }
// ------------------------------------------------------------------------------------------------
LightObj Circle::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 3, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), pos.x, pos.y, rad);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Circle & Circle::Get(StackStrF & str) const Circle & Circle::Get(StackStrF & str)
{ {
@ -566,6 +594,7 @@ void Register_Circle(HSQUIRRELVM vm)
.Func(_SC("SetPositionEx"), &Circle::SetPositionEx) .Func(_SC("SetPositionEx"), &Circle::SetPositionEx)
.FmtFunc(_SC("SetStr"), &Circle::SetStr) .FmtFunc(_SC("SetStr"), &Circle::SetStr)
.Func(_SC("Clear"), &Circle::Clear) .Func(_SC("Clear"), &Circle::Clear)
.FmtFunc(_SC("Format"), &Circle::Format)
.Func(_SC("ToPointsArray"), &Circle::ToPointsArray) .Func(_SC("ToPointsArray"), &Circle::ToPointsArray)
// Member Overloads // Member Overloads
.Overload< void (Circle::*)(void) >(_SC("Generate"), &Circle::Generate) .Overload< void (Circle::*)(void) >(_SC("Generate"), &Circle::Generate)

View File

@ -416,6 +416,11 @@ struct Circle
*/ */
Array ToPointsArray(SQInteger num_segments) const; Array ToPointsArray(SQInteger num_segments) const;
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the Circle type from a string. * Extract the values for components of the Circle type from a string.
*/ */

View File

@ -3,6 +3,7 @@
#include "Base/Color4.hpp" #include "Base/Color4.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -631,6 +632,33 @@ void Color3::Inverse()
b = static_cast< Value >(~b); b = static_cast< Value >(~b);
} }
// ------------------------------------------------------------------------------------------------
LightObj Color3::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 3, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), r, g, b);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Color3 & Color3::Get(StackStrF & str) const Color3 & Color3::Get(StackStrF & str)
{ {
@ -714,6 +742,7 @@ void Register_Color3(HSQUIRRELVM vm)
.FmtFunc(_SC("SetStr"), &Color3::SetStr) .FmtFunc(_SC("SetStr"), &Color3::SetStr)
.FmtFunc(_SC("SetName"), &Color3::SetName) .FmtFunc(_SC("SetName"), &Color3::SetName)
.Func(_SC("Clear"), &Color3::Clear) .Func(_SC("Clear"), &Color3::Clear)
.FmtFunc(_SC("Format"), &Color3::Format)
.Func(_SC("Random"), &Color3::Random) .Func(_SC("Random"), &Color3::Random)
.Func(_SC("Inverse"), &Color3::Inverse) .Func(_SC("Inverse"), &Color3::Inverse)
// Member Overloads // Member Overloads

View File

@ -498,6 +498,11 @@ struct Color3
*/ */
void Inverse(); void Inverse();
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the Color3 type from a string. * Extract the values for components of the Color3 type from a string.
*/ */

View File

@ -3,6 +3,7 @@
#include "Base/Color3.hpp" #include "Base/Color3.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -666,6 +667,33 @@ void Color4::Inverse()
a = static_cast< Value >(~a); a = static_cast< Value >(~a);
} }
// ------------------------------------------------------------------------------------------------
LightObj Color4::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 4, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), r, g, b, a);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Color4 & Color4::Get(StackStrF & str) const Color4 & Color4::Get(StackStrF & str)
{ {
@ -753,6 +781,7 @@ void Register_Color4(HSQUIRRELVM vm)
.FmtFunc(_SC("SetStr"), &Color4::SetStr) .FmtFunc(_SC("SetStr"), &Color4::SetStr)
.FmtFunc(_SC("SetName"), &Color4::SetName) .FmtFunc(_SC("SetName"), &Color4::SetName)
.Func(_SC("Clear"), &Color4::Clear) .Func(_SC("Clear"), &Color4::Clear)
.FmtFunc(_SC("Format"), &Color4::Format)
.Func(_SC("Random"), &Color4::Random) .Func(_SC("Random"), &Color4::Random)
.Func(_SC("Inverse"), &Color4::Inverse) .Func(_SC("Inverse"), &Color4::Inverse)
// Member Overloads // Member Overloads

View File

@ -507,6 +507,11 @@ struct Color4
* Extract the values for components of the Color4 type from a string. * Extract the values for components of the Color4 type from a string.
*/ */
static const Color4 & GetEx(SQChar delim, StackStrF & str); static const Color4 & GetEx(SQChar delim, StackStrF & str);
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
}; };
} // Namespace:: SqMod } // Namespace:: SqMod

View File

@ -4,6 +4,7 @@
#include "Base/Vector4.hpp" #include "Base/Vector4.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -719,6 +720,33 @@ const Quaternion & Quaternion::Get(StackStrF & str)
return Quaternion::GetEx(Quaternion::Delim, str); return Quaternion::GetEx(Quaternion::Delim, str);
} }
// ------------------------------------------------------------------------------------------------
LightObj Quaternion::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 4, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), x, y, z, w);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Quaternion & Quaternion::GetEx(SQChar delim, StackStrF & str) const Quaternion & Quaternion::GetEx(SQChar delim, StackStrF & str)
{ {
@ -797,6 +825,7 @@ void Register_Quaternion(HSQUIRRELVM vm)
.Func(_SC("SetVector4"), &Quaternion::SetVector4) .Func(_SC("SetVector4"), &Quaternion::SetVector4)
.FmtFunc(_SC("SetStr"), &Quaternion::SetStr) .FmtFunc(_SC("SetStr"), &Quaternion::SetStr)
.Func(_SC("Clear"), &Quaternion::Clear) .Func(_SC("Clear"), &Quaternion::Clear)
.FmtFunc(_SC("Format"), &Quaternion::Format)
.Func(_SC("DotProduct"), &Quaternion::DotProduct) .Func(_SC("DotProduct"), &Quaternion::DotProduct)
.Func(_SC("Normalize"), &Quaternion::Normalize) .Func(_SC("Normalize"), &Quaternion::Normalize)
.Func(_SC("FromAngleAxis"), &Quaternion::FromAngleAxis) .Func(_SC("FromAngleAxis"), &Quaternion::FromAngleAxis)

View File

@ -439,6 +439,11 @@ struct Quaternion
*/ */
Quaternion NlerpEx(const Quaternion & quat, Value t, bool shortest_path) const; Quaternion NlerpEx(const Quaternion & quat, Value t, bool shortest_path) const;
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the Quaternion type from a string. * Extract the values for components of the Quaternion type from a string.
*/ */

View File

@ -889,6 +889,58 @@ Color3 GetColorStr(CSStr name)
} }
} }
// ------------------------------------------------------------------------------------------------
bool BuildFormatString(String & out, StackStrF & fmt, Uint32 arg, const String & spec)
{
// Is the specified string empty?
if (fmt.mLen <= 0)
{
return false; // Nothing to parse
}
// Backup current string size so we can revert back if anything
const size_t size = out.size();
// Number of processed arguments
Uint32 count = 0;
// Attempt to predict the required space
out.reserve(size + static_cast< size_t >(fmt.mLen) + arg * 2);
// Previously processed characters and the current one
SQChar p2, p1=0, c=0;
// Look for the value specifier in the specified string
for (SQInteger i = 0; i <= fmt.mLen; ++i) {
// Advance to the peaked character
p2 = p1, p1 = c, c = fmt.mPtr[i];
// The escape character is literal?
if (p1 == '\\' && p2 == '\\')
{
out.push_back('\\');
// Safeguard against a sequence of escape characters
p1 = 0;
}
// The marker is literal?
if (p1 == '\\' && c == '$')
{
out.push_back('$');
}
// Is this a marker?
else if (c == '$') {
// Did we run out of allowed arguments?
if (count++ < arg) {
out.append(spec); // Append the format specifier to the string
} else {
// Discard everything so far
out.resize(size);
// Signal failure
SqThrowF("Requested (%u) values but only (%u) available", count, arg);
}
} else if (c != '\\') {
// Append the current character to the string
out.push_back(c);
}
}
// Parsed successfully
return true;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SqThrowLastF(CSStr msg, ...) void SqThrowLastF(CSStr msg, ...)
{ {

View File

@ -170,4 +170,9 @@ template < typename T > inline void SqSetDelimiter(SQInteger c)
T::Delim = ConvTo< SQChar >::From(c); T::Delim = ConvTo< SQChar >::From(c);
} }
/* ------------------------------------------------------------------------------------------------
* Used internally to build format strings for math types.
*/
bool BuildFormatString(String & out, StackStrF & fmt, Uint32 arg, const String & spec);
} // Namespace:: SqMod } // Namespace:: SqMod

View File

@ -2,6 +2,7 @@
#include "Base/Sphere.hpp" #include "Base/Sphere.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -467,6 +468,33 @@ Sphere Sphere::Abs() const
return {pos.Abs(), std::fabs(rad)}; return {pos.Abs(), std::fabs(rad)};
} }
// ------------------------------------------------------------------------------------------------
LightObj Sphere::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 4, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), pos.x, pos.y, pos.z, rad);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Sphere & Sphere::Get(StackStrF & str) const Sphere & Sphere::Get(StackStrF & str)
{ {
@ -538,6 +566,7 @@ void Register_Sphere(HSQUIRRELVM vm)
.Func(_SC("SetPositionEx"), &Sphere::SetPositionEx) .Func(_SC("SetPositionEx"), &Sphere::SetPositionEx)
.FmtFunc(_SC("SetStr"), &Sphere::SetStr) .FmtFunc(_SC("SetStr"), &Sphere::SetStr)
.Func(_SC("Clear"), &Sphere::Clear) .Func(_SC("Clear"), &Sphere::Clear)
.FmtFunc(_SC("Format"), &Sphere::Format)
// Member Overloads // Member Overloads
.Overload< void (Sphere::*)(void) >(_SC("Generate"), &Sphere::Generate) .Overload< void (Sphere::*)(void) >(_SC("Generate"), &Sphere::Generate)
.Overload< void (Sphere::*)(Val, Val, bool) >(_SC("Generate"), &Sphere::Generate) .Overload< void (Sphere::*)(Val, Val, bool) >(_SC("Generate"), &Sphere::Generate)

View File

@ -410,6 +410,11 @@ struct Sphere
*/ */
Sphere Abs() const; Sphere Abs() const;
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the Sphere type from a string. * Extract the values for components of the Sphere type from a string.
*/ */

View File

@ -3,6 +3,7 @@
#include "Base/Vector2i.hpp" #include "Base/Vector2i.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -375,6 +376,33 @@ Vector2 Vector2::Abs() const
return {std::fabs(x), std::fabs(y)}; return {std::fabs(x), std::fabs(y)};
} }
// ------------------------------------------------------------------------------------------------
LightObj Vector2::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 2, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), x, y);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Vector2 & Vector2::Get(StackStrF & str) const Vector2 & Vector2::Get(StackStrF & str)
{ {
@ -441,6 +469,7 @@ void Register_Vector2(HSQUIRRELVM vm)
.Func(_SC("SetVector2i"), &Vector2::SetVector2i) .Func(_SC("SetVector2i"), &Vector2::SetVector2i)
.FmtFunc(_SC("SetStr"), &Vector2::SetStr) .FmtFunc(_SC("SetStr"), &Vector2::SetStr)
.Func(_SC("Clear"), &Vector2::Clear) .Func(_SC("Clear"), &Vector2::Clear)
.FmtFunc(_SC("Format"), &Vector2::Format)
// Member Overloads // Member Overloads
.Overload< void (Vector2::*)(void) >(_SC("Generate"), &Vector2::Generate) .Overload< void (Vector2::*)(void) >(_SC("Generate"), &Vector2::Generate)
.Overload< void (Vector2::*)(Val, Val) >(_SC("Generate"), &Vector2::Generate) .Overload< void (Vector2::*)(Val, Val) >(_SC("Generate"), &Vector2::Generate)

View File

@ -338,6 +338,11 @@ struct Vector2
*/ */
Vector2 Abs() const; Vector2 Abs() const;
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector2 type from a string. * Extract the values for components of the Vector2 type from a string.
*/ */

View File

@ -3,6 +3,7 @@
#include "Base/Vector2.hpp" #include "Base/Vector2.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -521,6 +522,33 @@ Vector2i Vector2i::Abs() const
return {std::abs(x), std::abs(y)}; return {std::abs(x), std::abs(y)};
} }
// ------------------------------------------------------------------------------------------------
LightObj Vector2i::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 2, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), x, y);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Vector2i & Vector2i::Get(StackStrF & str) const Vector2i & Vector2i::Get(StackStrF & str)
{ {
@ -587,6 +615,7 @@ void Register_Vector2i(HSQUIRRELVM vm)
.Func(_SC("SetVector2"), &Vector2i::SetVector2) .Func(_SC("SetVector2"), &Vector2i::SetVector2)
.FmtFunc(_SC("SetStr"), &Vector2i::SetStr) .FmtFunc(_SC("SetStr"), &Vector2i::SetStr)
.Func(_SC("Clear"), &Vector2i::Clear) .Func(_SC("Clear"), &Vector2i::Clear)
.FmtFunc(_SC("Format"), &Vector2i::Format)
// Member Overloads // Member Overloads
.Overload< void (Vector2i::*)(void) >(_SC("Generate"), &Vector2i::Generate) .Overload< void (Vector2i::*)(void) >(_SC("Generate"), &Vector2i::Generate)
.Overload< void (Vector2i::*)(Val, Val) >(_SC("Generate"), &Vector2i::Generate) .Overload< void (Vector2i::*)(Val, Val) >(_SC("Generate"), &Vector2i::Generate)

View File

@ -443,6 +443,11 @@ struct Vector2i
*/ */
Vector2i Abs() const; Vector2i Abs() const;
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector2i type from a string. * Extract the values for components of the Vector2i type from a string.
*/ */

View File

@ -4,6 +4,7 @@
#include "Base/Quaternion.hpp" #include "Base/Quaternion.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -628,6 +629,33 @@ void Vector3::CenterRotateYZBy(Value degrees, const Vector3 & center)
z = static_cast< Value >((y * sn) + (z * cs)) + center.y; z = static_cast< Value >((y * sn) + (z * cs)) + center.y;
} }
// ------------------------------------------------------------------------------------------------
LightObj Vector3::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 3, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), x, y, z);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Vector3 & Vector3::Get(StackStrF & str) const Vector3 & Vector3::Get(StackStrF & str)
{ {
@ -715,6 +743,7 @@ void Register_Vector3(HSQUIRRELVM vm)
.Func(_SC("SetQuaternionEx"), &Vector3::SetQuaternionEx) .Func(_SC("SetQuaternionEx"), &Vector3::SetQuaternionEx)
.FmtFunc(_SC("SetStr"), &Vector3::SetStr) .FmtFunc(_SC("SetStr"), &Vector3::SetStr)
.Func(_SC("Clear"), &Vector3::Clear) .Func(_SC("Clear"), &Vector3::Clear)
.FmtFunc(_SC("Format"), &Vector3::Format)
.Func(_SC("Normalize"), &Vector3::Normalize) .Func(_SC("Normalize"), &Vector3::Normalize)
.Func(_SC("Dot"), &Vector3::DotProduct) .Func(_SC("Dot"), &Vector3::DotProduct)
.Func(_SC("AbsDot"), &Vector3::AbsDotProduct) .Func(_SC("AbsDot"), &Vector3::AbsDotProduct)

View File

@ -489,6 +489,11 @@ struct Vector3
*/ */
void CenterRotateYZBy(Value degrees, const Vector3 & center); void CenterRotateYZBy(Value degrees, const Vector3 & center);
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector3 type from a string. * Extract the values for components of the Vector3 type from a string.
*/ */

View File

@ -4,6 +4,7 @@
#include "Base/Quaternion.hpp" #include "Base/Quaternion.hpp"
#include "Base/Shared.hpp" #include "Base/Shared.hpp"
#include "Base/DynArg.hpp" #include "Base/DynArg.hpp"
#include "Base/Buffer.hpp"
#include "Library/Numeric/Random.hpp" #include "Library/Numeric/Random.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -470,6 +471,33 @@ const Vector4 & Vector4::Get(StackStrF & str)
return Vector4::GetEx(Vector4::Delim, str); return Vector4::GetEx(Vector4::Delim, str);
} }
// ------------------------------------------------------------------------------------------------
LightObj Vector4::Format(const String & spec, StackStrF & fmt) const
{
String out;
// Attempt to build the format string
if (!BuildFormatString(out, fmt, 4, spec))
{
return LightObj{}; // Default to null
}
// Empty string is unacceptable
else if (out.empty())
{
STHROWF("Unable to build a valid format string.");
}
// Grab a temporary buffer
Buffer buff(out.size());
// Generate the string
Buffer::SzType n = buff.WriteF(0, out.c_str(), x, y, z, w);
// Did the format failed?
if (!n && !out.empty())
{
STHROWF("Format failed. Please check format specifier and parameter count.");
}
// Return the resulted string
return LightObj{buff.Begin< SQChar >(), static_cast< SQInteger >(n)};
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Vector4 & Vector4::GetEx(SQChar delim, StackStrF & str) const Vector4 & Vector4::GetEx(SQChar delim, StackStrF & str)
{ {
@ -540,6 +568,7 @@ void Register_Vector4(HSQUIRRELVM vm)
.Func(_SC("SetQuaternionEx"), &Vector4::SetQuaternionEx) .Func(_SC("SetQuaternionEx"), &Vector4::SetQuaternionEx)
.FmtFunc(_SC("SetStr"), &Vector4::SetStr) .FmtFunc(_SC("SetStr"), &Vector4::SetStr)
.Func(_SC("Clear"), &Vector4::Clear) .Func(_SC("Clear"), &Vector4::Clear)
.FmtFunc(_SC("Format"), &Vector4::Format)
// Member Overloads // Member Overloads
.Overload< void (Vector4::*)(void) >(_SC("Generate"), &Vector4::Generate) .Overload< void (Vector4::*)(void) >(_SC("Generate"), &Vector4::Generate)
.Overload< void (Vector4::*)(Val, Val) >(_SC("Generate"), &Vector4::Generate) .Overload< void (Vector4::*)(Val, Val) >(_SC("Generate"), &Vector4::Generate)

View File

@ -363,6 +363,11 @@ struct Vector4
*/ */
Vector4 Abs() const; Vector4 Abs() const;
/* --------------------------------------------------------------------------------------------
* Generate a formatted string with the values from this instance.
*/
LightObj Format(const String & spec, StackStrF & fmt) const;
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Extract the values for components of the Vector4 type from a string. * Extract the values for components of the Vector4 type from a string.
*/ */