ray 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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) {
|