ROOT logo
// $Id$
// Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/**************************************************************************
 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
 * full copyright notice.                                                 *
 **************************************************************************/
#include <TObject.h>
#include <TList.h>
#include <TTimer.h>
#include <TROOT.h>

#include <TThread.h>
#include <TMutex.h>
#include <TCondition.h>

class CommandQueue : public TObject
{
public:
  class Command : public TObject
  {
  public:
    TString     fCommand;
    TCondition *fAwakeCond; // awake thread after command executed

    Command(const TString& cmd, TCondition* cond) : fCommand(cmd), fAwakeCond(cond) {}

    ClassDef(Command, 0); // An entry in the command-queue.
  };

  TList  fQueue;
  TMutex fQueueLock;
  TTimer fQueueTimer;
  Bool_t fQueueTimerSet;

  CommandQueue()
  {
    fQueueTimer.Connect("Timeout()", "CommandQueue", this, "ProcessQueue()");
    fQueueTimerSet = kFALSE;
  }

  // Destructor, cleanup missing.

  //--------------------------------

  void RegisterCommand(const TString& cmd, TCondition* cond=0)
  {
    fQueueLock.Lock();
    fQueue.Add(new Command(cmd, cond));
    if (!fQueueTimerSet) {
      // Force execution in main thread when it is free.
      fQueueTimer.Start(0, kTRUE);
      fQueueTimerSet = kTRUE;
    }
    fQueueLock.UnLock();
  }

  virtual void ProcessQueue()
  {
    Int_t n_proccessed = 0;

    while (1) {
      fQueueLock.Lock();
      Command* c = (Command*) fQueue.First();
      fQueue.RemoveFirst();
      fQueueLock.UnLock();

      { // Put this into virtual void ProcessComand(Command*);
	// Need also exception handling.
	gROOT->ProcessLineFast(c->fCommand);
	++n_proccessed;
	if (c->fAwakeCond != 0) {
	  c->fAwakeCond->GetMutex()->Lock();
	  c->fAwakeCond->Signal();
	  c->fAwakeCond->GetMutex()->UnLock();
	}
      }
      delete c;

      fQueueLock.Lock();
      if (fQueue.IsEmpty()) {
	fQueueTimerSet = kFALSE;
	fQueueLock.UnLock();
	break;
      }
      fQueueLock.UnLock();
    }

    printf("CommandQueue::ProcessQueue() processed %d commands.\n", n_proccessed);
  }

  ClassDef(CommandQueue,0); // Command queue for exection in global CINT context.
};

//=============================================================================
// Global variable
//=============================================================================

CommandQueue* g_cmd_queue = 0;

void command_queue()
{
  g_cmd_queue = new CommandQueue;
  printf("Starting command-queue ...\n");
}

// ============================================================================
// TEveUtil side
// ============================================================================

#include <TEve.h>
#include <TEveManager.h>
#include <TEvePointSet.h>

#include <TRandom.h>

void make_crap(void* arg)
{
  Int_t num = 1024;
  TRandom rnd(0);

  TEvePointSet* ps = new TEvePointSet("Testus", num);
  for (Int_t i=0; i<num; ++i) {
    ps->SetNextPoint(rnd.Uniform(-100, 100),
		     rnd.Uniform(-100, 100),
		     rnd.Uniform(-100, 100));
  }
  ps->SetMainColor(kRed);
  printf("make_crap() -> produced TEvePointSet* %p)\n", ps);

  ((CommandQueue*)arg)->RegisterCommand
    (Form("register_crap((TEveElement*)0x%lx)", ps));
}

void register_crap(TEveElement* el)
{
  printf("register_crap(TEveElement* %p)\n", el);
  gEve->AddElement(el);
  gEve->Redraw3D();
}

void test()
{
  TThread* thr = new TThread(make_crap, g_cmd_queue);
  thr->Run();
}
 command_queue.C:1
 command_queue.C:2
 command_queue.C:3
 command_queue.C:4
 command_queue.C:5
 command_queue.C:6
 command_queue.C:7
 command_queue.C:8
 command_queue.C:9
 command_queue.C:10
 command_queue.C:11
 command_queue.C:12
 command_queue.C:13
 command_queue.C:14
 command_queue.C:15
 command_queue.C:16
 command_queue.C:17
 command_queue.C:18
 command_queue.C:19
 command_queue.C:20
 command_queue.C:21
 command_queue.C:22
 command_queue.C:23
 command_queue.C:24
 command_queue.C:25
 command_queue.C:26
 command_queue.C:27
 command_queue.C:28
 command_queue.C:29
 command_queue.C:30
 command_queue.C:31
 command_queue.C:32
 command_queue.C:33
 command_queue.C:34
 command_queue.C:35
 command_queue.C:36
 command_queue.C:37
 command_queue.C:38
 command_queue.C:39
 command_queue.C:40
 command_queue.C:41
 command_queue.C:42
 command_queue.C:43
 command_queue.C:44
 command_queue.C:45
 command_queue.C:46
 command_queue.C:47
 command_queue.C:48
 command_queue.C:49
 command_queue.C:50
 command_queue.C:51
 command_queue.C:52
 command_queue.C:53
 command_queue.C:54
 command_queue.C:55
 command_queue.C:56
 command_queue.C:57
 command_queue.C:58
 command_queue.C:59
 command_queue.C:60
 command_queue.C:61
 command_queue.C:62
 command_queue.C:63
 command_queue.C:64
 command_queue.C:65
 command_queue.C:66
 command_queue.C:67
 command_queue.C:68
 command_queue.C:69
 command_queue.C:70
 command_queue.C:71
 command_queue.C:72
 command_queue.C:73
 command_queue.C:74
 command_queue.C:75
 command_queue.C:76
 command_queue.C:77
 command_queue.C:78
 command_queue.C:79
 command_queue.C:80
 command_queue.C:81
 command_queue.C:82
 command_queue.C:83
 command_queue.C:84
 command_queue.C:85
 command_queue.C:86
 command_queue.C:87
 command_queue.C:88
 command_queue.C:89
 command_queue.C:90
 command_queue.C:91
 command_queue.C:92
 command_queue.C:93
 command_queue.C:94
 command_queue.C:95
 command_queue.C:96
 command_queue.C:97
 command_queue.C:98
 command_queue.C:99
 command_queue.C:100
 command_queue.C:101
 command_queue.C:102
 command_queue.C:103
 command_queue.C:104
 command_queue.C:105
 command_queue.C:106
 command_queue.C:107
 command_queue.C:108
 command_queue.C:109
 command_queue.C:110
 command_queue.C:111
 command_queue.C:112
 command_queue.C:113
 command_queue.C:114
 command_queue.C:115
 command_queue.C:116
 command_queue.C:117
 command_queue.C:118
 command_queue.C:119
 command_queue.C:120
 command_queue.C:121
 command_queue.C:122
 command_queue.C:123
 command_queue.C:124
 command_queue.C:125
 command_queue.C:126
 command_queue.C:127
 command_queue.C:128
 command_queue.C:129
 command_queue.C:130
 command_queue.C:131
 command_queue.C:132
 command_queue.C:133
 command_queue.C:134
 command_queue.C:135
 command_queue.C:136
 command_queue.C:137
 command_queue.C:138
 command_queue.C:139
 command_queue.C:140
 command_queue.C:141
 command_queue.C:142
 command_queue.C:143
 command_queue.C:144
 command_queue.C:145
 command_queue.C:146
 command_queue.C:147
 command_queue.C:148