//---------------------------------------------------------------------------
  /*
   *Author  : ¿½¨R Xiao Chong
   *Email   : qs.xiao@gmail.com
   *Date    : 20060913
   *TODO    : priority item insertion into queue.
   *Compiler: BCB6
   *Warning :
  **/

#include <vcl.h>
#pragma hdrstop
#include "ThreadQueDemo.h"

//---------------------------------------------------------------------------
//#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;

void fun1(const WORK_ITEM &); // Forward declaration, use const just remaind
void fun2(const WORK_ITEM &); // not for changing purpose but saving copy time.

//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
  : TForm(Owner)
{

  mDoWorkFlag = ::CreateEvent(
        NULL,         // default security attributes
        TRUE,         // manual-reset event
        FALSE,         // initial state is signaled
        "NotifyWork"  // object name
        ); 
  if ( mDoWorkFlag == NULL)
  {
      ShowMessage(String().sprintf("CreateEvent failed (%d)\n", GetLastError()));
      Application->Terminate();
  }
  mWorker = new Worker(true); // set to true means not run immediately
  mWorker->FreeOnTerminate = true; // so that we dont need to delete manually

}
//---------------------------------------------------------------------------
void __fastcall TMainForm::PushWorkClick(TObject *Sender)
{
  static int item_no = 0;
  WORK_ITEM work_item;

  work_item.mNameParam = "Item1";
  work_item.mNo = 123;
  work_item.mpFunction = fun1; //assign user-define function define below
  mQue.push_back(work_item);
  Memo2->Lines->Add(String().sprintf("Item %d",++item_no));

  work_item.mNameParam = "Item2";
  work_item.mNo = 456;
  work_item.mpFunction = fun2;
  mQue.push_back(work_item);
  Memo2->Lines->Add(String().sprintf("Item %d",++item_no));

  ::SetEvent(mDoWorkFlag); // notify to do work


}
//---------------------------------------------------------------------------

void fun1(const WORK_ITEM &item)
{
  String s = String().sprintf("%s Num=%d from FUN_1",item.mNameParam,item.mNo);
  for (int i=0; i < 100000000; ++i); // just emulate some further process
  MainForm->Memo1->Lines->Add(s);
}

void fun2(const WORK_ITEM &item)
{
  String s = String().sprintf("%s Num=%d from FUN_2",item.mNameParam,item.mNo);
  for (int i=0; i < 300000000; ++i); // just emulate some further process
  MainForm->Memo1->Lines->Add(s);
}

void __fastcall TMainForm::ThreadStartClick(TObject *Sender)
{
  mWorker->Resume();
  ThreadStart->Enabled = false;
  PauseThread->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::StopThreadClick(TObject *Sender)
{
  // test if item work stop when thread terminate ONLY
  mWorker->Terminate();
  ThreadStart->Enabled = false;
  PauseThread->Enabled = false;
  StopThread->Enabled = false;

}
//---------------------------------------------------------------------------

void __fastcall TMainForm::PauseThreadClick(TObject *Sender)
{
  mWorker->Suspend();
  PauseThread->Enabled = false;
  ThreadStart->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
  ::CloseHandle(mDoWorkFlag); // release resource to windows
  mWorker->Terminate();
}
//---------------------------------------------------------------------------



