chipmunk 5.3.4.5 → 6.1.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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];
|