forked from JerryZhou/aoi
-
Notifications
You must be signed in to change notification settings - Fork 1
/
aoi.h
2415 lines (1855 loc) · 71 KB
/
aoi.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*!
Area Of Interest In Game Developing
Copyright [email protected]
Licence: Apache 2.0
Project: https://github.com/JerryZhou/aoi.git
Purpose: Resolve the AOI problem in game developing
with high run fps
with minimal memory cost,
Please see examples for more details.
*/
#ifndef __AOI_H_
#define __AOI_H_
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <time.h>
#include <stdint.h>
#include <stddef.h>
#include <inttypes.h>
#ifdef _WIN32
#include <windows.h>
#define snprintf _snprintf
// TODO: figure out a multiplatform version of uint64_t
// - maybe: https://code.google.com/p/msinttypes/
// - or: http://www.azillionmonkeys.com/qed/pstdint.h
typedef _int64 int64_t;
typedef _uint64 uint64_t;
typedef _int32 int32_t;
typedef _uint32 uint32_t;
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif /* end of: offsetof */
#ifndef container_of
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr);\
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif /* end of:container_of */
#else
#include <stdbool.h>
#include <inttypes.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>
#endif /* end of: _WIN32 */
/*****
* AOI: (Area Of Interesting)
* 1. 适用于大批量的对象管理和查询
* 2. 采用四叉树来进行管理,可以通过少量改动支持3D
* 3. 动态节点回收管理,减少内存, 节点的数量不会随着四叉树的层次变得不可控,与对象数量成线性关系
* 3. 缓存搜索上下文,减少无效搜索,对于零变更的区域,搜索会快速返回
* 4. 整个搜索过程,支持自定义过滤器进行单元过滤
* 5. AOI 支持对象的内存缓冲区管理
* 6. 线程不安全
* 7. 支持单位半径,不同单位可以定义不同的半径(开启半径感知,会损失一部分性能)
* 8. 只提供了搜索结构,不同单位的视野区域可以定义不一样
*
* 提高内存访问,建议启用 iimeta (1)
* 如果不需要单位半径感知 建议关闭 iiradius (0)
*/
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* 是否启动元信息: 记录类型对象的内存使用情况, 并加一层对象的内存缓冲区 */
#ifndef iimeta
# define iimeta 1
#endif
/* 是否启动单位半径支持 */
#ifndef iiradius
# define iiradius 1
#endif
/* if we support thread safe in meta system and ref */
#ifndef iithreadsafe
# define iithreadsafe 1
#endif
/* 常用布尔宏 */
#define iiyes 1
#define iiok 1
#define iino 0
/* 条件检查,不带assert */
#define icheck(con) do { if(!(con)) return; } while(0)
#define icheckret(con, ret) do { if(!(con)) return ret; } while(0)
/* flat array count */
#define icountof(arr) (sizeof(arr)/sizeof(arr[0]))
/* 常用的宏 */
#define imax(a, b) ((a) > (b) ? (a) : (b))
#define imin(a, b) ((a) < (b) ? (a) : (b))
#define iunused(v) (void)(v)
#define ilog(...) printf(__VA_ARGS__)
/* helper for printf isize */
#define __isize_format "(w:%lf, h:%lf)"
#define __isize_value(s) (s).w, (s).h
/* helper for printf ipos */
#define __ipos_format "(x:%lf, y:%lf)"
#define __ipos_value(p) (p).x, (p).y
/* helper for printf ipos3 */
#define __ipos3_format "(x:%lf, y:%lf, z:%lf)"
#define __ipos3_value(p) (p).x, (p).y, (p).z
/* helper for printf ivec2 */
#define __ivec2_format __ipos_format
#define __ivec2_value(i) __ipos_value((i).v)
/* helper for printf ivec3 */
#define __ivec3_format __ipos3_format
#define __ivec3_value(i) __ipos3_value((i).v)
/* helper for printf iline2d */
#define __iline2d_format "[start:"__ipos_format" end:"__ipos_format"]"
#define __iline2d_value(l) __ipos_value((l).start),__ipos_value((l).end)
/* helper for printf iline3d */
#define __iline3d_format "[start:"__ipos3_format" end:"__ipos3_format"]"
#define __iline3d_value(l) __ipos3_value((l).start),__ipos3_value((l).end)
/* helper for printf iplane */
#define __iplane_format "[normal:"__ivec3_format" pos:"__ipos3_format" dist:%lf]"
#define __iplane_value(p) __ivec3_value((p).normal),__ipos3_value((p).pos),(p).distance
/* helper for printf irect */
#define __irect_format "[pos:"__ipos_format" size:"__isize_format"]"
#define __irect_value(r) __ipos_value((r).pos),__isize_value((r).size)
/* helper for printf irect */
#define __icircle_format "[pos:"__ipos_format" radius:%lf]"
#define __icircle_value(c) __ipos_value((c).pos), (c).radius
/* 节点查找行为 */
typedef enum EnumFindBehavior {
/* 精确查找 */
EnumFindBehaviorAccurate,
/* 模糊查找 */
EnumFindBehaviorFuzzy,
}EnumFindBehavior;
/* 获取当前系统的微秒数 */
int64_t igetcurmicro();
/* 获取当前系统的毫秒数 */
int64_t igetcurtick();
/* 获取系统的下一个唯一的事件微秒数 */
int64_t igetnextmicro();
/* 精度 */
typedef double ireal;
/* 默认的 epsilon */
#define iepsilon 0.1e-6
/* 浮点比较 */
#define ireal_equal_in(a, b, eps) (fabs((a)-(b)) < (eps))
/*浮点数相等比较*/
#define ireal_equal(a, b) ireal_equal_in(a, b, iepsilon)
/*与零比较*/
#define ireal_equal_zero(a) ireal_equal(a, 0)
/* 比较: 小于 */
#define ireal_less_than(a, b, eps) ((a-b) < -eps)
#define ireal_less(a, b) ireal_less_than(a, b, iepsilon)
/* 比较: 大于 */
#define ireal_greater_than(a, b, eps) ((a-b) > eps)
#define ireal_greater(a, b) ireal_greater_than(a, b, iepsilon)
/*小于 0*/
#define ireal_less_zero(a) ireal_less_than(a, 0, iepsilon)
/*大于 0*/
#define ireal_greater_zero(a) ireal_greater_than(a, 0, iepsilon)
/* 编号 */
typedef int64_t iid;
/* type define */
typedef unsigned char ibyte;
typedef unsigned char ibool;
/* return the next pow of two */
int inextpot(int size);
/* sleeping the current thread */
void isleep(unsigned int milliseconds);
/*************************************************************/
/* imutex */
/*************************************************************/
/* recursive mutex */
typedef struct imutex {
#ifdef WIN32
HANDLE _mutex;
#else
pthread_mutex_t _mutex;
#endif
}imutex;
/*create resource*/
void imutexinit(imutex *mutex);
/*release resource*/
void imutexrelease(imutex *mutex);
/*lock mutex*/
void imutexlock(imutex *mx);
/*unlock mutex*/
void imutexunlock(imutex *mx);
/*************************************************************/
/* iatomic */
/*************************************************************/
/* [asf](https://svn.apache.org/repos/asf/avro/trunk/lang/c/src/avro/refcount.h) */
/* compare the store with expected, than store the value with desired */
uint32_t iatomiccompareexchange(volatile uint32_t *store, uint32_t expected, uint32_t desired);
/* fetch the old value and store the with add*/
uint32_t iatomicadd(volatile uint32_t *store, uint32_t value);
/* fetch the old value, than do exchange operator */
uint32_t iatomicexchange(volatile uint32_t *store, uint32_t value);
/* atomic increment, return the new value */
uint32_t iatomccincrement(volatile uint32_t *store);
/* atomic decrement, return the new value */
uint32_t iatomicdecrement(volatile uint32_t *store);
/*************************************************************/
/* ibase64 */
/*************************************************************/
/* caculating enough space for the base64 algorithm */
#define ibase64_encode_out_size(s) (((s) + 2) / 3 * 4 + 1) /*pendding a zero: c-style-ending*/
#define ibase64_decode_out_size(s) (((s)) / 4 * 3)
/* base64 encode */
int ibase64encode_n(const unsigned char *in, size_t inlen, char *out, size_t *outsize);
/* base64 decode */
int ibase64decode_n(const char *in, size_t inlen, unsigned char *out, size_t *outsize);
/*************************************************************/
/* ipos */
/*************************************************************/
/* 坐标 */
typedef struct ipos {
ireal x, y;
}ipos;
/* zero point */
extern const ipos kipos_zero;
/* 计算距离的平方 */
ireal idistancepow2(const ipos *p, const ipos *t);
/*************************************************************/
/* ipos */
/*************************************************************/
typedef struct ipos3 {
ireal x, y, z;
}ipos3;
/* zero of ipos3 */
extern const ipos3 kipos3_zero;
/* 计算距离的平方 */
ireal idistancepow3(const ipos3 *p, const ipos3 *t);
/* get the xy from the p with xz */
void ipos3takexz(const ipos3 *p, ipos *to);
/*************************************************************/
/* ivec2 */
/*************************************************************/
/* 向量, 完善基本的数学方法:
* 加法 ; 减法 ; 乘法 ; 除法 ; 点积(内积) ; 乘积(外积) ; 长度
* */
typedef union ivec2 {
ireal values[2];
struct {
ireal x, y;
} v;
}ivec2;
/* 两点相减得到向量 */
ivec2 ivec2subtractpoint(const ipos *p0, const ipos *p1);
/* 把点在这个方向上进行移动 */
ipos ivec2movepoint(const ivec2 *dir, ireal dist, const ipos *p);
/* 加法*/
ivec2 ivec2add(const ivec2 *l, const ivec2 *r);
/* 减法 */
ivec2 ivec2subtract(const ivec2 *l, const ivec2 *r);
/* 乘法 */
ivec2 ivec2multipy(const ivec2 *l, const ireal a);
/* 点积 */
ireal ivec2dot(const ivec2 *l, const ivec2 *r);
/* 乘积 : 二维向量不存在叉积
* ivec2 ivec2cross(const ivec2 *l, const ivec2 *r);
* */
/* 长度的平方 */
ireal ivec2lengthsqr(const ivec2 *l);
/* 长度 */
ireal ivec2length(const ivec2 *l);
/* 绝对值 */
ivec2 ivec2abs(const ivec2* l);
/* 归一化 */
ivec2 ivec2normalize(const ivec2 *l);
/* 平行分量, 确保 r 已经归一化 */
ivec2 ivec2parallel(const ivec2 *l, const ivec2 *r);
/* 垂直分量, 确保 r 已经归一化 */
ivec2 ivec2perpendicular(const ivec2 *l, const ivec2 *r);
/*************************************************************/
/* ivec3 */
/*************************************************************/
/* 向量 完善基本的数学方法 */
typedef union ivec3 {
ireal values[3];
struct {
ireal x, y, z;
}v;
}ivec3;
/* 两点相减得到向量 */
ivec3 ivec3subtractpoint(const ipos3 *p0, const ipos3 *p1);
/* 加法*/
ivec3 ivec3add(const ivec3 *l, const ivec3 *r);
/* 减法 */
ivec3 ivec3subtract(const ivec3 *l, const ivec3 *r);
/* 乘法 */
ivec3 ivec3multipy(const ivec3 *l, const ireal a);
/* 点积 */
ireal ivec3dot(const ivec3 *l, const ivec3 *r);
/* 乘积 */
ivec3 ivec3cross(const ivec3 *l, const ivec3 *r);
/* 长度的平方 */
ireal ivec3lengthsqr(const ivec3 *l);
/* 长度 */
ireal ivec3length(const ivec3 *l);
/* 绝对值 */
ivec3 ivec3abs(const ivec3* l);
/* 归一*/
ivec3 ivec3normalize(const ivec3 *l);
/* 平行分量, 确保 r 已经归一化 */
ivec3 ivec3parallel(const ivec3 *l, const ivec3 *r);
/* 垂直分量, 确保 r 已经归一化 */
ivec3 ivec3perpendicular(const ivec3 *l, const ivec3 *r);
/*************************************************************/
/* iline2d */
/*************************************************************/
typedef struct iline2d {
ipos start;
ipos end;
}iline2d;
/* start ==> end */
ivec2 iline2ddirection(const iline2d *line);
/* start ==> end , rorate -90 */
ivec2 iline2dnormal(const iline2d *line);
/**/
ireal iline2dlength(const iline2d *line);
/*
* Determines the signed distance from a point to this line. Consider the line as
* if you were standing on start of the line looking towards end. Posative distances
* are to the right of the line, negative distances are to the left.
* */
ireal iline2dsigneddistance(const iline2d *line, const ipos *point);
/*
* point classify
* */
typedef enum EnumPointClass{
EnumPointClass_On, /* The point is on, or very near, the line */
EnumPointClass_Left, /* looking from endpoint A to B, the test point is on the left */
EnumPointClass_Right /* looking from endpoint A to B, the test point is on the right */
}EnumPointClass;
/*
* Determines the signed distance from a point to this line. Consider the line as
* if you were standing on PointA of the line looking towards PointB. Posative distances
* are to the right of the line, negative distances are to the left.
* */
int iline2dclassifypoint(const iline2d *line, const ipos *point, ireal epsilon);
/*
* line classify
* */
typedef enum EnumLineClass {
EnumLineClass_Collinear, /* both lines are parallel and overlap each other */
EnumLineClass_Lines_Intersect, /* lines intersect, but their segments do not */
EnumLineClass_Segments_Intersect, /* both line segments bisect each other */
EnumLineClass_A_Bisects_B, /* line segment B is crossed by line A */
EnumLineClass_B_Bisects_A, /* line segment A is crossed by line B */
EnumLineClass_Paralell /* the lines are paralell */
}EnumLineClass;
/*
* Determines if two segments intersect, and if so the point of intersection. The current
* member line is considered line AB and the incomming parameter is considered line CD for
* the purpose of the utilized equations.
*
* A = PointA of the member line
* B = PointB of the member line
* C = PointA of the provided line
* D = PointB of the provided line
* */
int iline2dintersection(const iline2d *line, const iline2d *other, ipos *intersect);
/* Caculating the closest point in the segment to center pos */
ipos iline2dclosestpoint(const iline2d *line, const ipos *center, ireal epsilon);
/*************************************************************/
/* iline3d */
/*************************************************************/
typedef struct iline3d {
ipos3 start;
ipos3 end;
}iline3d;
/* start ==> end */
ivec3 iline3ddirection(const iline3d *line);
/**/
ireal iline3dlength(const iline3d *line);
/* Caculating the closest point in the segment to center pos */
ipos3 iline3dclosestpoint(const iline3d *line, const ipos3 *center, ireal epsilon);
/*************************************************************/
/* iplane */
/*************************************************************/
/*
* A Plane in 3D Space represented in point-normal form (Ax + By + Cz + D = 0).
* The convention for the distance constant D is:
* D = -(A, B, C) dot (X, Y, Z) */
typedef struct iplane {
ivec3 normal;
ipos3 pos;
ireal distance;
}iplane;
/* Setup Plane object given a clockwise ordering of 3D points */
void iplaneset(iplane *plane, const ipos3 *a, const ipos3 *b, const ipos3 *c);
/* TODO */
ireal iplanesigneddistance(const iplane *plane, const ipos3 *p);
/* Given Z and Y, Solve for X on the plane */
ireal iplanesolveforx(iplane *plane, ireal y, ireal z);
/* Given X and Z, Solve for Y on the plane */
ireal iplanesolvefory(iplane *plane, ireal x, ireal z);
/* Given X and Y, Solve for Z on the plane */
ireal iplanesolveforz(iplane *plane, ireal x, ireal y);
/*************************************************************/
/* isize */
/*************************************************************/
/* 大小 */
typedef struct isize {
ireal w, h;
}isize;
/*************************************************************/
/* irect */
/*************************************************************/
/* 矩形 */
typedef struct irect {
ipos pos;
isize size;
}irect;
/* 矩形包含: iiok, iino */
int irectcontains(const irect *con, const irect *r);
/* 矩形包含: iiok, iino */
int irectcontainspoint(const irect *con, const ipos *p);
/* down-left pos*/
ipos irectdownleft(const irect *con);
/* down-right pos*/
ipos irectdownright(const irect *con);
/* up-left pos*/
ipos irectupleft(const irect *con);
/* up-right pos*/
ipos irectupright(const irect *con);
/*************************************************************/
/* icircle */
/*************************************************************/
/* 圆形 */
typedef struct icircle {
ipos pos;
ireal radius;
}icircle;
/*圆形的关系 */
typedef enum EnumCircleRelation {
EnumCircleRelationBContainsA = -2,
EnumCircleRelationAContainsB = -1,
EnumCircleRelationNoIntersect = 0,
EnumCircleRelationIntersect = 1,
} EnumCircleRelation;
/* 圆形相交: iiok, iino */
int icircleintersect(const icircle *con, const icircle *c);
/* 圆形包含: iiok, iino */
int icirclecontains(const icircle *con, const icircle *c);
/* 圆形包含: iiok, iino */
int icirclecontainspoint(const icircle *con, const ipos *p);
/* 圆形的关系: EnumCircleRelationBContainsA(c包含con), */
/* EnumCircleRelationAContainsB(con包含c), */
/* EnumCircleRelationIntersect(相交), */
/* EnumCircleRelationNoIntersect(相离) */
int icirclerelation(const icircle *con, const icircle *c);
/* 矩形与圆是否相交 */
int irectintersect(const irect *con, const icircle *c);
/* Caculating the offset that circle should moved to avoid collided with the line */
ivec2 icircleoffset(const icircle* circle, const iline2d* line);
/* 名字的最大长度 */
#define IMaxNameLength 32
/*************************************************************/
/* iname */
/*************************************************************/
/* 名字 */
typedef struct iname {
char name[IMaxNameLength+1];
}iname;
/*************************************************************/
/* imeta */
/*************************************************************/
/* 内存操作 */
#define icalloc(n, size) calloc(n, size)
#define irealloc(ptr, size) realloc(ptr, size)
#define ifree(p) free(p)
#if (iimeta) /* if iimeta */
/* 最多支持100个类型对象 */
#define IMaxMetaCountForUser 100
/* 前置声明 */
struct imeta;
struct iobj;
/* tracing the iobj alloc */
typedef void (*ientryobjcalloctrace)(struct imeta *meta, struct iobj *obj);
/* tracing the iobj free */
typedef void (*ientryobjfreetrace)(struct imeta *meta, struct iobj *obj);
/* make all iobj has the hash values */
typedef int (*ientryobjhash)(struct imeta *meta, struct iobj *obj);
/* make all iobj can be compare with each other */
typedef int (*ientryobjcompare)(struct imeta *meta, struct iobj *lfs, struct iobj *rfs);
/* 基础的内存对象, 都具备缓冲功能 */
typedef struct iobj {
int size;
struct imeta *meta;
struct iobj *next;
char addr[];
}iobj;
/* 基础内存对象缓存 */
typedef struct iobjcache {
struct iobj *root;
int length;
int capacity;
}iobjcache;
/* 编码对象的元信息 */
typedef struct imeta {
const char* name;
struct iobjcache cache;
int size;
int64_t current;
int64_t alloced;
int64_t freed;
/* trace all obj calloc */
ientryobjcalloctrace tracecalloc;
/* trace all obj free */
ientryobjfreetrace tracefree;
/*all iobj can be do hash */
ientryobjhash _hash;
/*all iobj can be do compare */
ientryobjcompare _compare;
/* support thread safe for meta system */
#if (iithreadsafe)
imutex mutex; /*will never release resouce until program ended */
#endif
}imeta;
/*Hepler Macro for log*/
#define __imeta_format "Meta-Obj: (%15.15s, %5d) --> alloc: %9" PRId64 ", free: %9" PRId64 ", hold: %9" PRId64 " - count: %8" PRId64 " - cache(%6d/%6d)"
#define __imeta_value(meta) (meta).name,(meta).size,(meta).alloced,(meta).freed,imax((meta).current, 0),imax((meta).current,0)/((meta).size+sizeof(iobj)),(meta).cache.length,(meta).cache.capacity
/* 获取类型的元信息 */
imeta *imetaget(int idx);
/* 也可以手动注册一个元信息来管理自己的对象: 然后就可以通过 iobjmalloc 进行对象内存管理 */
/* 将会返回对象的meta索引 */
int imetaregister(const char* name, int size, int capacity);
/* 获取索引 */
#define imetaindex(type) imeta_##type##_index
/* 注册宏 */
#define iregister(type, capacity) imetaregister(#type, sizeof(type), capacity)
/* 声明 */
#define irealdeclareregister(type) int imetaindex(type)
/* 声明 */
#define iideclareregister(type) extern irealdeclareregister(type)
/* 注册宏 */
#define irealimplementregister(type, capacity) imetaindex(type) = iregister(type, capacity)
/* 注册宏 */
#define iimplementregister(type, capacity) int irealimplementregister(type, capacity)
/* 获取meta */
#define imetaof(type) imetaget(imetaindex(type))
/* 定义所有内部对象的meta索引 */
#define __ideclaremeta(type, capacity) imetaindex(type),
#define __iallmeta(XX) \
XX(iobj, 0) \
XX(iref, 0) \
XX(iwref, 0) \
XX(irangeite, 0) \
XX(ireflist, 1000) \
XX(irefjoint, 200000) \
XX(inode, 4000) \
XX(iunit, 2000) \
XX(imap, 0) \
XX(irefcache, 0) \
XX(ifilter, 2000) \
XX(isearchresult, 0) \
XX(irefautoreleasepool, 0) \
XX(iarray, 0) \
XX(islice, 0) \
XX(iringbuffer, 0) \
XX(idict, 0) \
XX(ipolygon3d, 0) \
XX(ipolygon2d, 0)
/* 定义所有元信息索引 */
typedef enum EnumMetaTypeIndex {
__iallmeta(__ideclaremeta)
EnumMetaTypeIndex_imax,
}EnumMetaTypeIndex;
/* 获取响应的内存:会经过Meta的Cache */
void *iaoicalloc(imeta *meta);
/* 释放内存:会经过Meta的Cache */
void iaoifree(void *p);
/* 尽可能的释放Meta相关的Cache */
void iaoicacheclear(imeta *meta);
/* 打印当前内存状态 */
void iaoimemorystate();
/* 获取指定对象的meta信息 */
imeta *iaoigetmeta(const void *p);
/* 指定对象是响应的类型: 一致返回iiok, 否则返回 iino */
int iaoiistype(const void *p, const char* type);
/* Trace the memory size */
typedef enum EnumAoiMemoerySizeKind {
EnumAoiMemoerySizeKind_Alloced,
EnumAoiMemoerySizeKind_Freed,
EnumAoiMemoerySizeKind_Hold,
} EnumAoiMemoerySizeKind;
/*获取当前的总的内存统计*/
int64_t iaoimemorysize(void *meta, int kind);
#define imetacacheclear(type) (iaoicacheclear(imetaof(type)))
#define iobjmalloc(type) ((type*)iaoicalloc(imetaof(type)))
#define iobjfree(p) do { iaoifree(p); p = NULL; } while(0)
#define iobjistype(p, type) iaoiistype((void*)p, #type)
#define iistype(p, type) (iaoigetmeta(p) == imetaof(type))
#else /* #if iimeta */
/* 打印当前内存状态: 空的内存状态 */
void iaoimemorystate() ;
int64_t iaoimemorysize(void * meta, int kind);
#define iobjmalloc(type) ((type*)icalloc(1, sizeof(type)))
#define iobjfree(p) do { ifree(p); p = NULL; } while(0)
#define iobjistype(p, type) iino
#define iistype(p, type) iino
#endif /* #if iimeta */
/*************************************************************/
/* iref */
/*************************************************************/
/* 定义引用计数,基础对象 */
#define irefdeclare volatile uint32_t ref; volatile struct iwref * wref; struct irefcache* cache; ientryfree free; ientrywatch watch
/* iref 转换成 target */
#define icast(type, v) ((type*)(v))
/* 转换成iref */
#define irefcast(v) icast(iref, v)
/* 前置声明 */
struct iref;
struct irefcache;
struct iwref;
/* iref 的析构函数 */
typedef void (*ientryfree)(struct iref* ref);
/* iref 的跟踪函数: 引用计数减小的时候会通知 */
typedef void (*ientrywatch)(struct iref* ref);
/* 引用计数结构体 */
typedef struct iref {
irefdeclare;
}iref;
/* 增加引用计数 */
int irefretain(iref *ref);
/* 释放引用计数 */
void irefrelease(iref *ref);
/* 引用宏 */
#define iretain(p) do { if(p) irefretain((iref*)(p)); } while(0)
/* 释放宏 */
#define irelease(p) do { if(p) irefrelease((iref*)(p)); } while(0)
/* 应用计数的赋值操作 */
#define iassign(dst, src) do { if(src != dst) { irelease(dst); iretain(src); dst = src; } } while(0)
/*************************************************************/
/* iwref */
/*************************************************************/
/* 弱引用: we can do operators as iref: iretain; irelease; iassign */
/* the iwref not thread safe: only use iwref in one thread context */
typedef struct iwref {
irefdeclare;
}iwref;
/* make a weak iref by ref */
iwref *iwrefmake(iref *ref);
/* make a weak iref by wref */
iwref *iwrefmakeby(iwref *wref);
/* make strong ref: need call irelease */
iref *iwrefstrong(iwref *wref);
/* make strong ref: unneed call irelease */
iref *iwrefunsafestrong(iwref *wref);
/* ref assign to weak ref */
#define iwassign(dst, src) do { if (dst && (iref*)(dst->wref) == (iref*)(src)) { \
break; } irelease(dst); dst = iwrefmake((iref*)(src)); } while(0)
/*************************************************************/
/* irefautoreleasepool */
/*************************************************************/
/* 前置声明 */
struct ireflist;
/* 自动释放池子 */
typedef struct irefautoreleasepool {
struct ireflist *list;
}irefautoreleasepool;
/* 申请自动释放池子 */
irefautoreleasepool * irefautoreleasebegin();
/* 自动释放 */
iref* irefautorelease(irefautoreleasepool *pool, iref *ref);
/* 结束自动释放 */
void irefautoreleaseend(irefautoreleasepool *pool);
/* 返回值本身的,引用retain */
iref *irefassistretain(iref *ref);
/* 便利宏用来使用autoreleasepool */
#define _iautoreleasepool irefautoreleasepool* pool = irefautoreleasebegin()
#define _iautomalloc(type) ((type*)irefautorelease(pool, irefassistretain((iref*)iobjmalloc(type))))
#define _iautorelease(p) irefautorelease(pool, (iref*)p)
#define _iautoreleaseall irefautoreleaseend(pool)
/*************************************************************/
/* ireflist */
/*************************************************************/
/* 节点 */
typedef struct irefjoint {
/* 附加的对象 */
iref *value;
/* 附加在上的 资源*/
void *res;
/* 必要的校验 */
struct ireflist *list;
/* 列表节点 */
struct irefjoint *next;
struct irefjoint *pre;
}irefjoint;
/* 构造列表节点 */
irefjoint* irefjointmake(iref *value);
/* 释放列表节点 */
void irefjointfree(irefjoint* joint);
/* 释放附加在列表节点上的资源 */
typedef void (*irefjoint_entry_res_free)(irefjoint *joint);
/* 引用对象列表 */
typedef struct ireflist {
irefdeclare;
/* 列表根节点, 也是列表的第一个节点 */
irefjoint *root;
/* 列表长度 */
size_t length;
/* 时间 */
int64_t tick;
/* free the res append in list */
irefjoint_entry_res_free entry;
}ireflist;
/* 创建列表 */
ireflist *ireflistmake();
/* 释放列表 */
void ireflistfree(ireflist *list);
/* 创建列表 */
ireflist *ireflistmakeentry(irefjoint_entry_res_free entry);
/* 获取列表长度 */
size_t ireflistlen(const ireflist *list);
/* 获取第一个节点 */
irefjoint* ireflistfirst(const ireflist *list);
/* 从列表里面查找第一个满足要求的节点 */
irefjoint* ireflistfind(const ireflist *list,
const iref *value);
/* 往列表增加节点: 前置节点 */
irefjoint* ireflistaddjoint(ireflist *list, irefjoint * joint);
/* 往列表增加节点: 前置节点(会增加引用计数) */
irefjoint* ireflistadd(ireflist *list, iref *value);
/* 往列表增加节点: 前置节点(会增加引用计数) */
irefjoint* ireflistaddres(ireflist *list, iref *value, void *res);
/* 从节点里面移除节点, 返回下一个节点 */
irefjoint* ireflistremovejoint(ireflist *list, irefjoint *joint);
/* 从节点里面移除节点 , 并且释放当前节点, 并且返回下一个节点 */
irefjoint* ireflistremovejointandfree(ireflist *list, irefjoint *joint);
/* 从节点里面移除节点: 并且会释放节点, 返回下一个节点 */
irefjoint* ireflistremove(ireflist *list, iref *value);
/* 释放所有节点 */
void ireflistremoveall(ireflist *list);
/*************************************************************/
/* irefneighbors */
/*************************************************************/
typedef struct irefneighbors {
irefdeclare;
/*
* 构成了一个有向图,可在联通上做单向通行
* */
/* 所有可以到达当前节点的邻居 other ===> this */
ireflist *neighbors_from;
/* 可走的列表 this ===> other */
ireflist *neighbors_to;
/* List joint resouce free entry */
irefjoint_entry_res_free neighbors_resfree;
}irefneighbors;
/*macro declare*/
#define irefneighborsdeclare \
irefdeclare; \
ireflist *neighbors_from; \
ireflist *neighbors_to; \
irefjoint_entry_res_free neighbors_resfree
/* 设置邻居间关系描述的 释放符号 */
void ineighborsbuild(irefneighbors *neighbors, irefjoint_entry_res_free entry);
/* 从节点图里面移除 */
void ineighborsclean(irefneighbors *neighbors);
/* 在有向图上加上一单向边 */
void ineighborsadd(irefneighbors *from, irefneighbors *to);
/* 在有向图上加上一单向边 */
void ineighborsaddvalue(irefneighbors *from, irefneighbors *to, void *from_to, void *to_from);
/* 在有向图上移除一条单向边 */
void ineighborsdel(irefneighbors *from, irefneighbors *to);
/*************************************************************/
/* iarray */
/*************************************************************/
struct iarray;
struct islice;
/* 如果是需要跟 kindex_invalid 进行交换就是置0 */
/* invalid index */
extern const int kindex_invalid;
/* 交换两个对象 */
typedef void (*iarray_entry_swap)(struct iarray *arr,
int i, int j);