@@ -17,55 +17,6 @@ namespace lol | |||||
* Safe enum helpers | * 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 */ | } /* namespace lol */ | ||||
@@ -24,22 +24,54 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
//CSGUsage -------------------------------------------------------------------- | |||||
/* A safe enum for MeshCSG operations. */ | /* 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 | class EasyMesh : public Mesh | ||||
{ | { | ||||
@@ -20,127 +20,256 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
struct MeshBuildOperation | |||||
//MeshBuildOperation ---------------------------------------------------------- | |||||
struct MeshBuildOperationBase : public StructSafeEnum | |||||
{ | { | ||||
DEF_VALUE | |||||
enum Type | |||||
{ | |||||
//When this flag is up, negative scaling will not invert faces. | //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 | //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 | class EasyMeshBuildData | ||||
{ | { | ||||
@@ -175,7 +304,7 @@ public: | |||||
inline vec2 &TexCoordScale2() { return m_texcoord_scale2; } | inline vec2 &TexCoordScale2() { return m_texcoord_scale2; } | ||||
//UV1 | //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) | TexCoordBuildType GetTexCoordBuildType(MeshType mt) | ||||
{ | { | ||||
uint32_t flag = (uint32_t)((m_texcoord_build_type[mt.ToScalar()] & ~(1)) >> 1); | uint32_t flag = (uint32_t)((m_texcoord_build_type[mt.ToScalar()] & ~(1)) >> 1); | ||||
@@ -263,7 +392,7 @@ public: | |||||
} | } | ||||
// UV2 | // 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) | TexCoordBuildType GetTexCoordBuildType2(MeshType mt) | ||||
{ | { | ||||
uint32_t flag = ((m_texcoord_build_type2[mt.ToScalar()] & ~(1)) >> 1); | uint32_t flag = ((m_texcoord_build_type2[mt.ToScalar()] & ~(1)) >> 1); | ||||
@@ -348,10 +477,10 @@ public: | |||||
return res * m_texcoord_scale + m_texcoord_offset2; | 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); } | inline void Set(MeshBuildOperation mbo, bool value) { if (value) Enable(mbo); else Disable(mbo); } | ||||
public: | public: | ||||
@@ -372,17 +501,25 @@ public: | |||||
uint32_t m_build_flags; | 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 */ | /* 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 | //a class whose goal is to keep a list of the adjacent vertices for mesh operations purposes | ||||
@@ -20,13 +20,28 @@ | |||||
namespace lol | 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. | //Vertex datas for easymesh vertex list. | ||||
//TODO : <COORD, NORM, COLOR, UV> | //TODO : <COORD, NORM, COLOR, UV> | ||||
@@ -18,21 +18,29 @@ | |||||
namespace lol | 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> | template<typename BASE, typename T = typename BASE::Type> | ||||
class SafeEnum : public BASE | class SafeEnum : public BASE | ||||
{ | { | ||||
@@ -47,20 +55,20 @@ public: | |||||
inline explicit SafeEnum(int i) : m_value(T(i)) {} | inline explicit SafeEnum(int i) : m_value(T(i)) {} | ||||
inline Type ToScalar() const { return m_value; } | 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 | /* FIXME: we all know this isn’t thread safe. But is it really | ||||
* a big deal? */ | * a big deal? */ | ||||
static map<int64_t, String> enum_map; | static map<int64_t, String> enum_map; | ||||
static bool ready = false; | 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>"; | 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 */ | } /* namespace lol */ | ||||
@@ -33,26 +33,57 @@ namespace lol | |||||
* now there is only TexCoord and not TexCoord0 TexCoord1 etc. because | * now there is only TexCoord and not TexCoord0 TexCoord1 etc. because | ||||
* we can always reorganise the vertex declaration for the indices to | * we can always reorganise the vertex declaration for the indices to | ||||
* match. If the need arises these enums will be added. */ | * 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 | struct ShaderVariableBase | ||||
{ | { | ||||
enum Type | enum Type | ||||
@@ -68,11 +99,19 @@ struct ShaderVariableBase | |||||
MAX | MAX | ||||
}; | }; | ||||
protected: | 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; | typedef SafeEnum<ShaderVariableBase> ShaderVariable; | ||||
//ShaderProgramBase ----------------------------------------------------------- | |||||
struct ShaderProgramBase | struct ShaderProgramBase | ||||
{ | { | ||||
enum Type | enum Type | ||||
@@ -84,8 +123,14 @@ struct ShaderProgramBase | |||||
MAX | MAX | ||||
}; | }; | ||||
protected: | 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; | typedef SafeEnum<ShaderProgramBase> ShaderProgram; | ||||
@@ -39,13 +39,29 @@ private: | |||||
/* A safe enum to indicate what kind of primitive to draw. Used in | /* A safe enum to indicate what kind of primitive to draw. Used in | ||||
* VertexDeclaration::DrawElements() for instance. */ | * 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 | class VertexStreamBase | ||||
{ | { | ||||
@@ -27,28 +27,43 @@ namespace lol | |||||
{ | { | ||||
//AxisBase -------------------------------------------------------------------- | //AxisBase -------------------------------------------------------------------- | ||||
struct AxisBase | |||||
struct AxisBase : public StructSafeEnum | |||||
{ | { | ||||
enum Type | enum Type | ||||
{ | { | ||||
X = 0, Y, Z, MAX, XY = 2, XYZ = 3, | X = 0, Y, Z, MAX, XY = 2, XYZ = 3, | ||||
}; | }; | ||||
protected: | 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; | typedef SafeEnum<AxisBase> Axis; | ||||
//DirectionBase --------------------------------------------------------------- | //DirectionBase --------------------------------------------------------------- | ||||
struct DirectionBase | |||||
struct DirectionBase : public StructSafeEnum | |||||
{ | { | ||||
enum Type | enum Type | ||||
{ | { | ||||
Up = 0, Down, Left, Right, MAX, | Up = 0, Down, Left, Right, MAX, | ||||
}; | }; | ||||
protected: | 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; | 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 const &tri_p0, vec3 const &tri_p1, vec3 const &tri_p2, | ||||
vec3 &vi); | 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_NOTHING 0 | ||||
#define RAY_ISECT_ALL 1 | #define RAY_ISECT_ALL 1 | ||||
@@ -322,12 +349,24 @@ bool TestRayVsPlane(const TV &ray_p0, const TV &ray_p1, | |||||
return true; | 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. | //Point/Plane : Normal must be given normalized. | ||||
template <typename TV> | template <typename TV> | ||||
@@ -20,18 +20,47 @@ | |||||
namespace lol | 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 | class File | ||||
{ | { | ||||
@@ -46,25 +46,50 @@ public: | |||||
virtual ~thread() {} | 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 | class ThreadJob | ||||
{ | { | ||||
@@ -63,7 +63,7 @@ bool MessageService::Send(MessageBucket id, const String& message) | |||||
{ | { | ||||
if (g_messageservice) | 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 g_messageservice->Send(id, message.C()); | ||||
} | } | ||||
return false; | return false; | ||||
@@ -73,9 +73,9 @@ bool MessageService::Send(MessageBucket id, const char* message) | |||||
{ | { | ||||
if (g_messageservice) | 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; | 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)); | bucket << MessageList(time(nullptr), String(message)); | ||||
return true; | return true; | ||||
} | } | ||||
@@ -87,7 +87,7 @@ bool MessageService::FetchFirst(MessageBucket id, String& message) | |||||
{ | { | ||||
if (g_messageservice) | 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; | time_t timestamp; | ||||
return g_messageservice->FetchFirst(id, message, 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) | 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; | MessageService& g = *g_messageservice; | ||||
array<MessageList>& bucket = g.m_bucket[id]; | |||||
array<MessageList>& bucket = g.m_bucket[id.ToScalar()]; | |||||
if (bucket.Count()) | if (bucket.Count()) | ||||
{ | { | ||||
@@ -118,7 +118,7 @@ bool MessageService::FetchAll(MessageBucket id, String& message) | |||||
{ | { | ||||
if (g_messageservice) | 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; | time_t timestamp; | ||||
return g_messageservice->FetchAll(id, message, 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) | 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; | MessageService& g = *g_messageservice; | ||||
array<MessageList>& bucket = g.m_bucket[id]; | |||||
array<MessageList>& bucket = g.m_bucket[id.ToScalar()]; | |||||
message = String(""); | message = String(""); | ||||
if (bucket.Count()) | if (bucket.Count()) | ||||
@@ -19,27 +19,47 @@ | |||||
namespace lol | 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 | //Message list container with time in it | ||||
struct MessageList | struct MessageList | ||||
@@ -23,11 +23,24 @@ lolunit_declare_fixture(EnumTest) | |||||
lolunit_declare_test(EnumToString) | 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; | MyEnum e = MyEnum::First; | ||||
lolunit_assert(e.ToString() == "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); | 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) | template<class T> inline T FindValue(const char* name) | ||||
{ | { | ||||
String n = name; | String n = name; | ||||