text: #pragma once
  
  #include <string>
  #include <helper/SCriticalSection.h>
  #include <helper/SNoCopyable.hpp>
  #include <helper/SFunctor.hpp>
  #include <helper/SSemaphore.h>
  namespace SOUI
  {
  
  class ThreadPrivate;
  struct IRunnable;
  
  /**
   * Thread class for creating a thread.
   */
  class Thread : public SNoCopyable
  {
  public:
      enum ThreadPriority
      {
          High = 1,
          Normal = 0,
          Low = -1,
      };
  
      /**
       * Get current thread ID.
       * @return current thread ID.
       */
      static long getCurrentThreadID();
  
      /**
       * Set stopping flag to thread. The thread may not be stopped immediately.
       */
      void stop();
  
      /**
       * Wait for thread stopped synchronized.
       */
      void waitForStop();
  
      /**
       * Get stopping flag.
       * @return true if stopping flag is set.
       */
      bool isStopping() ;
      /**
        * Get stopped flag.
        * @return true if stopping flag is set or start flag is false.
        */
      bool isStopped() ;
  
      /**
       * Get thread ID.
       * @return thread ID.
       */
      long getThreadID()
      {
          SAutoLock autoLock(_lock);
          return _threadID;
      }
  
      /**
       * Get thread name.
       * @return thread name.
       */
      std::string getName() ;
  
      /**
       * Identify whether thread is started.
       * @return true if started.
       */
      bool isStart()
      {
          SAutoLock autoLock(_lock);
          return _start;
      }
  
      /**
       * Default constructor.
       */
      Thread();
  
      /**
       * Destructor.
       */
      virtual ~Thread();
  
      /**
       * Invalid thread ID.
       */
      static const long INVALID_THREAD_ID;
  
  	bool start(IRunnable *runnable, const std::string &name, ThreadPriority priority = Normal);
  
  private:
      /**
       * For implementation on Windows,
       * we have to use this  Win32 thunk to call the c-style entry point : threadProc
       */
  #ifdef WIN32
  	static unsigned int WINAPI threadProcWin32thunk(void * lpParameter);
  #endif
      static void *threadProc(void *args);
  
      void clear();
      void setThreadName(const std::string &name);
      void setPriority(ThreadPriority priority);
  
      // Thread object itself must be thread-safe
      SCriticalSection _lock;
      bool _start;
      bool _stopping;
      IRunnable *_runnable;
      std::string _name;
      long _threadID;
      SSemaphore _startSem;
      ThreadPrivate &_private;
      ThreadPriority _priorityLevel;
  };
  
  }
  