Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
REveManager.cxx
Go to the documentation of this file.
1// @(#)root/eve7:$Id$
2// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <ROOT/REveManager.hxx>
13
14#include <ROOT/REveUtil.hxx>
16#include <ROOT/REveViewer.hxx>
17#include <ROOT/REveScene.hxx>
18#include <ROOT/REveClient.hxx>
19#include <ROOT/RWebWindow.hxx>
20#include <ROOT/RFileDialog.hxx>
21#include <ROOT/RLogger.hxx>
22#include <ROOT/REveSystem.hxx>
23
24#include "TGeoManager.h"
25#include "TGeoMatrix.h"
26#include "TObjString.h"
27#include "TROOT.h"
28#include "TSystem.h"
29#include "TFile.h"
30#include "TMap.h"
31#include "TExMap.h"
32#include "TEnv.h"
33#include "TColor.h"
34#include "TPRegexp.h"
35#include "TClass.h"
36#include "TMethod.h"
37#include "TMethodCall.h"
38#include "THttpServer.h"
39#include "TTimer.h"
40#include "TApplication.h"
41
42#include <fstream>
43#include <sstream>
44#include <iostream>
45#include <regex>
46
47#include <nlohmann/json.hpp>
48
49using namespace ROOT::Experimental;
50namespace REX = ROOT::Experimental;
51
52REveManager *REX::gEve = nullptr;
53
54thread_local std::vector<RLogEntry> gEveLogEntries;
55/** \class REveManager
56\ingroup REve
57Central application manager for Eve.
58Manages elements, GUI, GL scenes and GL viewers.
59
60Following parameters can be specified in .rootrc file
61
62WebEve.GLViewer: Three # kind of GLViewer, either Three, JSRoot or RCore
63WebEve.DisableShow: 1 # do not start new web browser when REveManager::Show is called
64WebEve.HTimeout: 200 # timeout in ms for elements highlight
65WebEve.DblClick: Off # mouse double click handling in GL viewer: Off or Reset
66WebEve.TableRowHeight: 33 # size of each row in pixels in the Table view, can be used to make design more compact
67*/
68
69////////////////////////////////////////////////////////////////////////////////
70
71REveManager::REveManager()
72 : // (Bool_t map_window, Option_t* opt) :
73 fExcHandler(nullptr), fVizDB(nullptr), fVizDBReplace(kTRUE), fVizDBUpdate(kTRUE), fGeometries(nullptr),
74 fGeometryAliases(nullptr),
75 fKeepEmptyCont(kFALSE)
76{
77 // Constructor.
78
79 static const REveException eh("REveManager::REveManager ");
80
81 if (REX::gEve)
82 throw eh + "There can be only one REve!";
83
84 REX::gEve = this;
85
87 fServerStatus.fTStart = std::time(nullptr);
88
90
91 fGeometries = new TMap;
95 fVizDB = new TMap;
97
98 fElementIdMap[0] = nullptr; // do not increase count for null element.
99
100 fWorld = new REveScene("EveWorld", "Top-level Eve Scene");
103
104 fSelectionList = new REveElement("Selection List");
105 fSelectionList->SetChildClass(TClass::GetClass<REveSelection>());
108 fSelection = new REveSelection("Global Selection", "", kRed, kViolet);
109 fSelection->SetIsMaster(true);
112 fHighlight = new REveSelection("Global Highlight", "", kGreen, kCyan);
113 fHighlight->SetIsMaster(true);
117
118 fViewers = new REveViewerList("Viewers");
121
122 fScenes = new REveSceneList("Scenes");
125
126 fGlobalScene = new REveScene("Geometry scene");
129
130 fEventScene = new REveScene("Event scene");
133
134 {
135 REveViewer *v = SpawnNewViewer("Default Viewer");
136 v->AddScene(fGlobalScene);
137 v->AddScene(fEventScene);
138 }
139
140 // !!! AMT increase threshold to enable color pick on client
142
144 fWebWindow->UseServerThreads();
145 fWebWindow->SetDefaultPage("file:rootui5sys/eve7/index.html");
146
147 const char *gl_viewer = gEnv->GetValue("WebEve.GLViewer", "RCore");
148 const char *gl_dblclick = gEnv->GetValue("WebEve.DblClick", "Off");
149 Int_t htimeout = gEnv->GetValue("WebEve.HTimeout", 250);
150 Int_t table_row_height = gEnv->GetValue("WebEve.TableRowHeight", 0);
151 fWebWindow->SetUserArgs(Form("{ GLViewer: \"%s\", DblClick: \"%s\", HTimeout: %d, TableRowHeight: %d }", gl_viewer,
152 gl_dblclick, htimeout, table_row_height));
153
154 if (strcmp(gl_viewer, "RCore") == 0)
155 fIsRCore = true;
156
157 // this is call-back, invoked when message received via websocket
158 fWebWindow->SetCallBacks([this](unsigned connid) { WindowConnect(connid); },
159 [this](unsigned connid, const std::string &arg) { WindowData(connid, arg); },
160 [this](unsigned connid) { WindowDisconnect(connid); });
161 fWebWindow->SetGeometry(900, 700); // configure predefined window geometry
162 fWebWindow->SetConnLimit(100); // maximal number of connections
163 fWebWindow->SetMaxQueueLength(30); // number of allowed entries in the window queue
164
165 fMIRExecThread = std::thread{[this] { MIRExecThread(); }};
166
167 // activate interpreter error report
168 gInterpreter->ReportDiagnosticsToErrorHandler();
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// Destructor.
174
176{
177 fMIRExecThread.join();
178
179 // QQQQ How do we stop THttpServer / fWebWindow?
180
185 // Not needed - no more top-items: fScenes->Destroy();
186 fScenes = nullptr;
187
190 // Not needed - no more top-items: fViewers->Destroy();
191 fViewers = nullptr;
192
193 // fWindowManager->DestroyWindows();
194 // fWindowManager->DecDenyDestroy();
195 // fWindowManager->Destroy();
196 // fWindowManager = 0;
197
200
201 delete fGeometryAliases;
202 delete fGeometries;
203 delete fVizDB;
204 delete fExcHandler;
205}
206
207////////////////////////////////////////////////////////////////////////////////
208/// Create a new GL viewer.
209
210REveViewer *REveManager::SpawnNewViewer(const char *name, const char *title)
211{
212 REveViewer *v = new REveViewer(name, title);
214 return v;
215}
216
217////////////////////////////////////////////////////////////////////////////////
218/// Create a new scene.
219
220REveScene *REveManager::SpawnNewScene(const char *name, const char *title)
221{
222 REveScene *s = new REveScene(name, title);
224 return s;
225}
226
228{
229 printf("REveManager::RegisterRedraw3D() obsolete\n");
230}
231
232////////////////////////////////////////////////////////////////////////////////
233/// Perform 3D redraw of scenes and viewers whose contents has
234/// changed.
235
237{
238 printf("REveManager::DoRedraw3D() obsolete\n");
239}
240
241////////////////////////////////////////////////////////////////////////////////
242/// Perform 3D redraw of all scenes and viewers.
243
244void REveManager::FullRedraw3D(Bool_t /*resetCameras*/, Bool_t /*dropLogicals*/)
245{
246 printf("REveManager::FullRedraw3D() obsolete\n");
247}
248
249////////////////////////////////////////////////////////////////////////////////
250/// Clear all selection objects. Can make things easier for EVE when going to
251/// the next event. Still, destruction os selected object should still work
252/// correctly as long as it is executed within a change cycle.
253
255{
256 for (auto el : fSelectionList->fChildren) {
257 dynamic_cast<REveSelection *>(el)->ClearSelection();
258 }
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// Add an element. If parent is not specified it is added into
263/// current event (which is created if does not exist).
264
266{
267 if (parent == nullptr) {
268 // XXXX
269 }
270
271 parent->AddElement(element);
272}
273
274////////////////////////////////////////////////////////////////////////////////
275/// Add a global element, i.e. one that does not change on each
276/// event, like geometry or projection manager.
277/// If parent is not specified it is added to a global scene.
278
280{
281 if (!parent)
282 parent = fGlobalScene;
283
284 parent->AddElement(element);
285}
286
287////////////////////////////////////////////////////////////////////////////////
288/// Remove element from parent.
289
291{
292 parent->RemoveElement(element);
293}
294
295////////////////////////////////////////////////////////////////////////////////
296/// Lookup ElementId in element map and return corresponding REveElement*.
297/// Returns nullptr if the id is not found
298
300{
301 auto it = fElementIdMap.find(id);
302 return (it != fElementIdMap.end()) ? it->second : nullptr;
303}
304
305////////////////////////////////////////////////////////////////////////////////
306/// Assign a unique ElementId to given element.
307
309{
310 static const REveException eh("REveManager::AssignElementId ");
311
313 throw eh + "ElementId map is full.";
314
315next_free_id:
316 while (fElementIdMap.find(++fLastElementId) != fElementIdMap.end())
317 ;
318 if (fLastElementId == 0)
319 goto next_free_id;
320 // MT - alternatively, we could spawn a thread to find next thousand or so ids and
321 // put them in a vector of ranges. Or collect them when they are freed.
322 // Don't think this won't happen ... online event display can run for months
323 // and easily produce 100000 objects per minute -- about a month to use up all id space!
324
325 element->fElementId = fLastElementId;
326 fElementIdMap.insert(std::make_pair(fLastElementId, element));
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Activate EVE browser (summary view) for specified element id
332
334{
335 nlohmann::json msg = {};
336 msg["content"] = "BrowseElement";
337 msg["id"] = id;
338
339 fWebWindow->Send(0, msg.dump());
340}
341
342////////////////////////////////////////////////////////////////////////////////
343/// Called from REveElement prior to its destruction so the
344/// framework components (like object editor) can unreference it.
345
347{
348 if (el->fImpliedSelected > 0) {
349 for (auto slc : fSelectionList->fChildren) {
350 REveSelection *sel = dynamic_cast<REveSelection *>(slc);
351 sel->RemoveImpliedSelectedReferencesTo(el);
352 }
353
354 if (el->fImpliedSelected != 0)
355 Error("REveManager::PreDeleteElement", "ImpliedSelected not zero (%d) after cleanup of selections.",
356 el->fImpliedSelected);
357 }
358 // Primary selection deregistration is handled through Niece removal from Aunts.
359
360 if (el->fElementId != 0) {
361 auto it = fElementIdMap.find(el->fElementId);
362 if (it != fElementIdMap.end()) {
363 if (it->second == el) {
364 fElementIdMap.erase(it);
366 } else
367 Error("PreDeleteElement", "element ptr in ElementIdMap does not match the argument element.");
368 } else
369 Error("PreDeleteElement", "element id %u was not registered in ElementIdMap.", el->fElementId);
370 } else
371 Error("PreDeleteElement", "element with 0 ElementId passed in.");
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Insert a new visualization-parameter database entry. Returns
376/// true if the element is inserted successfully.
377/// If entry with the same key already exists the behaviour depends on the
378/// 'replace' flag:
379/// - true - The old model is deleted and new one is inserted (default).
380/// Clients of the old model are transferred to the new one and
381/// if 'update' flag is true (default), the new model's parameters
382/// are assigned to all clients.
383/// - false - The old model is kept, false is returned.
384///
385/// If insert is successful, the ownership of the model-element is
386/// transferred to the manager.
387
389{
390 TPair *pair = (TPair *)fVizDB->FindObject(tag);
391 if (pair) {
392 if (replace) {
393 model->IncDenyDestroy();
394 model->SetRnrChildren(kFALSE);
395
396 REveElement *old_model = dynamic_cast<REveElement *>(pair->Value());
397 if (old_model) {
398 while (old_model->HasChildren()) {
399 REveElement *el = old_model->FirstChild();
400 el->SetVizModel(model);
401 if (update) {
402 el->CopyVizParams(model);
404 }
405 }
406 old_model->DecDenyDestroy();
407 }
408 pair->SetValue(dynamic_cast<TObject *>(model));
409 return kTRUE;
410 } else {
411 return kFALSE;
412 }
413 } else {
414 model->IncDenyDestroy();
415 model->SetRnrChildren(kFALSE);
416 fVizDB->Add(new TObjString(tag), dynamic_cast<TObject *>(model));
417 return kTRUE;
418 }
419}
420
421////////////////////////////////////////////////////////////////////////////////
422/// Insert a new visualization-parameter database entry with the default
423/// parameters for replace and update, as specified by members
424/// fVizDBReplace(default=kTRUE) and fVizDBUpdate(default=kTRUE).
425/// See docs of the above function.
426
428{
429 return InsertVizDBEntry(tag, model, fVizDBReplace, fVizDBUpdate);
430}
431
432////////////////////////////////////////////////////////////////////////////////
433/// Find a visualization-parameter database entry corresponding to tag.
434/// If the entry is not found 0 is returned.
435
437{
438 return dynamic_cast<REveElement *>(fVizDB->GetValue(tag));
439}
440
441////////////////////////////////////////////////////////////////////////////////
442/// Load visualization-parameter database from file filename. The
443/// replace, update arguments replace the values of fVizDBReplace
444/// and fVizDBUpdate members for the duration of the macro
445/// execution.
446
448{
449 Bool_t ex_replace = fVizDBReplace;
450 Bool_t ex_update = fVizDBUpdate;
451 fVizDBReplace = replace;
453
455
456 fVizDBReplace = ex_replace;
457 fVizDBUpdate = ex_update;
458}
459
460////////////////////////////////////////////////////////////////////////////////
461/// Load visualization-parameter database from file filename.
462/// State of data-members fVizDBReplace and fVizDBUpdate determine
463/// how the registered entries are handled.
464
466{
468 Redraw3D();
469}
470
471////////////////////////////////////////////////////////////////////////////////
472/// Save visualization-parameter database to file filename.
473
475{
476 TPMERegexp re("(.+)\\.\\w+");
477 if (re.Match(filename) != 2) {
478 Error("SaveVizDB", "filename does not match required format '(.+)\\.\\w+'.");
479 return;
480 }
481
482 TString exp_filename(filename);
483 gSystem->ExpandPathName(exp_filename);
484
485 std::ofstream out(exp_filename, std::ios::out | std::ios::trunc);
486 out << "void " << re[1] << "()\n";
487 out << "{\n";
488 out << " REveManager::Create();\n";
489
491
492 Int_t var_id = 0;
493 TString var_name;
494 TIter next(fVizDB);
495 TObjString *key;
496 while ((key = (TObjString *)next())) {
497 REveElement *mdl = dynamic_cast<REveElement *>(fVizDB->GetValue(key));
498 if (mdl) {
499 var_name.Form("x%03d", var_id++);
500 mdl->SaveVizParams(out, key->String(), var_name);
501 } else {
502 Warning("SaveVizDB", "Saving failed for key '%s'.", key->String().Data());
503 }
504 }
505
506 out << "}\n";
507 out.close();
508}
509
510////////////////////////////////////////////////////////////////////////////////
511/// Get geometry with given filename.
512/// This is cached internally so the second time this function is
513/// called with the same argument the same geo-manager is returned.
514/// gGeoManager is set to the return value.
515
517{
518 static const REveException eh("REveManager::GetGeometry ");
519
520 TString exp_filename = filename;
521 gSystem->ExpandPathName(exp_filename);
522 printf("REveManager::GetGeometry loading: '%s' -> '%s'.\n", filename.Data(), exp_filename.Data());
523
525 if (gGeoManager) {
527 } else {
528 Bool_t locked = TGeoManager::IsLocked();
529 if (locked) {
530 Warning("REveManager::GetGeometry", "TGeoManager is locked ... unlocking it.");
532 }
533 if (TGeoManager::Import(filename) == 0) {
534 throw eh + "TGeoManager::Import() failed for '" + exp_filename + "'.";
535 }
536 if (locked) {
538 }
539
541
542 // Import colors exported by Gled, if they exist.
543 {
544 TFile f(exp_filename, "READ");
545 TObjArray *collist = (TObjArray *)f.Get("ColorList");
546 f.Close();
547 if (collist) {
549 TGeoVolume *vol;
550 while ((vol = (TGeoVolume *)next()) != nullptr) {
551 Int_t oldID = vol->GetLineColor();
552 TColor *col = (TColor *)collist->At(oldID);
553 Float_t r, g, b;
554 col->GetRGB(r, g, b);
555 Int_t newID = TColor::GetColor(r, g, b);
556 vol->SetLineColor(newID);
557 }
558 }
559 }
560
562 }
563 return gGeoManager;
564}
565
566////////////////////////////////////////////////////////////////////////////////
567/// Get geometry with given alias.
568/// The alias must be registered via RegisterGeometryAlias().
569
571{
572 static const REveException eh("REveManager::GetGeometry ");
573
574 TObjString *full_name = (TObjString *)fGeometryAliases->GetValue(alias);
575 if (!full_name)
576 throw eh + "geometry alias '" + alias + "' not registered.";
577 return GetGeometry(full_name->String());
578}
579
580////////////////////////////////////////////////////////////////////////////////
581/// Get the default geometry.
582/// It should be registered via RegisterGeometryName("Default", `<URL>`).
583
585{
586 return GetGeometryByAlias("Default");
587}
588
589////////////////////////////////////////////////////////////////////////////////
590/// Register 'name' as an alias for geometry file 'filename'.
591/// The old aliases are silently overwritten.
592/// After that the geometry can be retrieved also by calling:
593/// REX::gEve->GetGeometryByName(name);
594
596{
598}
599
600////////////////////////////////////////////////////////////////////////////////
601/// Work-around uber ugly hack used in SavePrimitive and co.
602
604{
605 TIter nextcl(gROOT->GetListOfClasses());
606 TClass *cls;
607 while ((cls = (TClass *)nextcl())) {
609 }
610}
611
612////////////////////////////////////////////////////////////////////////////////
613/// Register new directory to THttpServer
614// For example: AddLocation("mydir/", "/test/EveWebApp/ui5");
615//
616void REveManager::AddLocation(const std::string &locationName, const std::string &path)
617{
618 fWebWindow->GetServer()->AddLocation(locationName.c_str(), path.c_str());
619}
620
621////////////////////////////////////////////////////////////////////////////////
622/// Set content of default window HTML page
623// Got example: SetDefaultHtmlPage("file:currentdir/test.html")
624//
625void REveManager::SetDefaultHtmlPage(const std::string &path)
626{
627 fWebWindow->SetDefaultPage(path.c_str());
628}
629
630////////////////////////////////////////////////////////////////////////////////
631/// Set client version, used as prefix in scripts URL
632/// When changed, web browser will reload all related JS files while full URL will be different
633/// Default is empty value - no extra string in URL
634/// Version should be string like "1.2" or "ver1.subv2" and not contain any special symbols
635void REveManager::SetClientVersion(const std::string &version)
636{
637 fWebWindow->SetClientVersion(version);
638}
639
640////////////////////////////////////////////////////////////////////////////////
641/// If global REveManager* REX::gEve is not set initialize it.
642/// Returns REX::gEve.
643
645{
646 static const REveException eh("REveManager::Create ");
647
648 if (!REX::gEve) {
649 // XXXX Initialize some server stuff ???
650
651 REX::gEve = new REveManager();
652 }
653 return REX::gEve;
654}
655
656////////////////////////////////////////////////////////////////////////////////
657/// Properly terminate global REveManager.
658
660{
661 if (!REX::gEve)
662 return;
663
664 delete REX::gEve;
665 REX::gEve = nullptr;
666}
667
668void REveManager::ExecuteInMainThread(std::function<void()> func)
669{
670 class XThreadTimer : public TTimer {
671 std::function<void()> foo_;
672 public:
673 XThreadTimer(std::function<void()> f) : foo_(f)
674 {
675 SetTime(0);
677 gSystem->AddTimer(this);
678 }
679 Bool_t Notify() override
680 {
681 foo_();
682 gSystem->RemoveTimer(this);
683 delete this;
684 return kTRUE;
685 }
686 };
687
688 new XThreadTimer(func);
689}
690
692{
694 // QQQQ Should call Terminate() but it needs to:
695 // - properly stop MIRExecThread;
696 // - shutdown civet/THttp/RWebWindow
698 });
699}
700
701////////////////////////////////////////////////////////////////////////////////
702/// Process new connection from web window
703
704void REveManager::WindowConnect(unsigned connid)
705{
706 std::unique_lock<std::mutex> lock(fServerState.fMutex);
707
709 {
710 fServerState.fCV.wait(lock);
711 }
712
713 fConnList.emplace_back(connid);
714 printf("connection established %u\n", connid);
715
716 // QQQQ do we want mir-time here as well? maybe set it at the end of function?
717 // Note, this is all under lock, so nobody will get state out in between.
718 fServerStatus.fTLastMir = fServerStatus.fTLastConnect = std::time(nullptr);
720
721 // This prepares core and render data buffers.
722 printf("\nEVEMNG ............. streaming the world scene.\n");
723
724 fWorld->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
726
727 printf(" sending json, len = %d\n", (int)fWorld->fOutputJson.size());
728 Send(connid, fWorld->fOutputJson);
729 printf(" for now assume world-scene has no render data, binary-size=%d\n", fWorld->fTotalBinarySize);
730 assert(fWorld->fTotalBinarySize == 0);
731
732 for (auto &c : fScenes->RefChildren()) {
733 REveScene *scene = dynamic_cast<REveScene *>(c);
734
735 scene->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
736 printf("\nEVEMNG ............. streaming scene %s [%s]\n", scene->GetCTitle(), scene->GetCName());
737
738 // This prepares core and render data buffers.
739 scene->StreamElements();
740
741 printf(" sending json, len = %d\n", (int)scene->fOutputJson.size());
742 Send(connid, scene->fOutputJson);
743
744 if (scene->fTotalBinarySize > 0) {
745 printf(" sending binary, len = %d\n", scene->fTotalBinarySize);
746 SendBinary(connid, &scene->fOutputBinary[0], scene->fTotalBinarySize);
747 } else {
748 printf(" NOT sending binary, len = %d\n", scene->fTotalBinarySize);
749 }
750 }
751
752 fServerState.fCV.notify_all();
753}
754
755////////////////////////////////////////////////////////////////////////////////
756/// Process disconnect of web window
757
758void REveManager::WindowDisconnect(unsigned connid)
759{
760 std::unique_lock<std::mutex> lock(fServerState.fMutex);
762 {
763 fServerState.fCV.wait(lock);
764 }
765 auto conn = fConnList.end();
766 for (auto i = fConnList.begin(); i != fConnList.end(); ++i) {
767 if (i->fId == connid) {
768 conn = i;
769 break;
770 }
771 }
772 // this should not happen, just check
773 if (conn == fConnList.end()) {
774 printf("error, connection not found!");
775 } else {
776 printf("connection closed %u\n", connid);
777 fConnList.erase(conn);
778 for (auto &c : fScenes->RefChildren()) {
779 REveScene *scene = dynamic_cast<REveScene *>(c);
780 scene->RemoveSubscriber(connid);
781 }
782 fWorld->RemoveSubscriber(connid);
783 }
784
785 fServerStatus.fTLastDisconnect = std::time(nullptr);
787
788 fServerState.fCV.notify_all();
789}
790
791////////////////////////////////////////////////////////////////////////////////
792/// Process data from web window
793
794void REveManager::WindowData(unsigned connid, const std::string &arg)
795{
796 static const REveException eh("REveManager::WindowData ");
797
798 // find connection object
799 bool found = false;
800 for (auto &conn : fConnList) {
801 if (conn.fId == connid) {
802 found = true;
803 break;
804 }
805 }
806
807 // this should not happen, just check
808 if (!found) {
809 R__LOG_ERROR(REveLog()) << "Internal error - no connection with id " << connid << " found";
810 return;
811 }
812 // client status data
813 if (arg.compare("__REveDoneChanges") == 0)
814 {
815 std::unique_lock<std::mutex> lock(fServerState.fMutex);
816
817 for (auto &conn : fConnList) {
818 if (conn.fId == connid) {
819 conn.fState = Conn::Free;
820 break;
821 }
822 }
823
824 if (ClientConnectionsFree()) {
826 fServerState.fCV.notify_all();
827 }
828
829 return;
830 }
831 else if (arg.compare( 0, 10, "FILEDIALOG") == 0)
832 {
834 return;
835 }
836
837 nlohmann::json cj = nlohmann::json::parse(arg);
838 if (gDebug > 0)
839 ::Info("REveManager::WindowData", "MIR test %s\n", cj.dump().c_str());
840
841 std::string cmd = cj["mir"];
842 int id = cj["fElementId"];
843 std::string ctype = cj["class"];
844
845 ScheduleMIR(cmd, id, ctype);
846}
847
848//
849//____________________________________________________________________
850void REveManager::ScheduleMIR(const std::string &cmd, ElementId_t id, const std::string& ctype)
851{
852 std::unique_lock<std::mutex> lock(fServerState.fMutex);
853 fServerStatus.fTLastMir = std::time(nullptr);
854 fMIRqueue.push(std::shared_ptr<MIR>(new MIR(cmd, id, ctype)));
856 fServerState.fCV.notify_all();
857}
858
859//
860//____________________________________________________________________
861void REveManager::ExecuteMIR(std::shared_ptr<MIR> mir)
862{
863 static const REveException eh("REveManager::ExecuteMIR ");
864
865 class ChangeSentry {
866 public:
867 ChangeSentry()
868 {
869 gEve->GetWorld()->BeginAcceptingChanges();
870 gEve->GetScenes()->AcceptChanges(true);
871 }
872 ~ChangeSentry()
873 {
874 gEve->GetScenes()->AcceptChanges(false);
875 gEve->GetWorld()->EndAcceptingChanges();
876 }
877 };
878 ChangeSentry cs;
879
880 //if (gDebug > 0)
881 ::Info("REveManager::ExecuteCommand", "MIR cmd %s", mir->fCmd.c_str());
882
883 try {
884 REveElement *el = FindElementById(mir->fId);
885 if ( ! el) throw eh + "Element with id " + mir->fId + " not found";
886
887 static const std::regex cmd_re("^(\\w[\\w\\d]*)\\(\\s*(.*)\\s*\\)\\s*;?\\s*$", std::regex::optimize);
888 std::smatch m;
889 std::regex_search(mir->fCmd, m, cmd_re);
890 if (m.size() != 3)
891 throw eh + "Command string parse error: '" + mir->fCmd + "'.";
892
893 static const TClass *elem_cls = TClass::GetClass<REX::REveElement>();
894
895 TClass *call_cls = TClass::GetClass(mir->fCtype.c_str());
896 if ( ! call_cls)
897 throw eh + "Class '" + mir->fCtype + "' not found.";
898
899 void *el_casted = call_cls->DynamicCast(elem_cls, el, false);
900 if ( ! el_casted)
901 throw eh + "Dynamic cast from REveElement to '" + mir->fCtype + "' failed.";
902
903 std::string tag(mir->fCtype + "::" + m.str(1));
904 std::shared_ptr<TMethodCall> mc;
905
906 auto mmi = fMethCallMap.find(tag);
907 if (mmi != fMethCallMap.end())
908 {
909 mc = mmi->second;
910 }
911 else
912 {
913 const TMethod *meth = call_cls->GetMethodAllAny(m.str(1).c_str());
914 if ( ! meth)
915 throw eh + "Can not find TMethod matching '" + m.str(1) + "'.";
916 mc = std::make_shared<TMethodCall>(meth);
917 fMethCallMap.insert(std::make_pair(tag, mc));
918 }
919
921 mc->Execute(el_casted, m.str(2).c_str());
922
923 // Alternative implementation through Cling. "Leaks" 200 kB per call.
924 // This might be needed for function calls that involve data-types TMethodCall
925 // can not handle.
926 // std::stringstream cmd;
927 // cmd << "((" << mir->fCtype << "*)" << std::hex << std::showbase << (size_t)el << ")->" << mir->fCmd << ";";
928 // std::cout << cmd.str() << std::endl;
929 // gROOT->ProcessLine(cmd.str().c_str());
930 } catch (std::exception &e) {
931 R__LOG_ERROR(REveLog()) << "REveManager::ExecuteCommand " << e.what() << std::endl;
932 } catch (...) {
933 R__LOG_ERROR(REveLog()) << "REveManager::ExecuteCommand unknow execption \n";
934 }
935}
936
937//
938//____________________________________________________________________
940{
941 nlohmann::json jobj = {};
942 jobj["content"] = "BeginChanges";
943 fWebWindow->Send(0, jobj.dump());
944
945 // Process changes in scenes.
948 jobj["content"] = "EndChanges";
949
950 if (!gEveLogEntries.empty()) {
951 constexpr static int numLevels = static_cast<int>(ELogLevel::kDebug) + 1;
952 constexpr static std::array<const char *, numLevels> sTag{
953 {"{unset-error-level please report}", "FATAL", "Error", "Warning", "Info", "Debug"}};
954
955 jobj["log"] = nlohmann::json::array();
956 std::stringstream strm;
957 for (auto entry : gEveLogEntries) {
958 nlohmann::json item = {};
959 item["lvl"] = entry.fLevel;
960 int cappedLevel = std::min(static_cast<int>(entry.fLevel), numLevels - 1);
961 strm << "Server " << sTag[cappedLevel] << ":";
962
963 if (!entry.fLocation.fFuncName.empty())
964 strm << " " << entry.fLocation.fFuncName;
965 strm << " " << entry.fMessage;
966 item["msg"] = strm.str();
967 jobj["log"].push_back(item);
968 strm.clear();
969 }
970 gEveLogEntries.clear();
971 }
972
973 fWebWindow->Send(0, jobj.dump());
974}
975
976//
977//____________________________________________________________________
979{
980#if defined(R__LINUX)
981 pthread_setname_np(pthread_self(), "mir_exec");
982#endif
983 while (true)
984 {
985 std::unique_lock<std::mutex> lock(fServerState.fMutex);
986 abcLabel:
987 if (fMIRqueue.empty())
988 {
989 fServerState.fCV.wait(lock);
990 goto abcLabel;
991 }
993 {
994 std::shared_ptr<MIR> mir = fMIRqueue.front();
995 fMIRqueue.pop();
996
998 lock.unlock();
999
1000 ExecuteMIR(mir);
1001
1002 lock.lock();
1005 }
1006 }
1007}
1008
1009
1010//____________________________________________________________________
1011void REveManager::Send(unsigned connid, const std::string &data)
1012{
1013 fWebWindow->Send(connid, data);
1014}
1015
1016void REveManager::SendBinary(unsigned connid, const void *data, std::size_t len)
1017{
1018 fWebWindow->SendBinary(connid, data, len);
1019}
1020
1022{
1023 for (auto &conn : fConnList) {
1024 if (conn.fState != Conn::Free)
1025 return false;
1026 }
1027
1028 return true;
1029}
1030
1032{
1033 for (auto &conn : fConnList) {
1034 if (conn.fId == cinnId)
1035 {
1036 conn.fState = Conn::WaitingResponse;
1037 break;
1038 }
1039 }
1040}
1041
1043{
1044 for (auto &conn : fConnList) {
1045 if (conn.fId == cinnId)
1046 {
1047 conn.fState = Conn::Processing;
1048 break;
1049 }
1050 }
1051}
1052
1053//////////////////////////////////////////////////////////////////
1054/// Show eve manager in specified browser.
1055
1056/// If rootrc variable WebEve.DisableShow is set, HTTP server will be
1057/// started and access URL printed on stdout.
1058
1060{
1061 if (gEnv->GetValue("WebEve.DisableShow", 0) != 0) {
1062 std::string url = fWebWindow->GetUrl(true);
1063 printf("EVE URL %s\n", url.c_str());
1064 } else {
1065 fWebWindow->Show(args);
1066 }
1067}
1068
1069
1070//____________________________________________________________________
1072{
1073 {
1074 std::unique_lock<std::mutex> lock(fServerState.fMutex);
1076 fServerState.fCV.wait(lock);
1077 }
1079 }
1081 GetScenes()->AcceptChanges(true);
1082}
1083
1084//____________________________________________________________________
1086{
1087 GetScenes()->AcceptChanges(false);
1089
1091
1092 std::unique_lock<std::mutex> lock(fServerState.fMutex);
1094 fServerState.fCV.notify_all();
1095}
1096
1097//____________________________________________________________________
1099{
1100 std::unique_lock<std::mutex> lock(fServerState.fMutex);
1102#if defined(_MSC_VER)
1103 std::timespec_get(&fServerStatus.fTReport, TIME_UTC);
1104#else
1105 fServerStatus.fTReport = std::time_t(nullptr);
1106#endif
1107 st = fServerStatus;
1108}
1109
1110/** \class REveManager::ChangeGuard
1111\ingroup REve
1112RAII guard for locking Eve manager (ctor) and processing changes (dtor).
1113*/
1114
1115//////////////////////////////////////////////////////////////////////
1116//
1117// Helper struct to guard update mechanism
1118//
1120{
1121 gEve->BeginChange();
1122}
1123
1125{
1126 gEve->EndChange();
1127}
1128
1129// Error handler streams error-level messages to client log
1130void REveManager::ErrorHandler(Int_t level, Bool_t abort, const char * location, const char *msg)
1131{
1132 if (level >= kError)
1133 {
1135 entry.fMessage = msg;
1136 gEveLogEntries.emplace_back(entry);
1137 }
1138 ::DefaultErrorHandler(level, abort, location, msg);
1139}
1140
1141/** \class REveManager::RExceptionHandler
1142\ingroup REve
1143Exception handler for Eve exceptions.
1144*/
1145
1146////////////////////////////////////////////////////////////////////////////////
1147/// Handle exceptions deriving from REveException.
1148
1150{
1151 REveException *ex = dynamic_cast<REveException *>(&exc);
1152 if (ex) {
1153 Info("Handle", "Exception %s", ex->what());
1154 // REX::gEve->SetStatusLine(ex->Data());
1155 gSystem->Beep();
1156 return kSEHandled;
1157 }
1158 return kSEProceed;
1159}
1160
1161
1162////////////////////////////////////////////////////////////////////////////////
1163/// Utility to stream loggs to client.
1164
1166{
1167 gEveLogEntries.emplace_back(entry);
1168 return true;
1169}
thread_local std::vector< RLogEntry > gEveLogEntries
#define R__LOG_ERROR(...)
Definition RLogger.hxx:362
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define g(i)
Definition RSha256.hxx:105
#define e(i)
Definition RSha256.hxx:103
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
@ kRed
Definition Rtypes.h:66
@ kGreen
Definition Rtypes.h:66
@ kCyan
Definition Rtypes.h:66
@ kViolet
Definition Rtypes.h:67
R__EXTERN TApplication * gApplication
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
The default error handler function.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:230
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:197
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:241
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition TError.cxx:102
R__EXTERN TEveManager * gEve
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t sel
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
char name[80]
Definition TGX11.cxx:110
R__EXTERN TGeoManager * gGeoManager
R__EXTERN TGeoIdentity * gGeoIdentity
Definition TGeoMatrix.h:478
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:585
#define gROOT
Definition TROOT.h:405
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
R__EXTERN TVirtualMutex * gSystemMutex
Definition TSystem.h:244
R__EXTERN TSystem * gSystem
Definition TSystem.h:560
#define R__LOCKGUARD2(mutex)
void DecDenyDestroy()
Decreases the deny-destroy count of the element.
void SaveVizParams(std::ostream &out, const TString &tag, const TString &var)
Save visualization parameters for this element with given tag.
const char * GetCTitle() const
const char * GetCName() const
virtual void AddElement(REveElement *el)
Add el to the list of children.
virtual Bool_t SetRnrChildren(Bool_t rnr)
Set render state of this element's children, i.e.
virtual void DestroyElements()
Destroy all children of this element.
REveElement * FirstChild() const
Returns the first child element or 0 if the list is empty.
void IncDenyDestroy()
Increases the deny-destroy count of the element.
virtual void CopyVizParams(const REveElement *el)
Copy visualization parameters from element el.
void SetVizModel(REveElement *model)
Set visualization-parameter model element.
virtual void RemoveElement(REveElement *el)
Remove el from the list of children.
virtual void PropagateVizParamsToProjecteds()
Propagate visualization parameters to dependent elements.
REveException Exception-type thrown by Eve classes.
Definition REveTypes.hxx:41
bool Emit(const RLogEntry &entry) override
Utility to stream loggs to client.
virtual EStatus Handle(std::exception &exc)
Handle exceptions deriving from REveException.
void ClearROOTClassSaved()
Work-around uber ugly hack used in SavePrimitive and co.
void ScheduleMIR(const std::string &cmd, ElementId_t i, const std::string &ctype)
void RegisterGeometryAlias(const TString &alias, const TString &filename)
Register 'name' as an alias for geometry file 'filename'.
void PreDeleteElement(REveElement *element)
Called from REveElement prior to its destruction so the framework components (like object editor) can...
void ExecuteMIR(std::shared_ptr< MIR > mir)
REveSceneList * GetScenes() const
void ClearAllSelections()
Clear all selection objects.
RExceptionHandler * fExcHandler
exception handler
void AssignElementId(REveElement *element)
Assign a unique ElementId to given element.
TGeoManager * GetDefaultGeometry()
Get the default geometry.
static void ExecuteInMainThread(std::function< void()> func)
void GetServerStatus(REveServerStatus &)
void SetDefaultHtmlPage(const std::string &path)
Set content of default window HTML page.
void AddLocation(const std::string &name, const std::string &path)
Register new directory to THttpServer.
void Send(unsigned connid, const std::string &data)
static void Terminate()
Properly terminate global REveManager.
REveElement * FindElementById(ElementId_t id) const
Lookup ElementId in element map and return corresponding REveElement*.
void SaveVizDB(const TString &filename)
Save visualization-parameter database to file filename.
TGeoManager * GetGeometryByAlias(const TString &alias)
Get geometry with given alias.
std::unordered_map< ElementId_t, REveElement * > fElementIdMap
static REveManager * Create()
If global REveManager* REX::gEve is not set initialize it.
std::unordered_map< std::string, std::shared_ptr< TMethodCall > > fMethCallMap
void WindowConnect(unsigned connid)
Process new connection from web window.
REveElement * FindVizDBEntry(const TString &tag)
Find a visualization-parameter database entry corresponding to tag.
TGeoManager * GetGeometry(const TString &filename)
Get geometry with given filename.
static void ErrorHandler(Int_t level, Bool_t abort, const char *location, const char *msg)
std::shared_ptr< ROOT::Experimental::RWebWindow > fWebWindow
std::queue< std::shared_ptr< MIR > > fMIRqueue
void LoadVizDB(const TString &filename, Bool_t replace, Bool_t update)
Load visualization-parameter database from file filename.
void DoRedraw3D()
Perform 3D redraw of scenes and viewers whose contents has changed.
void SendBinary(unsigned connid, const void *data, std::size_t len)
void AddElement(REveElement *element, REveElement *parent=nullptr)
Add an element.
void SetClientVersion(const std::string &version)
Set client version, used as prefix in scripts URL When changed, web browser will reload all related J...
void AddGlobalElement(REveElement *element, REveElement *parent=nullptr)
Add a global element, i.e.
void Redraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE)
void SceneSubscriberWaitingResponse(unsigned cinnId)
REveScene * SpawnNewScene(const char *name, const char *title="")
Create a new scene.
void SceneSubscriberProcessingChanges(unsigned cinnId)
void RemoveElement(REveElement *element, REveElement *parent)
Remove element from parent.
virtual ~REveManager()
Destructor.
void WindowDisconnect(unsigned connid)
Process disconnect of web window.
void FullRedraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE)
Perform 3D redraw of all scenes and viewers.
REveViewer * SpawnNewViewer(const char *name, const char *title="")
Create a new GL viewer.
Bool_t InsertVizDBEntry(const TString &tag, REveElement *model, Bool_t replace, Bool_t update)
Insert a new visualization-parameter database entry.
void BrowseElement(ElementId_t id)
Activate EVE browser (summary view) for specified element id.
void WindowData(unsigned connid, const std::string &arg)
Process data from web window.
void Show(const RWebDisplayArgs &args="")
Show eve manager in specified browser.
void DestroyScenes()
Destroy all scenes and their contents.
void AcceptChanges(bool)
Set accept changes flag on all scenes.
void AddSubscriber(std::unique_ptr< REveClient > &&sub)
Definition REveScene.cxx:60
std::vector< char > fOutputBinary
!
Definition REveScene.hxx:78
void RemoveSubscriber(unsigned int)
Definition REveScene.cxx:71
REveSelection Container for selected and highlighted elements.
static void Macro(const char *mac)
Execute macro 'mac'. Do not reload the macro.
Definition REveUtil.cxx:94
REveViewerList List of Viewers providing common operations on REveViewer collections.
void AddElement(REveElement *el) override
Call base-class implementation.
REveViewer Reve representation of TGLViewer.
static std::shared_ptr< RFileDialog > Embedded(const std::shared_ptr< RWebWindow > &window, const std::string &args)
Create dialog instance to use as embedded dialog inside other widget Embedded dialog started on the c...
A diagnostic that can be emitted by the RLogManager.
Definition RLogger.hxx:178
Holds different arguments for starting browser with RWebDisplayHandle::Display() method.
static std::shared_ptr< RWebWindow > Create()
Create new RWebWindow Using default RWebWindowsManager.
virtual void Terminate(Int_t status=0)
Terminate the application by call TSystem::Exit() unless application has been told to return from Run...
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
void * DynamicCast(const TClass *base, void *obj, Bool_t up=kTRUE)
Cast obj of this class type up to baseclass cl if up is true.
Definition TClass.cxx:4915
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
Definition TClass.cxx:4384
@ kClassSaved
Definition TClass.h:95
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2968
The color creation and management class.
Definition TColor.h:19
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition TColor.h:52
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1823
static void SetColorThreshold(Float_t t)
This method specifies the color threshold used by GetColor to retrieve a color.
Definition TColor.cxx:1895
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
TEveSceneList * GetScenes() const
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:51
An identity transformation.
Definition TGeoMatrix.h:384
The manager class for any TGeo geometry.
Definition TGeoManager.h:45
static void UnlockGeometry()
Unlock current geometry.
TObjArray * GetListOfVolumes() const
TObjArray * GetListOfMatrices() const
static Bool_t IsLocked()
Check lock state.
static TGeoManager * Import(const char *filename, const char *name="", Option_t *option="")
static function Import a geometry from a gdml or ROOT file
static void LockGeometry()
Lock current geometry so that no other geometry can be imported.
TGeoVolume * GetTopVolume() const
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition TGeoVolume.h:49
void VisibleDaughters(Bool_t vis=kTRUE)
set visibility for daughters
virtual void SetLineColor(Color_t lcolor)
Set the line color.
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition TMap.h:40
void Add(TObject *obj) override
This function may not be used (but we need to provide it since it is a pure virtual in TCollection).
Definition TMap.cxx:54
virtual void SetOwnerKeyValue(Bool_t ownkeys=kTRUE, Bool_t ownvals=kTRUE)
Set ownership for keys and values.
Definition TMap.cxx:352
TObject * FindObject(const char *keyname) const override
Check if a (key,value) pair exists with keyname as name of the key.
Definition TMap.cxx:215
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition TMap.cxx:236
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
An array of TObjects.
Definition TObjArray.h:31
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
void ResetBit(UInt_t f)
Definition TObject.h:200
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition TPRegexp.h:97
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition TPRegexp.cxx:706
Class used by TMap to store (key,value) pairs.
Definition TMap.h:102
void SetValue(TObject *val)
Definition TMap.h:122
TObject * Value() const
Definition TMap.h:121
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:380
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2334
void Beep(Int_t freq=-1, Int_t duration=-1, Bool_t setDefault=kFALSE)
Beep for duration milliseconds with a tone of frequency freq.
Definition TSystem.cxx:327
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1277
virtual int GetPid()
Get process id.
Definition TSystem.cxx:710
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition TSystem.cxx:474
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2490
virtual TTimer * RemoveTimer(TTimer *t)
Remove timer from list of system timers.
Definition TSystem.cxx:484
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
Double_t ex[n]
Definition legend1.C:17
R__EXTERN REveManager * gEve
@ kDebug
Debug information; only useful for developers; can have added verbosity up to 255-kDebug.
RLogChannel & REveLog()
Log channel for Eve diagnostics.
Definition REveTypes.cxx:47
basic_json<> json
TMarker m
Definition textangle.C:8