PageRenderTime 16ms CodeModel.GetById 9ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/rel-1-3-27/SWIG/Lib/ruby/rubytracking.swg

#
Unknown | 115 lines | 95 code | 20 blank | 0 comment | 0 complexity | 3b0af61e82d193ba5e88fa00ac9b2d96 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1/***********************************************************************
  2 * rubytracking.swg
  3 *
  4 * This file contains support for tracking mappings from 
  5 * Ruby objects to C++ objects.  This functionality is needed
  6 * to implement mark functions for Ruby's mark and sweep
  7 * garbage collector.
  8 ************************************************************************/
  9
 10/* Global Ruby hash table to store Trackings from C/C++
 11   structs to Ruby Objects. */
 12static VALUE swig_ruby_trackings;
 13
 14/* Setup a Ruby hash table to store Trackings */
 15static void SWIG_RubyInitializeTrackings() {
 16	/* Create a ruby hash table to store Trackings from C++ 
 17	objects to Ruby objects.  Also make sure to tell
 18	the garabage collector about the hash table. */
 19	swig_ruby_trackings = rb_hash_new();
 20	rb_gc_register_address(&swig_ruby_trackings);
 21}
 22
 23/* Get a Ruby number to reference a pointer */
 24static VALUE SWIG_RubyPtrToReference(void* ptr) {
 25	/* We cast the pointer to an unsigned long
 26	 and then store a reference to it using
 27	 a Ruby number object. */
 28
 29	/* Convert the pointer to a Ruby number */
 30	unsigned long value = (unsigned long) ptr;
 31	return LONG2NUM(value);
 32}
 33
 34/* Get a Ruby number to reference an object */
 35static VALUE SWIG_RubyObjectToReference(VALUE object) {
 36	/* We cast the object to an unsigned long
 37	 and then store a reference to it using
 38	 a Ruby number object. */
 39
 40	/* Convert the Object to a Ruby number */
 41	unsigned long value = (unsigned long) object;
 42	return LONG2NUM(value);
 43}
 44
 45/* Get a Ruby object from a previously stored reference */
 46static VALUE SWIG_RubyReferenceToObject(VALUE reference) {
 47	/* The provided Ruby number object is a reference
 48	to the Ruby object we want.*/
 49
 50	/* First convert the Ruby number to a C number */
 51	unsigned long value = NUM2LONG(reference);
 52	return (VALUE) value;
 53}
 54
 55/* Add a Tracking from a C/C++ struct to a Ruby object */
 56static void SWIG_RubyAddTracking(void* ptr, VALUE object) {
 57	/* In a Ruby hash table we store the pointer and
 58	the associated Ruby object.  The trick here is
 59	that we cannot store the Ruby object directly - if
 60	we do then it cannot be garbage collected.  So
 61	instead we typecast it as a unsigned long and
 62	convert it to a Ruby number object.*/
 63
 64	/* Get a reference to the pointer as a Ruby number */
 65	VALUE key = SWIG_RubyPtrToReference(ptr);
 66
 67	/* Get a reference to the Ruby object as a Ruby number */
 68	VALUE value = SWIG_RubyObjectToReference(object);
 69
 70  /* Store the mapping to the global hash table. */
 71	rb_hash_aset(swig_ruby_trackings, key, value);
 72}
 73
 74/* Get the Ruby object that owns the specified C/C++ struct */
 75static VALUE SWIG_RubyInstanceFor(void* ptr) {
 76	/* Get a reference to the pointer as a Ruby number */
 77	VALUE key = SWIG_RubyPtrToReference(ptr);
 78
 79	/* Now lookup the value stored in the global hash table */
 80	VALUE value = rb_hash_aref(swig_ruby_trackings, key);
 81	
 82	if (value == Qnil) {
 83	  /* No object exists - return nil. */
 84		return Qnil;
 85	}
 86	else {
 87		/* Convert this value to Ruby object */
 88		return SWIG_RubyReferenceToObject(value);
 89	}
 90}
 91
 92/* Remove a Tracking from a C/C++ struct to a Ruby object */
 93static void SWIG_RubyRemoveTracking(void* ptr) {
 94	/* Get a reference to the pointer as a Ruby number */
 95	VALUE key = SWIG_RubyPtrToReference(ptr);
 96
 97	/* Define delete method - in C++ this could be marked as
 98	   static but unfortunately not in C. */
 99	VALUE delete_function = rb_intern("delete");
100
101	/* Delete the object from the hash table by calling Ruby's
102	   do this we need to call the Hash.delete method.*/
103	rb_funcall(swig_ruby_trackings, delete_function, 1, key);
104}
105
106/* This is a helper method that unlinks a Ruby object from its
107   underlying C++ object.  This is needed if the lifetime of the
108   Ruby object is longer than the C++ object */
109static void SWIG_RubyUnlinkObjects(void* ptr) {
110	VALUE object = SWIG_RubyInstanceFor(ptr);
111
112	if (object != Qnil) {
113		DATA_PTR(object) = 0;
114	}
115}