1 //=============================================================================
2 //
3 // Adventure Game Studio (AGS)
4 //
5 // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
6 // The full list of copyright holders can be found in the Copyright.txt
7 // file, which is part of this source code distribution.
8 //
9 // The AGS source code is provided under the Artistic License 2.0.
10 // A copy of this license can be found in the file License.txt and at
11 // http://www.opensource.org/licenses/artistic-license-2.0.php
12 //
13 //=============================================================================
14 
15 #ifndef __AGS_EE_PLATFORM__THREAD_WINDOWS_H
16 #define __AGS_EE_PLATFORM__THREAD_WINDOWS_H
17 
18 // FIXME: This is a horrible hack to avoid conflicts between Allegro and Windows
19 #define BITMAP WINDOWS_BITMAP
20 #include <windows.h>
21 #undef BITMAP
22 
23 
24 namespace AGS
25 {
26 namespace Engine
27 {
28 
29 
30 class WindowsThread : public BaseThread
31 {
32 public:
WindowsThread()33   WindowsThread()
34   {
35     _thread = NULL;
36     _running = false;
37   }
38 
~WindowsThread()39   ~WindowsThread()
40   {
41     Stop();
42   }
43 
Create(AGSThreadEntry entryPoint,bool looping)44   inline bool Create(AGSThreadEntry entryPoint, bool looping)
45   {
46     _looping = looping;
47     _entry = entryPoint;
48     _thread = CreateThread(NULL, 0, _thread_start, this, CREATE_SUSPENDED, NULL);
49 
50     return (_thread != NULL);
51   }
52 
Start()53   inline bool Start()
54   {
55     if ((_thread != NULL) && (!_running))
56     {
57       DWORD result = ResumeThread(_thread);
58 
59       _running = (result != (DWORD) - 1);
60       return _running;
61     }
62     else
63     {
64       return false;
65     }
66   }
67 
Stop()68   bool Stop()
69   {
70     if ((_thread != NULL) && (_running))
71     {
72       if (_looping)
73       {
74         _looping = false;
75         WaitForSingleObject(_thread, INFINITE);
76       }
77 
78       CloseHandle(_thread);
79 
80       _running = false;
81       _thread = NULL;
82       return true;
83     }
84     else
85     {
86       return false;
87     }
88   }
89 
90 private:
91   HANDLE _thread;
92   bool   _running;
93   bool   _looping;
94 
95   AGSThreadEntry _entry;
96 
_thread_start(LPVOID lpParam)97   static DWORD __stdcall _thread_start(LPVOID lpParam)
98   {
99     AGSThreadEntry entry = ((WindowsThread *)lpParam)->_entry;
100     bool *looping = &((WindowsThread *)lpParam)->_looping;
101 
102     do
103     {
104       entry();
105     }
106     while (*looping);
107 
108     return 0;
109   }
110 };
111 
112 
113 typedef WindowsThread Thread;
114 
115 
116 } // namespace Engine
117 } // namespace AGS
118 
119 #endif // __AGS_EE_PLATFORM__THREAD_WINDOWS_H
120