director.swg 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /* -----------------------------------------------------------------------------
  2. * director.swg
  3. *
  4. * This file contains support for director classes so that Ruby proxy
  5. * methods can be called from C++.
  6. * ----------------------------------------------------------------------------- */
  7. /*
  8. Use -DSWIG_DIRECTOR_NOUEH if you prefer to avoid the use of the
  9. Undefined Exception Handler provided by swig.
  10. */
  11. #ifndef SWIG_DIRECTOR_NOUEH
  12. #ifndef SWIG_DIRECTOR_UEH
  13. #define SWIG_DIRECTOR_UEH
  14. #endif
  15. #endif
  16. #include <string>
  17. #include <iostream>
  18. #include <exception>
  19. #include <map>
  20. # define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
  21. namespace Swig {
  22. /* memory handler */
  23. struct GCItem {
  24. virtual ~GCItem() {
  25. }
  26. virtual swig_ruby_owntype get_own() const {
  27. swig_ruby_owntype own = {0, 0};
  28. return own;
  29. }
  30. };
  31. struct GCItem_var {
  32. GCItem_var(GCItem *item = 0) : _item(item) {
  33. }
  34. GCItem_var& operator=(GCItem *item) {
  35. GCItem *tmp = _item;
  36. _item = item;
  37. delete tmp;
  38. return *this;
  39. }
  40. ~GCItem_var() {
  41. delete _item;
  42. }
  43. GCItem *operator->() const {
  44. return _item;
  45. }
  46. private:
  47. GCItem *_item;
  48. };
  49. template <typename Type>
  50. struct GCItem_T : GCItem {
  51. GCItem_T(Type *ptr) : _ptr(ptr) {
  52. }
  53. virtual ~GCItem_T() {
  54. delete _ptr;
  55. }
  56. private:
  57. Type *_ptr;
  58. };
  59. struct GCItem_Object : GCItem {
  60. GCItem_Object(swig_ruby_owntype own) : _own(own) {
  61. }
  62. virtual ~GCItem_Object() {
  63. }
  64. swig_ruby_owntype get_own() const {
  65. return _own;
  66. }
  67. private:
  68. swig_ruby_owntype _own;
  69. };
  70. template <typename Type>
  71. struct GCArray_T : GCItem {
  72. GCArray_T(Type *ptr) : _ptr(ptr) {
  73. }
  74. virtual ~GCArray_T() {
  75. delete[] _ptr;
  76. }
  77. private:
  78. Type *_ptr;
  79. };
  80. /* body args */
  81. struct body_args {
  82. VALUE recv;
  83. ID id;
  84. int argc;
  85. VALUE *argv;
  86. };
  87. /* Base class for director exceptions */
  88. class DirectorException : public std::exception {
  89. protected:
  90. VALUE swig_error;
  91. std::string swig_msg;
  92. protected:
  93. DirectorException(VALUE error) : swig_error(error) {
  94. }
  95. DirectorException(VALUE error, const char *hdr, const char *msg ="") : swig_error(error), swig_msg(hdr) {
  96. if (msg[0]) {
  97. swig_msg += " ";
  98. swig_msg += msg;
  99. }
  100. if (swig_msg.size()) {
  101. VALUE str = rb_str_new(swig_msg.data(), swig_msg.size());
  102. swig_error = rb_exc_new3(error, str);
  103. } else {
  104. swig_error = error;
  105. }
  106. }
  107. public:
  108. virtual ~DirectorException() throw() {
  109. }
  110. VALUE getType() const {
  111. return CLASS_OF(swig_error);
  112. }
  113. VALUE getError() const {
  114. return swig_error;
  115. }
  116. /* Deprecated, use what() instead */
  117. const std::string& getMessage() const {
  118. return swig_msg;
  119. }
  120. const char *what() const throw() {
  121. return swig_msg.c_str();
  122. }
  123. };
  124. /* unknown exception handler */
  125. class UnknownExceptionHandler {
  126. #ifdef SWIG_DIRECTOR_UEH
  127. static void handler() {
  128. try {
  129. throw;
  130. } catch (DirectorException& e) {
  131. std::cerr << "SWIG Director exception caught:" << std::endl
  132. << e.what() << std::endl;
  133. } catch (std::exception& e) {
  134. std::cerr << "std::exception caught: "<< e.what() << std::endl;
  135. } catch (...) {
  136. std::cerr << "Unknown exception caught." << std::endl;
  137. }
  138. std::cerr << std::endl
  139. << "Ruby interpreter traceback:" << std::endl;
  140. std::cerr << std::endl;
  141. std::cerr << "This exception was caught by the SWIG unexpected exception handler." << std::endl
  142. << "Try using %feature(\"director:except\") to avoid reaching this point." << std::endl
  143. << std::endl
  144. << "Exception is being re-thrown, program will like abort/terminate." << std::endl;
  145. throw;
  146. }
  147. public:
  148. std::unexpected_handler old;
  149. UnknownExceptionHandler(std::unexpected_handler nh = handler) {
  150. old = std::set_unexpected(nh);
  151. }
  152. ~UnknownExceptionHandler() {
  153. std::set_unexpected(old);
  154. }
  155. #endif
  156. };
  157. /* Type mismatch in the return value from a Ruby method call */
  158. class DirectorTypeMismatchException : public DirectorException {
  159. public:
  160. DirectorTypeMismatchException(VALUE error, const char *msg="")
  161. : DirectorException(error, "SWIG director type mismatch", msg) {
  162. }
  163. DirectorTypeMismatchException(const char *msg="")
  164. : DirectorException(rb_eTypeError, "SWIG director type mismatch", msg) {
  165. }
  166. static void raise(VALUE error, const char *msg) {
  167. throw DirectorTypeMismatchException(error, msg);
  168. }
  169. static void raise(const char *msg) {
  170. throw DirectorTypeMismatchException(msg);
  171. }
  172. };
  173. /* Any Ruby exception that occurs during a director method call */
  174. class DirectorMethodException : public DirectorException {
  175. public:
  176. DirectorMethodException(VALUE error)
  177. : DirectorException(error) {
  178. }
  179. DirectorMethodException(const char *msg = "")
  180. : DirectorException(rb_eRuntimeError, "SWIG director method error.", msg) {
  181. }
  182. static void raise(VALUE error) {
  183. throw DirectorMethodException(error);
  184. }
  185. };
  186. /* Attempted to call a pure virtual method via a director method */
  187. class DirectorPureVirtualException : public DirectorException
  188. {
  189. public:
  190. DirectorPureVirtualException(const char *msg = "")
  191. : DirectorException(rb_eRuntimeError, "SWIG director pure virtual method called", msg) {
  192. }
  193. static void raise(const char *msg) {
  194. throw DirectorPureVirtualException(msg);
  195. }
  196. };
  197. /* Simple thread abstraction for pthreads on win32 */
  198. #ifdef __THREAD__
  199. # define __PTHREAD__
  200. # if defined(_WIN32) || defined(__WIN32__)
  201. # define pthread_mutex_lock EnterCriticalSection
  202. # define pthread_mutex_unlock LeaveCriticalSection
  203. # define pthread_mutex_t CRITICAL_SECTION
  204. # define SWIG_MUTEX_INIT(var) var
  205. # else
  206. # include <pthread.h>
  207. # define SWIG_MUTEX_INIT(var) var = PTHREAD_MUTEX_INITIALIZER
  208. # endif
  209. #endif
  210. #ifdef __PTHREAD__
  211. struct Guard {
  212. pthread_mutex_t *_mutex;
  213. Guard(pthread_mutex_t &mutex) : _mutex(&mutex) {
  214. pthread_mutex_lock(_mutex);
  215. }
  216. ~Guard() {
  217. pthread_mutex_unlock(_mutex);
  218. }
  219. };
  220. # define SWIG_GUARD(mutex) Guard _guard(mutex)
  221. #else
  222. # define SWIG_GUARD(mutex)
  223. #endif
  224. /* director base class */
  225. class Director {
  226. private:
  227. /* pointer to the wrapped Ruby object */
  228. VALUE swig_self;
  229. /* flag indicating whether the object is owned by Ruby or c++ */
  230. mutable bool swig_disown_flag;
  231. public:
  232. /* wrap a Ruby object. */
  233. Director(VALUE self) : swig_self(self), swig_disown_flag(false) {
  234. }
  235. /* discard our reference at destruction */
  236. virtual ~Director() {
  237. }
  238. /* return a pointer to the wrapped Ruby object */
  239. VALUE swig_get_self() const {
  240. return swig_self;
  241. }
  242. /* acquire ownership of the wrapped Ruby object (the sense of "disown" is from Ruby) */
  243. void swig_disown() const {
  244. if (!swig_disown_flag) {
  245. swig_disown_flag = true;
  246. }
  247. }
  248. /* ownership management */
  249. private:
  250. typedef std::map<void *, GCItem_var> swig_ownership_map;
  251. mutable swig_ownership_map swig_owner;
  252. #ifdef __PTHREAD__
  253. static pthread_mutex_t swig_mutex_own;
  254. #endif
  255. public:
  256. template <typename Type>
  257. void swig_acquire_ownership_array(Type *vptr) const {
  258. if (vptr) {
  259. SWIG_GUARD(swig_mutex_own);
  260. swig_owner[vptr] = new GCArray_T<Type>(vptr);
  261. }
  262. }
  263. template <typename Type>
  264. void swig_acquire_ownership(Type *vptr) const {
  265. if (vptr) {
  266. SWIG_GUARD(swig_mutex_own);
  267. swig_owner[vptr] = new GCItem_T<Type>(vptr);
  268. }
  269. }
  270. void swig_acquire_ownership_obj(void *vptr, swig_ruby_owntype own) const {
  271. if (vptr && own.datafree) {
  272. SWIG_GUARD(swig_mutex_own);
  273. swig_owner[vptr] = new GCItem_Object(own);
  274. }
  275. }
  276. swig_ruby_owntype swig_release_ownership(void *vptr) const {
  277. swig_ruby_owntype own = {0, 0};
  278. if (vptr) {
  279. SWIG_GUARD(swig_mutex_own);
  280. swig_ownership_map::iterator iter = swig_owner.find(vptr);
  281. if (iter != swig_owner.end()) {
  282. own.datafree = iter->second->get_own().datafree;
  283. swig_owner.erase(iter);
  284. }
  285. }
  286. return own;
  287. }
  288. };
  289. }