PageRenderTime 49ms CodeModel.GetById 16ms 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. /* Global Ruby hash table to store Trackings from C/C++
  10. structs to Ruby Objects. */
  11. static VALUE swig_ruby_trackings;
  12. /* Setup a Ruby hash table to store Trackings */
  13. static void SWIG_RubyInitializeTrackings() {
  14. /* Create a ruby hash table to store Trackings from C++
  15. objects to Ruby objects. Also make sure to tell
  16. the garabage collector about the hash table. */
  17. swig_ruby_trackings = rb_hash_new();
  18. rb_gc_register_address(&swig_ruby_trackings);
  19. }
  20. /* Get a Ruby number to reference a pointer */
  21. static VALUE SWIG_RubyPtrToReference(void* ptr) {
  22. /* We cast the pointer to an unsigned long
  23. and then store a reference to it using
  24. a Ruby number object. */
  25. /* Convert the pointer to a Ruby number */
  26. unsigned long value = (unsigned long) ptr;
  27. return LONG2NUM(value);
  28. }
  29. /* Get a Ruby number to reference an object */
  30. static VALUE SWIG_RubyObjectToReference(VALUE object) {
  31. /* We cast the object to an unsigned long
  32. and then store a reference to it using
  33. a Ruby number object. */
  34. /* Convert the Object to a Ruby number */
  35. unsigned long value = (unsigned long) object;
  36. return LONG2NUM(value);
  37. }
  38. /* Get a Ruby object from a previously stored reference */
  39. static VALUE SWIG_RubyReferenceToObject(VALUE reference) {
  40. /* The provided Ruby number object is a reference
  41. to the Ruby object we want.*/
  42. /* First convert the Ruby number to a C number */
  43. unsigned long value = NUM2LONG(reference);
  44. return (VALUE) value;
  45. }
  46. /* Add a Tracking from a C/C++ struct to a Ruby object */
  47. static void SWIG_RubyAddTracking(void* ptr, VALUE object) {
  48. /* In a Ruby hash table we store the pointer and
  49. the associated Ruby object. The trick here is
  50. that we cannot store the Ruby object directly - if
  51. we do then it cannot be garbage collected. So
  52. instead we typecast it as a unsigned long and
  53. convert it to a Ruby number object.*/
  54. /* Get a reference to the pointer as a Ruby number */
  55. VALUE key = SWIG_RubyPtrToReference(ptr);
  56. /* Get a reference to the Ruby object as a Ruby number */
  57. VALUE value = SWIG_RubyObjectToReference(object);
  58. /* Store the mapping to the global hash table. */
  59. rb_hash_aset(swig_ruby_trackings, key, value);
  60. }
  61. /* Get the Ruby object that owns the specified C/C++ struct */
  62. static VALUE SWIG_RubyInstanceFor(void* ptr) {
  63. /* Get a reference to the pointer as a Ruby number */
  64. VALUE key = SWIG_RubyPtrToReference(ptr);
  65. /* Now lookup the value stored in the global hash table */
  66. VALUE value = rb_hash_aref(swig_ruby_trackings, key);
  67. if (value == Qnil) {
  68. /* No object exists - return nil. */
  69. return Qnil;
  70. }
  71. else {
  72. /* Convert this value to Ruby object */
  73. return SWIG_RubyReferenceToObject(value);
  74. }
  75. }
  76. /* Remove a Tracking from a C/C++ struct to a Ruby object */
  77. static void SWIG_RubyRemoveTracking(void* ptr) {
  78. /* Get a reference to the pointer as a Ruby number */
  79. VALUE key = SWIG_RubyPtrToReference(ptr);
  80. /* Define delete method - in C++ this could be marked as
  81. static but unfortunately not in C. */
  82. VALUE delete_function = rb_intern("delete");
  83. /* Delete the object from the hash table by calling Ruby's
  84. do this we need to call the Hash.delete method.*/
  85. rb_funcall(swig_ruby_trackings, delete_function, 1, key);
  86. }
  87. /* This is a helper method that unlinks a Ruby object from its
  88. underlying C++ object. This is needed if the lifetime of the
  89. Ruby object is longer than the C++ object */
  90. static void SWIG_RubyUnlinkObjects(void* ptr) {
  91. VALUE object = SWIG_RubyInstanceFor(ptr);
  92. if (object != Qnil) {
  93. DATA_PTR(object) = 0;
  94. }
  95. }