| @@ -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; | ||||