threads.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // threads and tls support
  2. package al
  3. /*
  4. #include <stdlib.h>
  5. #include <allegro5/allegro.h>
  6. #include "helpers.h"
  7. #include "callbacks.h"
  8. */
  9. import "C"
  10. import "runtime"
  11. import "unsafe"
  12. type Thread struct {
  13. handle * C.ALLEGRO_THREAD
  14. }
  15. // Converts a thread to it's underlying C pointer
  16. func (self * Thread) toC() *C.ALLEGRO_THREAD {
  17. return (*C.ALLEGRO_THREAD)(self.handle)
  18. }
  19. // Destroys the thread.
  20. func (self *Thread) Destroy() {
  21. if self.handle != nil {
  22. C.al_destroy_thread(self.toC())
  23. }
  24. self.handle = nil
  25. }
  26. // Wraps a C thread into a go thread
  27. func wrapThreadRaw(data *C.ALLEGRO_THREAD) *Thread {
  28. if data == nil {
  29. return nil
  30. }
  31. return &Thread{data}
  32. }
  33. // Sets up a finalizer for this Thread that calls Destroy()
  34. func (self *Thread) SetDestroyFinalizer() *Thread {
  35. if self != nil {
  36. runtime.SetFinalizer(self, func(me *Thread) { me.Destroy() })
  37. }
  38. return self
  39. }
  40. // Wraps a C thread into a go thread and sets up a finalizer that calls Destroy()
  41. func wrapThread(data *C.ALLEGRO_THREAD) *Thread {
  42. self := wrapThreadRaw(data)
  43. return self.SetDestroyFinalizer()
  44. }
  45. type Cond struct {
  46. handle * C.ALLEGRO_COND
  47. }
  48. // Converts a cond to it's underlying C pointer
  49. func (self * Cond) toC() *C.ALLEGRO_COND {
  50. return (*C.ALLEGRO_COND)(self.handle)
  51. }
  52. // Destroys the cond.
  53. func (self *Cond) Destroy() {
  54. if self.handle != nil {
  55. C.al_destroy_cond(self.toC())
  56. }
  57. self.handle = nil
  58. }
  59. // Wraps a C cond into a go cond
  60. func wrapCondRaw(data *C.ALLEGRO_COND) *Cond {
  61. if data == nil {
  62. return nil
  63. }
  64. return &Cond{data}
  65. }
  66. // Sets up a finalizer for this Cond that calls Destroy()
  67. func (self *Cond) SetDestroyFinalizer() *Cond {
  68. if self != nil {
  69. runtime.SetFinalizer(self, func(me *Cond) { me.Destroy() })
  70. }
  71. return self
  72. }
  73. // Wraps a C cond into a go cond and sets up a finalizer that calls Destroy()
  74. func wrapCond(data *C.ALLEGRO_COND) *Cond {
  75. self := wrapCondRaw(data)
  76. return self.SetDestroyFinalizer()
  77. }
  78. type Mutex struct {
  79. handle * C.ALLEGRO_MUTEX
  80. }
  81. // Converts a mutex to it's underlying C pointer
  82. func (self * Mutex) toC() *C.ALLEGRO_MUTEX {
  83. return (*C.ALLEGRO_MUTEX)(self.handle)
  84. }
  85. // Destroys the mutex.
  86. func (self *Mutex) Destroy() {
  87. if self.handle != nil {
  88. C.al_destroy_mutex(self.toC())
  89. }
  90. self.handle = nil
  91. }
  92. // Wraps a C mutex into a go mutex
  93. func wrapMutexRaw(data *C.ALLEGRO_MUTEX) *Mutex {
  94. if data == nil {
  95. return nil
  96. }
  97. return &Mutex{data}
  98. }
  99. // Sets up a finalizer for this Mutex that calls Destroy()
  100. func (self *Mutex) SetDestroyFinalizer() *Mutex {
  101. if self != nil {
  102. runtime.SetFinalizer(self, func(me *Mutex) { me.Destroy() })
  103. }
  104. return self
  105. }
  106. // Wraps a C mutex into a go mutex and sets up a finalizer that calls Destroy()
  107. func wrapMutex(data *C.ALLEGRO_MUTEX) *Mutex {
  108. self := wrapMutexRaw(data)
  109. return self.SetDestroyFinalizer()
  110. }
  111. func CreateThread(fn ThreadCallbackFunction, data unsafe.Pointer) *Thread {
  112. cbd := & threadCallbackData{fn , data}
  113. ct := C.al_create_thread((*[0]byte)(C.go_create_thread_callback), unsafe.Pointer(cbd))
  114. return wrapThread(ct)
  115. }
  116. func (thread * Thread) Start() {
  117. C.al_start_thread(thread.toC())
  118. }
  119. func (thread * Thread) Join() (data interface {}) {
  120. gdata:= make([]byte, 64)
  121. gptr := unsafe.Pointer(&gdata)
  122. cptr := &gptr
  123. /* XXX: I am not sure this hack will work. */
  124. C.al_join_thread(thread.toC(), cptr)
  125. return gdata
  126. }
  127. func (thread * Thread) ShouldStop() (bool) {
  128. return bool(C.al_get_thread_should_stop(thread.toC()))
  129. }
  130. func (thread * Thread) SetShouldStop() {
  131. C.al_set_thread_should_stop(thread.toC())
  132. }
  133. func RunDetachedThread(fn ThreadCallbackFunction, data unsafe.Pointer) {
  134. cbd := & threadCallbackData{fn , data}
  135. C.al_run_detached_thread((*[0]byte)(C.go_create_thread_callback), unsafe.Pointer(cbd))
  136. }
  137. func CreateMutex() * Mutex {
  138. return wrapMutex(C.al_create_mutex())
  139. }
  140. func CreateMutexRecursive() * Mutex {
  141. return wrapMutex(C.al_create_mutex_recursive())
  142. }
  143. func (mutex * Mutex) Lock() {
  144. C.al_lock_mutex(mutex.toC())
  145. }
  146. func (mutex * Mutex) Unlock() {
  147. C.al_unlock_mutex(mutex.toC())
  148. }
  149. func CreateCond() * Cond {
  150. return wrapCond(C.al_create_cond())
  151. }
  152. func (cond * Cond) Wait(mutex * Mutex) {
  153. C.al_wait_cond(cond.toC(), mutex.toC())
  154. }
  155. func (cond * Cond) WaitUntil(mutex * Mutex, timeout * Timeout) {
  156. C.al_wait_cond_until(cond.toC(), mutex.toC(), timeout.toC())
  157. }
  158. func (cond * Cond) Broadcast(mutex * Mutex) {
  159. C.al_broadcast_cond(cond.toC())
  160. }
  161. func (cond * Cond) Signal(mutex * Mutex) {
  162. C.al_signal_cond(cond.toC())
  163. }
  164. const (
  165. STATE_NEW_DISPLAY_PARAMETERS= C.ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS
  166. STATE_NEW_BITMAP_PARAMETERS = C.ALLEGRO_STATE_NEW_BITMAP_PARAMETERS
  167. STATE_DISPLAY = C.ALLEGRO_STATE_DISPLAY
  168. STATE_TARGET_BITMAP = C.ALLEGRO_STATE_TARGET_BITMAP
  169. STATE_BLENDER = C.ALLEGRO_STATE_BLENDER
  170. STATE_NEW_FILE_INTERFACE = C.ALLEGRO_STATE_NEW_FILE_INTERFACE
  171. STATE_TRANSFORM = C.ALLEGRO_STATE_TRANSFORM
  172. STATE_PROJECTION_TRANSFORM = C.ALLEGRO_STATE_PROJECTION_TRANSFORM
  173. STATE_BITMAP = C.ALLEGRO_STATE_BITMAP
  174. STATE_ALL = C.ALLEGRO_STATE_ALL
  175. )
  176. type State C.ALLEGRO_STATE;
  177. func StoreState(flags int) * State {
  178. state := &C.ALLEGRO_STATE{}
  179. C.al_store_state(state, C.int(flags))
  180. return (*State)(state)
  181. }
  182. func (state * State) Restore() {
  183. cstate := (*C.ALLEGRO_STATE)(state)
  184. C.al_restore_state(cstate);
  185. }