ray 0.2.0 → 0.2.1
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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +0 -1
- data/ext/drawable.c +21 -0
- data/ext/extconf.rb +1 -1
- data/ext/image.c +18 -0
- data/ext/matrix.c +29 -0
- data/ext/mo.c +194 -139
- data/ext/mo.h +57 -12
- data/ext/polygon.c +5 -0
- data/ext/say_buffer.c +24 -34
- data/ext/say_buffer_slice.c +24 -30
- data/ext/say_context.c +38 -0
- data/ext/say_context.h +24 -0
- data/ext/say_drawable.c +45 -38
- data/ext/say_drawable.h +1 -0
- data/ext/say_image.c +33 -16
- data/ext/say_image.h +4 -0
- data/ext/say_image_target.c +15 -26
- data/ext/say_index_buffer.c +8 -12
- data/ext/say_index_buffer_slice.c +22 -28
- data/ext/say_matrix.c +32 -0
- data/ext/say_matrix.h +6 -0
- data/ext/say_music.c +5 -3
- data/ext/say_pixel_bus.c +14 -17
- data/ext/say_shader.c +36 -32
- data/ext/say_target.c +3 -8
- data/ext/say_x11_window.h +9 -7
- data/ext/sprite.c +1 -0
- data/ext/text.c +2 -0
- data/lib/ray/matrix.rb +8 -2
- data/lib/ray/ray.rb +1 -1
- data/lib/ray/scene.rb +1 -2
- data/samples/turtle/byzantium.rb +1 -1
- data/samples/turtle/mandala.rb +1 -1
- data/test/drawable_test.rb +12 -0
- data/test/helpers.rb +7 -4
- data/test/image_test.rb +4 -0
- data/test/matrix_test.rb +14 -0
- metadata +327 -327
- data/samples/opengl/instancing.rbc +0 -3231
- data/samples/shaders/geometry.rbc +0 -2074
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c843cd687fe51478f64ee9e801e9ee9132f6ee4b
|
4
|
+
data.tar.gz: dc17809793037e626252a10c884847236cd0834b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b94b4d5571a75a68ddd840ddae8987c0ac4e71a7823f5019021ac9ea127f03658c7c582c9c6bba81ecc44732d4e4510a8c557964c242373d194d8d9bcca3377e
|
7
|
+
data.tar.gz: 8c4e58c2d0d9df0817349e4e1cc662b7e1645876435b44dd4f2dd62ab364e3510b0468f8ec5ab87ea9e1ef2631c9cececdd6ae0d18dfca38693eb5fd439e68fb
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Ray - Copyright (c) 2011 - Mon ouïe
|
2
|
+
|
3
|
+
This software is provided 'as-is', without any express or
|
4
|
+
implied warranty. In no event will the authors be held
|
5
|
+
liable for any damages arising from the use of this software.
|
6
|
+
|
7
|
+
Permission is granted to anyone to use this software for any purpose,
|
8
|
+
including commercial applications, and to alter it and redistribute
|
9
|
+
it freely, subject to the following restrictions:
|
10
|
+
|
11
|
+
1. The origin of this software must not be misrepresented;
|
12
|
+
you must not claim that you wrote the original software.
|
13
|
+
If you use this software in a product, an acknowledgment
|
14
|
+
in the product documentation would be appreciated but
|
15
|
+
is not required.
|
16
|
+
|
17
|
+
2. Altered source versions must be plainly marked as such,
|
18
|
+
and must not be misrepresented as being the original software.
|
19
|
+
|
20
|
+
3. This notice may not be removed or altered from any
|
21
|
+
source distribution.
|
data/README.md
CHANGED
data/ext/drawable.c
CHANGED
@@ -123,6 +123,8 @@ VALUE ray_drawable_alloc(VALUE self) {
|
|
123
123
|
|
124
124
|
VALUE rb = Data_Wrap_Struct(self, NULL, ray_drawable_free, obj);
|
125
125
|
|
126
|
+
rb_iv_set(rb, "@shader_attributes", Qnil);
|
127
|
+
|
126
128
|
obj->drawable = NULL;
|
127
129
|
obj->obj = rb;
|
128
130
|
|
@@ -389,6 +391,23 @@ VALUE ray_drawable_set_matrix(VALUE self, VALUE val) {
|
|
389
391
|
return val;
|
390
392
|
}
|
391
393
|
|
394
|
+
/*
|
395
|
+
* @overload default_matrix
|
396
|
+
* Default transformation matrix
|
397
|
+
*
|
398
|
+
* This is useful when matrix is set to a custom matrix or matrix_proc is
|
399
|
+
* non-nil. It allows to retrieve the matrix that would be used otherwise, for
|
400
|
+
* instance to multiply it by another matrix to apply more transformations.
|
401
|
+
*
|
402
|
+
* @return [Ray::Matrix]
|
403
|
+
*/
|
404
|
+
static
|
405
|
+
VALUE ray_drawable_default_matrix(VALUE self) {
|
406
|
+
say_matrix *mat = say_drawable_get_default_matrix(ray_rb2drawable(self));
|
407
|
+
return Data_Wrap_Struct(rb_path2class("Ray::Matrix"), NULL, say_matrix_free,
|
408
|
+
mat);
|
409
|
+
}
|
410
|
+
|
392
411
|
/*
|
393
412
|
* @overload transform(point)
|
394
413
|
* Applies the transformations to a point
|
@@ -577,6 +596,8 @@ void Init_ray_drawable() {
|
|
577
596
|
|
578
597
|
rb_define_method(ray_cDrawable, "matrix", ray_drawable_matrix, 0);
|
579
598
|
rb_define_method(ray_cDrawable, "matrix=", ray_drawable_set_matrix, 1);
|
599
|
+
rb_define_method(ray_cDrawable, "default_matrix",
|
600
|
+
ray_drawable_default_matrix, 0);
|
580
601
|
rb_define_method(ray_cDrawable, "transform", ray_drawable_transform, 1);
|
581
602
|
/* @endgroup */
|
582
603
|
|
data/ext/extconf.rb
CHANGED
data/ext/image.c
CHANGED
@@ -230,12 +230,29 @@ VALUE ray_image_tex_rect(VALUE self, VALUE rect) {
|
|
230
230
|
/*
|
231
231
|
* Binds the texture, which will be used as GL_TEXTURE_2D when drawing with
|
232
232
|
* OpenGL
|
233
|
+
*
|
234
|
+
* This is equivalent to calling #bind_to with unit set to 0.
|
233
235
|
*/
|
234
236
|
VALUE ray_image_bind(VALUE self) {
|
235
237
|
say_image_bind(ray_rb2image(self));
|
236
238
|
return self;
|
237
239
|
}
|
238
240
|
|
241
|
+
/*
|
242
|
+
* @overload bind_to(unit)
|
243
|
+
* Binds the texture to a given unit (0 <= unit < 32)
|
244
|
+
* @param [Integer] unit Texture unit
|
245
|
+
*/
|
246
|
+
VALUE ray_image_bind_to(VALUE self, VALUE unit) {
|
247
|
+
int c_unit = NUM2INT(unit);
|
248
|
+
if (c_unit >= 32 || c_unit < 0)
|
249
|
+
rb_raise(rb_eRangeError, "texture unit %d out of bounds", c_unit);
|
250
|
+
|
251
|
+
say_image_bind_to(ray_rb2image(self), c_unit);
|
252
|
+
|
253
|
+
return self;
|
254
|
+
}
|
255
|
+
|
239
256
|
/*
|
240
257
|
* @return [Integer] Identifer of the image's texture
|
241
258
|
*/
|
@@ -322,6 +339,7 @@ void Init_ray_image() {
|
|
322
339
|
|
323
340
|
/* @group OpenGL access */
|
324
341
|
rb_define_method(ray_cImage, "bind", ray_image_bind, 0);
|
342
|
+
rb_define_method(ray_cImage, "bind_to", ray_image_bind_to, 1);
|
325
343
|
rb_define_method(ray_cImage, "texture", ray_image_texture, 0);
|
326
344
|
/* @endgroup */
|
327
345
|
}
|
data/ext/matrix.c
CHANGED
@@ -336,6 +336,33 @@ VALUE ray_matrix_perspective(VALUE self,
|
|
336
336
|
return self;
|
337
337
|
}
|
338
338
|
|
339
|
+
/*
|
340
|
+
* @overload set_transformation(origin, pos, z, scale, angle)
|
341
|
+
* Resets the matrix content to a 2D transformation matrix
|
342
|
+
*
|
343
|
+
* @param [Vector2] origin Origin of all the transformations
|
344
|
+
* @param [Vector2] pos Position of the object
|
345
|
+
* @param [Float] z Z ordering
|
346
|
+
* @param [Vector2] scale Scaling factor
|
347
|
+
* @param [Float] angle Rotation
|
348
|
+
*/
|
349
|
+
static
|
350
|
+
VALUE ray_matrix_set_transformation(VALUE self,
|
351
|
+
VALUE origin,
|
352
|
+
VALUE pos, VALUE z,
|
353
|
+
VALUE scale,
|
354
|
+
VALUE angle) {
|
355
|
+
rb_check_frozen(self);
|
356
|
+
|
357
|
+
say_matrix_set_transformation(ray_rb2matrix(self),
|
358
|
+
ray_convert_to_vector2(origin),
|
359
|
+
ray_convert_to_vector2(pos),
|
360
|
+
NUM2DBL(z),
|
361
|
+
ray_convert_to_vector2(scale),
|
362
|
+
NUM2DBL(angle));
|
363
|
+
|
364
|
+
return self;
|
365
|
+
}
|
339
366
|
|
340
367
|
/*
|
341
368
|
Document-class: Ray::Matrix
|
@@ -371,4 +398,6 @@ void Init_ray_matrix() {
|
|
371
398
|
rb_define_method(ray_cMatrix, "look_at", ray_matrix_look_at, 3);
|
372
399
|
rb_define_method(ray_cMatrix, "orthogonal", ray_matrix_orthogonal, 6);
|
373
400
|
rb_define_method(ray_cMatrix, "perspective", ray_matrix_perspective, 4);
|
401
|
+
rb_define_method(ray_cMatrix, "set_transformation",
|
402
|
+
ray_matrix_set_transformation, 5);
|
374
403
|
}
|
data/ext/mo.c
CHANGED
@@ -28,7 +28,7 @@ void mo_array_init(mo_array *ary, size_t el_size) {
|
|
28
28
|
}
|
29
29
|
|
30
30
|
void mo_array_release(mo_array *ary) {
|
31
|
-
if (ary->release
|
31
|
+
if (ary->release) {
|
32
32
|
void *end = mo_array_end(ary);
|
33
33
|
for (void *i = mo_array_begin(ary); i < end; mo_array_next(ary, &i))
|
34
34
|
ary->release(i);
|
@@ -168,114 +168,174 @@ void mo_array_reserve(mo_array *ary, size_t size) {
|
|
168
168
|
if (ary->capa > size)
|
169
169
|
return;
|
170
170
|
|
171
|
-
ary->buffer = realloc(ary->buffer, size * ary->
|
171
|
+
ary->buffer = realloc(ary->buffer, size * ary->capa);
|
172
172
|
ary->capa = size;
|
173
173
|
}
|
174
174
|
|
175
175
|
void mo_array_shrink(mo_array *ary) {
|
176
|
-
|
177
|
-
ary->buffer = realloc(ary->buffer, ary->size * ary->el_size);
|
176
|
+
ary->buffer = realloc(ary->buffer, ary->size * ary->capa);
|
178
177
|
ary->capa = ary->size;
|
179
178
|
}
|
180
179
|
|
181
180
|
/**
|
182
|
-
*
|
181
|
+
* String.
|
183
182
|
*/
|
184
183
|
|
185
|
-
|
186
|
-
|
184
|
+
void mo_string_init(mo_string *str) {
|
185
|
+
mo_array_init(str, sizeof(char));
|
186
|
+
mo_array_resize(str, 1);
|
187
|
+
mo_string_at(str, 0) = '\0';
|
188
|
+
}
|
189
|
+
|
190
|
+
void mo_string_init_from_cstr(mo_string *str, const char *cstr) {
|
191
|
+
mo_string_init(str);
|
192
|
+
mo_string_replace(str, cstr);
|
193
|
+
}
|
194
|
+
|
195
|
+
void mo_string_init_from_buf(mo_string *str, const char *cstr, size_t size) {
|
196
|
+
mo_string_init(str);
|
197
|
+
mo_array_resize(str, size + 1);
|
198
|
+
memcpy(mo_string_cstr(str), cstr, size);
|
199
|
+
mo_string_at(str, size) = '\0';
|
200
|
+
}
|
201
|
+
|
202
|
+
void mo_string_replace(mo_string *str, const char *cstr) {
|
203
|
+
mo_array_resize(str, strlen(cstr) + 1);
|
204
|
+
strcpy(mo_string_cstr(str), cstr);
|
205
|
+
}
|
206
|
+
|
207
|
+
size_t mo_string_len(mo_string *str) {
|
208
|
+
return str->size - 1;
|
209
|
+
}
|
210
|
+
|
211
|
+
void mo_string_append(mo_string *str, const char *cstr) {
|
212
|
+
size_t old_size = str->size;
|
213
|
+
|
214
|
+
mo_array_resize(str, old_size + strlen(cstr));
|
215
|
+
strcpy(mo_array_get_ptr(str, old_size - 1, char), cstr);
|
216
|
+
}
|
217
|
+
|
218
|
+
char *mo_string_cstr(mo_string *str) {
|
219
|
+
return (char*)str->buffer;
|
220
|
+
}
|
221
|
+
|
222
|
+
int mo_string_cmp(mo_string *a, mo_string *b) {
|
223
|
+
return strcmp(mo_string_cstr(a), mo_string_cstr(b));
|
224
|
+
}
|
225
|
+
|
226
|
+
/**
|
227
|
+
* Doubly linked list.
|
228
|
+
*/
|
187
229
|
|
188
|
-
|
230
|
+
void mo_list_init(mo_list *list, size_t el_size) {
|
231
|
+
list->head = list->last = NULL;
|
189
232
|
|
190
233
|
list->release = NULL;
|
191
234
|
list->copy = NULL;
|
192
235
|
|
193
236
|
list->el_size = el_size;
|
194
|
-
|
195
|
-
return list;
|
196
237
|
}
|
197
238
|
|
198
|
-
void
|
199
|
-
|
200
|
-
|
239
|
+
void mo_list_release(mo_list *list) {
|
240
|
+
mo_list_it *it = list->head;
|
241
|
+
|
242
|
+
while (it) {
|
243
|
+
mo_list_it *next = it->next;
|
201
244
|
|
202
245
|
if (list->release)
|
203
|
-
list->release(
|
204
|
-
free(
|
246
|
+
list->release(it->data);
|
247
|
+
free(it);
|
205
248
|
|
206
|
-
|
207
|
-
}
|
249
|
+
it = next;
|
250
|
+
}
|
208
251
|
}
|
209
252
|
|
210
|
-
mo_list *
|
211
|
-
mo_list *
|
253
|
+
mo_list *mo_list_create(size_t el_size) {
|
254
|
+
mo_list *list = malloc(sizeof(mo_list));
|
255
|
+
mo_list_init(list, el_size);
|
256
|
+
return list;
|
257
|
+
}
|
212
258
|
|
213
|
-
|
214
|
-
|
259
|
+
void mo_list_free(mo_list *list) {
|
260
|
+
mo_list_release(list);
|
261
|
+
free(list);
|
262
|
+
}
|
215
263
|
|
216
|
-
|
217
|
-
|
264
|
+
void mo_list_prepend(mo_list *list, mo_list_it *it, void *data) {
|
265
|
+
mo_list_it *new_it = malloc(offsetof(mo_list_it, data) + list->el_size);
|
218
266
|
|
219
|
-
|
267
|
+
new_it->next = it;
|
220
268
|
|
221
|
-
|
222
|
-
|
269
|
+
if (it && it->prev) {
|
270
|
+
new_it->prev = it->prev;
|
271
|
+
it->prev->next = new_it;
|
272
|
+
}
|
273
|
+
else
|
274
|
+
new_it->prev = NULL;
|
223
275
|
|
224
|
-
|
276
|
+
if (it)
|
277
|
+
it->prev = new_it;
|
225
278
|
|
226
|
-
if (
|
227
|
-
|
228
|
-
else if (data)
|
229
|
-
memcpy(prev->data, data, prev->el_size);
|
279
|
+
if (!list->last)
|
280
|
+
list->last = new_it;
|
230
281
|
|
231
|
-
|
232
|
-
|
282
|
+
if (it == list->head)
|
283
|
+
list->head = new_it;
|
233
284
|
|
234
|
-
|
235
|
-
|
285
|
+
if (list->copy)
|
286
|
+
list->copy(new_it->data, data);
|
287
|
+
else
|
288
|
+
memcpy(new_it->data, data, list->el_size);
|
289
|
+
}
|
236
290
|
|
237
|
-
|
238
|
-
|
291
|
+
void mo_list_insert(mo_list *list, mo_list_it *it, void *data) {
|
292
|
+
mo_list_it *new_it = malloc(offsetof(mo_list_it, data) + list->el_size);
|
239
293
|
|
240
|
-
|
241
|
-
list->next->prev = next;
|
294
|
+
new_it->prev = it;
|
242
295
|
|
243
|
-
|
296
|
+
if (it && it->next) {
|
297
|
+
new_it->next = it->next;
|
298
|
+
it->next->prev = new_it;
|
299
|
+
}
|
300
|
+
else
|
301
|
+
new_it->next = NULL;
|
244
302
|
|
245
|
-
|
246
|
-
|
303
|
+
if (it)
|
304
|
+
it->next = new_it;
|
247
305
|
|
248
|
-
|
306
|
+
if (!list->head)
|
307
|
+
list->head = new_it;
|
249
308
|
|
250
|
-
if (
|
251
|
-
|
252
|
-
else if (data)
|
253
|
-
memcpy(next->data, data, next->el_size);
|
309
|
+
if (it == list->last)
|
310
|
+
list->last = new_it;
|
254
311
|
|
255
|
-
|
312
|
+
if (list->copy)
|
313
|
+
list->copy(new_it->data, data);
|
314
|
+
else
|
315
|
+
memcpy(new_it->data, data, list->el_size);
|
256
316
|
}
|
257
317
|
|
258
|
-
|
259
|
-
if (
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
list->next->prev = list->prev;
|
318
|
+
void mo_list_delete(mo_list *list, mo_list_it *it) {
|
319
|
+
if (it->prev)
|
320
|
+
it->prev->next = it->next;
|
321
|
+
else /* is head */
|
322
|
+
list->head = it->next;
|
264
323
|
|
265
|
-
|
324
|
+
if (it->next)
|
325
|
+
it->next->prev = it->prev;
|
326
|
+
else /* is tail */
|
327
|
+
list->last = it->prev;
|
266
328
|
|
267
329
|
if (list->release)
|
268
|
-
list->release(
|
269
|
-
free(
|
270
|
-
|
271
|
-
return next;
|
330
|
+
list->release(it->data);
|
331
|
+
free(it);
|
272
332
|
}
|
273
333
|
|
274
|
-
void mo_list_set(mo_list *list, void *data) {
|
334
|
+
void mo_list_set(mo_list *list, mo_list_it *it, void *data) {
|
275
335
|
if (list->copy)
|
276
|
-
list->copy(
|
336
|
+
list->copy(it->data, data);
|
277
337
|
else
|
278
|
-
memcpy(
|
338
|
+
memcpy(it->data, data, list->el_size);
|
279
339
|
}
|
280
340
|
|
281
341
|
/**
|
@@ -287,34 +347,11 @@ void mo_hash_zero_ptr(void *ptr) {
|
|
287
347
|
*(void**)ptr = NULL;
|
288
348
|
}
|
289
349
|
|
290
|
-
static
|
291
|
-
void mo_hash_list_free(void *ptr) {
|
292
|
-
mo_list *list = *(mo_list**)ptr;
|
293
|
-
if (list) mo_list_free(list);
|
294
|
-
}
|
295
|
-
|
296
|
-
static
|
297
|
-
void mo_hash_bucket_free(void *ptr) {
|
298
|
-
uint8_t *start = ptr;
|
299
|
-
|
300
|
-
mo_hash *hash = *(mo_hash**)start;
|
301
|
-
if (!hash)
|
302
|
-
return;
|
303
|
-
|
304
|
-
if (hash->key_release)
|
305
|
-
hash->key_release(start + sizeof(mo_hash*));
|
306
|
-
|
307
|
-
if (hash->release)
|
308
|
-
hash->release(start + sizeof(mo_hash*) + hash->key_size);
|
309
|
-
}
|
310
|
-
|
311
|
-
static
|
312
350
|
void mo_hash_init(mo_hash *hash, size_t key_size, size_t el_size) {
|
313
|
-
mo_array_init(&hash->buffer, sizeof(
|
351
|
+
mo_array_init(&hash->buffer, sizeof(mo_hash_list*));
|
314
352
|
|
315
|
-
hash->buffer.init
|
353
|
+
hash->buffer.init = mo_hash_zero_ptr;
|
316
354
|
mo_array_resize(&hash->buffer, 16);
|
317
|
-
hash->buffer.release = mo_hash_list_free;
|
318
355
|
|
319
356
|
hash->release = NULL;
|
320
357
|
hash->copy = NULL;
|
@@ -331,8 +368,23 @@ void mo_hash_init(mo_hash *hash, size_t key_size, size_t el_size) {
|
|
331
368
|
hash->hash_of = NULL;
|
332
369
|
}
|
333
370
|
|
334
|
-
static
|
335
371
|
void mo_hash_release(mo_hash *hash) {
|
372
|
+
for (size_t i = 0; i < hash->buffer.size; i++) {
|
373
|
+
mo_hash_list *it = mo_array_get_as(&hash->buffer, i, mo_hash_list*);
|
374
|
+
|
375
|
+
while (it) {
|
376
|
+
mo_hash_list *next = it->next;
|
377
|
+
|
378
|
+
if (hash->key_release)
|
379
|
+
hash->key_release(it->data);
|
380
|
+
if (hash->release)
|
381
|
+
hash->release(it->data + hash->key_size);
|
382
|
+
free(it);
|
383
|
+
|
384
|
+
it = next;
|
385
|
+
}
|
386
|
+
}
|
387
|
+
|
336
388
|
mo_array_release(&hash->buffer);
|
337
389
|
}
|
338
390
|
|
@@ -349,12 +401,11 @@ void mo_hash_free(mo_hash *hash) {
|
|
349
401
|
|
350
402
|
bool mo_hash_has_key(mo_hash *hash, void *key) {
|
351
403
|
int id = hash->hash_of(key) % hash->buffer.size;
|
352
|
-
|
404
|
+
mo_hash_list *it = mo_array_get_as(&hash->buffer, id, mo_hash_list*);
|
353
405
|
|
354
|
-
|
355
|
-
if (hash->key_cmp(
|
406
|
+
for (; it; it = it->next) {
|
407
|
+
if (hash->key_cmp(it->data, key) == 0)
|
356
408
|
return true;
|
357
|
-
bucket = bucket->next;
|
358
409
|
}
|
359
410
|
|
360
411
|
return false;
|
@@ -362,12 +413,11 @@ bool mo_hash_has_key(mo_hash *hash, void *key) {
|
|
362
413
|
|
363
414
|
void *mo_hash_get(mo_hash *hash, void *key) {
|
364
415
|
int id = hash->hash_of(key) % hash->buffer.size;
|
365
|
-
|
416
|
+
mo_hash_list *it = mo_array_get_as(&hash->buffer, id, mo_hash_list*);
|
366
417
|
|
367
|
-
|
368
|
-
if (hash->key_cmp(
|
369
|
-
return
|
370
|
-
bucket = bucket->next;
|
418
|
+
for (; it; it = it->next) {
|
419
|
+
if (hash->key_cmp(it->data, key) == 0)
|
420
|
+
return it->data + hash->key_size;
|
371
421
|
}
|
372
422
|
|
373
423
|
return NULL;
|
@@ -402,34 +452,22 @@ void mo_hash_grow(mo_hash *hash) {
|
|
402
452
|
/*
|
403
453
|
* Release the current hash, and use the copy instead.
|
404
454
|
*/
|
405
|
-
|
406
|
-
*hash = copy;
|
407
|
-
|
408
|
-
/*
|
409
|
-
* Because each element actually contains a pointer to the hash, we need to
|
410
|
-
* update it.
|
411
|
-
*/
|
455
|
+
mo_array_release(&hash->buffer);
|
412
456
|
|
413
|
-
|
414
|
-
for (; !mo_hash_it_is_end(&it); mo_hash_it_next(&it)) {
|
415
|
-
mo_hash **data = (mo_hash**)(it.list->data);
|
416
|
-
*data = hash;
|
417
|
-
}
|
457
|
+
*hash = copy;
|
418
458
|
}
|
419
459
|
|
420
460
|
static
|
421
461
|
void mo_hash_fill_bucket(mo_hash *hash, void *store, void *key, void *data) {
|
422
|
-
*(mo_hash**)store = hash;
|
423
|
-
|
424
462
|
if (hash->key_copy)
|
425
|
-
hash->key_copy((uint8_t*)store
|
463
|
+
hash->key_copy((uint8_t*)store, key);
|
426
464
|
else
|
427
|
-
memcpy((uint8_t*)store
|
465
|
+
memcpy((uint8_t*)store, key, hash->key_size);
|
428
466
|
|
429
467
|
if (hash->copy)
|
430
|
-
hash->copy((uint8_t*)store +
|
468
|
+
hash->copy((uint8_t*)store + hash->key_size, data);
|
431
469
|
else
|
432
|
-
memcpy((uint8_t*)store +
|
470
|
+
memcpy((uint8_t*)store + hash->key_size, data,
|
433
471
|
hash->el_size);
|
434
472
|
}
|
435
473
|
|
@@ -438,30 +476,31 @@ void mo_hash_set(mo_hash *hash, void *key, void *data) {
|
|
438
476
|
mo_hash_grow(hash);
|
439
477
|
|
440
478
|
int id = hash->hash_of(key) % hash->buffer.size;
|
441
|
-
|
479
|
+
mo_hash_list *bucket = mo_array_get_as(&hash->buffer, id, mo_hash_list*);
|
442
480
|
|
443
481
|
hash->size += 1;
|
444
482
|
|
445
483
|
if (!bucket) {
|
446
|
-
bucket =
|
447
|
-
|
484
|
+
bucket = malloc(offsetof(mo_hash_list, data) +
|
485
|
+
hash->key_size + hash->el_size);
|
448
486
|
|
487
|
+
bucket->next = NULL;
|
449
488
|
mo_hash_fill_bucket(hash, bucket->data, key, data);
|
450
489
|
|
451
|
-
mo_array_get_as(&hash->buffer, id,
|
490
|
+
mo_array_get_as(&hash->buffer, id, mo_hash_list*) = bucket;
|
452
491
|
}
|
453
492
|
else {
|
454
|
-
|
493
|
+
mo_hash_list *it = bucket, *last = bucket;
|
494
|
+
|
455
495
|
while (it) {
|
456
|
-
if (hash->key_cmp(it->data
|
496
|
+
if (hash->key_cmp(it->data, key) == 0) {
|
457
497
|
hash->size -= 1;
|
458
498
|
|
459
499
|
if (hash->copy) {
|
460
|
-
hash->copy(it->data +
|
500
|
+
hash->copy(it->data + hash->key_size, data);
|
461
501
|
}
|
462
502
|
else {
|
463
|
-
memcpy(it->data +
|
464
|
-
hash->el_size);
|
503
|
+
memcpy(it->data + hash->key_size, data, hash->el_size);
|
465
504
|
}
|
466
505
|
|
467
506
|
return;
|
@@ -471,28 +510,41 @@ void mo_hash_set(mo_hash *hash, void *key, void *data) {
|
|
471
510
|
it = it->next;
|
472
511
|
}
|
473
512
|
|
474
|
-
last =
|
513
|
+
last = malloc(offsetof(mo_hash_list, data) +
|
514
|
+
hash->key_size + hash->el_size);
|
515
|
+
last->next = NULL;
|
475
516
|
mo_hash_fill_bucket(hash, last->data, key, data);
|
517
|
+
|
518
|
+
bucket->next = last;
|
476
519
|
}
|
477
520
|
}
|
478
521
|
|
479
522
|
void mo_hash_del(mo_hash *hash, void *key) {
|
480
523
|
int id = hash->hash_of(key) % hash->buffer.size;
|
481
|
-
|
524
|
+
mo_hash_list *bucket = mo_array_get_as(&hash->buffer, id, mo_hash_list*);
|
482
525
|
|
483
|
-
|
526
|
+
mo_hash_list *it = bucket, *next = bucket->next, *prev = NULL;
|
484
527
|
while (it) {
|
485
|
-
if (hash->key_cmp(it->data
|
528
|
+
if (hash->key_cmp(it->data, key) == 0) {
|
486
529
|
hash->size -= 1;
|
487
|
-
|
530
|
+
|
531
|
+
if (prev)
|
532
|
+
prev->next = it->next;
|
533
|
+
else /* is head */
|
534
|
+
mo_array_get_as(&hash->buffer, id, mo_hash_list*) = next;
|
535
|
+
|
536
|
+
if (hash->key_release)
|
537
|
+
hash->key_release(it->data);
|
538
|
+
if (hash->release)
|
539
|
+
hash->release(it->data + hash->key_size);
|
540
|
+
free(it);
|
541
|
+
|
488
542
|
break;
|
489
543
|
}
|
490
544
|
|
491
|
-
|
545
|
+
prev = it;
|
546
|
+
it = it->next;
|
492
547
|
}
|
493
|
-
|
494
|
-
if (it == bucket) /* Head changed */
|
495
|
-
mo_array_get_as(&hash->buffer, id, mo_list*) = next;
|
496
548
|
}
|
497
549
|
|
498
550
|
mo_hash_it mo_hash_begin(mo_hash *hash) {
|
@@ -503,7 +555,9 @@ mo_hash_it mo_hash_begin(mo_hash *hash) {
|
|
503
555
|
};
|
504
556
|
|
505
557
|
for (ret.id = 0; ret.id < hash->buffer.size; ret.id++) {
|
506
|
-
|
558
|
+
mo_hash_list *bucket = mo_array_get_as(&hash->buffer, ret.id,
|
559
|
+
mo_hash_list*);
|
560
|
+
|
507
561
|
if (bucket) {
|
508
562
|
ret.list = bucket;
|
509
563
|
break;
|
@@ -518,11 +572,11 @@ bool mo_hash_it_is_end(mo_hash_it *it) {
|
|
518
572
|
}
|
519
573
|
|
520
574
|
void *mo_hash_it_key(mo_hash_it *it) {
|
521
|
-
return it->list->data
|
575
|
+
return it->list->data;
|
522
576
|
}
|
523
577
|
|
524
578
|
void *mo_hash_it_val(mo_hash_it *it) {
|
525
|
-
return it->list->data +
|
579
|
+
return it->list->data + it->hash->key_size;
|
526
580
|
}
|
527
581
|
|
528
582
|
void mo_hash_it_next(mo_hash_it *it) {
|
@@ -532,7 +586,8 @@ void mo_hash_it_next(mo_hash_it *it) {
|
|
532
586
|
it->list = NULL;
|
533
587
|
|
534
588
|
for (it->id++; it->id < it->hash->buffer.size; it->id++) {
|
535
|
-
|
589
|
+
mo_hash_list *bucket = mo_array_get_as(&it->hash->buffer, it->id,
|
590
|
+
mo_hash_list*);
|
536
591
|
if (bucket) {
|
537
592
|
it->list = bucket;
|
538
593
|
return;
|
@@ -559,7 +614,7 @@ int mo_hash_pointer_cmp(const void *a, const void *b) {
|
|
559
614
|
}
|
560
615
|
|
561
616
|
int mo_hash_of_u32(void *ptr) {
|
562
|
-
return
|
617
|
+
return *(uint32_t*)ptr * MAGIC_NUMBER;
|
563
618
|
}
|
564
619
|
|
565
620
|
int mo_hash_u32_cmp(const void *a, const void *b) {
|
@@ -571,7 +626,7 @@ int mo_hash_u32_cmp(const void *a, const void *b) {
|
|
571
626
|
}
|
572
627
|
|
573
628
|
int mo_hash_of_size(void *ptr) {
|
574
|
-
return
|
629
|
+
return *(size_t*)ptr * MAGIC_NUMBER;
|
575
630
|
}
|
576
631
|
|
577
632
|
int mo_hash_size_cmp(const void *a, const void *b) {
|