@@ -17,55 +17,6 @@ namespace lol | |||
* Safe enum helpers | |||
*/ | |||
map<int64_t, String> BuildEnumMap(String const &str, char const **custom) | |||
{ | |||
return BuildEnumMap(str.C(), custom); | |||
} | |||
map<int64_t, String> BuildEnumMap(char const *str, char const **custom) | |||
{ | |||
map<int64_t, String> ret; | |||
char const *parser = str; | |||
int64_t next_value = 0; | |||
int64_t cur_idx = 0; | |||
for (;;) | |||
{ | |||
/* Find name */ | |||
while (*parser == ' ' || *parser == ',') | |||
++parser; | |||
if (!*parser) | |||
break; | |||
/* Parse name */ | |||
char const *name = parser; | |||
while (*parser && *parser != ' ' && *parser != ',' && *parser != '=') | |||
++parser; | |||
char const *name_end = parser; | |||
/* Find the value (if any) */ | |||
uint64_t current_value = next_value; | |||
while (*parser == ' ' || *parser == '=') | |||
++parser; | |||
if (*parser && *parser != ',') | |||
{ | |||
#if defined _WIN32 | |||
current_value = _strtoi64(parser, nullptr, 0); | |||
#else | |||
current_value = strtoll(parser, nullptr, 0); | |||
#endif | |||
while (*parser && *parser != ' ' && *parser != ',') | |||
++parser; | |||
} | |||
/* Store in the map */ | |||
ret[current_value] = (!custom) ? (String(name, (int)(name_end - name))) : (String(custom[cur_idx])); | |||
next_value = current_value + 1; | |||
cur_idx++; | |||
} | |||
return ret; | |||
} | |||
} /* namespace lol */ | |||
@@ -24,22 +24,54 @@ | |||
namespace lol | |||
{ | |||
//CSGUsage -------------------------------------------------------------------- | |||
/* A safe enum for MeshCSG operations. */ | |||
LOL_SAFE_ENUM(CSGUsage, | |||
Union, | |||
Substract, | |||
SubstractLoss, // will remove B from A, but not add inverted B | |||
And, | |||
Xor | |||
); | |||
struct CSGUsageBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
Union, | |||
Substract, | |||
SubstractLoss, // will remove B from A, but not add inverted B | |||
And, | |||
Xor | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Union] = "Union"; | |||
enum_map[Substract] = "Substract"; | |||
enum_map[SubstractLoss] = "SubstractLoss"; | |||
enum_map[And] = "And"; | |||
enum_map[Xor] = "Xor"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<CSGUsageBase> CSGUsage; | |||
LOL_SAFE_ENUM(MeshTransform, | |||
Taper, | |||
Twist, | |||
Bend, | |||
Stretch, | |||
Shear | |||
); | |||
//MeshTransform --------------------------------------------------------------- | |||
struct MeshTransformBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
Taper, | |||
Twist, | |||
Bend, | |||
Stretch, | |||
Shear | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Taper] = "Taper"; | |||
enum_map[Twist] = "Twist"; | |||
enum_map[Bend] = "Bend"; | |||
enum_map[Stretch] = "Stretch"; | |||
enum_map[Shear] = "Shear"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<MeshTransformBase> MeshTransform; | |||
class EasyMesh : public Mesh | |||
{ | |||
@@ -20,127 +20,256 @@ | |||
namespace lol | |||
{ | |||
struct MeshBuildOperation | |||
//MeshBuildOperation ---------------------------------------------------------- | |||
struct MeshBuildOperationBase : public StructSafeEnum | |||
{ | |||
DEF_VALUE | |||
enum Type | |||
{ | |||
//When this flag is up, negative scaling will not invert faces. | |||
ADD_VALUE_SET(ScaleWinding , (1 << 0)) | |||
ADD_VALUE_SET(CommandRecording , (1 << 1)) | |||
ADD_VALUE_SET(CommandExecution , (1 << 2)) | |||
ADD_VALUE_SET(QuadWeighting , (1 << 3)) | |||
ADD_VALUE_SET(IgnoreQuadWeighting , (1 << 4)) | |||
ADD_VALUE_SET(PostBuildComputeNormals , (1 << 5)) | |||
ADD_VALUE_SET(PreventVertCleanup , (1 << 6)) | |||
ADD_VALUE_SET(All , 0xffff) | |||
END_E_VALUE | |||
LOL_DECLARE_ENUM_METHODS(MeshBuildOperation) | |||
ScaleWinding = (1 << 0), | |||
CommandRecording = (1 << 1), | |||
CommandExecution = (1 << 2), | |||
QuadWeighting = (1 << 3), | |||
IgnoreQuadWeighting = (1 << 4), | |||
PostBuildComputeNormals = (1 << 5), | |||
PreventVertCleanup = (1 << 6), | |||
All = 0xffff, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[ScaleWinding] = "ScaleWinding"; | |||
enum_map[CommandRecording] = "CommandRecording"; | |||
enum_map[CommandExecution] = "CommandExecution"; | |||
enum_map[QuadWeighting] = "QuadWeighting"; | |||
enum_map[IgnoreQuadWeighting] = "IgnoreQuadWeighting"; | |||
enum_map[PostBuildComputeNormals] = "PostBuildComputeNormals"; | |||
enum_map[PreventVertCleanup] = "PreventVertCleanup"; | |||
enum_map[All] = "All"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<MeshBuildOperationBase> MeshBuildOperation; | |||
struct EasyMeshCmdType | |||
//EasyMeshCmdType ------------------------------------------------------------- | |||
struct EasyMeshCmdTypeBase : public StructSafeEnum | |||
{ | |||
DEF_VALUE | |||
ADD_VALUE(MeshCsg) | |||
ADD_VALUE(LoopStart) | |||
ADD_VALUE(LoopEnd) | |||
ADD_VALUE(OpenBrace) | |||
ADD_VALUE(CloseBrace) | |||
ADD_VALUE(ScaleWinding) | |||
ADD_VALUE(QuadWeighting) | |||
ADD_VALUE(PostBuildNormal) | |||
ADD_VALUE(PreventVertCleanup) | |||
ADD_VALUE(SetColorA) | |||
ADD_VALUE(SetColorB) | |||
ADD_VALUE(SetVertColor) | |||
ADD_VALUE(VerticesMerge) | |||
ADD_VALUE(VerticesSeparate) | |||
ADD_VALUE(Translate) | |||
ADD_VALUE(Rotate) | |||
ADD_VALUE(RadialJitter) | |||
ADD_VALUE(MeshTranform) | |||
ADD_VALUE(Scale) | |||
ADD_VALUE(DupAndScale) | |||
ADD_VALUE(Chamfer) | |||
ADD_VALUE(SplitTriangles) | |||
ADD_VALUE(SmoothMesh) | |||
ADD_VALUE(AppendCylinder) | |||
ADD_VALUE(AppendCapsule) | |||
ADD_VALUE(AppendTorus) | |||
ADD_VALUE(AppendBox) | |||
ADD_VALUE(AppendStar) | |||
ADD_VALUE(AppendExpandedStar) | |||
ADD_VALUE(AppendDisc) | |||
ADD_VALUE(AppendSimpleTriangle) | |||
ADD_VALUE(AppendSimpleQuad) | |||
ADD_VALUE(AppendCog) | |||
END_E_VALUE | |||
LOL_DECLARE_ENUM_METHODS(EasyMeshCmdType) | |||
enum Type | |||
{ | |||
MeshCsg, | |||
LoopStart, | |||
LoopEnd, | |||
OpenBrace, | |||
CloseBrace, | |||
ScaleWinding, | |||
QuadWeighting, | |||
PostBuildNormal, | |||
PreventVertCleanup, | |||
SetColorA, | |||
SetColorB, | |||
SetVertColor, | |||
VerticesMerge, | |||
VerticesSeparate, | |||
Translate, | |||
Rotate, | |||
RadialJitter, | |||
MeshTranform, | |||
Scale, | |||
DupAndScale, | |||
Chamfer, | |||
SplitTriangles, | |||
SmoothMesh, | |||
AppendCylinder, | |||
AppendCapsule, | |||
AppendTorus, | |||
AppendBox, | |||
AppendStar, | |||
AppendExpandedStar, | |||
AppendDisc, | |||
AppendSimpleTriangle, | |||
AppendSimpleQuad, | |||
AppendCog, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[MeshCsg] = "MeshCsg"; | |||
enum_map[LoopStart] = "LoopStart"; | |||
enum_map[LoopEnd] = "LoopEnd"; | |||
enum_map[OpenBrace] = "OpenBrace"; | |||
enum_map[CloseBrace] = "CloseBrace"; | |||
enum_map[ScaleWinding] = "ScaleWinding"; | |||
enum_map[QuadWeighting] = "QuadWeighting"; | |||
enum_map[PostBuildNormal] = "PostBuildNormal"; | |||
enum_map[PreventVertCleanup] = "PreventVertCleanup"; | |||
enum_map[SetColorA] = "SetColorA"; | |||
enum_map[SetColorB] = "SetColorB"; | |||
enum_map[SetVertColor] = "SetVertColor"; | |||
enum_map[VerticesMerge] = "VerticesMerge"; | |||
enum_map[VerticesSeparate] = "VerticesSeparate"; | |||
enum_map[Translate] = "Translate"; | |||
enum_map[Rotate] = "Rotate"; | |||
enum_map[RadialJitter] = "RadialJitter"; | |||
enum_map[MeshTranform] = "MeshTranform"; | |||
enum_map[Scale] = "Scale"; | |||
enum_map[DupAndScale] = "DupAndScale"; | |||
enum_map[Chamfer] = "Chamfer"; | |||
enum_map[SplitTriangles] = "SplitTriangles"; | |||
enum_map[SmoothMesh] = "SmoothMesh"; | |||
enum_map[AppendCylinder] = "AppendCylinder"; | |||
enum_map[AppendCapsule] = "AppendCapsule"; | |||
enum_map[AppendTorus] = "AppendTorus"; | |||
enum_map[AppendBox] = "AppendBox"; | |||
enum_map[AppendStar] = "AppendStar"; | |||
enum_map[AppendExpandedStar] = "AppendExpandedStar"; | |||
enum_map[AppendDisc] = "AppendDisc"; | |||
enum_map[AppendSimpleTriangle] = "AppendSimpleTriangle"; | |||
enum_map[AppendSimpleQuad] = "AppendSimpleQuad"; | |||
enum_map[AppendCog] = "AppendCog"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<EasyMeshCmdTypeBase> EasyMeshCmdType; | |||
LOL_SAFE_ENUM(MeshType, | |||
Triangle, | |||
Quad, | |||
Box, | |||
Sphere, | |||
Capsule, | |||
Torus, | |||
Cylinder, | |||
Disc, | |||
Star, | |||
ExpandedStar, | |||
Cog, | |||
MAX | |||
); | |||
struct TexCoordBuildType | |||
//MeshTypeBase ---------------------------------------------------------------- | |||
struct MeshTypeBase : public StructSafeEnum | |||
{ | |||
DEF_VALUE | |||
ADD_VALUE_SET(TriangleDefault , 0) | |||
ADD_VALUE_SET(QuadDefault , 0) | |||
ADD_VALUE_SET(BoxDefault , 0) | |||
ADD_VALUE_SET(SphereDefault , 0) | |||
ADD_VALUE_SET(CapsuleDefault , 0) | |||
ADD_VALUE_SET(TorusDefault , 0) | |||
ADD_VALUE_SET(CylinderDefault , 0) | |||
ADD_VALUE_SET(DiscDefault , 0) | |||
ADD_VALUE_SET(StarDefault , 0) | |||
ADD_VALUE_SET(ExpandedStarDefault , 0) | |||
ADD_VALUE_SET(CogDefault , 0) | |||
/* A safe enum for Primitive edge face. */ | |||
enum Type | |||
{ | |||
Triangle, | |||
Quad, | |||
Box, | |||
Sphere, | |||
Capsule, | |||
Torus, | |||
Cylinder, | |||
Disc, | |||
Star, | |||
ExpandedStar, | |||
Cog, | |||
MAX | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Triangle] = "Triangle"; | |||
enum_map[Quad] = "Quad"; | |||
enum_map[Box] = "Box"; | |||
enum_map[Sphere] = "Sphere"; | |||
enum_map[Capsule] = "Capsule"; | |||
enum_map[Torus] = "Torus"; | |||
enum_map[Cylinder] = "Cylinder"; | |||
enum_map[Disc] = "Disc"; | |||
enum_map[Star] = "Star"; | |||
enum_map[ExpandedStar] = "ExpandedStar"; | |||
enum_map[Cog] = "Cog"; | |||
enum_map[MAX] = "MAX"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<MeshTypeBase> MeshType; | |||
//TexCoordBuildType ----------------------------------------------------------- | |||
struct TexCoordBuildTypeBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
TriangleDefault, | |||
QuadDefault, | |||
BoxDefault, | |||
SphereDefault, | |||
CapsuleDefault, | |||
TorusDefault, | |||
CylinderDefault, | |||
DiscDefault, | |||
StarDefault, | |||
ExpandedStarDefault, | |||
CogDefault, | |||
//NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE | |||
ADD_VALUE_SET(Max , 1) | |||
END_E_VALUE | |||
Max | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[TriangleDefault] = "TriangleDefault"; | |||
enum_map[QuadDefault] = "QuadDefault"; | |||
enum_map[BoxDefault] = "BoxDefault"; | |||
enum_map[SphereDefault] = "SphereDefault"; | |||
enum_map[CapsuleDefault] = "CapsuleDefault"; | |||
enum_map[TorusDefault] = "TorusDefault"; | |||
enum_map[CylinderDefault] = "CylinderDefault"; | |||
enum_map[DiscDefault] = "DiscDefault"; | |||
enum_map[StarDefault] = "StarDefault"; | |||
enum_map[ExpandedStarDefault] = "ExpandedStarDefault"; | |||
enum_map[CogDefault] = "CogDefault"; | |||
enum_map[Max] = "Max"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<TexCoordBuildTypeBase> TexCoordBuildType; | |||
LOL_DECLARE_ENUM_METHODS(TexCoordBuildType) | |||
//MeshFaceType ---------------------------------------------------------------- | |||
struct MeshFaceTypeBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
BoxFront = 0, | |||
QuadDefault = 0, | |||
BoxLeft = 1, | |||
BoxBack = 2, | |||
BoxRight = 3, | |||
BoxTop = 4, | |||
BoxBottom = 5, | |||
MAX | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[BoxFront] = "BoxFront"; | |||
enum_map[QuadDefault] = "QuadDefault"; | |||
enum_map[BoxLeft] = "BoxLeft"; | |||
enum_map[BoxBack] = "BoxBack"; | |||
enum_map[BoxRight] = "BoxRight"; | |||
enum_map[BoxTop] = "BoxTop"; | |||
enum_map[BoxBottom] = "BoxBottom"; | |||
enum_map[MAX] = "MAX"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<MeshFaceTypeBase> MeshFaceType; | |||
LOL_SAFE_ENUM(MeshFaceType, | |||
BoxFront = 0, | |||
QuadDefault = 0, | |||
BoxLeft = 1, | |||
BoxBack = 2, | |||
BoxRight = 3, | |||
BoxTop = 4, | |||
BoxBottom = 5, | |||
Max | |||
); | |||
LOL_SAFE_ENUM(TexCoordPos, | |||
BL, // Bottom Left | |||
BR, // Bottom Right | |||
TL, // Top Left | |||
TR // Top Right | |||
); | |||
//TexCoordPos ----------------------------------------------------------------- | |||
struct TexCoordPosBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
BL, // Bottom Left | |||
BR, // Bottom Right | |||
TL, // Top Left | |||
TR // Top Right | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[BL] = "BL"; | |||
enum_map[BR] = "BR"; | |||
enum_map[TL] = "TL"; | |||
enum_map[TR] = "TR"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<TexCoordPosBase> TexCoordPos; | |||
class EasyMeshBuildData | |||
{ | |||
@@ -175,7 +304,7 @@ public: | |||
inline vec2 &TexCoordScale2() { return m_texcoord_scale2; } | |||
//UV1 | |||
void SetTexCoordBuildType(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type[mt.ToScalar()] = (1 << (tcbt + 1)) | (m_texcoord_build_type[mt.ToScalar()] & 1); } | |||
void SetTexCoordBuildType(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type[mt.ToScalar()] = (1 << (tcbt.ToScalar() + 1)) | (m_texcoord_build_type[mt.ToScalar()] & 1); } | |||
TexCoordBuildType GetTexCoordBuildType(MeshType mt) | |||
{ | |||
uint32_t flag = (uint32_t)((m_texcoord_build_type[mt.ToScalar()] & ~(1)) >> 1); | |||
@@ -263,7 +392,7 @@ public: | |||
} | |||
// UV2 | |||
void SetTexCoordBuildType2(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type2[mt.ToScalar()] = (1 << (tcbt + 1)) | (m_texcoord_build_type2[mt.ToScalar()] & 1); } | |||
void SetTexCoordBuildType2(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type2[mt.ToScalar()] = (1 << (tcbt.ToScalar() + 1)) | (m_texcoord_build_type2[mt.ToScalar()] & 1); } | |||
TexCoordBuildType GetTexCoordBuildType2(MeshType mt) | |||
{ | |||
uint32_t flag = ((m_texcoord_build_type2[mt.ToScalar()] & ~(1)) >> 1); | |||
@@ -348,10 +477,10 @@ public: | |||
return res * m_texcoord_scale + m_texcoord_offset2; | |||
} | |||
inline bool IsEnabled(MeshBuildOperation mbo) { return (m_build_flags & mbo) != 0; } | |||
inline void Enable(MeshBuildOperation mbo) { m_build_flags |= mbo; } | |||
inline void Disable(MeshBuildOperation mbo) { m_build_flags &= ~mbo; } | |||
inline void Toggle(MeshBuildOperation mbo) { m_build_flags ^= mbo; } | |||
inline bool IsEnabled(MeshBuildOperation mbo) { return (m_build_flags & mbo.ToScalar()) != 0; } | |||
inline void Enable(MeshBuildOperation mbo) { m_build_flags |= mbo.ToScalar(); } | |||
inline void Disable(MeshBuildOperation mbo) { m_build_flags &= ~mbo.ToScalar(); } | |||
inline void Toggle(MeshBuildOperation mbo) { m_build_flags ^= mbo.ToScalar(); } | |||
inline void Set(MeshBuildOperation mbo, bool value) { if (value) Enable(mbo); else Disable(mbo); } | |||
public: | |||
@@ -372,17 +501,25 @@ public: | |||
uint32_t m_build_flags; | |||
}; | |||
/* A safe enum for VertexDictionnary operations. */ | |||
struct VDictType | |||
//VDictType -- A safe enum for VertexDictionnary operations. ------------------ | |||
struct VDictTypeBase : public StructSafeEnum | |||
{ | |||
DEF_VALUE | |||
ADD_VALUE_SET(DoesNotExist , -3) | |||
ADD_VALUE_SET(Alone , -2) | |||
ADD_VALUE_SET(Master , -1) | |||
END_E_VALUE | |||
LOL_DECLARE_ENUM_METHODS(VDictType) | |||
enum Type | |||
{ | |||
DoesNotExist = -3, | |||
Alone = -2, | |||
Master = -1, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[DoesNotExist] = "DoesNotExist"; | |||
enum_map[Alone] = "Alone"; | |||
enum_map[Master] = "Master"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<VDictTypeBase> VDictType; | |||
/* TODO : replace VDict by a proper Half-edge system */ | |||
//a class whose goal is to keep a list of the adjacent vertices for mesh operations purposes | |||
@@ -20,13 +20,28 @@ | |||
namespace lol | |||
{ | |||
// Utility enum for renderers | |||
LOL_SAFE_ENUM(MeshRender, | |||
NeedData, | |||
NeedConvert, | |||
CanRender, | |||
IgnoreRender, | |||
); | |||
//MeshRenderBase -------------------------------------------------------------- | |||
//Utility enum for renderers | |||
struct MeshRenderBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
NeedData, | |||
NeedConvert, | |||
CanRender, | |||
IgnoreRender, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[NeedData] = "NeedData"; | |||
enum_map[NeedConvert] = "NeedConvert"; | |||
enum_map[CanRender] = "CanRender"; | |||
enum_map[IgnoreRender] = "IgnoreRender"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<MeshRenderBase> MeshRender; | |||
//Vertex datas for easymesh vertex list. | |||
//TODO : <COORD, NORM, COLOR, UV> | |||
@@ -18,21 +18,29 @@ | |||
namespace lol | |||
{ | |||
extern map<int64_t, String> BuildEnumMap(char const *str, char const **custom); | |||
class Enum | |||
////MyType -------------------------------------------------------------------- | |||
//struct MyTypeBase : public StructSafeEnum | |||
//{ | |||
// enum Type | |||
// { | |||
// }; | |||
//protected: | |||
// virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
// { | |||
// enum_map[] = ""; | |||
// return true; | |||
// } | |||
//}; | |||
//typedef SafeEnum<MyTypeBase> MyType; | |||
//----------------------------------------------------------------------------- | |||
struct StructSafeEnum | |||
{ | |||
public: | |||
template<typename T> | |||
static String EnumToString(T const& parameter) | |||
{ | |||
UNUSED(parameter); | |||
// Create your own | |||
ASSERT(0); | |||
return String(); | |||
} | |||
protected: | |||
/* Convert to string stuff */ | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) { return false; } | |||
}; | |||
//----------------------------------------------------------------------------- | |||
template<typename BASE, typename T = typename BASE::Type> | |||
class SafeEnum : public BASE | |||
{ | |||
@@ -47,20 +55,20 @@ public: | |||
inline explicit SafeEnum(int i) : m_value(T(i)) {} | |||
inline Type ToScalar() const { return m_value; } | |||
/* Convert to string description */ | |||
inline class String ToString() const | |||
/* Convert to string stuff */ | |||
inline class String ToString() | |||
{ | |||
/* FIXME: we all know this isn’t thread safe. But is it really | |||
* a big deal? */ | |||
static map<int64_t, String> enum_map; | |||
static bool ready = false; | |||
if (!ready) | |||
enum_map = BuildEnumMap(BASE::GetDescription(), BASE::GetCustomString()); | |||
ready = true; | |||
if (enum_map.has_key((int64_t)m_value)) | |||
return enum_map[(int64_t)m_value]; | |||
if (ready || BuildEnumMap(enum_map)) | |||
{ | |||
ready = true; | |||
if (enum_map.has_key((int64_t)m_value)) | |||
return enum_map[(int64_t)m_value]; | |||
} | |||
return "<invalid enum>"; | |||
} | |||
@@ -91,92 +99,5 @@ public: | |||
} | |||
}; | |||
#define LOL_OPEN_SAFE_ENUM(name, ...) \ | |||
struct name ## Base \ | |||
{ \ | |||
enum Type {__VA_ARGS__}; \ | |||
protected: \ | |||
static inline char const *GetDescription() { return #__VA_ARGS__; } | |||
#define LOL_SAFE_ENUM_CUSTOM_TOSTRING(...) \ | |||
static inline char const **GetCustomString() \ | |||
{ \ | |||
static char const *custom_list[] = { __VA_ARGS__ }; \ | |||
return &custom_list[0]; \ | |||
} | |||
#define LOL_CLOSE_SAFE_ENUM(name) \ | |||
}; \ | |||
typedef SafeEnum<name ## Base> name; | |||
#define LOL_SAFE_ENUM(name, ...) \ | |||
struct name ## Base \ | |||
{ \ | |||
enum Type {__VA_ARGS__}; \ | |||
protected: \ | |||
static inline char const *GetDescription() { return #__VA_ARGS__; } \ | |||
static inline char const **GetCustomString() { return nullptr; } \ | |||
}; \ | |||
typedef SafeEnum<name ## Base> name; | |||
//-- STRUCT TEMPLATE: | |||
// enum E { | |||
// DEF_VALUE | |||
// ADD_VALUE(NEW_VALUE) | |||
// ADD_VALUE_SET(NEW_VALUE, VALUE_SET) | |||
// END_E_VALUE | |||
// DEF_TEXT | |||
// ADD_TEXT(NEW_VALUE) | |||
// END_TEXT | |||
// LOL_DECLARE_ENUM_METHODS(E) | |||
// }; | |||
#define LOL_DECLARE_ENUM_METHODS(E) \ | |||
inline E() : m_value(MAX) {} \ | |||
inline E(Value v) : m_value(v) {} \ | |||
inline E(const int8_t & v) : m_value((Value)v) {} \ | |||
inline E(const int16_t & v) : m_value((Value)v) {} \ | |||
inline E(const int32_t & v) : m_value((Value)v) {} \ | |||
inline E(const int64_t & v) : m_value((Value)v) {} \ | |||
inline E(const uint8_t & v) : m_value((Value)v) {} \ | |||
inline E(const uint16_t & v) : m_value((Value)v) {} \ | |||
inline E(const uint32_t & v) : m_value((Value)v) {} \ | |||
inline E(const uint64_t & v) : m_value((Value)v) {} \ | |||
inline operator Value() { return m_value; } \ | |||
inline int32_t I() { return (int32_t ) m_value; } \ | |||
inline int8_t I8() { return (int8_t ) m_value; } \ | |||
inline int16_t I16() { return (int16_t ) m_value; } \ | |||
inline int32_t I32() { return (int32_t ) m_value; } \ | |||
inline int64_t I64() { return (int64_t ) m_value; } \ | |||
inline uint32_t UI() { return (uint32_t) m_value; } \ | |||
inline uint8_t UI8() { return (uint8_t ) m_value; } \ | |||
inline uint16_t UI16() { return (uint16_t) m_value; } \ | |||
inline uint32_t UI32() { return (uint32_t) m_value; } \ | |||
inline uint64_t UI64() { return (uint64_t) m_value; } \ | |||
bool operator==(const E & v) { return m_value == v.m_value; } \ | |||
bool operator!=(const E & v) { return m_value != v.m_value; } \ | |||
bool operator<(const E & v) { return m_value < v.m_value; } \ | |||
bool operator>(const E & v) { return m_value > v.m_value; } \ | |||
bool operator<=(const E & v) { return m_value <= v.m_value; } \ | |||
bool operator>=(const E & v) { return m_value >= v.m_value; } | |||
#define DEF_VALUE enum Value { INVALID = -1, | |||
#define ADD_VALUE(NEW_VALUE) NEW_VALUE, | |||
#define ADD_VALUE_SET(NEW_VALUE, VALUE_SET) NEW_VALUE = VALUE_SET, | |||
#define END_E_VALUE MAX } m_value; | |||
#define DEF_TEXT \ | |||
inline String C() \ | |||
{ \ | |||
static const String text[] = { | |||
#define ADD_TEXT(NEW_TEXT) String(#NEW_TEXT), | |||
#define ADD_TEXT_PADDING String(""), | |||
#define END_TEXT \ | |||
}; \ | |||
if (m_value < 0 || m_value >= MAX) \ | |||
return "INVALID"; \ | |||
return text[m_value]; \ | |||
}; | |||
} /* namespace lol */ | |||
@@ -33,26 +33,57 @@ namespace lol | |||
* now there is only TexCoord and not TexCoord0 TexCoord1 etc. because | |||
* we can always reorganise the vertex declaration for the indices to | |||
* match. If the need arises these enums will be added. */ | |||
LOL_SAFE_ENUM(VertexUsage, | |||
Position, | |||
BlendWeight, | |||
BlendIndices, | |||
Normal, | |||
PointSize, | |||
TexCoord, | |||
TexCoordExt, | |||
Tangent, | |||
Binormal, | |||
TessFactor, | |||
PositionT, | |||
Color, | |||
Fog, | |||
Depth, | |||
Sample, | |||
MAX, | |||
); | |||
//Enum definitions ------------------------------------------------------------ | |||
//VertexUsageBase ------------------------------------------------------------- | |||
struct VertexUsageBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
Position, | |||
BlendWeight, | |||
BlendIndices, | |||
Normal, | |||
PointSize, | |||
TexCoord, | |||
TexCoordExt, | |||
Tangent, | |||
Binormal, | |||
TessFactor, | |||
PositionT, | |||
Color, | |||
Fog, | |||
Depth, | |||
Sample, | |||
MAX, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Position] = "Position"; | |||
enum_map[BlendWeight] = "BlendWeight"; | |||
enum_map[BlendIndices] = "BlendIndices"; | |||
enum_map[Normal] = "Normal"; | |||
enum_map[PointSize] = "PointSize"; | |||
enum_map[TexCoord] = "TexCoord"; | |||
enum_map[TexCoordExt] = "TexCoordExt"; | |||
enum_map[Tangent] = "Tangent"; | |||
enum_map[Binormal] = "Binormal"; | |||
enum_map[TessFactor] = "TessFactor"; | |||
enum_map[PositionT] = "PositionT"; | |||
enum_map[Color] = "Color"; | |||
enum_map[Fog] = "Fog"; | |||
enum_map[Depth] = "Depth"; | |||
enum_map[Sample] = "Sample"; | |||
enum_map[MAX] = "MAX"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<VertexUsageBase> VertexUsage; | |||
//----------------------------------------------------------------------------- | |||
//Enum definitions | |||
//----------------------------------------------------------------------------- | |||
//ShaderVariableBase ---------------------------------------------------------- | |||
struct ShaderVariableBase | |||
{ | |||
enum Type | |||
@@ -68,11 +99,19 @@ struct ShaderVariableBase | |||
MAX | |||
}; | |||
protected: | |||
static inline char const *GetDescription() { return nullptr; } | |||
static inline char const **GetCustomString() { return nullptr; } | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Attribute] = "Attribute"; | |||
enum_map[Uniform] = "Uniform"; | |||
enum_map[Varying] = "Varying"; | |||
enum_map[InOut] = "InOut"; | |||
enum_map[MAX] = "MAX"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<ShaderVariableBase> ShaderVariable; | |||
//ShaderProgramBase ----------------------------------------------------------- | |||
struct ShaderProgramBase | |||
{ | |||
enum Type | |||
@@ -84,8 +123,14 @@ struct ShaderProgramBase | |||
MAX | |||
}; | |||
protected: | |||
static inline char const *GetDescription() { return nullptr; } | |||
static inline char const **GetCustomString() { return nullptr; } | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Geometry] = "Geometry"; | |||
enum_map[Vertex] = "Vertex"; | |||
enum_map[Pixel] = "Pixel"; | |||
enum_map[MAX] = "MAX"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<ShaderProgramBase> ShaderProgram; | |||
@@ -39,13 +39,29 @@ private: | |||
/* A safe enum to indicate what kind of primitive to draw. Used in | |||
* VertexDeclaration::DrawElements() for instance. */ | |||
LOL_SAFE_ENUM(MeshPrimitive, | |||
Triangles, | |||
TriangleStrips, | |||
TriangleFans, | |||
Points, | |||
Lines, | |||
); | |||
//MeshPrimitiveBase -- A safe enum for Primitive edge face. ------------------- | |||
struct MeshPrimitiveBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
Triangles, | |||
TriangleStrips, | |||
TriangleFans, | |||
Points, | |||
Lines, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Triangles] = "Triangles"; | |||
enum_map[TriangleStrips] = "TriangleStrips"; | |||
enum_map[TriangleFans] = "TriangleFans"; | |||
enum_map[Points] = "Points"; | |||
enum_map[Lines] = "Lines"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<MeshPrimitiveBase> MeshPrimitive; | |||
class VertexStreamBase | |||
{ | |||
@@ -27,28 +27,43 @@ namespace lol | |||
{ | |||
//AxisBase -------------------------------------------------------------------- | |||
struct AxisBase | |||
struct AxisBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
X = 0, Y, Z, MAX, XY = 2, XYZ = 3, | |||
}; | |||
protected: | |||
static inline char const *GetDescription() { return "X,Y,Z,MAX,XY,XYZ"; } | |||
static inline char const **GetCustomString() { return nullptr; } | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[X] = "X"; | |||
enum_map[Y] = "Y"; | |||
enum_map[Z] = "Z"; | |||
enum_map[MAX] = "MAX"; | |||
enum_map[XY] = "XY"; | |||
enum_map[XYZ] = "XYZ"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<AxisBase> Axis; | |||
//DirectionBase --------------------------------------------------------------- | |||
struct DirectionBase | |||
struct DirectionBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
Up = 0, Down, Left, Right, MAX, | |||
}; | |||
protected: | |||
static inline char const *GetDescription() { return "Up,Down,Left,Right,MAX"; } | |||
static inline char const **GetCustomString() { return nullptr; } | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Up] = "Up"; | |||
enum_map[Down] = "Down"; | |||
enum_map[Left] = "Left"; | |||
enum_map[Right] = "Right"; | |||
enum_map[MAX] = "MAX"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<DirectionBase> Direction; | |||
@@ -265,18 +280,30 @@ bool TestRayVsTriangle(vec3 const &ray_point, vec3 const &ray_dir, | |||
vec3 const &tri_p0, vec3 const &tri_p1, vec3 const &tri_p2, | |||
vec3 &vi); | |||
struct RayIntersect | |||
//RayIntersect ---------------------------------------------------------------- | |||
struct RayIntersectBase : public StructSafeEnum | |||
{ | |||
DEF_VALUE | |||
ADD_VALUE(Nothing) | |||
ADD_VALUE(All) | |||
ADD_VALUE(None) | |||
ADD_VALUE(P0) | |||
ADD_VALUE(P1) | |||
END_E_VALUE | |||
LOL_DECLARE_ENUM_METHODS(RayIntersect) | |||
enum Type | |||
{ | |||
Nothing, | |||
All, | |||
None, | |||
P0, | |||
P1, | |||
}; | |||
//LOL_DECLARE_ENUM_METHODS(RayIntersectBase) | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Nothing] = "Nothing"; | |||
enum_map[All] = "All"; | |||
enum_map[None] = "None"; | |||
enum_map[P0] = "P0"; | |||
enum_map[P1] = "P1"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<RayIntersectBase> RayIntersect; | |||
#define RAY_ISECT_NOTHING 0 | |||
#define RAY_ISECT_ALL 1 | |||
@@ -322,12 +349,24 @@ bool TestRayVsPlane(const TV &ray_p0, const TV &ray_p1, | |||
return true; | |||
} | |||
/* A safe enum for Primitive edge face. */ | |||
LOL_SAFE_ENUM(PlaneIntersection, | |||
Back, | |||
Front, | |||
Plane, | |||
); | |||
//PlaneIntersectionBase ------------------------------------------------------- | |||
struct PlaneIntersectionBase : public StructSafeEnum | |||
{ | |||
/* A safe enum for Primitive edge face. */ | |||
enum Type | |||
{ | |||
Back, Front, Plane, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Back] = "Back"; | |||
enum_map[Front] = "Front"; | |||
enum_map[Plane] = "Plane"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<PlaneIntersectionBase> PlaneIntersection; | |||
//Point/Plane : Normal must be given normalized. | |||
template <typename TV> | |||
@@ -20,18 +20,47 @@ | |||
namespace lol | |||
{ | |||
LOL_SAFE_ENUM(FileAccess, | |||
Read = 0, | |||
Write | |||
); | |||
LOL_SAFE_ENUM(StreamType, | |||
StdIn, | |||
StdOut, | |||
StdErr, | |||
File, | |||
FileBinary | |||
); | |||
//FileAccessBase -------------------------------------------------------------- | |||
struct FileAccessBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
Read = 0, | |||
Write | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[Read] = "Read"; | |||
enum_map[Write] = "Write"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<FileAccessBase> FileAccess; | |||
//StreamTypeBase -------------------------------------------------------------- | |||
struct StreamTypeBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
StdIn, | |||
StdOut, | |||
StdErr, | |||
File, | |||
FileBinary | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[StdIn] = "StdIn"; | |||
enum_map[StdOut] = "StdOut"; | |||
enum_map[StdErr] = "StdErr"; | |||
enum_map[File] = "File"; | |||
enum_map[FileBinary] = "FileBinary"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<StreamTypeBase> StreamType; | |||
class File | |||
{ | |||
@@ -46,25 +46,50 @@ public: | |||
virtual ~thread() {} | |||
}; | |||
struct ThreadStatus | |||
//ThreadStatus ---------------------------------------------------------------- | |||
struct ThreadStatusBase : public StructSafeEnum | |||
{ | |||
DEF_VALUE | |||
ADD_VALUE(NOTHING) | |||
ADD_VALUE(THREAD_STARTED) | |||
ADD_VALUE(THREAD_STOPPED) | |||
END_E_VALUE | |||
LOL_DECLARE_ENUM_METHODS(ThreadStatus) | |||
enum Type | |||
{ | |||
NOTHING, | |||
THREAD_STARTED, | |||
THREAD_STOPPED, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[NOTHING] = "NOTHING"; | |||
enum_map[THREAD_STARTED] = "THREAD_STARTED"; | |||
enum_map[THREAD_STOPPED] = "THREAD_STOPPED"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<ThreadStatusBase> ThreadStatus; | |||
LOL_SAFE_ENUM(ThreadJobType, | |||
NONE, | |||
WORK_TODO, | |||
WORK_DONE, | |||
WORK_FAILED, | |||
WORK_FETCHED, | |||
THREAD_STOP | |||
); | |||
struct ThreadJobTypeBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
NONE, | |||
WORK_TODO, | |||
WORK_DONE, | |||
WORK_FAILED, | |||
WORK_FETCHED, | |||
THREAD_STOP | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[NONE] = "NONE"; | |||
enum_map[WORK_TODO] = "WORK_TODO"; | |||
enum_map[WORK_DONE] = "WORK_DONE"; | |||
enum_map[WORK_FAILED] = "WORK_FAILED"; | |||
enum_map[WORK_FETCHED] = "WORK_FETCHED"; | |||
enum_map[THREAD_STOP] = "THREAD_STOP"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<ThreadJobTypeBase> ThreadJobType; | |||
class ThreadJob | |||
{ | |||
@@ -63,7 +63,7 @@ bool MessageService::Send(MessageBucket id, const String& message) | |||
{ | |||
if (g_messageservice) | |||
{ | |||
ASSERT(0 <= id && (int)id < g_messageservice->m_bucket.Count()); | |||
ASSERT(0 <= id.ToScalar() && id.ToScalar() < g_messageservice->m_bucket.Count()); | |||
return g_messageservice->Send(id, message.C()); | |||
} | |||
return false; | |||
@@ -73,9 +73,9 @@ bool MessageService::Send(MessageBucket id, const char* message) | |||
{ | |||
if (g_messageservice) | |||
{ | |||
ASSERT(0 <= id && (int)id < g_messageservice->m_bucket.Count()); | |||
ASSERT(0 <= id.ToScalar() && id.ToScalar() < g_messageservice->m_bucket.Count()); | |||
MessageService& g = *g_messageservice; | |||
array<MessageList>& bucket = g.m_bucket[id]; | |||
array<MessageList>& bucket = g.m_bucket[id.ToScalar()]; | |||
bucket << MessageList(time(nullptr), String(message)); | |||
return true; | |||
} | |||
@@ -87,7 +87,7 @@ bool MessageService::FetchFirst(MessageBucket id, String& message) | |||
{ | |||
if (g_messageservice) | |||
{ | |||
ASSERT(0 <= id && (int)id < g_messageservice->m_bucket.Count()); | |||
ASSERT(0 <= id.ToScalar() && id.ToScalar() < g_messageservice->m_bucket.Count()); | |||
time_t timestamp; | |||
return g_messageservice->FetchFirst(id, message, timestamp); | |||
} | |||
@@ -98,9 +98,9 @@ bool MessageService::FetchFirst(MessageBucket id, String& message, time_t& times | |||
{ | |||
if (g_messageservice) | |||
{ | |||
ASSERT(0 <= id && (int)id < g_messageservice->m_bucket.Count()); | |||
ASSERT(0 <= id.ToScalar() && id.ToScalar() < g_messageservice->m_bucket.Count()); | |||
MessageService& g = *g_messageservice; | |||
array<MessageList>& bucket = g.m_bucket[id]; | |||
array<MessageList>& bucket = g.m_bucket[id.ToScalar()]; | |||
if (bucket.Count()) | |||
{ | |||
@@ -118,7 +118,7 @@ bool MessageService::FetchAll(MessageBucket id, String& message) | |||
{ | |||
if (g_messageservice) | |||
{ | |||
ASSERT(0 <= id && (int)id < g_messageservice->m_bucket.Count()); | |||
ASSERT(0 <= id.ToScalar() && id.ToScalar() < g_messageservice->m_bucket.Count()); | |||
time_t timestamp; | |||
return g_messageservice->FetchAll(id, message, timestamp); | |||
} | |||
@@ -129,9 +129,9 @@ bool MessageService::FetchAll(MessageBucket id, String& message, time_t& first_t | |||
{ | |||
if (g_messageservice) | |||
{ | |||
ASSERT(0 <= id && (int)id < g_messageservice->m_bucket.Count()); | |||
ASSERT(0 <= id.ToScalar() && id.ToScalar() < g_messageservice->m_bucket.Count()); | |||
MessageService& g = *g_messageservice; | |||
array<MessageList>& bucket = g.m_bucket[id]; | |||
array<MessageList>& bucket = g.m_bucket[id.ToScalar()]; | |||
message = String(""); | |||
if (bucket.Count()) | |||
@@ -19,27 +19,47 @@ | |||
namespace lol | |||
{ | |||
// Utility enum for message service | |||
struct MessageBucket | |||
//MessageBucket -- Utility enum for message service --------------------------- | |||
struct MessageBucketBase : public StructSafeEnum | |||
{ | |||
DEF_VALUE | |||
ADD_VALUE(AppIn) | |||
ADD_VALUE(AppOut) | |||
ADD_VALUE(Bckt0) | |||
ADD_VALUE(Bckt1) | |||
ADD_VALUE(Bckt2) | |||
ADD_VALUE(Bckt3) | |||
ADD_VALUE(Bckt4) | |||
ADD_VALUE(Bckt5) | |||
ADD_VALUE(Bckt6) | |||
ADD_VALUE(Bckt7) | |||
ADD_VALUE(Bckt8) | |||
ADD_VALUE(Bckt9) | |||
END_E_VALUE | |||
LOL_DECLARE_ENUM_METHODS(MessageBucket) | |||
enum Type | |||
{ | |||
AppIn, | |||
AppOut, | |||
Bckt0, | |||
Bckt1, | |||
Bckt2, | |||
Bckt3, | |||
Bckt4, | |||
Bckt5, | |||
Bckt6, | |||
Bckt7, | |||
Bckt8, | |||
Bckt9, | |||
MAX | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[AppIn] = "AppIn"; | |||
enum_map[AppOut] = "AppOut"; | |||
enum_map[Bckt0] = "Bckt0"; | |||
enum_map[Bckt1] = "Bckt1"; | |||
enum_map[Bckt2] = "Bckt2"; | |||
enum_map[Bckt3] = "Bckt3"; | |||
enum_map[Bckt4] = "Bckt4"; | |||
enum_map[Bckt5] = "Bckt5"; | |||
enum_map[Bckt6] = "Bckt6"; | |||
enum_map[Bckt7] = "Bckt7"; | |||
enum_map[Bckt8] = "Bckt8"; | |||
enum_map[Bckt9] = "Bckt9"; | |||
enum_map[MAX] = "MAX"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<MessageBucketBase> MessageBucket; | |||
//Message list container with time in it | |||
struct MessageList | |||
@@ -23,11 +23,24 @@ lolunit_declare_fixture(EnumTest) | |||
lolunit_declare_test(EnumToString) | |||
{ | |||
LOL_SAFE_ENUM(MyEnum, | |||
First = -10, | |||
Second, | |||
Third = 5, | |||
); | |||
struct MyEnumBase : public StructSafeEnum | |||
{ | |||
enum Type | |||
{ | |||
First = -10, | |||
Second, | |||
Third = 5, | |||
}; | |||
protected: | |||
virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | |||
{ | |||
enum_map[First] = "First"; | |||
enum_map[Second] = "Second"; | |||
enum_map[Third] = "Third"; | |||
return true; | |||
} | |||
}; | |||
typedef SafeEnum<MyEnumBase> MyEnum; | |||
MyEnum e = MyEnum::First; | |||
lolunit_assert(e.ToString() == "First"); | |||
@@ -60,7 +60,7 @@ template< class T > inline int GetRandom(array<T> src) | |||
return (r_total > .0f)?(r_j):(-1); | |||
} | |||
// Gets the value for the given LOL_SAFE_ENUM type. | |||
// Gets the value for the given enum type. | |||
template<class T> inline T FindValue(const char* name) | |||
{ | |||
String n = name; | |||