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