Permalink
Browse files

yes, I'm still working on #ShinyCocos

  • Loading branch information...
Rolando Abarca
Rolando Abarca committed Apr 13, 2010
1 parent 7a80739 commit 9ebda7fcfc853db266b4b49c01bdbc5fa5a9be42
Showing with 82 additions and 46 deletions.
  1. +65 −25 Integration/SC_CocosNode.m
  2. +1 −9 Integration/SC_init.m
  3. +10 −10 Integration/ShinyCocos.m
  4. +6 −2 Template/vendor/main.rb
View
@@ -28,6 +28,19 @@
#import "rb_chipmunk.h"
VALUE rb_cCocosNode;
+ccHashSet *scheduledMethods;
+
+typedef struct hashMethod_ {
+ VALUE object;
+ VALUE methods;
+} hashMethod;
+
+static int scheduledMethodsEql(void *ptr, void *elt)
+{
+ hashMethod *first = (hashMethod *)ptr;
+ hashMethod *second = (hashMethod *)elt;
+ return (first->object == second->object);
+}
#pragma mark CocosNode extension
@@ -70,6 +83,7 @@ @interface CocosNode (SC_Extension)
- (void)rb_on_enter;
- (void)rb_on_enter_transition_did_finish;
- (void)rb_on_exit;
+- (void)rb_dealloc;
- (void)rb_draw;
// chipmunk support
@@ -123,6 +137,20 @@ - (void)rb_on_exit {
}
}
+- (void)rb_dealloc {
+ [self rb_dealloc];
+ if (userData) {
+ // get rid of scheduledMethods if any
+ hashMethod tmpMethod;
+ tmpMethod.object = (VALUE)userData;
+ hashMethod *methods = ccHashSetFind(scheduledMethods, CC_HASH_INT(userData), &tmpMethod);
+ if (methods) {
+ VALUE rb_methods = methods->methods;
+ rb_gc_unregister_address(&rb_methods);
+ }
+ }
+}
+
- (void)rb_draw {
[self rb_draw];
if (userData) {
@@ -150,25 +178,19 @@ - (void)chipmunk_step:(ccTime)delta {
- (void)rbScheduler:(ccTime)delta {
if (!userData)
return;
- VALUE methods = rb_ivar_get((VALUE)userData, id_sc_ivar_scheduled_methods);
- if (methods != Qnil) {
+ hashMethod tmpMethod;
+ tmpMethod.object = (VALUE)userData;
+ hashMethod *methods = ccHashSetFind(scheduledMethods, CC_HASH_INT(userData), &tmpMethod);
+ if (methods) {
int i;
VALUE rb_delta = rb_float_new(delta);
- tSCProtectWrapper *w = (tSCProtectWrapper *)malloc(sizeof(tSCProtectWrapper));
- for (i=0; i < RARRAY_LEN(methods); i++) {
- ID m_id = rb_to_id(RARRAY_PTR(methods)[i]);
- // simulating thread_exclusive
- /*
- VALUE critical = rb_thread_critical;
- rb_thread_critical = 1;
- w->obj = (VALUE)userData;
- w->method = m_id;
- w->delta = rb_delta;
- rb_ensure(sc_protect_wrapper, (VALUE)w, sc_set_critical, (VALUE)critical);
- */
+ VALUE rb_methods = methods->methods;
+ for (i=0; i < RARRAY_LEN(rb_methods); i++) {
+ ID m_id = rb_to_id(RARRAY_PTR(rb_methods)[i]);
sc_protect_funcall((VALUE)userData, m_id, 1, rb_delta);
}
- free(w);
+ } else {
+ CCLOG(@"running scheduled method for %d, but no ary set?", userData);
}
}
@@ -745,13 +767,20 @@ VALUE rb_cCocosNode_attach_chipmunk_shape(VALUE object, VALUE rb_shape) {
*/
VALUE rb_cCocosNode_schedule(VALUE object, VALUE method) {
Check_Type(method, T_SYMBOL);
- VALUE methods = rb_ivar_get(object, id_sc_ivar_scheduled_methods);
- if (methods == Qnil) {
- methods = rb_ary_new3(1, method);
- rb_ivar_set(object, id_sc_ivar_scheduled_methods, methods);
+ hashMethod tmpMethod;
+ tmpMethod.object = (VALUE)object;
+ hashMethod *methods = (hashMethod *)ccHashSetFind(scheduledMethods, CC_HASH_INT(object), &tmpMethod);
+ if (!methods) {
+ CCLOG(@"**** inserting new scheduled method for object %d", object);
+ methods = (hashMethod *)malloc(sizeof(hashMethod));
+ methods->object = object;
+ VALUE rb_methods = rb_ary_new3(1, method);
+ methods->methods = rb_methods;
+ rb_gc_register_address(&rb_methods);
+ ccHashSetInsert(scheduledMethods, CC_HASH_INT(object), methods, nil);
[CC_NODE(object) schedule:@selector(rbScheduler:)];
} else {
- rb_ary_push(methods, method);
+ rb_ary_push(methods->methods, method);
}
return object;
@@ -762,15 +791,23 @@ VALUE rb_cCocosNode_schedule(VALUE object, VALUE method) {
*/
VALUE rb_cCocosNode_unschedule(VALUE object, VALUE method) {
Check_Type(method, T_SYMBOL);
- VALUE methods = rb_ivar_get(object, id_sc_ivar_scheduled_methods);
- if (methods != Qnil) {
- sc_protect_funcall(methods, id_sc_delete, 1, method);
+ hashMethod tmpMethod;
+ tmpMethod.object = (VALUE)object;
+ hashMethod *methods = (hashMethod *)ccHashSetFind(scheduledMethods, CC_HASH_INT(object), &tmpMethod);
+ if (methods) {
+ sc_protect_funcall(methods->methods, id_sc_delete, 1, method);
if (RARRAY_LEN(methods) == 0) {
// empty array, unschedule the ruby scheduler
[CC_NODE(object) unschedule:@selector(rbScheduler)];
+ // and remove the object from the hash
+ VALUE rb_methods = methods->methods;
+ rb_gc_unregister_address(&rb_methods);
+ ccHashSetRemove(scheduledMethods, CC_HASH_INT(object), methods);
+ free(methods);
}
+ return methods->methods;
}
- return methods;
+ return Qnil;
}
/*
@@ -969,5 +1006,8 @@ void init_rb_cCocosNode() {
sc_method_swap([CocosNode class], @selector(onEnter), @selector(rb_on_enter));
sc_method_swap([CocosNode class], @selector(onEnterTransitionDidFinish), @selector(rb_on_enter_transition_did_finish));
sc_method_swap([CocosNode class], @selector(onExit), @selector(rb_on_exit));
-// sc_method_swap([CocosNode class], @selector(draw), @selector(rb_draw)); // BUG
+ sc_method_swap([CocosNode class], @selector(dealloc), @selector(rb_dealloc));
+
+ // hash for scheduled methods
+ scheduledMethods = ccHashSetNew(20, scheduledMethodsEql);
}
View
@@ -293,16 +293,8 @@ void Init_ShinyCocos() {
rb_define_const(rb_mCocos2D, "REACHABLE_VIA_WIFI_NETWORK", INT2FIX(ReachableViaWiFiNetwork));
}
-void Init_encdb();
-void Init_stringio();
-void Init_syck();
-void Init_zlib();
-void Init_thread();
+extern void Init_zlib();
void Init_SC_Ruby_Extensions() {
-// Init_encdb();
-// Init_stringio();
-// Init_syck();
Init_zlib();
- Init_thread();
}
View
@@ -37,17 +37,17 @@ void ShinyCocosSetup(NSString *devLibs) {
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *rubyLib = [NSString stringWithFormat:@"%@/lib", resourcePath];
NSString *rubyVendor = [NSString stringWithFormat:@"%@/vendor", resourcePath];
- NSString *entryPoint = [NSString stringWithFormat:@"%@/main.rb", resourcePath];
+ NSString *entryPoint = [NSString stringWithFormat:@"%@/main.rb", rubyVendor];
sc_argc = 2;
- sc_argv = (char **)malloc(sizeof(char *) * 2);
+ sc_argv = (char **)malloc(sizeof(char *) * (sc_argc));
sc_argv[0] = "ShinyCocos";
- sc_argv[1] = (char *)[entryPoint cStringUsingEncoding:NSUTF8StringEncoding];
+ sc_argv[1] = (char *)[entryPoint UTF8String];
- // ruby_sysinit(&sc_argc, &sc_argv);
{
RUBY_INIT_STACK;
ruby_init();
+ ruby_options(sc_argc, sc_argv);
}
/* add the bundle resource path to the search path */
@@ -67,7 +67,7 @@ void ShinyCocosSetup(NSString *devLibs) {
extern void sc_require(char *fname);
void ShinyCocosStart(UIWindow *window, id appDelegate) {
- int state;
+ int state_;
_appDelegate = appDelegate;
/* hide the top bar */
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
@@ -77,15 +77,15 @@ void ShinyCocosStart(UIWindow *window, id appDelegate) {
[[Director sharedDirector] attachInWindow:window];
[window makeKeyAndVisible];
- ruby_script("main.rb");
+ ruby_script("ShinyCocos"); // set the name script
// test for secure_require
if (rb_obj_respond_to(rb_mKernel, rb_intern("secure_require"), 0)) {
- rb_protect(RUBY_METHOD_FUNC(sc_require), (VALUE)"main", &state);
+ rb_protect(RUBY_METHOD_FUNC(sc_require), (VALUE)"main", &state_);
} else {
- rb_protect(RUBY_METHOD_FUNC(rb_require), (VALUE)"main", &state);
+ rb_protect(RUBY_METHOD_FUNC(rb_require), (VALUE)"main", &state_);
}
- if (state != 0)
- sc_error(state);
+ if (state_ != 0)
+ sc_error(state_);
}
void ShinyCocosInitChipmunk() {
View
@@ -18,5 +18,9 @@ def touches_ended(touches)
end
end
-Cocos2D::Director.set_orientation Cocos2D::Director::ORIENTATION_LANDSCAPE_RIGHT
-Cocos2D::Director.run_scene DemoScene.new
+if $0 == "ShinyCocos"
+ Cocos2D::Director.set_orientation Cocos2D::Director::ORIENTATION_LANDSCAPE_RIGHT
+ Cocos2D::Director.run_scene DemoScene.new
+else
+ $stderr.puts "This script should be run only from a ShinyCocos environment"
+end

2 comments on commit 9ebda7f

@jonsterling

This comment has been minimized.

Show comment Hide comment
@jonsterling

jonsterling Apr 13, 2010

What are the prospects for ShinyCocos, given §3.3.1? I was really hoping that the time would come where iPhone games could be written in Ruby.

What are the prospects for ShinyCocos, given §3.3.1? I was really hoping that the time would come where iPhone games could be written in Ruby.

@rolandoam

This comment has been minimized.

Show comment Hide comment
@rolandoam

rolandoam Apr 13, 2010

Owner

on the old 3.3.1 we were in the same grey line than Lua but now, we're kind of screw. We have a little game accepted in the Store, it was using an older version of ShinyCocos.
I'm not sure what the exact future of ShinyCocos is, but during the development time I have learned a lot about iPhone dev and ruby internals. I think I now have a clearer vision of what I would like ShinyCocos 2.0 to be.

Owner

rolandoam replied Apr 13, 2010

on the old 3.3.1 we were in the same grey line than Lua but now, we're kind of screw. We have a little game accepted in the Store, it was using an older version of ShinyCocos.
I'm not sure what the exact future of ShinyCocos is, but during the development time I have learned a lot about iPhone dev and ruby internals. I think I now have a clearer vision of what I would like ShinyCocos 2.0 to be.

Please sign in to comment.