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.
Files changed (73) hide show
  1. data/ext/chipmunk/chipmunk.c +199 -28
  2. data/ext/chipmunk/chipmunk.h +123 -68
  3. data/ext/chipmunk/chipmunk_ffi.h +129 -11
  4. data/ext/chipmunk/chipmunk_private.h +232 -16
  5. data/ext/chipmunk/chipmunk_types.h +94 -30
  6. data/ext/chipmunk/chipmunk_unsafe.h +12 -3
  7. data/ext/chipmunk/constraints/cpConstraint.h +90 -34
  8. data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
  9. data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
  10. data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
  11. data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
  12. data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
  13. data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
  14. data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
  15. data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
  16. data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
  17. data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
  18. data/ext/chipmunk/constraints/util.h +36 -44
  19. data/ext/chipmunk/cpArbiter.c +159 -94
  20. data/ext/chipmunk/cpArbiter.h +135 -129
  21. data/ext/chipmunk/cpArray.c +37 -56
  22. data/ext/chipmunk/cpBB.c +1 -12
  23. data/ext/chipmunk/cpBB.h +80 -18
  24. data/ext/chipmunk/cpBBTree.c +891 -0
  25. data/ext/chipmunk/cpBody.c +185 -47
  26. data/ext/chipmunk/cpBody.h +156 -124
  27. data/ext/chipmunk/cpCollision.c +126 -115
  28. data/ext/chipmunk/cpConstraint.c +10 -6
  29. data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
  30. data/ext/chipmunk/cpDampedSpring.c +25 -18
  31. data/ext/chipmunk/cpGearJoint.c +23 -17
  32. data/ext/chipmunk/cpGrooveJoint.c +26 -22
  33. data/ext/chipmunk/cpHashSet.c +51 -51
  34. data/ext/chipmunk/cpPinJoint.c +26 -19
  35. data/ext/chipmunk/cpPivotJoint.c +23 -19
  36. data/ext/chipmunk/cpPolyShape.c +93 -69
  37. data/ext/chipmunk/cpPolyShape.h +33 -69
  38. data/ext/chipmunk/cpRatchetJoint.c +26 -21
  39. data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
  40. data/ext/chipmunk/cpShape.c +122 -133
  41. data/ext/chipmunk/cpShape.h +146 -95
  42. data/ext/chipmunk/cpSimpleMotor.c +24 -17
  43. data/ext/chipmunk/cpSlideJoint.c +28 -26
  44. data/ext/chipmunk/cpSpace.c +251 -196
  45. data/ext/chipmunk/cpSpace.h +173 -103
  46. data/ext/chipmunk/cpSpaceComponent.c +236 -159
  47. data/ext/chipmunk/cpSpaceHash.c +259 -159
  48. data/ext/chipmunk/cpSpaceQuery.c +127 -59
  49. data/ext/chipmunk/cpSpaceStep.c +235 -197
  50. data/ext/chipmunk/cpSpatialIndex.c +69 -0
  51. data/ext/chipmunk/cpSpatialIndex.h +227 -0
  52. data/ext/chipmunk/cpSweep1D.c +254 -0
  53. data/ext/chipmunk/cpVect.c +11 -26
  54. data/ext/chipmunk/cpVect.h +76 -71
  55. data/ext/chipmunk/extconf.rb +4 -31
  56. data/ext/chipmunk/prime.h +1 -1
  57. data/ext/chipmunk/rb_chipmunk.c +36 -45
  58. data/ext/chipmunk/rb_chipmunk.h +6 -3
  59. data/ext/chipmunk/rb_cpArbiter.c +2 -2
  60. data/ext/chipmunk/rb_cpBB.c +116 -35
  61. data/ext/chipmunk/rb_cpBody.c +5 -12
  62. data/ext/chipmunk/rb_cpConstraint.c +144 -9
  63. data/ext/chipmunk/rb_cpShape.c +69 -78
  64. data/ext/chipmunk/rb_cpSpace.c +81 -76
  65. metadata +61 -61
  66. data/LICENSE +0 -22
  67. data/README +0 -110
  68. data/Rakefile +0 -102
  69. data/ext/chipmunk/cpArray.h +0 -49
  70. data/ext/chipmunk/cpCollision.h +0 -28
  71. data/ext/chipmunk/cpHashSet.h +0 -82
  72. data/ext/chipmunk/cpSpaceHash.h +0 -110
  73. 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, cpFloat dt_inv)
31
+ preStep(cpDampedSpring *spring, cpFloat dt)
35
32
  {
36
- CONSTRAINT_BEGIN(spring, a, b);
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
- apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, f_spring*dt));
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
- CONSTRAINT_BEGIN(spring, a, b);
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) - spring->target_vrn;
69
+ cpFloat vrn = normal_relative_velocity(a, b, r1, r2, n);
67
70
 
68
71
  // compute velocity loss from drag
69
- // not 100% certain this is derived correctly, though it makes sense
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
- apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, v_damp*spring->nMass));
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(cpConstraint *constraint)
81
+ getImpulse(cpDampedSpring *spring)
78
82
  {
79
- return 0.0f;
83
+ return spring->jAcc;
80
84
  }
81
85
 
82
86
  static const cpConstraintClass klass = {
83
- (cpConstraintPreStepFunction)preStep,
84
- (cpConstraintApplyImpulseFunction)applyImpulse,
85
- (cpConstraintGetImpulseFunction)getImpulse,
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 *)cpmalloc(sizeof(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
 
@@ -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, cpFloat dt_inv)
26
+ preStep(cpGearJoint *joint, cpFloat dt)
29
27
  {
30
- CONSTRAINT_BEGIN(joint, a, b);
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.biasCoef*dt_inv*(b->a*joint->ratio - a->a - joint->phase), -maxBias, maxBias);
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
- // apply joint torque
43
- cpFloat j = joint->jAcc;
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
- CONSTRAINT_BEGIN(joint, a, b);
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, -joint->jMax, joint->jMax);
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
- (cpConstraintPreStepFunction)preStep,
75
- (cpConstraintApplyImpulseFunction)applyImpulse,
76
- (cpConstraintGetImpulseFunction)getImpulse,
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 *)cpmalloc(sizeof(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, cpFloat dt_inv)
26
+ preStep(cpGrooveJoint *joint, cpFloat dt)
29
27
  {
30
- CONSTRAINT_BEGIN(joint, a, b);
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, &joint->k1, &joint->k2);
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.biasCoef*dt_inv), joint->constraint.maxBias);
66
-
67
- // apply accumulated impulse
68
- apply_impulses(a, b, joint->r1, joint->r2, joint->jAcc);
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->jMaxLen);
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
- CONSTRAINT_BEGIN(joint, a, b);
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 = mult_k(cpvsub(joint->bias, vr), joint->k1, joint->k2);
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
- (cpConstraintPreStepFunction)preStep,
106
- (cpConstraintApplyImpulseFunction)applyImpulse,
107
- (cpConstraintGetImpulseFunction)getImpulse,
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 *)cpmalloc(sizeof(cpGrooveJoint));
118
+ return (cpGrooveJoint *)cpcalloc(1, sizeof(cpGrooveJoint));
115
119
  }
116
120
 
117
121
  cpGrooveJoint *
@@ -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
- static void freeWrap(void *ptr, void *unused){cpfree(ptr);}
25
+ typedef struct cpHashSetBin {
26
+ void *elt;
27
+ cpHashValue hash;
28
+ struct cpHashSetBin *next;
29
+ } cpHashSetBin;
29
30
 
30
- void
31
- cpHashSetDestroy(cpHashSet *set)
32
- {
33
- // Free the table.
34
- cpfree(set->table);
31
+ struct cpHashSet {
32
+ unsigned int entries, size;
35
33
 
36
- cpArrayEach(set->allocatedBuffers, freeWrap, NULL);
37
- cpArrayFree(set->allocatedBuffers);
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
- cpHashSetDestroy(set);
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
- cpHashSetAlloc(void)
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
- cpHashSet *
75
- cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)
75
+ void
76
+ cpHashSetSetDefaultValue(cpHashSet *set, void *default_value)
76
77
  {
77
- return cpHashSetInit(cpHashSetAlloc(), size, eqlFunc, trans);
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
- int idx = bin->hash%newSize;
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
- cpAssert(count, "Buffer size is too small.");
135
+ cpAssertHard(count, "Internal Error: Buffer size is too small.");
135
136
 
136
- cpHashSetBin *buffer = (cpHashSetBin *)cpmalloc(CP_BUFFER_BYTES);
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 the first instead
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
- int idx = hash%set->size;
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 = set->trans(ptr, data); // Transform the pointer.
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
- int idx = hash%set->size;
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 bin pointer to point to the next bin.
194
+ // Update the previous linked list pointer
193
195
  (*prev_ptr) = bin->next;
194
196
  set->entries--;
195
197
 
196
- void *return_value = bin->elt;
197
-
198
+ void *elt = bin->elt;
198
199
  recycleBin(set, bin);
199
200
 
200
- return return_value;
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
- int idx = hash%set->size;
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, cpHashSetIterFunc func, void *data)
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
- // Iterate over all the chains.
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];