cycleDataWriter.I 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file cycleDataWriter.I
  10. * @author drose
  11. * @date 2002-02-21
  12. */
  13. #ifndef CPPPARSER
  14. #ifdef DO_PIPELINING
  15. // This is the implementation for full support of pipelining (as well as the
  16. // sanity-check only implementation).
  17. /**
  18. *
  19. */
  20. template<class CycleDataType>
  21. INLINE CycleDataWriter<CycleDataType>::
  22. CycleDataWriter(PipelineCycler<CycleDataType> &cycler, Thread *current_thread) :
  23. _cycler(&cycler),
  24. _current_thread(current_thread)
  25. {
  26. _pointer = _cycler->write(_current_thread);
  27. nassertv(_pointer != nullptr);
  28. }
  29. /**
  30. * This two-parameter constructor, with a bool parameter for the second
  31. * parameter, automatically propagates the CycleData pointer upstream from the
  32. * current stage, either stopping at the first pointer encountered that's
  33. * different, going or all the way to stage 0, according to force_to_0. See
  34. * PipelineCycler::write_upstream().
  35. */
  36. template<class CycleDataType>
  37. INLINE CycleDataWriter<CycleDataType>::
  38. CycleDataWriter(PipelineCycler<CycleDataType> &cycler, bool force_to_0,
  39. Thread *current_thread) :
  40. _cycler(&cycler),
  41. _current_thread(current_thread)
  42. {
  43. _pointer = _cycler->write_upstream(force_to_0, _current_thread);
  44. nassertv(_pointer != nullptr);
  45. }
  46. /**
  47. * This special constructor "steals" a reference count from the already-locked
  48. * cdata object. It does not increment the lock count of this object, but
  49. * will release it when the destructor is called.
  50. *
  51. * This is designed for special functions that return an already-locked cdata
  52. * object and expect the caller to unlock it.
  53. */
  54. template<class CycleDataType>
  55. INLINE CycleDataWriter<CycleDataType>::
  56. CycleDataWriter(PipelineCycler<CycleDataType> &cycler, CycleDataType *locked_cdata,
  57. Thread *current_thread) :
  58. _cycler(&cycler),
  59. _current_thread(current_thread)
  60. {
  61. _pointer = locked_cdata;
  62. nassertv(_pointer != nullptr);
  63. }
  64. /**
  65. *
  66. */
  67. template<class CycleDataType>
  68. INLINE CycleDataWriter<CycleDataType>::
  69. CycleDataWriter(const CycleDataWriter<CycleDataType> &copy) :
  70. _cycler(copy._cycler),
  71. _current_thread(copy._current_thread),
  72. _pointer(copy._pointer)
  73. {
  74. nassertv(_pointer != nullptr);
  75. _cycler->increment_write(_pointer);
  76. }
  77. /**
  78. *
  79. */
  80. template<class CycleDataType>
  81. INLINE void CycleDataWriter<CycleDataType>::
  82. operator = (const CycleDataWriter<CycleDataType> &copy) {
  83. nassertv(_pointer == nullptr);
  84. nassertv(_current_thread == copy._current_thread);
  85. _cycler = copy._cycler;
  86. _pointer = copy._pointer;
  87. nassertv(_pointer != nullptr);
  88. _cycler->increment_write(_pointer);
  89. }
  90. /**
  91. * This flavor of the constructor elevates the pointer from the
  92. * CycleDataLockedReader from a read to a write pointer (and invalidates the
  93. * reader).
  94. */
  95. template<class CycleDataType>
  96. INLINE CycleDataWriter<CycleDataType>::
  97. CycleDataWriter(PipelineCycler<CycleDataType> &cycler,
  98. CycleDataLockedReader<CycleDataType> &take_from) :
  99. _cycler(&cycler),
  100. _current_thread(take_from.get_current_thread())
  101. {
  102. _pointer = _cycler->elevate_read(take_from.take_pointer(), _current_thread);
  103. }
  104. /**
  105. * This flavor of the constructor elevates the pointer from the
  106. * CycleDataLockedReader from a read to a write pointer (and invalidates the
  107. * reader). It also propagates the pointer back upstream; see
  108. * PipelineCycler::write_upstream().
  109. */
  110. template<class CycleDataType>
  111. INLINE CycleDataWriter<CycleDataType>::
  112. CycleDataWriter(PipelineCycler<CycleDataType> &cycler,
  113. CycleDataLockedReader<CycleDataType> &take_from,
  114. bool force_to_0) :
  115. _cycler(&cycler),
  116. _current_thread(take_from.get_current_thread())
  117. {
  118. _pointer = _cycler->elevate_read_upstream(take_from.take_pointer(),
  119. force_to_0, _current_thread);
  120. }
  121. /**
  122. *
  123. */
  124. template<class CycleDataType>
  125. INLINE CycleDataWriter<CycleDataType>::
  126. CycleDataWriter(CycleDataWriter<CycleDataType> &&from) noexcept :
  127. _cycler(from._cycler),
  128. _current_thread(from._current_thread),
  129. _pointer(from._pointer)
  130. {
  131. from._pointer = nullptr;
  132. }
  133. /**
  134. *
  135. */
  136. template<class CycleDataType>
  137. INLINE void CycleDataWriter<CycleDataType>::
  138. operator = (CycleDataWriter<CycleDataType> &&from) noexcept {
  139. nassertv(_pointer == nullptr);
  140. nassertv(_current_thread == from._current_thread);
  141. _cycler = from._cycler;
  142. _pointer = from._pointer;
  143. from._pointer = nullptr;
  144. }
  145. /**
  146. *
  147. */
  148. template<class CycleDataType>
  149. INLINE CycleDataWriter<CycleDataType>::
  150. ~CycleDataWriter() {
  151. if (_pointer != nullptr) {
  152. _cycler->release_write(_pointer);
  153. }
  154. }
  155. /**
  156. * This provides an indirect member access to the actual CycleData data.
  157. */
  158. template<class CycleDataType>
  159. INLINE CycleDataType *CycleDataWriter<CycleDataType>::
  160. operator -> () {
  161. nassertr(_pointer != nullptr, _cycler->cheat());
  162. return _pointer;
  163. }
  164. /**
  165. * This provides an indirect member access to the actual CycleData data.
  166. */
  167. template<class CycleDataType>
  168. INLINE const CycleDataType *CycleDataWriter<CycleDataType>::
  169. operator -> () const {
  170. nassertr(_pointer != nullptr, _cycler->cheat());
  171. return _pointer;
  172. }
  173. /**
  174. * This allows the CycleDataWriter to be passed to any function that expects a
  175. * CycleDataType pointer.
  176. */
  177. template<class CycleDataType>
  178. INLINE CycleDataWriter<CycleDataType>::
  179. operator CycleDataType * () {
  180. nassertr(_pointer != nullptr, _cycler->cheat());
  181. return _pointer;
  182. }
  183. /**
  184. * Returns the Thread pointer of the currently-executing thread, as passed to
  185. * the constructor of this object.
  186. */
  187. template<class CycleDataType>
  188. INLINE Thread *CycleDataWriter<CycleDataType>::
  189. get_current_thread() const {
  190. return _current_thread;
  191. }
  192. #else // !DO_PIPELINING
  193. // This is the trivial, do-nothing implementation.
  194. /**
  195. *
  196. */
  197. template<class CycleDataType>
  198. INLINE CycleDataWriter<CycleDataType>::
  199. CycleDataWriter(PipelineCycler<CycleDataType> &cycler, Thread *) {
  200. _pointer = cycler.cheat();
  201. }
  202. /**
  203. *
  204. */
  205. template<class CycleDataType>
  206. INLINE CycleDataWriter<CycleDataType>::
  207. CycleDataWriter(PipelineCycler<CycleDataType> &cycler, bool, Thread *) {
  208. _pointer = cycler.cheat();
  209. }
  210. /**
  211. *
  212. */
  213. template<class CycleDataType>
  214. INLINE CycleDataWriter<CycleDataType>::
  215. CycleDataWriter(PipelineCycler<CycleDataType> &, CycleDataType *locked_cdata,
  216. Thread *) {
  217. _pointer = locked_cdata;
  218. }
  219. /**
  220. *
  221. */
  222. template<class CycleDataType>
  223. INLINE CycleDataWriter<CycleDataType>::
  224. CycleDataWriter(const CycleDataWriter<CycleDataType> &copy) :
  225. _pointer(copy._pointer)
  226. {
  227. }
  228. /**
  229. *
  230. */
  231. template<class CycleDataType>
  232. INLINE void CycleDataWriter<CycleDataType>::
  233. operator = (const CycleDataWriter<CycleDataType> &copy) {
  234. _pointer = copy._pointer;
  235. }
  236. /**
  237. * This flavor of the constructor elevates the pointer from the
  238. * CycleDataLockedReader from a read to a write pointer (and invalidates the
  239. * reader).
  240. */
  241. template<class CycleDataType>
  242. INLINE CycleDataWriter<CycleDataType>::
  243. CycleDataWriter(PipelineCycler<CycleDataType> &,
  244. CycleDataLockedReader<CycleDataType> &take_from) :
  245. _pointer((CycleDataType *)take_from.take_pointer())
  246. {
  247. }
  248. /**
  249. * This flavor of the constructor elevates the pointer from the
  250. * CycleDataLockedReader from a read to a write pointer (and invalidates the
  251. * reader). It also propagates the pointer back upstream; see
  252. * PipelineCycler::write_upstream().
  253. */
  254. template<class CycleDataType>
  255. INLINE CycleDataWriter<CycleDataType>::
  256. CycleDataWriter(PipelineCycler<CycleDataType> &,
  257. CycleDataLockedReader<CycleDataType> &take_from,
  258. bool force_to_0) :
  259. _pointer((CycleDataType *)take_from.take_pointer())
  260. {
  261. }
  262. /**
  263. *
  264. */
  265. template<class CycleDataType>
  266. INLINE CycleDataWriter<CycleDataType>::
  267. ~CycleDataWriter() {
  268. }
  269. /**
  270. * This provides an indirect member access to the actual CycleData data.
  271. */
  272. template<class CycleDataType>
  273. INLINE CycleDataType *CycleDataWriter<CycleDataType>::
  274. operator -> () {
  275. return _pointer;
  276. }
  277. /**
  278. * This provides an indirect member access to the actual CycleData data.
  279. */
  280. template<class CycleDataType>
  281. INLINE const CycleDataType *CycleDataWriter<CycleDataType>::
  282. operator -> () const {
  283. return _pointer;
  284. }
  285. /**
  286. * This allows the CycleDataWriter to be passed to any function that expects a
  287. * CycleDataType pointer.
  288. */
  289. template<class CycleDataType>
  290. INLINE CycleDataWriter<CycleDataType>::
  291. operator CycleDataType * () {
  292. return _pointer;
  293. }
  294. /**
  295. * Returns the Thread pointer of the currently-executing thread, as passed to
  296. * the constructor of this object.
  297. */
  298. template<class CycleDataType>
  299. INLINE Thread *CycleDataWriter<CycleDataType>::
  300. get_current_thread() const {
  301. return Thread::get_current_thread();
  302. }
  303. #endif // DO_PIPELINING
  304. #endif // CPPPARSER