MRI-Binding: Bind #initialize_copy for clonable classes
This replaces the previously directly bound #clone methods, which weren't really the "the Ruby way". Rubys default Object#clone will call into our #init_copy methods instead. Partly incorporates pull request #3 by /cremno.
This commit is contained in:
		
							parent
							
								
									7549778dc6
								
							
						
					
					
						commit
						b7a2ba830c
					
				
					 4 changed files with 37 additions and 28 deletions
				
			
		| 
						 | 
					@ -196,26 +196,16 @@ rb_bool_new(bool value)
 | 
				
			||||||
		return objectLoad<Typ>(argc, argv, self); \
 | 
							return objectLoad<Typ>(argc, argv, self); \
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CLONE_FUNC(Klass) \
 | 
					#define INITCOPY_FUN(Klass) \
 | 
				
			||||||
	static mrb_value \
 | 
						RB_METHOD(Klass##InitializeCopy) \
 | 
				
			||||||
	Klass##Clone(mrb_state *mrb, mrb_value self) \
 | 
					 | 
				
			||||||
	{ \
 | 
						{ \
 | 
				
			||||||
		Klass *k = getPrivateData<Klass>(mrb, self); \
 | 
							VALUE orig; \
 | 
				
			||||||
		mrb_value dupObj = mrb_obj_clone(mrb, self); \
 | 
							rb_get_args(argc, argv, "o", &orig, RB_ARG_END); \
 | 
				
			||||||
		Klass *dupK = new Klass(*k); \
 | 
							if (!OBJ_INIT_COPY(self, orig)) /* When would this fail??*/\
 | 
				
			||||||
		setPrivateData(mrb, dupObj, dupK, Klass##Type); \
 | 
								return self; \
 | 
				
			||||||
		return dupObj; \
 | 
							Klass *k = getPrivateData<Klass>(orig); \
 | 
				
			||||||
	}
 | 
							setPrivateData(self, new Klass(*k)); \
 | 
				
			||||||
 | 
							return self; \
 | 
				
			||||||
#define CLONE_FUN(Klass) \
 | 
					 | 
				
			||||||
	RB_METHOD(Klass##Clone) \
 | 
					 | 
				
			||||||
	{ \
 | 
					 | 
				
			||||||
		RB_UNUSED_PARAM \
 | 
					 | 
				
			||||||
		Klass *k = getPrivateData<Klass>(self); \
 | 
					 | 
				
			||||||
		VALUE dupObj = rb_obj_clone(self); \
 | 
					 | 
				
			||||||
		Klass *dupK = new Klass(*k); \
 | 
					 | 
				
			||||||
		setPrivateData(dupObj, dupK); \
 | 
					 | 
				
			||||||
		return dupObj; \
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* If we're not binding a disposable class,
 | 
					/* If we're not binding a disposable class,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -291,7 +291,7 @@ RB_METHOD(bitmapTextSize)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_PROP_OBJ(Bitmap, Font, Font, "font")
 | 
					DEF_PROP_OBJ(Bitmap, Font, Font, "font")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CLONE_FUN(Bitmap)
 | 
					INITCOPY_FUN(Bitmap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -304,7 +304,8 @@ bitmapBindingInit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	disposableBindingInit<Bitmap>(klass);
 | 
						disposableBindingInit<Bitmap>(klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_rb_define_method(klass, "initialize",  bitmapInitialize);
 | 
						_rb_define_method(klass, "initialize",      bitmapInitialize);
 | 
				
			||||||
 | 
						_rb_define_method(klass, "initialize_copy", BitmapInitializeCopy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_rb_define_method(klass, "width",       bitmapWidth);
 | 
						_rb_define_method(klass, "width",       bitmapWidth);
 | 
				
			||||||
	_rb_define_method(klass, "height",      bitmapHeight);
 | 
						_rb_define_method(klass, "height",      bitmapHeight);
 | 
				
			||||||
| 
						 | 
					@ -320,6 +321,4 @@ bitmapBindingInit()
 | 
				
			||||||
	_rb_define_method(klass, "text_size",   bitmapTextSize);
 | 
						_rb_define_method(klass, "text_size",   bitmapTextSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_PROP_BIND(Bitmap, Font, "font");
 | 
						INIT_PROP_BIND(Bitmap, Font, "font");
 | 
				
			||||||
 | 
					 | 
				
			||||||
	_rb_define_method(klass, "clone",       BitmapClone);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,9 +148,9 @@ MARSH_LOAD_FUN(Color)
 | 
				
			||||||
MARSH_LOAD_FUN(Tone)
 | 
					MARSH_LOAD_FUN(Tone)
 | 
				
			||||||
MARSH_LOAD_FUN(Rect)
 | 
					MARSH_LOAD_FUN(Rect)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CLONE_FUN(Tone)
 | 
					INITCOPY_FUN(Tone)
 | 
				
			||||||
CLONE_FUN(Color)
 | 
					INITCOPY_FUN(Color)
 | 
				
			||||||
CLONE_FUN(Rect)
 | 
					INITCOPY_FUN(Rect)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define INIT_BIND(Klass) \
 | 
					#define INIT_BIND(Klass) \
 | 
				
			||||||
{ \
 | 
					{ \
 | 
				
			||||||
| 
						 | 
					@ -160,8 +160,8 @@ CLONE_FUN(Rect)
 | 
				
			||||||
	rb_define_class_method(klass, "_load", Klass##Load); \
 | 
						rb_define_class_method(klass, "_load", Klass##Load); \
 | 
				
			||||||
	serializableBindingInit<Klass>(klass); \
 | 
						serializableBindingInit<Klass>(klass); \
 | 
				
			||||||
	_rb_define_method(klass, "initialize", Klass##Initialize); \
 | 
						_rb_define_method(klass, "initialize", Klass##Initialize); \
 | 
				
			||||||
 | 
						_rb_define_method(klass, "initialize_copy", Klass##InitializeCopy); \
 | 
				
			||||||
	_rb_define_method(klass, "set", Klass##Set); \
 | 
						_rb_define_method(klass, "set", Klass##Set); \
 | 
				
			||||||
	_rb_define_method(klass, "clone", Klass##Clone); \
 | 
					 | 
				
			||||||
	_rb_define_method(klass, "==", Klass##Equal); \
 | 
						_rb_define_method(klass, "==", Klass##Equal); \
 | 
				
			||||||
	_rb_define_method(klass, "to_s", Klass##Stringify); \
 | 
						_rb_define_method(klass, "to_s", Klass##Stringify); \
 | 
				
			||||||
	_rb_define_method(klass, "inspect", Klass##Stringify); \
 | 
						_rb_define_method(klass, "inspect", Klass##Stringify); \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,25 @@ RB_METHOD(fontInitialize)
 | 
				
			||||||
	return self;
 | 
						return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RB_METHOD(fontInitializeCopy)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						VALUE orig;
 | 
				
			||||||
 | 
						rb_get_args(argc, argv, "o", &orig, RB_ARG_END);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!OBJ_INIT_COPY(self, orig))
 | 
				
			||||||
 | 
							return self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Font *f = getPrivateData<Font>(orig);
 | 
				
			||||||
 | 
						Font *dup = new Font(*f);
 | 
				
			||||||
 | 
						setPrivateData(self, dup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Wrap property objects */
 | 
				
			||||||
 | 
						f->setColor(new Color(*f->getColor()));
 | 
				
			||||||
 | 
						wrapProperty(self, f->getColor(), "color", ColorType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(FontGetName)
 | 
					RB_METHOD(FontGetName)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RB_UNUSED_PARAM;
 | 
						RB_UNUSED_PARAM;
 | 
				
			||||||
| 
						 | 
					@ -164,7 +183,8 @@ fontBindingInit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rb_define_class_method(klass, "exist?", fontDoesExist);
 | 
						rb_define_class_method(klass, "exist?", fontDoesExist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_rb_define_method(klass, "initialize", fontInitialize);
 | 
						_rb_define_method(klass, "initialize",      fontInitialize);
 | 
				
			||||||
 | 
						_rb_define_method(klass, "initialize_copy", fontInitializeCopy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_PROP_BIND(Font, Name, "name");
 | 
						INIT_PROP_BIND(Font, Name, "name");
 | 
				
			||||||
	INIT_PROP_BIND(Font, Size, "size");
 | 
						INIT_PROP_BIND(Font, Size, "size");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue