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.
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];