Map the guests to a ruby hash to avoid creating new ruby objects on each call of Guest.each or Guest[].
This commit is contained in:
+35
-41
@@ -120,79 +120,73 @@ static void dumm_init()
|
||||
/**
|
||||
* Guest bindings
|
||||
*/
|
||||
static VALUE guest_find(VALUE class, VALUE key)
|
||||
static VALUE guest_hash_create(VALUE class)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
guest_t *guest, *found = NULL;
|
||||
|
||||
if (TYPE(key) == T_SYMBOL)
|
||||
{
|
||||
key = rb_convert_type(key, T_STRING, "String", "to_s");
|
||||
}
|
||||
guest_t *guest;
|
||||
VALUE hash = rb_hash_new();
|
||||
enumerator = dumm->create_guest_enumerator(dumm);
|
||||
while (enumerator->enumerate(enumerator, &guest))
|
||||
{
|
||||
if (streq(guest->get_name(guest), StringValuePtr(key)))
|
||||
{
|
||||
found = guest;
|
||||
break;
|
||||
}
|
||||
rb_hash_aset(hash, rb_str_new2(guest->get_name(guest)),
|
||||
Data_Wrap_Struct(class, NULL, NULL, guest));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!found)
|
||||
return hash;
|
||||
}
|
||||
|
||||
static VALUE guest_hash(VALUE class)
|
||||
{
|
||||
ID id = rb_intern("@@guests");
|
||||
if (!rb_cvar_defined(class, id))
|
||||
{
|
||||
return Qnil;
|
||||
VALUE hash = guest_hash_create(class);
|
||||
rb_cvar_set(class, id, hash, 0);
|
||||
return hash;
|
||||
}
|
||||
return Data_Wrap_Struct(class, NULL, NULL, found);
|
||||
return rb_cvar_get(class, id);
|
||||
}
|
||||
|
||||
static VALUE guest_find(VALUE class, VALUE key)
|
||||
{
|
||||
if (TYPE(key) != T_STRING)
|
||||
{
|
||||
key = rb_convert_type(key, T_STRING, "String", "to_s");
|
||||
}
|
||||
return rb_hash_aref(guest_hash(class), key);
|
||||
}
|
||||
|
||||
static VALUE guest_get(VALUE class, VALUE key)
|
||||
{
|
||||
VALUE guest = guest_find(class, key);
|
||||
if (NIL_P(guest))
|
||||
{
|
||||
rb_raise(rb_eRuntimeError, "guest not found");
|
||||
}
|
||||
return guest;
|
||||
return guest_find(class, key);
|
||||
}
|
||||
|
||||
static VALUE guest_each(int argc, VALUE *argv, VALUE class)
|
||||
{
|
||||
linked_list_t *list;
|
||||
enumerator_t *enumerator;
|
||||
guest_t *guest;
|
||||
|
||||
if (!rb_block_given_p())
|
||||
{
|
||||
rb_raise(rb_eArgError, "must be called with a block");
|
||||
}
|
||||
list = linked_list_create();
|
||||
enumerator = dumm->create_guest_enumerator(dumm);
|
||||
while (enumerator->enumerate(enumerator, &guest))
|
||||
{
|
||||
list->insert_last(list, guest);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
while (list->remove_first(list, (void**)&guest) == SUCCESS)
|
||||
{
|
||||
rb_yield(Data_Wrap_Struct(class, NULL, NULL, guest));
|
||||
}
|
||||
list->destroy(list);
|
||||
rb_block_call(guest_hash(class), rb_intern("each_value"), 0, 0,
|
||||
rb_yield, 0);
|
||||
return class;
|
||||
}
|
||||
|
||||
static VALUE guest_new(VALUE class, VALUE name, VALUE kernel,
|
||||
VALUE master, VALUE args)
|
||||
{
|
||||
VALUE self;
|
||||
guest_t *guest;
|
||||
|
||||
guest = dumm->create_guest(dumm, StringValuePtr(name), StringValuePtr(kernel),
|
||||
StringValuePtr(master), StringValuePtr(args));
|
||||
guest = dumm->create_guest(dumm, StringValuePtr(name),
|
||||
StringValuePtr(kernel), StringValuePtr(master),
|
||||
StringValuePtr(args));
|
||||
if (!guest)
|
||||
{
|
||||
rb_raise(rb_eRuntimeError, "creating guest failed");
|
||||
}
|
||||
return Data_Wrap_Struct(class, NULL, NULL, guest);
|
||||
self = Data_Wrap_Struct(class, NULL, NULL, guest);
|
||||
rb_hash_aset(guest_hash(class), name, self);
|
||||
return self;
|
||||
}
|
||||
|
||||
static VALUE guest_to_s(VALUE self)
|
||||
|
||||
Reference in New Issue
Block a user