Mojoc strictly follow this code style to ensure the C code readability and uniformity. This code style is important to understanding how Mojoc works.
- Basic Naming
- Variable Naming
- Abbreviated Naming
- Goto Label Naming
- Enum Naming
- Function Naming
- Struct Naming
- Macro Naming
- Array Naming
- Others Naming
The basic use CamelCased, this is BigCamelCased, this is smallCamelCased.
-
The common variable use
smallCamelCased.int keyLength; int valueTypeSize; SkeletonBone* bone; SkeletonBoneData* boneData; Drawable* drawable;
-
The const use
smallCamelCased.static const char* ids[AudioId_Length]; static const char* saveDataFileName = "MojocSaveDataFile"; static const int bezierSize = (BEZIER_SEGMENTS + 1) * 2 - 1; static const float subDivPre = subDivStep3 / pre5;
-
The bool variable (including member variables) begin with prefix
is, then the whole issmallCamelCased.SLboolean isLoopEnabled; bool isFound; bool isRemoved; particle->isActive
-
The singleton variable begin with prefix
A, then the whole isBigCamelCased.extern struct AComponent AComponent [1]; extern struct ADrawable ADrawable [1]; extern struct AParticle AParticle [1]; extern struct AApplication AApplication[1];
-
The variable of function get out argument begin with prefix
out, then the whole issmallCamelCased.void (*OnSaveData)(void** outSaveData, int* outLength); void (*Inverse) (Matrix4* matrix4, Matrix4* outInverse); void Init (int valueTypeSize, ArrayIntMap* outArrayIntMap);
-
The variable of function pointer use
BigCamelCased.typedef struct { void (*OnPause) (void); void (*OnResume) (void); void (*OnDestroy)(void); } ApplicationCallbacks; typedef float (*TweenActionValueOnGet)(void* target); typedef void (*TweenActionValueOnSet)(void* target, float value); typedef struct { TweenActionValueOnGet OnGet; TweenActionValueOnSet OnSet; } TweenActionValueGetSet;
- The abbreviated words use
uppercasewords orlowercasewords.typedef struct { } RGB; RGB rgb; RGB myRGB; RGB rgbDatas[10]; RGB myRGBData; void SetRGB (RGB* rgb); void RGBSet (RGB* rgb); void SetRGBData(RGB* rgb);
-
The goto label tag use
BigCamelCased. But goto label address use common variable rule.goto ParseArrayEnd; goto ParseObjectEnd; goto UseVBO; goto UseVAO; goto *coroutine->step;
-
The enum use
BigCamelCased, and must have prefix separated by_.enum { HeroState_Stand, HeroState_DieOver, }; enum { CollisionGroup_HeroBody = 1, CollisionGroup_HeroAttack = 1 << 1, };
-
The typedef enum use
BigCamelCased, and must have prefix separated by_.typedef enum { FontTextAlignment_HorizontalLeft, FontTextAlignment_HorizontalRight, FontTextAlignment_VerticalTop, FontTextAlignment_VerticalBottom, } FontTextAlignment; typedef enum { InputTouchType_Up = 1, InputTouchType_Down = 2, InputTouchType_Move = 3, InputTouchType_Cancel = 4, } InputTouchType;
-
The global function and global inline function use
BigCamelCased, and must have prefix separated by_.extern void Application_Main (void); static inline void AApplication_AppendChild(Component* child); static inline float AGLTool_ToGLWidth (float screenWidth); static inline float AMath_Random (void);
-
The local function and local inline function use
BigCamelCased;static void LoadingRun (Coroutine* coroutine); static inline float GetWorldScaleY(Drawable* drawable);
-
The typedef function use
BigCamelCased, and must have prefix.typedef float (*TweenActionValueOnGet)(void* target); typedef void (*TweenActionValueOnSet)(void* target, float value); typedef void (*CoroutineRun) (Coroutine* coroutine);
-
The function operation may not succeed, begin with prefix
Try, then the whole isBigCamelCased.void* (*TryPut) (ArrayIntMap* arrayIntMap, intptr_t key, void* valuePtr); bool (*TryRemove)(ArrayIntMap* arrayIntMap, intptr_t key);
-
The function return boolean which is operation purpose, begin with prefix
IsorTestorCheck, then the whole isBigCamelCased.bool (*IsContains) (ArrayIntSet* arrayIntSet, intptr_t element); bool (*TestPolygonPoint) (Array(float)* vertexArr, float x, float y); bool ADrawable_CheckVisible(Drawable* drawable);
-
The function begin with prefix
Release, means free the struct members memory, after then the pointer needs to be freed manually.void (*Release) (Mesh* mesh); void (*ReleaseQuad)(DrawAtlas* drawAtlas, SubMesh* subMesh);
-
The function begin with the prefix
Destroy, means free the struct members and self memory, after then the pointer cannot be used.void (*Destroy)(void); void (*Destroy)(Texture* texture);
-
The function begin with prefix
Create, means return the malloc pointer, so useReleaseandfreeorDestroyfor delete.ArrayList* (*Create) (int elementTypeSize); ArrayList* (*CreateWithSize) (int elementTypeSize, int size); ArrayList* (*CreateWithCapacity)(int elementTypeSize, int capacity);
-
The function begin with prefix
Init, means the pointer members memory on stack, so useReleaseorDestroyfor delete memory.void (*Init) (int elementTypeSize, ArrayList* outArrayList); void (*InitWithSize) (int elementTypeSize, int size, ArrayList* outArrayList); void (*InitWithCapacity)(int elementTypeSize, int capacity, ArrayList* outArrayList);
-
The function if no args then type
voidarg.Drawable* (*Create) (void); int (*GetDrawCalls)(void); struct ATweenTool* (*AddAction) (void);
-
The function have suffix
Impl, means the function must be implemented in.cfile.extern void Application_MainImpl(void); struct ATweenActionValueGetSetImpl { TweenActionValueGetSet moveX [1]; TweenActionValueGetSet moveY [1]; TweenActionValueGetSet scaleX [1]; TweenActionValueGetSet scaleY [1]; TweenActionValueGetSet rotateZ[1]; TweenActionValueGetSet fadeTo [1]; }; extern struct ATweenActionValueGetSetImpl ATweenActionValueGetSetImpl[1];
- The struct (union) or typedef struct (union), use
BigCamelCased.
-
The head define macro, use
uppercasewords separated by_and have suffixH.#ifndef STYLE_GUIDE_H #define STYLE_GUIDE_H
-
The macro without parameters, use
uppercasewords separated by_.#define MATH_PI 3.141592653589793 #define MATH_2PI 6.283185307179586 #define MATH_PI2 1.570796326794897
-
The macro with parameters, use
BigCamelCased, and must have prefix separated by_.#define AMath_Min(x, y) #define AStruct_GetParent2(memberPtr, structType) #define ACoroutine_YieldFrames(waitFrames)
-
The local macro in
.cfile, useBigCamelCased, no prefix required, and must#undefin same.cfile.#define CheckIndex(tag, index) #define CheckCallback(callback) #define CheckFingerId(tag, fingerId) #undef CheckIndex #undef CheckCallback #undef CheckFingerId
-
The macro type parameter must have suffix
Type.#define ArrayList(ElementType) #define AArrayIntSet_Init(ElementType, increase) #define AArrayList_Pop(arrayList, ElementType)
-
Array as parameter, use
[]form, not*form.void (*SetTimeToBuff)(char buff [], int seconds); int (*BinarySearch) (const float values[], int valuesLength, float target);
-
Array as parameter, use
[length]form, if the length is clear.void (*GetLanguageCode)(char outLanguageCode[2]);
-
Array variable use
[length]form, if the length is clear.extern struct AMesh AMesh[1]; struct AGLInfo { GLfloat pointSizeRange[2]; GLfloat lineWidthRange[2]; } ArrayIntSet set[1] = AArrayIntSet_Init(ElementType, increase);
-
Array composite literal use
[length]form, if the length is clear.#define AColor_Make(r, g, b, a) (Color[1]) {{r, g, b, a }} #define AMatrix_Make(...) (Matrix4[1]) {{__VA_ARGS__}} InitSprite(outSprite, texture, (Array(Quad)[1]) {quad, 1});
- The following cases use
BigCamelCased.- File Name
- Folder Name
- Resource Name
- Use
4 spaceskey indent, nottabkey. - One line
120 chars. - The pointer
*on type name side.int* p1; int** p2 = &p1; void* Function(char* str);
- In code block try
verticalalignment.See all the examples above.
-
The operator at least
one spaceon both sides.vertexX + (y - vertexY) / (preY - vertexY) * (preX - vertexX)
-
The
if, while, for, switch, must have{}, andone spacewith().if (...) { } while (...) { } for (...) { } switch (...) { }
-
The case
4 spacesindent, and the break4 spacesindent in switch case.switch (...) { case 0: break; case 1: { break; } }
-
The goto label indent with the current line.
static void Function() { goto Label: Label1: int a; Label2: int b; Label3: int c; }
-
The conditional compile, indent with the current line.
typedef struct { Sprite sprite[1]; PhysicsBody* body; Enemy* enemy; ArrowHitType hitType; #ifdef APP_DEBUG Drawable debugDrawable[1]; #endif } Arrow; void Function() { int a; #ifdef APP_DEBUG int b; #endif } #ifdef APP_DEBUG Drawable debugDrawable[1]; #endif
-
The
{}and{{}}vertical alignment or on the same line.{ ... } // vertical alignment {{ ... }} // vertical alignment {...} // same line {{...}} // same line -
The
{{}}used for array init.struct AGameMap AGameMap[1] = {{ .Init = Init, .Run = Run, .RandomMap = RandomMap, }}; Vector3 vector[1] = {{ drawable->modelMatrix->m0, drawable->modelMatrix->m1, drawable->modelMatrix->m2, }}; #define AMatrix_Make(...) (Matrix4[1]) {{__VA_ARGS__}}
-
The
()if need to wrap, then vertical alignment.AMath_Max ( animationData->duration, AArray_Get ( deformTimeline->frameArr, deformTimeline->frameArr->length - 1, float ) ); static void ReadAnimationDeform ( SkeletonData* skeletonData, JsonObject* jsonDeform, SkeletonAnimationData* animationData, ArrayList* skeletonTimelineArr ) { }
-
Empty
two linesaround functions.static int a = 100; static void Function1() { } static inline void Function2() { } struct A { }
-
Empty
two linesbetween different contents.#include "AAA.h" #include "BBB.h" typedef float (*Function1)(void* target); typedef float (*Function2)(); struct A { } struct B { } extern struct B B[1];
-
Outside function body use
/***/./** * Comment struct */ struct A { /** * Comment property */ int a; /** * Comment function */ void (*Function)(); }
-
In function body use
//.void Function() { // comment in function body. }
-
Comment block or multiline code.
/* This is means comment block or multiline code. */ /* This is means comment block or multiline code. */
-
Use comment line to separate different logical related contents.
void Function1(); //-------------------- void Function2(); void Function3() { int a; //---------------- int b; }
-
Use comment line to mark macros
#ifdef Platform_Xor multiple#endif.#ifndef PLATFORM_H #define PLATFORM_H //------------------------ #ifdef IS_PLATFORM_ANDROID //------------------------ // platform codes. //--------------------------- #endif // IS_PLATFORM_ANDROID //--------------------------- //------------------ #endif // PLATFORM_H //------------------
-
The parameter macro, used only when
inlinefunction not working.-
such as shortcut parameters of function call.
/** * Shortcut of AArrayList->GetAdd. * return element. */ #define AArrayList_GetAdd(arrayList, ElementType) \ (*(ElementType*) AArrayList->GetAdd(arrayList))
-
such as macro specific functionality.
#define CheckIndex(tag, index) \ ALog_A \ ( \ ((index) < arrayList->size && (index) >= 0), \ "AArrayList " tag " failed index error, index = %d, size = %d", \ index, \ arrayList->size \ )
-
such as generic parameter.
/** * Marked ArrayList element type. * ElementType: element data type */ #define ArrayList(ElementType) ArrayList
-
such as varargs.
#define ALog_A(e, ...) e ? (void) 0 : ALog_E(__VA_ARGS__), assert(e);
-
-
Do not use number as
booleanvalue. -
The
coefficientnumber usesintunless it is afloat.float f1 = sprite->width / 2; float f2 = sprite->width / 2.5f;
-
Use
++iwhenever possible.for (int i = 0; i < 10; ++i) { }
-
Assignment appears in the
iforwhilestatement, adding brackets.int intVal; if ((intVal = GetInt())) { int tmp = intVal * 100; } int intVal1; int intVal2 = GetInt(); while ((intVal1 = intVal2)) { int tmp = intVal1 * 100; }
-
The
constvariable cannot be modified. -
Use
enuminstead of macro#definewhenever possible. -
Use a monospaced font.
😈 Follow the Style, Feel the Power !