ROOT logo
// @(#)root/eve:$Id$
// Author: Matevz Tadel 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 "AliEveMacroExecutor.h"
#include "AliEveMacro.h"
#include "AliEveEventManager.h"
#include "AliSysInfo.h"

#include <TEveUtil.h>
#include <TList.h>
#include <TROOT.h>

#include <TEveManager.h>
#include <TGFileDialog.h>
#include <TGMenu.h>

#include <TSystem.h>
#include <TPRegexp.h>
#include <RVersion.h>


//______________________________________________________________________________
//
// Contains a list of AliEveMacros.
// The macros are added via AddMacro() and are owned by the executor.
// The macros can be executed via ExecMacros().
// They are executed in order in which they are registered.

ClassImp(AliEveMacroExecutor)

//______________________________________________________________________________
AliEveMacroExecutor::AliEveMacroExecutor() :
  TObject(),
  fMacros(new TList)
{
  // Constructor.

  fMacros->SetOwner(kTRUE);
}

//______________________________________________________________________________
AliEveMacroExecutor::~AliEveMacroExecutor()
{
  // Destructor.

  delete fMacros;
}

/******************************************************************************/

void AliEveMacroExecutor::AddMacro(AliEveMacro* mac)
{
  // Add a new macro. Ownership transfered to the executor.

  static const TEveException kEH("AliEveMacroExecutor::AddMacro ");

  const TString mname = mac->GetMacro();
  if ( ! mname.IsNull() && TEveUtil::CheckMacro(mname) == kFALSE)
  {
    TEveUtil::LoadMacro(mname);  
  }
  fMacros->Add(mac);
}

AliEveMacro* AliEveMacroExecutor::FindMacro(const TString& func)
{
  // Find macro with given function name (it is supposed to be unique).
  // Returns 0 if not found.

  TIter next(fMacros);
  AliEveMacro* mac;
  while ((mac = (AliEveMacro*) next()))
  {
    if (mac->GetFunc() == func)
      return mac;
  }
  return 0;
}

/******************************************************************************/

void AliEveMacroExecutor::RemoveMacros()
{
  fMacros->Clear();
}

/******************************************************************************/

#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
#include "Api.h"
#endif
#include "TInterpreter.h"

void AliEveMacroExecutor::ExecMacros()
{
  // Execute registered macros.

  TIter next(fMacros);
  AliEveMacro* mac;
  while ((mac = (AliEveMacro*) next()))
  {
    // printf ("macro '%s'; func '%s'; args '%s'\n", mac->GetMacro().Data(), mac->GetFunc().Data(), mac->GetArgs().Data());

    mac->ResetExecState();
    
    if (mac->GetActive() == kFALSE || mac->GetFunc().IsNull())
    {
      continue;
    }

    if ((mac->RequiresRunLoader() && ! AliEveEventManager::HasRunLoader()) ||
        (mac->RequiresESD()       && ! AliEveEventManager::HasESD())       ||
        (mac->RequiresESDfriend() && ! AliEveEventManager::HasESDfriend()) ||
        (mac->RequiresRawReader() && ! AliEveEventManager::HasRawReader()) ||
	(mac->RequiresAOD()       && ! AliEveEventManager::HasAOD()))
    {
      mac->SetExecNoData();
      continue;
    }

    TString cmd(mac->FormForExec());
    try
    {
      Long_t                   result = 0;
      TInterpreter::EErrorCode error  = TInterpreter::kNoError;

      AliSysInfo::AddStamp(Form("%s_%s_before",mac->GetMacro().Data(), mac->GetFunc().Data()));
      result = gInterpreter->ProcessLine(cmd, &error);
      AliSysInfo::AddStamp(Form("%s_%s_after",mac->GetMacro().Data(), mac->GetFunc().Data()));

#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
      // Try to fix broken cint state? Code taken form pyroot.
      if (G__get_return(0) > G__RETURN_NORMAL)
      {
	printf ("*** FIXING CINT STATE AFTER RETURN ***\n");
	G__security_recover(0);
      }
#endif
      if (error != TInterpreter::kNoError)
      {
        mac->SetExecError();
        Error("ExecMacros", "Executing %s::%s, CINT error ... hopefully recovered.",
              mac->GetMacro().Data(), cmd.Data());
      }
      else
      {
        TEveElement *el  = (TEveElement*) result;
        TObject     *obj = dynamic_cast<TObject*>(el);
        if (el != 0 && obj == 0)
        {
          Warning("ExecMacros", "Executing %s::%s, returned TEveElement seems bad, setting it to 0.",
                  mac->GetMacro().Data(), cmd.Data());
          el = 0;
        }
        mac->SetExecOK(el);
      }
    }
    catch(TEveException& exc)
    {
      mac->SetExecException(exc);
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
      // Try to fix broken cint state? Code taken form pyroot.
      if (G__get_return(0) > G__RETURN_NORMAL)
      {
	printf ("*** FIXING CINT STATE AFTER EXCEPTION ***\n");
	G__security_recover(0);
      }
#endif
      Error("ExecMacros", "Executing %s::%s, caught exception: '%s'.",
	    mac->GetMacro().Data(), cmd.Data(), exc.Data());
    }
  }
}

/******************************************************************************/

#include <iostream>
#include <fstream>
using namespace std;

namespace
{
const char *gMacroSaveAsTypes[] = {"CINT Macro", "*.C",
                                   0, 0};
}

void AliEveMacroExecutor::SaveAddedMacros()
{

  TGFileInfo fi;
  fi.fFileTypes   = gMacroSaveAsTypes;
  fi.fIniDir      = StrDup(""); // current directory
  fi.fFileTypeIdx = 0;
  fi.fOverwrite   = kTRUE;
  new TGFileDialog(gClient->GetDefaultRoot(), gEve->GetMainWindow(), kFDSave, &fi);
  if (!fi.fFilename) return;

  TPMERegexp filere(".*/([^/]+$)");
  if (filere.Match(fi.fFilename) != 2)
  {
    Warning("AliEvePopupHandler", "file '%s' bad.", fi.fFilename);
    return;
  }
  printf("Saving...\n");

  TString file(filere[1]);
  TString file1;
  if (!file.EndsWith(".C"))
  file1 = file + ".C";
  gSystem->ChangeDirectory(fi.fIniDir);
  ofstream myfile;
  myfile.open (file1);

  TIter next(fMacros);
  AliEveMacro* mac;


  myfile <<"//Macro generated automatically by AliEveMacroExecutor\n\n";

  myfile <<"void "<<file<<"(){\n\n";
  myfile <<"  AliEveMacroExecutor *exec = AliEveEventManager::GetMaster()->GetExecutor();\n";
  myfile <<"  exec->RemoveMacros();\n";
  myfile <<"  TEveBrowser *browser = gEve->GetBrowser();\n";
  myfile <<"  browser->ShowCloseTab(kFALSE);\n";
      
  while ((mac = (AliEveMacro*) next()))
  {
    myfile <<"  exec->AddMacro(new AliEveMacro("<<mac->GetSources()<<", "<<char(34)<<mac->GetTags()<<char(34)<<", "
     <<char(34)<<mac->GetMacro()<<char(34)<<", "<<char(34)<<mac->GetFunc()<<char(34)<<", "<<char(34)<<mac->GetArgs()
     <<char(34)<<", "<<mac->GetActive()<<"));\n\n";
  }

  myfile <<"  TEveWindowSlot *slot = TEveWindow::CreateWindowInTab(browser->GetTabRight());\n";
  myfile <<"  slot->StartEmbedding();\n";
  myfile <<"  AliEveMacroExecutorWindow* exewin = new AliEveMacroExecutorWindow(exec);\n";
  myfile <<"  slot->StopEmbedding("<<char(34)<<"DataSelection"<<char(34)<<");\n";
  myfile <<"  exewin->PopulateMacros();\n\n";

  myfile <<"\n}";
  myfile.close();
  printf("Saved...\n");

}
 AliEveMacroExecutor.cxx:1
 AliEveMacroExecutor.cxx:2
 AliEveMacroExecutor.cxx:3
 AliEveMacroExecutor.cxx:4
 AliEveMacroExecutor.cxx:5
 AliEveMacroExecutor.cxx:6
 AliEveMacroExecutor.cxx:7
 AliEveMacroExecutor.cxx:8
 AliEveMacroExecutor.cxx:9
 AliEveMacroExecutor.cxx:10
 AliEveMacroExecutor.cxx:11
 AliEveMacroExecutor.cxx:12
 AliEveMacroExecutor.cxx:13
 AliEveMacroExecutor.cxx:14
 AliEveMacroExecutor.cxx:15
 AliEveMacroExecutor.cxx:16
 AliEveMacroExecutor.cxx:17
 AliEveMacroExecutor.cxx:18
 AliEveMacroExecutor.cxx:19
 AliEveMacroExecutor.cxx:20
 AliEveMacroExecutor.cxx:21
 AliEveMacroExecutor.cxx:22
 AliEveMacroExecutor.cxx:23
 AliEveMacroExecutor.cxx:24
 AliEveMacroExecutor.cxx:25
 AliEveMacroExecutor.cxx:26
 AliEveMacroExecutor.cxx:27
 AliEveMacroExecutor.cxx:28
 AliEveMacroExecutor.cxx:29
 AliEveMacroExecutor.cxx:30
 AliEveMacroExecutor.cxx:31
 AliEveMacroExecutor.cxx:32
 AliEveMacroExecutor.cxx:33
 AliEveMacroExecutor.cxx:34
 AliEveMacroExecutor.cxx:35
 AliEveMacroExecutor.cxx:36
 AliEveMacroExecutor.cxx:37
 AliEveMacroExecutor.cxx:38
 AliEveMacroExecutor.cxx:39
 AliEveMacroExecutor.cxx:40
 AliEveMacroExecutor.cxx:41
 AliEveMacroExecutor.cxx:42
 AliEveMacroExecutor.cxx:43
 AliEveMacroExecutor.cxx:44
 AliEveMacroExecutor.cxx:45
 AliEveMacroExecutor.cxx:46
 AliEveMacroExecutor.cxx:47
 AliEveMacroExecutor.cxx:48
 AliEveMacroExecutor.cxx:49
 AliEveMacroExecutor.cxx:50
 AliEveMacroExecutor.cxx:51
 AliEveMacroExecutor.cxx:52
 AliEveMacroExecutor.cxx:53
 AliEveMacroExecutor.cxx:54
 AliEveMacroExecutor.cxx:55
 AliEveMacroExecutor.cxx:56
 AliEveMacroExecutor.cxx:57
 AliEveMacroExecutor.cxx:58
 AliEveMacroExecutor.cxx:59
 AliEveMacroExecutor.cxx:60
 AliEveMacroExecutor.cxx:61
 AliEveMacroExecutor.cxx:62
 AliEveMacroExecutor.cxx:63
 AliEveMacroExecutor.cxx:64
 AliEveMacroExecutor.cxx:65
 AliEveMacroExecutor.cxx:66
 AliEveMacroExecutor.cxx:67
 AliEveMacroExecutor.cxx:68
 AliEveMacroExecutor.cxx:69
 AliEveMacroExecutor.cxx:70
 AliEveMacroExecutor.cxx:71
 AliEveMacroExecutor.cxx:72
 AliEveMacroExecutor.cxx:73
 AliEveMacroExecutor.cxx:74
 AliEveMacroExecutor.cxx:75
 AliEveMacroExecutor.cxx:76
 AliEveMacroExecutor.cxx:77
 AliEveMacroExecutor.cxx:78
 AliEveMacroExecutor.cxx:79
 AliEveMacroExecutor.cxx:80
 AliEveMacroExecutor.cxx:81
 AliEveMacroExecutor.cxx:82
 AliEveMacroExecutor.cxx:83
 AliEveMacroExecutor.cxx:84
 AliEveMacroExecutor.cxx:85
 AliEveMacroExecutor.cxx:86
 AliEveMacroExecutor.cxx:87
 AliEveMacroExecutor.cxx:88
 AliEveMacroExecutor.cxx:89
 AliEveMacroExecutor.cxx:90
 AliEveMacroExecutor.cxx:91
 AliEveMacroExecutor.cxx:92
 AliEveMacroExecutor.cxx:93
 AliEveMacroExecutor.cxx:94
 AliEveMacroExecutor.cxx:95
 AliEveMacroExecutor.cxx:96
 AliEveMacroExecutor.cxx:97
 AliEveMacroExecutor.cxx:98
 AliEveMacroExecutor.cxx:99
 AliEveMacroExecutor.cxx:100
 AliEveMacroExecutor.cxx:101
 AliEveMacroExecutor.cxx:102
 AliEveMacroExecutor.cxx:103
 AliEveMacroExecutor.cxx:104
 AliEveMacroExecutor.cxx:105
 AliEveMacroExecutor.cxx:106
 AliEveMacroExecutor.cxx:107
 AliEveMacroExecutor.cxx:108
 AliEveMacroExecutor.cxx:109
 AliEveMacroExecutor.cxx:110
 AliEveMacroExecutor.cxx:111
 AliEveMacroExecutor.cxx:112
 AliEveMacroExecutor.cxx:113
 AliEveMacroExecutor.cxx:114
 AliEveMacroExecutor.cxx:115
 AliEveMacroExecutor.cxx:116
 AliEveMacroExecutor.cxx:117
 AliEveMacroExecutor.cxx:118
 AliEveMacroExecutor.cxx:119
 AliEveMacroExecutor.cxx:120
 AliEveMacroExecutor.cxx:121
 AliEveMacroExecutor.cxx:122
 AliEveMacroExecutor.cxx:123
 AliEveMacroExecutor.cxx:124
 AliEveMacroExecutor.cxx:125
 AliEveMacroExecutor.cxx:126
 AliEveMacroExecutor.cxx:127
 AliEveMacroExecutor.cxx:128
 AliEveMacroExecutor.cxx:129
 AliEveMacroExecutor.cxx:130
 AliEveMacroExecutor.cxx:131
 AliEveMacroExecutor.cxx:132
 AliEveMacroExecutor.cxx:133
 AliEveMacroExecutor.cxx:134
 AliEveMacroExecutor.cxx:135
 AliEveMacroExecutor.cxx:136
 AliEveMacroExecutor.cxx:137
 AliEveMacroExecutor.cxx:138
 AliEveMacroExecutor.cxx:139
 AliEveMacroExecutor.cxx:140
 AliEveMacroExecutor.cxx:141
 AliEveMacroExecutor.cxx:142
 AliEveMacroExecutor.cxx:143
 AliEveMacroExecutor.cxx:144
 AliEveMacroExecutor.cxx:145
 AliEveMacroExecutor.cxx:146
 AliEveMacroExecutor.cxx:147
 AliEveMacroExecutor.cxx:148
 AliEveMacroExecutor.cxx:149
 AliEveMacroExecutor.cxx:150
 AliEveMacroExecutor.cxx:151
 AliEveMacroExecutor.cxx:152
 AliEveMacroExecutor.cxx:153
 AliEveMacroExecutor.cxx:154
 AliEveMacroExecutor.cxx:155
 AliEveMacroExecutor.cxx:156
 AliEveMacroExecutor.cxx:157
 AliEveMacroExecutor.cxx:158
 AliEveMacroExecutor.cxx:159
 AliEveMacroExecutor.cxx:160
 AliEveMacroExecutor.cxx:161
 AliEveMacroExecutor.cxx:162
 AliEveMacroExecutor.cxx:163
 AliEveMacroExecutor.cxx:164
 AliEveMacroExecutor.cxx:165
 AliEveMacroExecutor.cxx:166
 AliEveMacroExecutor.cxx:167
 AliEveMacroExecutor.cxx:168
 AliEveMacroExecutor.cxx:169
 AliEveMacroExecutor.cxx:170
 AliEveMacroExecutor.cxx:171
 AliEveMacroExecutor.cxx:172
 AliEveMacroExecutor.cxx:173
 AliEveMacroExecutor.cxx:174
 AliEveMacroExecutor.cxx:175
 AliEveMacroExecutor.cxx:176
 AliEveMacroExecutor.cxx:177
 AliEveMacroExecutor.cxx:178
 AliEveMacroExecutor.cxx:179
 AliEveMacroExecutor.cxx:180
 AliEveMacroExecutor.cxx:181
 AliEveMacroExecutor.cxx:182
 AliEveMacroExecutor.cxx:183
 AliEveMacroExecutor.cxx:184
 AliEveMacroExecutor.cxx:185
 AliEveMacroExecutor.cxx:186
 AliEveMacroExecutor.cxx:187
 AliEveMacroExecutor.cxx:188
 AliEveMacroExecutor.cxx:189
 AliEveMacroExecutor.cxx:190
 AliEveMacroExecutor.cxx:191
 AliEveMacroExecutor.cxx:192
 AliEveMacroExecutor.cxx:193
 AliEveMacroExecutor.cxx:194
 AliEveMacroExecutor.cxx:195
 AliEveMacroExecutor.cxx:196
 AliEveMacroExecutor.cxx:197
 AliEveMacroExecutor.cxx:198
 AliEveMacroExecutor.cxx:199
 AliEveMacroExecutor.cxx:200
 AliEveMacroExecutor.cxx:201
 AliEveMacroExecutor.cxx:202
 AliEveMacroExecutor.cxx:203
 AliEveMacroExecutor.cxx:204
 AliEveMacroExecutor.cxx:205
 AliEveMacroExecutor.cxx:206
 AliEveMacroExecutor.cxx:207
 AliEveMacroExecutor.cxx:208
 AliEveMacroExecutor.cxx:209
 AliEveMacroExecutor.cxx:210
 AliEveMacroExecutor.cxx:211
 AliEveMacroExecutor.cxx:212
 AliEveMacroExecutor.cxx:213
 AliEveMacroExecutor.cxx:214
 AliEveMacroExecutor.cxx:215
 AliEveMacroExecutor.cxx:216
 AliEveMacroExecutor.cxx:217
 AliEveMacroExecutor.cxx:218
 AliEveMacroExecutor.cxx:219
 AliEveMacroExecutor.cxx:220
 AliEveMacroExecutor.cxx:221
 AliEveMacroExecutor.cxx:222
 AliEveMacroExecutor.cxx:223
 AliEveMacroExecutor.cxx:224
 AliEveMacroExecutor.cxx:225
 AliEveMacroExecutor.cxx:226
 AliEveMacroExecutor.cxx:227
 AliEveMacroExecutor.cxx:228
 AliEveMacroExecutor.cxx:229
 AliEveMacroExecutor.cxx:230
 AliEveMacroExecutor.cxx:231
 AliEveMacroExecutor.cxx:232
 AliEveMacroExecutor.cxx:233
 AliEveMacroExecutor.cxx:234
 AliEveMacroExecutor.cxx:235
 AliEveMacroExecutor.cxx:236
 AliEveMacroExecutor.cxx:237
 AliEveMacroExecutor.cxx:238
 AliEveMacroExecutor.cxx:239
 AliEveMacroExecutor.cxx:240
 AliEveMacroExecutor.cxx:241
 AliEveMacroExecutor.cxx:242
 AliEveMacroExecutor.cxx:243
 AliEveMacroExecutor.cxx:244
 AliEveMacroExecutor.cxx:245
 AliEveMacroExecutor.cxx:246
 AliEveMacroExecutor.cxx:247
 AliEveMacroExecutor.cxx:248
 AliEveMacroExecutor.cxx:249