box2d-ruby 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +336 -0
  4. data/examples/contact_events.rb +22 -0
  5. data/examples/debug_draw.rb +15 -0
  6. data/examples/falling_ball.rb +19 -0
  7. data/examples/rugl_debug_draw.rb +68 -0
  8. data/examples/stagecraft_debug_draw.rb +64 -0
  9. data/examples/support/box2d_debug_lines.rb +125 -0
  10. data/ext/box2d/CMakeLists.txt +35 -0
  11. data/ext/box2d/extconf.rb +42 -0
  12. data/ext/box2d/native.c +9 -0
  13. data/ext/box2d/vendor/box2d/LICENSE +21 -0
  14. data/ext/box2d/vendor/box2d/VERSION +1 -0
  15. data/ext/box2d/vendor/box2d/include/box2d/base.h +131 -0
  16. data/ext/box2d/vendor/box2d/include/box2d/box2d.h +1222 -0
  17. data/ext/box2d/vendor/box2d/include/box2d/collision.h +830 -0
  18. data/ext/box2d/vendor/box2d/include/box2d/id.h +144 -0
  19. data/ext/box2d/vendor/box2d/include/box2d/math_functions.h +761 -0
  20. data/ext/box2d/vendor/box2d/include/box2d/types.h +1457 -0
  21. data/ext/box2d/vendor/box2d/src/CMakeLists.txt +223 -0
  22. data/ext/box2d/vendor/box2d/src/aabb.c +132 -0
  23. data/ext/box2d/vendor/box2d/src/aabb.h +56 -0
  24. data/ext/box2d/vendor/box2d/src/arena_allocator.c +112 -0
  25. data/ext/box2d/vendor/box2d/src/arena_allocator.h +48 -0
  26. data/ext/box2d/vendor/box2d/src/array.c +8 -0
  27. data/ext/box2d/vendor/box2d/src/array.h +179 -0
  28. data/ext/box2d/vendor/box2d/src/atomic.h +79 -0
  29. data/ext/box2d/vendor/box2d/src/bitset.c +67 -0
  30. data/ext/box2d/vendor/box2d/src/bitset.h +65 -0
  31. data/ext/box2d/vendor/box2d/src/body.c +1884 -0
  32. data/ext/box2d/vendor/box2d/src/body.h +194 -0
  33. data/ext/box2d/vendor/box2d/src/box2d.natvis +41 -0
  34. data/ext/box2d/vendor/box2d/src/broad_phase.c +524 -0
  35. data/ext/box2d/vendor/box2d/src/broad_phase.h +83 -0
  36. data/ext/box2d/vendor/box2d/src/constants.h +54 -0
  37. data/ext/box2d/vendor/box2d/src/constraint_graph.c +322 -0
  38. data/ext/box2d/vendor/box2d/src/constraint_graph.h +58 -0
  39. data/ext/box2d/vendor/box2d/src/contact.c +650 -0
  40. data/ext/box2d/vendor/box2d/src/contact.h +148 -0
  41. data/ext/box2d/vendor/box2d/src/contact_solver.c +2120 -0
  42. data/ext/box2d/vendor/box2d/src/contact_solver.h +54 -0
  43. data/ext/box2d/vendor/box2d/src/core.c +178 -0
  44. data/ext/box2d/vendor/box2d/src/core.h +149 -0
  45. data/ext/box2d/vendor/box2d/src/ctz.h +112 -0
  46. data/ext/box2d/vendor/box2d/src/distance.c +1415 -0
  47. data/ext/box2d/vendor/box2d/src/distance_joint.c +556 -0
  48. data/ext/box2d/vendor/box2d/src/dynamic_tree.c +1989 -0
  49. data/ext/box2d/vendor/box2d/src/geometry.c +1028 -0
  50. data/ext/box2d/vendor/box2d/src/hull.c +328 -0
  51. data/ext/box2d/vendor/box2d/src/id_pool.c +79 -0
  52. data/ext/box2d/vendor/box2d/src/id_pool.h +35 -0
  53. data/ext/box2d/vendor/box2d/src/island.c +977 -0
  54. data/ext/box2d/vendor/box2d/src/island.h +89 -0
  55. data/ext/box2d/vendor/box2d/src/joint.c +1272 -0
  56. data/ext/box2d/vendor/box2d/src/joint.h +335 -0
  57. data/ext/box2d/vendor/box2d/src/manifold.c +1726 -0
  58. data/ext/box2d/vendor/box2d/src/math_functions.c +159 -0
  59. data/ext/box2d/vendor/box2d/src/motor_joint.c +283 -0
  60. data/ext/box2d/vendor/box2d/src/mouse_joint.c +214 -0
  61. data/ext/box2d/vendor/box2d/src/mover.c +73 -0
  62. data/ext/box2d/vendor/box2d/src/prismatic_joint.c +656 -0
  63. data/ext/box2d/vendor/box2d/src/revolute_joint.c +534 -0
  64. data/ext/box2d/vendor/box2d/src/sensor.c +389 -0
  65. data/ext/box2d/vendor/box2d/src/sensor.h +36 -0
  66. data/ext/box2d/vendor/box2d/src/shape.c +1714 -0
  67. data/ext/box2d/vendor/box2d/src/shape.h +123 -0
  68. data/ext/box2d/vendor/box2d/src/solver.c +2038 -0
  69. data/ext/box2d/vendor/box2d/src/solver.h +155 -0
  70. data/ext/box2d/vendor/box2d/src/solver_set.c +613 -0
  71. data/ext/box2d/vendor/box2d/src/solver_set.h +57 -0
  72. data/ext/box2d/vendor/box2d/src/table.c +238 -0
  73. data/ext/box2d/vendor/box2d/src/table.h +37 -0
  74. data/ext/box2d/vendor/box2d/src/timer.c +185 -0
  75. data/ext/box2d/vendor/box2d/src/types.c +151 -0
  76. data/ext/box2d/vendor/box2d/src/weld_joint.c +310 -0
  77. data/ext/box2d/vendor/box2d/src/wheel_joint.c +551 -0
  78. data/ext/box2d/vendor/box2d/src/world.c +3301 -0
  79. data/ext/box2d/vendor/box2d/src/world.h +192 -0
  80. data/generator/generate.rb +316 -0
  81. data/generator/layout_probe.c +507 -0
  82. data/generator/verify_layouts.rb +32 -0
  83. data/lib/box2d/body.rb +172 -0
  84. data/lib/box2d/body_definition.rb +38 -0
  85. data/lib/box2d/body_shapes.rb +135 -0
  86. data/lib/box2d/chain.rb +61 -0
  87. data/lib/box2d/debug_draw.rb +118 -0
  88. data/lib/box2d/events.rb +103 -0
  89. data/lib/box2d/fixed_stepper.rb +39 -0
  90. data/lib/box2d/handle.rb +46 -0
  91. data/lib/box2d/hit.rb +5 -0
  92. data/lib/box2d/joint.rb +197 -0
  93. data/lib/box2d/native.rb +1462 -0
  94. data/lib/box2d/native_loader.rb +45 -0
  95. data/lib/box2d/pixel_scale.rb +29 -0
  96. data/lib/box2d/shape.rb +109 -0
  97. data/lib/box2d/shape_definition.rb +44 -0
  98. data/lib/box2d/value_conversion.rb +80 -0
  99. data/lib/box2d/version.rb +7 -0
  100. data/lib/box2d/world.rb +135 -0
  101. data/lib/box2d/world_joints.rb +156 -0
  102. data/lib/box2d/world_queries.rb +122 -0
  103. data/lib/box2d/world_registry.rb +95 -0
  104. data/lib/box2d.rb +31 -0
  105. data/script/build_platform_gem.rb +24 -0
  106. data/script/deterministic_scene.rb +56 -0
  107. data/script/update_deterministic_snapshot.rb +11 -0
  108. data/script/verify_platform_gem.rb +24 -0
  109. metadata +164 -0
@@ -0,0 +1,179 @@
1
+ // SPDX-FileCopyrightText: 2023 Erin Catto
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ #pragma once
5
+
6
+ #include "core.h"
7
+
8
+ // Macro generated functions for dynamic arrays
9
+ // Pros
10
+ // - type safe
11
+ // - array data debuggable (visible count and capacity)
12
+ // - bounds checking
13
+ // - forward declaration
14
+ // - simple implementation
15
+ // - generates functions (like C++ templates)
16
+ // - functions have https://en.wikipedia.org/wiki/Sequence_point
17
+ // - avoids stretchy buffer dropped pointer update bugs
18
+ // Cons
19
+ // - cannot debug
20
+ // - breaks code navigation
21
+
22
+ // todo_erin consider code-gen: https://github.com/IbrahimHindawi/haikal
23
+
24
+ // Array declaration that doesn't need the type T to be defined
25
+ #define B2_ARRAY_DECLARE( T, PREFIX ) \
26
+ typedef struct \
27
+ { \
28
+ struct T* data; \
29
+ int count; \
30
+ int capacity; \
31
+ } PREFIX##Array; \
32
+ PREFIX##Array PREFIX##Array_Create( int capacity ); \
33
+ void PREFIX##Array_Reserve( PREFIX##Array* a, int newCapacity ); \
34
+ void PREFIX##Array_Destroy( PREFIX##Array* a )
35
+
36
+ #define B2_DECLARE_ARRAY_NATIVE( T, PREFIX ) \
37
+ typedef struct \
38
+ { \
39
+ T* data; \
40
+ int count; \
41
+ int capacity; \
42
+ } PREFIX##Array; \
43
+ /* Create array with initial capacity. Zero initialization is also supported */ \
44
+ PREFIX##Array PREFIX##Array_Create( int capacity ); \
45
+ void PREFIX##Array_Reserve( PREFIX##Array* a, int newCapacity ); \
46
+ void PREFIX##Array_Destroy( PREFIX##Array* a )
47
+
48
+ // Inline array functions that need the type T to be defined
49
+ #define B2_ARRAY_INLINE( T, PREFIX ) \
50
+ /* Resize */ \
51
+ static inline void PREFIX##Array_Resize( PREFIX##Array* a, int count ) \
52
+ { \
53
+ PREFIX##Array_Reserve( a, count ); \
54
+ a->count = count; \
55
+ } \
56
+ /* Get */ \
57
+ static inline T* PREFIX##Array_Get( PREFIX##Array* a, int index ) \
58
+ { \
59
+ B2_ASSERT( 0 <= index && index < a->count ); \
60
+ return a->data + index; \
61
+ } \
62
+ /* Add */ \
63
+ static inline T* PREFIX##Array_Add( PREFIX##Array* a ) \
64
+ { \
65
+ if ( a->count == a->capacity ) \
66
+ { \
67
+ int newCapacity = a->capacity < 2 ? 2 : a->capacity + ( a->capacity >> 1 ); \
68
+ PREFIX##Array_Reserve( a, newCapacity ); \
69
+ } \
70
+ a->count += 1; \
71
+ return a->data + ( a->count - 1 ); \
72
+ } \
73
+ /* Push */ \
74
+ static inline void PREFIX##Array_Push( PREFIX##Array* a, T value ) \
75
+ { \
76
+ if ( a->count == a->capacity ) \
77
+ { \
78
+ int newCapacity = a->capacity < 2 ? 2 : a->capacity + ( a->capacity >> 1 ); \
79
+ PREFIX##Array_Reserve( a, newCapacity ); \
80
+ } \
81
+ a->data[a->count] = value; \
82
+ a->count += 1; \
83
+ } \
84
+ /* Set */ \
85
+ static inline void PREFIX##Array_Set( PREFIX##Array* a, int index, T value ) \
86
+ { \
87
+ B2_ASSERT( 0 <= index && index < a->count ); \
88
+ a->data[index] = value; \
89
+ } \
90
+ /* RemoveSwap */ \
91
+ static inline int PREFIX##Array_RemoveSwap( PREFIX##Array* a, int index ) \
92
+ { \
93
+ B2_ASSERT( 0 <= index && index < a->count ); \
94
+ int movedIndex = B2_NULL_INDEX; \
95
+ if ( index != a->count - 1 ) \
96
+ { \
97
+ movedIndex = a->count - 1; \
98
+ a->data[index] = a->data[movedIndex]; \
99
+ } \
100
+ a->count -= 1; \
101
+ return movedIndex; \
102
+ } \
103
+ /* Pop */ \
104
+ static inline T PREFIX##Array_Pop( PREFIX##Array* a ) \
105
+ { \
106
+ B2_ASSERT( a->count > 0 ); \
107
+ T value = a->data[a->count - 1]; \
108
+ a->count -= 1; \
109
+ return value; \
110
+ } \
111
+ /* Clear */ \
112
+ static inline void PREFIX##Array_Clear( PREFIX##Array* a ) \
113
+ { \
114
+ a->count = 0; \
115
+ } \
116
+ /* ByteCount */ \
117
+ static inline int PREFIX##Array_ByteCount( PREFIX##Array* a ) \
118
+ { \
119
+ return (int)( a->capacity * sizeof( T ) ); \
120
+ }
121
+
122
+ // Array implementations to be instantiated in a source file where the type T is known
123
+ #define B2_ARRAY_SOURCE( T, PREFIX ) \
124
+ /* Create */ \
125
+ PREFIX##Array PREFIX##Array_Create( int capacity ) \
126
+ { \
127
+ PREFIX##Array a = { 0 }; \
128
+ if ( capacity > 0 ) \
129
+ { \
130
+ a.data = b2Alloc( capacity * sizeof( T ) ); \
131
+ a.capacity = capacity; \
132
+ } \
133
+ return a; \
134
+ } \
135
+ /* Reserve */ \
136
+ void PREFIX##Array_Reserve( PREFIX##Array* a, int newCapacity ) \
137
+ { \
138
+ if ( newCapacity <= a->capacity ) \
139
+ { \
140
+ return; \
141
+ } \
142
+ a->data = b2GrowAlloc( a->data, a->capacity * sizeof( T ), newCapacity * sizeof( T ) ); \
143
+ a->capacity = newCapacity; \
144
+ } \
145
+ /* Destroy */ \
146
+ void PREFIX##Array_Destroy( PREFIX##Array* a ) \
147
+ { \
148
+ b2Free( a->data, a->capacity * sizeof( T ) ); \
149
+ a->data = NULL; \
150
+ a->count = 0; \
151
+ a->capacity = 0; \
152
+ }
153
+
154
+ B2_DECLARE_ARRAY_NATIVE( int, b2Int );
155
+ B2_ARRAY_INLINE( int, b2Int )
156
+
157
+ // Declare all the arrays
158
+ B2_ARRAY_DECLARE( b2Body, b2Body );
159
+ B2_ARRAY_DECLARE( b2BodyMoveEvent, b2BodyMoveEvent );
160
+ B2_ARRAY_DECLARE( b2BodySim, b2BodySim );
161
+ B2_ARRAY_DECLARE( b2BodyState, b2BodyState );
162
+ B2_ARRAY_DECLARE( b2ChainShape, b2ChainShape );
163
+ B2_ARRAY_DECLARE( b2Contact, b2Contact );
164
+ B2_ARRAY_DECLARE( b2ContactBeginTouchEvent, b2ContactBeginTouchEvent );
165
+ B2_ARRAY_DECLARE( b2ContactEndTouchEvent, b2ContactEndTouchEvent );
166
+ B2_ARRAY_DECLARE( b2ContactHitEvent, b2ContactHitEvent );
167
+ B2_ARRAY_DECLARE( b2ContactSim, b2ContactSim );
168
+ B2_ARRAY_DECLARE( b2Island, b2Island );
169
+ B2_ARRAY_DECLARE( b2IslandSim, b2IslandSim );
170
+ B2_ARRAY_DECLARE( b2Joint, b2Joint );
171
+ B2_ARRAY_DECLARE( b2JointSim, b2JointSim );
172
+ B2_ARRAY_DECLARE( b2Sensor, b2Sensor );
173
+ B2_ARRAY_DECLARE( b2SensorBeginTouchEvent, b2SensorBeginTouchEvent );
174
+ B2_ARRAY_DECLARE( b2SensorEndTouchEvent, b2SensorEndTouchEvent );
175
+ B2_ARRAY_DECLARE( b2SensorTaskContext, b2SensorTaskContext );
176
+ B2_ARRAY_DECLARE( b2Shape, b2Shape );
177
+ B2_ARRAY_DECLARE( b2ShapeRef, b2ShapeRef );
178
+ B2_ARRAY_DECLARE( b2SolverSet, b2SolverSet );
179
+ B2_ARRAY_DECLARE( b2TaskContext, b2TaskContext );
@@ -0,0 +1,79 @@
1
+ // SPDX-FileCopyrightText: 2023 Erin Catto
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ #pragma once
5
+
6
+ #include "core.h"
7
+
8
+ #include <stdint.h>
9
+
10
+ #if defined( _MSC_VER )
11
+ #include <intrin.h>
12
+ #endif
13
+
14
+ static inline void b2AtomicStoreInt( b2AtomicInt* a, int value )
15
+ {
16
+ #if defined( _MSC_VER )
17
+ (void)_InterlockedExchange( (long*)&a->value, value );
18
+ #elif defined( __GNUC__ ) || defined( __clang__ )
19
+ __atomic_store_n( &a->value, value, __ATOMIC_SEQ_CST );
20
+ #else
21
+ #error "Unsupported platform"
22
+ #endif
23
+ }
24
+
25
+ static inline int b2AtomicLoadInt( b2AtomicInt* a )
26
+ {
27
+ #if defined( _MSC_VER )
28
+ return _InterlockedOr( (long*)&a->value, 0 );
29
+ #elif defined( __GNUC__ ) || defined( __clang__ )
30
+ return __atomic_load_n( &a->value, __ATOMIC_SEQ_CST );
31
+ #else
32
+ #error "Unsupported platform"
33
+ #endif
34
+ }
35
+
36
+ static inline int b2AtomicFetchAddInt( b2AtomicInt* a, int increment )
37
+ {
38
+ #if defined( _MSC_VER )
39
+ return _InterlockedExchangeAdd( (long*)&a->value, (long)increment );
40
+ #elif defined( __GNUC__ ) || defined( __clang__ )
41
+ return __atomic_fetch_add( &a->value, increment, __ATOMIC_SEQ_CST );
42
+ #else
43
+ #error "Unsupported platform"
44
+ #endif
45
+ }
46
+
47
+ static inline bool b2AtomicCompareExchangeInt( b2AtomicInt* a, int expected, int desired )
48
+ {
49
+ #if defined( _MSC_VER )
50
+ return _InterlockedCompareExchange( (long*)&a->value, (long)desired, (long)expected ) == expected;
51
+ #elif defined( __GNUC__ ) || defined( __clang__ )
52
+ // The value written to expected is ignored
53
+ return __atomic_compare_exchange_n( &a->value, &expected, desired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
54
+ #else
55
+ #error "Unsupported platform"
56
+ #endif
57
+ }
58
+
59
+ static inline void b2AtomicStoreU32( b2AtomicU32* a, uint32_t value )
60
+ {
61
+ #if defined( _MSC_VER )
62
+ (void)_InterlockedExchange( (long*)&a->value, value );
63
+ #elif defined( __GNUC__ ) || defined( __clang__ )
64
+ __atomic_store_n( &a->value, value, __ATOMIC_SEQ_CST );
65
+ #else
66
+ #error "Unsupported platform"
67
+ #endif
68
+ }
69
+
70
+ static inline uint32_t b2AtomicLoadU32( b2AtomicU32* a )
71
+ {
72
+ #if defined( _MSC_VER )
73
+ return (uint32_t)_InterlockedOr( (long*)&a->value, 0 );
74
+ #elif defined( __GNUC__ ) || defined( __clang__ )
75
+ return __atomic_load_n( &a->value, __ATOMIC_SEQ_CST );
76
+ #else
77
+ #error "Unsupported platform"
78
+ #endif
79
+ }
@@ -0,0 +1,67 @@
1
+ // SPDX-FileCopyrightText: 2023 Erin Catto
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ #include "bitset.h"
5
+
6
+ #include <string.h>
7
+
8
+ b2BitSet b2CreateBitSet( uint32_t bitCapacity )
9
+ {
10
+ b2BitSet bitSet = { 0 };
11
+
12
+ bitSet.blockCapacity = ( bitCapacity + sizeof( uint64_t ) * 8 - 1 ) / ( sizeof( uint64_t ) * 8 );
13
+ bitSet.blockCount = 0;
14
+ bitSet.bits = b2Alloc( bitSet.blockCapacity * sizeof( uint64_t ) );
15
+ memset( bitSet.bits, 0, bitSet.blockCapacity * sizeof( uint64_t ) );
16
+ return bitSet;
17
+ }
18
+
19
+ void b2DestroyBitSet( b2BitSet* bitSet )
20
+ {
21
+ b2Free( bitSet->bits, bitSet->blockCapacity * sizeof( uint64_t ) );
22
+ bitSet->blockCapacity = 0;
23
+ bitSet->blockCount = 0;
24
+ bitSet->bits = NULL;
25
+ }
26
+
27
+ void b2SetBitCountAndClear( b2BitSet* bitSet, uint32_t bitCount )
28
+ {
29
+ uint32_t blockCount = ( bitCount + sizeof( uint64_t ) * 8 - 1 ) / ( sizeof( uint64_t ) * 8 );
30
+ if ( bitSet->blockCapacity < blockCount )
31
+ {
32
+ b2DestroyBitSet( bitSet );
33
+ uint32_t newBitCapacity = bitCount + ( bitCount >> 1 );
34
+ *bitSet = b2CreateBitSet( newBitCapacity );
35
+ }
36
+
37
+ bitSet->blockCount = blockCount;
38
+ memset( bitSet->bits, 0, bitSet->blockCount * sizeof( uint64_t ) );
39
+ }
40
+
41
+ void b2GrowBitSet( b2BitSet* bitSet, uint32_t blockCount )
42
+ {
43
+ B2_ASSERT( blockCount > bitSet->blockCount );
44
+ if ( blockCount > bitSet->blockCapacity )
45
+ {
46
+ uint32_t oldCapacity = bitSet->blockCapacity;
47
+ bitSet->blockCapacity = blockCount + blockCount / 2;
48
+ uint64_t* newBits = b2Alloc( bitSet->blockCapacity * sizeof( uint64_t ) );
49
+ memset( newBits, 0, bitSet->blockCapacity * sizeof( uint64_t ) );
50
+ B2_ASSERT( bitSet->bits != NULL );
51
+ memcpy( newBits, bitSet->bits, oldCapacity * sizeof( uint64_t ) );
52
+ b2Free( bitSet->bits, oldCapacity * sizeof( uint64_t ) );
53
+ bitSet->bits = newBits;
54
+ }
55
+
56
+ bitSet->blockCount = blockCount;
57
+ }
58
+
59
+ void b2InPlaceUnion( b2BitSet* B2_RESTRICT setA, const b2BitSet* B2_RESTRICT setB )
60
+ {
61
+ B2_ASSERT( setA->blockCount == setB->blockCount );
62
+ uint32_t blockCount = setA->blockCount;
63
+ for ( uint32_t i = 0; i < blockCount; ++i )
64
+ {
65
+ setA->bits[i] |= setB->bits[i];
66
+ }
67
+ }
@@ -0,0 +1,65 @@
1
+ // SPDX-FileCopyrightText: 2023 Erin Catto
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ #pragma once
5
+
6
+ #include "core.h"
7
+
8
+ #include <stdbool.h>
9
+ #include <stdint.h>
10
+
11
+ // Bit set provides fast operations on large arrays of bits.
12
+ typedef struct b2BitSet
13
+ {
14
+ uint64_t* bits;
15
+ uint32_t blockCapacity;
16
+ uint32_t blockCount;
17
+ } b2BitSet;
18
+
19
+ b2BitSet b2CreateBitSet( uint32_t bitCapacity );
20
+ void b2DestroyBitSet( b2BitSet* bitSet );
21
+ void b2SetBitCountAndClear( b2BitSet* bitSet, uint32_t bitCount );
22
+ void b2InPlaceUnion( b2BitSet* setA, const b2BitSet* setB );
23
+ void b2GrowBitSet( b2BitSet* bitSet, uint32_t blockCount );
24
+
25
+ static inline void b2SetBit( b2BitSet* bitSet, uint32_t bitIndex )
26
+ {
27
+ uint32_t blockIndex = bitIndex / 64;
28
+ B2_ASSERT( blockIndex < bitSet->blockCount );
29
+ bitSet->bits[blockIndex] |= ( (uint64_t)1 << bitIndex % 64 );
30
+ }
31
+
32
+ static inline void b2SetBitGrow( b2BitSet* bitSet, uint32_t bitIndex )
33
+ {
34
+ uint32_t blockIndex = bitIndex / 64;
35
+ if ( blockIndex >= bitSet->blockCount )
36
+ {
37
+ b2GrowBitSet( bitSet, blockIndex + 1 );
38
+ }
39
+ bitSet->bits[blockIndex] |= ( (uint64_t)1 << bitIndex % 64 );
40
+ }
41
+
42
+ static inline void b2ClearBit( b2BitSet* bitSet, uint32_t bitIndex )
43
+ {
44
+ uint32_t blockIndex = bitIndex / 64;
45
+ if ( blockIndex >= bitSet->blockCount )
46
+ {
47
+ return;
48
+ }
49
+ bitSet->bits[blockIndex] &= ~( (uint64_t)1 << bitIndex % 64 );
50
+ }
51
+
52
+ static inline bool b2GetBit( const b2BitSet* bitSet, uint32_t bitIndex )
53
+ {
54
+ uint32_t blockIndex = bitIndex / 64;
55
+ if ( blockIndex >= bitSet->blockCount )
56
+ {
57
+ return false;
58
+ }
59
+ return ( bitSet->bits[blockIndex] & ( (uint64_t)1 << bitIndex % 64 ) ) != 0;
60
+ }
61
+
62
+ static inline int b2GetBitSetBytes( b2BitSet* bitSet )
63
+ {
64
+ return bitSet->blockCapacity * sizeof( uint64_t );
65
+ }