chipmunk 5.3.4.5 → 6.1.3.0.rc1
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.
- data/ext/chipmunk/chipmunk.c +199 -28
- data/ext/chipmunk/chipmunk.h +123 -68
- data/ext/chipmunk/chipmunk_ffi.h +129 -11
- data/ext/chipmunk/chipmunk_private.h +232 -16
- data/ext/chipmunk/chipmunk_types.h +94 -30
- data/ext/chipmunk/chipmunk_unsafe.h +12 -3
- data/ext/chipmunk/constraints/cpConstraint.h +90 -34
- data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
- data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
- data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
- data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
- data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
- data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
- data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
- data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
- data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
- data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
- data/ext/chipmunk/constraints/util.h +36 -44
- data/ext/chipmunk/cpArbiter.c +159 -94
- data/ext/chipmunk/cpArbiter.h +135 -129
- data/ext/chipmunk/cpArray.c +37 -56
- data/ext/chipmunk/cpBB.c +1 -12
- data/ext/chipmunk/cpBB.h +80 -18
- data/ext/chipmunk/cpBBTree.c +891 -0
- data/ext/chipmunk/cpBody.c +185 -47
- data/ext/chipmunk/cpBody.h +156 -124
- data/ext/chipmunk/cpCollision.c +126 -115
- data/ext/chipmunk/cpConstraint.c +10 -6
- data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
- data/ext/chipmunk/cpDampedSpring.c +25 -18
- data/ext/chipmunk/cpGearJoint.c +23 -17
- data/ext/chipmunk/cpGrooveJoint.c +26 -22
- data/ext/chipmunk/cpHashSet.c +51 -51
- data/ext/chipmunk/cpPinJoint.c +26 -19
- data/ext/chipmunk/cpPivotJoint.c +23 -19
- data/ext/chipmunk/cpPolyShape.c +93 -69
- data/ext/chipmunk/cpPolyShape.h +33 -69
- data/ext/chipmunk/cpRatchetJoint.c +26 -21
- data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
- data/ext/chipmunk/cpShape.c +122 -133
- data/ext/chipmunk/cpShape.h +146 -95
- data/ext/chipmunk/cpSimpleMotor.c +24 -17
- data/ext/chipmunk/cpSlideJoint.c +28 -26
- data/ext/chipmunk/cpSpace.c +251 -196
- data/ext/chipmunk/cpSpace.h +173 -103
- data/ext/chipmunk/cpSpaceComponent.c +236 -159
- data/ext/chipmunk/cpSpaceHash.c +259 -159
- data/ext/chipmunk/cpSpaceQuery.c +127 -59
- data/ext/chipmunk/cpSpaceStep.c +235 -197
- data/ext/chipmunk/cpSpatialIndex.c +69 -0
- data/ext/chipmunk/cpSpatialIndex.h +227 -0
- data/ext/chipmunk/cpSweep1D.c +254 -0
- data/ext/chipmunk/cpVect.c +11 -26
- data/ext/chipmunk/cpVect.h +76 -71
- data/ext/chipmunk/extconf.rb +4 -31
- data/ext/chipmunk/prime.h +1 -1
- data/ext/chipmunk/rb_chipmunk.c +36 -45
- data/ext/chipmunk/rb_chipmunk.h +6 -3
- data/ext/chipmunk/rb_cpArbiter.c +2 -2
- data/ext/chipmunk/rb_cpBB.c +116 -35
- data/ext/chipmunk/rb_cpBody.c +5 -12
- data/ext/chipmunk/rb_cpConstraint.c +144 -9
- data/ext/chipmunk/rb_cpShape.c +69 -78
- data/ext/chipmunk/rb_cpSpace.c +81 -76
- metadata +61 -61
- data/LICENSE +0 -22
- data/README +0 -110
- data/Rakefile +0 -102
- data/ext/chipmunk/cpArray.h +0 -49
- data/ext/chipmunk/cpCollision.h +0 -28
- data/ext/chipmunk/cpHashSet.h +0 -82
- data/ext/chipmunk/cpSpaceHash.h +0 -110
- data/lib/chipmunk.rb +0 -194
@@ -19,9 +19,6 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
#include <stdlib.h>
|
23
|
-
#include <math.h>
|
24
|
-
|
25
22
|
#include "chipmunk_private.h"
|
26
23
|
#include "constraints/util.h"
|
27
24
|
|
@@ -31,9 +28,10 @@ defaultSpringForce(cpDampedSpring *spring, cpFloat dist){
|
|
31
28
|
}
|
32
29
|
|
33
30
|
static void
|
34
|
-
preStep(cpDampedSpring *spring, cpFloat dt
|
31
|
+
preStep(cpDampedSpring *spring, cpFloat dt)
|
35
32
|
{
|
36
|
-
|
33
|
+
cpBody *a = spring->constraint.a;
|
34
|
+
cpBody *b = spring->constraint.b;
|
37
35
|
|
38
36
|
spring->r1 = cpvrotate(spring->anchr1, a->rot);
|
39
37
|
spring->r2 = cpvrotate(spring->anchr2, b->rot);
|
@@ -43,6 +41,7 @@ preStep(cpDampedSpring *spring, cpFloat dt, cpFloat dt_inv)
|
|
43
41
|
spring->n = cpvmult(delta, 1.0f/(dist ? dist : INFINITY));
|
44
42
|
|
45
43
|
cpFloat k = k_scalar(a, b, spring->r1, spring->r2, spring->n);
|
44
|
+
cpAssertSoft(k != 0.0, "Unsolvable spring.");
|
46
45
|
spring->nMass = 1.0f/k;
|
47
46
|
|
48
47
|
spring->target_vrn = 0.0f;
|
@@ -50,46 +49,52 @@ preStep(cpDampedSpring *spring, cpFloat dt, cpFloat dt_inv)
|
|
50
49
|
|
51
50
|
// apply spring force
|
52
51
|
cpFloat f_spring = spring->springForceFunc((cpConstraint *)spring, dist);
|
53
|
-
|
52
|
+
cpFloat j_spring = spring->jAcc = f_spring*dt;
|
53
|
+
apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, j_spring));
|
54
54
|
}
|
55
55
|
|
56
|
+
static void applyCachedImpulse(cpDampedSpring *spring, cpFloat dt_coef){}
|
57
|
+
|
56
58
|
static void
|
57
|
-
applyImpulse(cpDampedSpring *spring)
|
59
|
+
applyImpulse(cpDampedSpring *spring, cpFloat dt)
|
58
60
|
{
|
59
|
-
|
61
|
+
cpBody *a = spring->constraint.a;
|
62
|
+
cpBody *b = spring->constraint.b;
|
60
63
|
|
61
64
|
cpVect n = spring->n;
|
62
65
|
cpVect r1 = spring->r1;
|
63
66
|
cpVect r2 = spring->r2;
|
64
67
|
|
65
68
|
// compute relative velocity
|
66
|
-
cpFloat vrn = normal_relative_velocity(a, b, r1, r2, n)
|
69
|
+
cpFloat vrn = normal_relative_velocity(a, b, r1, r2, n);
|
67
70
|
|
68
71
|
// compute velocity loss from drag
|
69
|
-
|
70
|
-
cpFloat v_damp = -vrn*spring->v_coef;
|
72
|
+
cpFloat v_damp = (spring->target_vrn - vrn)*spring->v_coef;
|
71
73
|
spring->target_vrn = vrn + v_damp;
|
72
74
|
|
73
|
-
|
75
|
+
cpFloat j_damp = v_damp*spring->nMass;
|
76
|
+
spring->jAcc += j_damp;
|
77
|
+
apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, j_damp));
|
74
78
|
}
|
75
79
|
|
76
80
|
static cpFloat
|
77
|
-
getImpulse(
|
81
|
+
getImpulse(cpDampedSpring *spring)
|
78
82
|
{
|
79
|
-
return
|
83
|
+
return spring->jAcc;
|
80
84
|
}
|
81
85
|
|
82
86
|
static const cpConstraintClass klass = {
|
83
|
-
(
|
84
|
-
(
|
85
|
-
(
|
87
|
+
(cpConstraintPreStepImpl)preStep,
|
88
|
+
(cpConstraintApplyCachedImpulseImpl)applyCachedImpulse,
|
89
|
+
(cpConstraintApplyImpulseImpl)applyImpulse,
|
90
|
+
(cpConstraintGetImpulseImpl)getImpulse,
|
86
91
|
};
|
87
92
|
CP_DefineClassGetter(cpDampedSpring)
|
88
93
|
|
89
94
|
cpDampedSpring *
|
90
95
|
cpDampedSpringAlloc(void)
|
91
96
|
{
|
92
|
-
return (cpDampedSpring *)
|
97
|
+
return (cpDampedSpring *)cpcalloc(1, sizeof(cpDampedSpring));
|
93
98
|
}
|
94
99
|
|
95
100
|
cpDampedSpring *
|
@@ -105,6 +110,8 @@ cpDampedSpringInit(cpDampedSpring *spring, cpBody *a, cpBody *b, cpVect anchr1,
|
|
105
110
|
spring->damping = damping;
|
106
111
|
spring->springForceFunc = (cpDampedSpringForceFunc)defaultSpringForce;
|
107
112
|
|
113
|
+
spring->jAcc = 0.0f;
|
114
|
+
|
108
115
|
return spring;
|
109
116
|
}
|
110
117
|
|
data/ext/chipmunk/cpGearJoint.c
CHANGED
@@ -19,44 +19,49 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
#include <stdlib.h>
|
23
|
-
|
24
22
|
#include "chipmunk_private.h"
|
25
23
|
#include "constraints/util.h"
|
26
24
|
|
27
25
|
static void
|
28
|
-
preStep(cpGearJoint *joint, cpFloat dt
|
26
|
+
preStep(cpGearJoint *joint, cpFloat dt)
|
29
27
|
{
|
30
|
-
|
28
|
+
cpBody *a = joint->constraint.a;
|
29
|
+
cpBody *b = joint->constraint.b;
|
31
30
|
|
32
31
|
// calculate moment of inertia coefficient.
|
33
32
|
joint->iSum = 1.0f/(a->i_inv*joint->ratio_inv + joint->ratio*b->i_inv);
|
34
33
|
|
35
34
|
// calculate bias velocity
|
36
35
|
cpFloat maxBias = joint->constraint.maxBias;
|
37
|
-
joint->bias = cpfclamp(-joint->constraint.
|
38
|
-
|
39
|
-
// compute max impulse
|
40
|
-
joint->jMax = J_MAX(joint, dt);
|
36
|
+
joint->bias = cpfclamp(-bias_coef(joint->constraint.errorBias, dt)*(b->a*joint->ratio - a->a - joint->phase)/dt, -maxBias, maxBias);
|
37
|
+
}
|
41
38
|
|
42
|
-
|
43
|
-
|
39
|
+
static void
|
40
|
+
applyCachedImpulse(cpGearJoint *joint, cpFloat dt_coef)
|
41
|
+
{
|
42
|
+
cpBody *a = joint->constraint.a;
|
43
|
+
cpBody *b = joint->constraint.b;
|
44
|
+
|
45
|
+
cpFloat j = joint->jAcc*dt_coef;
|
44
46
|
a->w -= j*a->i_inv*joint->ratio_inv;
|
45
47
|
b->w += j*b->i_inv;
|
46
48
|
}
|
47
49
|
|
48
50
|
static void
|
49
|
-
applyImpulse(cpGearJoint *joint)
|
51
|
+
applyImpulse(cpGearJoint *joint, cpFloat dt)
|
50
52
|
{
|
51
|
-
|
53
|
+
cpBody *a = joint->constraint.a;
|
54
|
+
cpBody *b = joint->constraint.b;
|
52
55
|
|
53
56
|
// compute relative rotational velocity
|
54
57
|
cpFloat wr = b->w*joint->ratio - a->w;
|
55
58
|
|
59
|
+
cpFloat jMax = joint->constraint.maxForce*dt;
|
60
|
+
|
56
61
|
// compute normal impulse
|
57
62
|
cpFloat j = (joint->bias - wr)*joint->iSum;
|
58
63
|
cpFloat jOld = joint->jAcc;
|
59
|
-
joint->jAcc = cpfclamp(jOld + j, -
|
64
|
+
joint->jAcc = cpfclamp(jOld + j, -jMax, jMax);
|
60
65
|
j = joint->jAcc - jOld;
|
61
66
|
|
62
67
|
// apply impulse
|
@@ -71,16 +76,17 @@ getImpulse(cpGearJoint *joint)
|
|
71
76
|
}
|
72
77
|
|
73
78
|
static const cpConstraintClass klass = {
|
74
|
-
(
|
75
|
-
(
|
76
|
-
(
|
79
|
+
(cpConstraintPreStepImpl)preStep,
|
80
|
+
(cpConstraintApplyCachedImpulseImpl)applyCachedImpulse,
|
81
|
+
(cpConstraintApplyImpulseImpl)applyImpulse,
|
82
|
+
(cpConstraintGetImpulseImpl)getImpulse,
|
77
83
|
};
|
78
84
|
CP_DefineClassGetter(cpGearJoint)
|
79
85
|
|
80
86
|
cpGearJoint *
|
81
87
|
cpGearJointAlloc(void)
|
82
88
|
{
|
83
|
-
return (cpGearJoint *)
|
89
|
+
return (cpGearJoint *)cpcalloc(1, sizeof(cpGearJoint));
|
84
90
|
}
|
85
91
|
|
86
92
|
cpGearJoint *
|
@@ -19,15 +19,14 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
#include <stdlib.h>
|
23
|
-
|
24
22
|
#include "chipmunk_private.h"
|
25
23
|
#include "constraints/util.h"
|
26
24
|
|
27
25
|
static void
|
28
|
-
preStep(cpGrooveJoint *joint, cpFloat dt
|
26
|
+
preStep(cpGrooveJoint *joint, cpFloat dt)
|
29
27
|
{
|
30
|
-
|
28
|
+
cpBody *a = joint->constraint.a;
|
29
|
+
cpBody *b = joint->constraint.b;
|
31
30
|
|
32
31
|
// calculate endpoints in worldspace
|
33
32
|
cpVect ta = cpBodyLocal2World(a, joint->grv_a);
|
@@ -55,30 +54,34 @@ preStep(cpGrooveJoint *joint, cpFloat dt, cpFloat dt_inv)
|
|
55
54
|
}
|
56
55
|
|
57
56
|
// Calculate mass tensor
|
58
|
-
k_tensor(a, b, joint->r1, joint->r2
|
59
|
-
|
60
|
-
// compute max impulse
|
61
|
-
joint->jMaxLen = J_MAX(joint, dt);
|
57
|
+
joint->k = k_tensor(a, b, joint->r1, joint->r2);
|
62
58
|
|
63
59
|
// calculate bias velocity
|
64
60
|
cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));
|
65
|
-
joint->bias = cpvclamp(cpvmult(delta, -joint->constraint.
|
66
|
-
|
67
|
-
|
68
|
-
|
61
|
+
joint->bias = cpvclamp(cpvmult(delta, -bias_coef(joint->constraint.errorBias, dt)/dt), joint->constraint.maxBias);
|
62
|
+
}
|
63
|
+
|
64
|
+
static void
|
65
|
+
applyCachedImpulse(cpGrooveJoint *joint, cpFloat dt_coef)
|
66
|
+
{
|
67
|
+
cpBody *a = joint->constraint.a;
|
68
|
+
cpBody *b = joint->constraint.b;
|
69
|
+
|
70
|
+
apply_impulses(a, b, joint->r1, joint->r2, cpvmult(joint->jAcc, dt_coef));
|
69
71
|
}
|
70
72
|
|
71
73
|
static inline cpVect
|
72
|
-
grooveConstrain(cpGrooveJoint *joint, cpVect j){
|
74
|
+
grooveConstrain(cpGrooveJoint *joint, cpVect j, cpFloat dt){
|
73
75
|
cpVect n = joint->grv_tn;
|
74
76
|
cpVect jClamp = (joint->clamp*cpvcross(j, n) > 0.0f) ? j : cpvproject(j, n);
|
75
|
-
return cpvclamp(jClamp, joint->
|
77
|
+
return cpvclamp(jClamp, joint->constraint.maxForce*dt);
|
76
78
|
}
|
77
79
|
|
78
80
|
static void
|
79
|
-
applyImpulse(cpGrooveJoint *joint)
|
81
|
+
applyImpulse(cpGrooveJoint *joint, cpFloat dt)
|
80
82
|
{
|
81
|
-
|
83
|
+
cpBody *a = joint->constraint.a;
|
84
|
+
cpBody *b = joint->constraint.b;
|
82
85
|
|
83
86
|
cpVect r1 = joint->r1;
|
84
87
|
cpVect r2 = joint->r2;
|
@@ -86,9 +89,9 @@ applyImpulse(cpGrooveJoint *joint)
|
|
86
89
|
// compute impulse
|
87
90
|
cpVect vr = relative_velocity(a, b, r1, r2);
|
88
91
|
|
89
|
-
cpVect j =
|
92
|
+
cpVect j = cpMat2x2Transform(joint->k, cpvsub(joint->bias, vr));
|
90
93
|
cpVect jOld = joint->jAcc;
|
91
|
-
joint->jAcc = grooveConstrain(joint, cpvadd(jOld, j));
|
94
|
+
joint->jAcc = grooveConstrain(joint, cpvadd(jOld, j), dt);
|
92
95
|
j = cpvsub(joint->jAcc, jOld);
|
93
96
|
|
94
97
|
// apply impulse
|
@@ -102,16 +105,17 @@ getImpulse(cpGrooveJoint *joint)
|
|
102
105
|
}
|
103
106
|
|
104
107
|
static const cpConstraintClass klass = {
|
105
|
-
(
|
106
|
-
(
|
107
|
-
(
|
108
|
+
(cpConstraintPreStepImpl)preStep,
|
109
|
+
(cpConstraintApplyCachedImpulseImpl)applyCachedImpulse,
|
110
|
+
(cpConstraintApplyImpulseImpl)applyImpulse,
|
111
|
+
(cpConstraintGetImpulseImpl)getImpulse,
|
108
112
|
};
|
109
113
|
CP_DefineClassGetter(cpGrooveJoint)
|
110
114
|
|
111
115
|
cpGrooveJoint *
|
112
116
|
cpGrooveJointAlloc(void)
|
113
117
|
{
|
114
|
-
return (cpGrooveJoint *)
|
118
|
+
return (cpGrooveJoint *)cpcalloc(1, sizeof(cpGrooveJoint));
|
115
119
|
}
|
116
120
|
|
117
121
|
cpGrooveJoint *
|
data/ext/chipmunk/cpHashSet.c
CHANGED
@@ -19,48 +19,49 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
#include <stdlib.h>
|
23
|
-
#include <assert.h>
|
24
|
-
|
25
22
|
#include "chipmunk_private.h"
|
26
23
|
#include "prime.h"
|
27
24
|
|
28
|
-
|
25
|
+
typedef struct cpHashSetBin {
|
26
|
+
void *elt;
|
27
|
+
cpHashValue hash;
|
28
|
+
struct cpHashSetBin *next;
|
29
|
+
} cpHashSetBin;
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
{
|
33
|
-
// Free the table.
|
34
|
-
cpfree(set->table);
|
31
|
+
struct cpHashSet {
|
32
|
+
unsigned int entries, size;
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
cpHashSetEqlFunc eql;
|
35
|
+
void *default_value;
|
36
|
+
|
37
|
+
cpHashSetBin **table;
|
38
|
+
cpHashSetBin *pooledBins;
|
39
|
+
|
40
|
+
cpArray *allocatedBuffers;
|
41
|
+
};
|
39
42
|
|
40
43
|
void
|
41
44
|
cpHashSetFree(cpHashSet *set)
|
42
45
|
{
|
43
46
|
if(set){
|
44
|
-
|
47
|
+
cpfree(set->table);
|
48
|
+
|
49
|
+
cpArrayFreeEach(set->allocatedBuffers, cpfree);
|
50
|
+
cpArrayFree(set->allocatedBuffers);
|
51
|
+
|
45
52
|
cpfree(set);
|
46
53
|
}
|
47
54
|
}
|
48
55
|
|
49
56
|
cpHashSet *
|
50
|
-
|
51
|
-
{
|
52
|
-
return (cpHashSet *)cpcalloc(1, sizeof(cpHashSet));
|
53
|
-
}
|
54
|
-
|
55
|
-
cpHashSet *
|
56
|
-
cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)
|
57
|
+
cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc)
|
57
58
|
{
|
59
|
+
cpHashSet *set = (cpHashSet *)cpcalloc(1, sizeof(cpHashSet));
|
60
|
+
|
58
61
|
set->size = next_prime(size);
|
59
62
|
set->entries = 0;
|
60
63
|
|
61
64
|
set->eql = eqlFunc;
|
62
|
-
set->trans = trans;
|
63
|
-
|
64
65
|
set->default_value = NULL;
|
65
66
|
|
66
67
|
set->table = (cpHashSetBin **)cpcalloc(set->size, sizeof(cpHashSetBin *));
|
@@ -71,10 +72,10 @@ cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTrans
|
|
71
72
|
return set;
|
72
73
|
}
|
73
74
|
|
74
|
-
|
75
|
-
|
75
|
+
void
|
76
|
+
cpHashSetSetDefaultValue(cpHashSet *set, void *default_value)
|
76
77
|
{
|
77
|
-
|
78
|
+
set->default_value = default_value;
|
78
79
|
}
|
79
80
|
|
80
81
|
static int
|
@@ -87,18 +88,18 @@ static void
|
|
87
88
|
cpHashSetResize(cpHashSet *set)
|
88
89
|
{
|
89
90
|
// Get the next approximate doubled prime.
|
90
|
-
int newSize = next_prime(set->size + 1);
|
91
|
+
unsigned int newSize = next_prime(set->size + 1);
|
91
92
|
// Allocate a new table.
|
92
93
|
cpHashSetBin **newTable = (cpHashSetBin **)cpcalloc(newSize, sizeof(cpHashSetBin *));
|
93
94
|
|
94
95
|
// Iterate over the chains.
|
95
|
-
for(int i=0; i<set->size; i++){
|
96
|
+
for(unsigned int i=0; i<set->size; i++){
|
96
97
|
// Rehash the bins into the new table.
|
97
98
|
cpHashSetBin *bin = set->table[i];
|
98
99
|
while(bin){
|
99
100
|
cpHashSetBin *next = bin->next;
|
100
101
|
|
101
|
-
|
102
|
+
cpHashValue idx = bin->hash%newSize;
|
102
103
|
bin->next = newTable[idx];
|
103
104
|
newTable[idx] = bin;
|
104
105
|
|
@@ -131,41 +132,44 @@ getUnusedBin(cpHashSet *set)
|
|
131
132
|
} else {
|
132
133
|
// Pool is exhausted, make more
|
133
134
|
int count = CP_BUFFER_BYTES/sizeof(cpHashSetBin);
|
134
|
-
|
135
|
+
cpAssertHard(count, "Internal Error: Buffer size is too small.");
|
135
136
|
|
136
|
-
cpHashSetBin *buffer = (cpHashSetBin *)
|
137
|
+
cpHashSetBin *buffer = (cpHashSetBin *)cpcalloc(1, CP_BUFFER_BYTES);
|
137
138
|
cpArrayPush(set->allocatedBuffers, buffer);
|
138
139
|
|
139
|
-
// push all but the first one, return
|
140
|
+
// push all but the first one, return it instead
|
140
141
|
for(int i=1; i<count; i++) recycleBin(set, buffer + i);
|
141
142
|
return buffer;
|
142
143
|
}
|
143
144
|
}
|
144
145
|
|
146
|
+
int
|
147
|
+
cpHashSetCount(cpHashSet *set)
|
148
|
+
{
|
149
|
+
return set->entries;
|
150
|
+
}
|
151
|
+
|
145
152
|
void *
|
146
|
-
cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data)
|
153
|
+
cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data, cpHashSetTransFunc trans)
|
147
154
|
{
|
148
|
-
|
155
|
+
cpHashValue idx = hash%set->size;
|
149
156
|
|
150
157
|
// Find the bin with the matching element.
|
151
158
|
cpHashSetBin *bin = set->table[idx];
|
152
159
|
while(bin && !set->eql(ptr, bin->elt))
|
153
160
|
bin = bin->next;
|
154
161
|
|
155
|
-
// Create it necessary.
|
162
|
+
// Create it if necessary.
|
156
163
|
if(!bin){
|
157
164
|
bin = getUnusedBin(set);
|
158
165
|
bin->hash = hash;
|
159
|
-
bin->elt =
|
166
|
+
bin->elt = (trans ? trans(ptr, data) : data);
|
160
167
|
|
161
168
|
bin->next = set->table[idx];
|
162
169
|
set->table[idx] = bin;
|
163
170
|
|
164
171
|
set->entries++;
|
165
|
-
|
166
|
-
// Resize the set if it's full.
|
167
|
-
if(setIsFull(set))
|
168
|
-
cpHashSetResize(set);
|
172
|
+
if(setIsFull(set)) cpHashSetResize(set);
|
169
173
|
}
|
170
174
|
|
171
175
|
return bin->elt;
|
@@ -174,11 +178,9 @@ cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data)
|
|
174
178
|
void *
|
175
179
|
cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)
|
176
180
|
{
|
177
|
-
|
181
|
+
cpHashValue idx = hash%set->size;
|
178
182
|
|
179
|
-
// Pointer to the previous bin pointer.
|
180
183
|
cpHashSetBin **prev_ptr = &set->table[idx];
|
181
|
-
// Pointer the the current bin.
|
182
184
|
cpHashSetBin *bin = set->table[idx];
|
183
185
|
|
184
186
|
// Find the bin
|
@@ -189,15 +191,14 @@ cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)
|
|
189
191
|
|
190
192
|
// Remove it if it exists.
|
191
193
|
if(bin){
|
192
|
-
// Update the previous
|
194
|
+
// Update the previous linked list pointer
|
193
195
|
(*prev_ptr) = bin->next;
|
194
196
|
set->entries--;
|
195
197
|
|
196
|
-
void *
|
197
|
-
|
198
|
+
void *elt = bin->elt;
|
198
199
|
recycleBin(set, bin);
|
199
200
|
|
200
|
-
return
|
201
|
+
return elt;
|
201
202
|
}
|
202
203
|
|
203
204
|
return NULL;
|
@@ -206,7 +207,7 @@ cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)
|
|
206
207
|
void *
|
207
208
|
cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr)
|
208
209
|
{
|
209
|
-
|
210
|
+
cpHashValue idx = hash%set->size;
|
210
211
|
cpHashSetBin *bin = set->table[idx];
|
211
212
|
while(bin && !set->eql(ptr, bin->elt))
|
212
213
|
bin = bin->next;
|
@@ -215,9 +216,9 @@ cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr)
|
|
215
216
|
}
|
216
217
|
|
217
218
|
void
|
218
|
-
cpHashSetEach(cpHashSet *set,
|
219
|
+
cpHashSetEach(cpHashSet *set, cpHashSetIteratorFunc func, void *data)
|
219
220
|
{
|
220
|
-
for(int i=0; i<set->size; i++){
|
221
|
+
for(unsigned int i=0; i<set->size; i++){
|
221
222
|
cpHashSetBin *bin = set->table[i];
|
222
223
|
while(bin){
|
223
224
|
cpHashSetBin *next = bin->next;
|
@@ -230,8 +231,7 @@ cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data)
|
|
230
231
|
void
|
231
232
|
cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data)
|
232
233
|
{
|
233
|
-
|
234
|
-
for(int i=0; i<set->size; i++){
|
234
|
+
for(unsigned int i=0; i<set->size; i++){
|
235
235
|
// The rest works similarly to cpHashSetRemove() above.
|
236
236
|
cpHashSetBin **prev_ptr = &set->table[i];
|
237
237
|
cpHashSetBin *bin = set->table[i];
|