Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
8.2 KiB

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