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
uppercase
words orlowercase
words.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
Is
orTest
orCheck
, 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 useRelease
andfree
orDestroy
for 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 useRelease
orDestroy
for 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
void
arg.Drawable* (*Create) (void); int (*GetDrawCalls)(void); struct ATweenTool* (*AddAction) (void);
-
The function have suffix
Impl
, means the function must be implemented in.c
file.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
uppercase
words separated by_
and have suffixH
.#ifndef STYLE_GUIDE_H #define STYLE_GUIDE_H
-
The macro without parameters, use
uppercase
words 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
.c
file, useBigCamelCased
, no prefix required, and must#undef
in same.c
file.#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 spaces
key indent, nottab
key. - One line
120 chars
. - The pointer
*
on type name side.int* p1; int** p2 = &p1; void* Function(char* str);
- In code block try
vertical
alignment.See all the examples above.
-
The operator at least
one space
on both sides.vertexX + (y - vertexY) / (preY - vertexY) * (preX - vertexX)
-
The
if, while, for, switch
, must have{}
, andone space
with()
.if (...) { } while (...) { } for (...) { } switch (...) { }
-
The case
4 spaces
indent, and the break4 spaces
indent 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 lines
around functions.static int a = 100; static void Function1() { } static inline void Function2() { } struct A { }
-
Empty
two lines
between 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_X
or 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
inline
function 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
boolean
value. -
The
coefficient
number usesint
unless it is afloat
.float f1 = sprite->width / 2; float f2 = sprite->width / 2.5f;
-
Use
++i
whenever possible.for (int i = 0; i < 10; ++i) { }
-
Assignment appears in the
if
orwhile
statement, adding brackets.int intVal; if ((intVal = GetInt())) { int tmp = intVal * 100; } int intVal1; int intVal2 = GetInt(); while ((intVal1 = intVal2)) { int tmp = intVal1 * 100; }
-
The
const
variable cannot be modified. -
Use
enum
instead of macro#define
whenever possible. -
Use a monospaced font.
😈 Follow the Style, Feel the Power !