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/REveCamera.hxx>
15#include <ROOT/REveUtil.hxx>
17#include <ROOT/REveViewer.hxx>
18#include <ROOT/REveScene.hxx>
20#include <ROOT/REveClient.hxx>
21#include <ROOT/RWebWindow.hxx>
22#include <ROOT/RLogger.hxx>
23#include <ROOT/REveSystem.hxx>
26
27#include "TGeoManager.h"
28#include "TGeoMatrix.h"
29#include "TObjString.h"
30#include "TROOT.h"
31#include "TSystem.h"
32#include "TFile.h"
33#include "TMap.h"
34#include "TExMap.h"
35#include "TEnv.h"
36#include "TColor.h"
37#include "TPRegexp.h"
38#include "TClass.h"
39#include "TMethod.h"
40#include "TMethodCall.h"
41#include "THttpServer.h"
42#include "TTimer.h"
43#include "TApplication.h"
44
45#include <fstream>
46#include <memory>
47#include <sstream>
48#include <iostream>
49#include <regex>
50
51#include <nlohmann/json.hpp>
52
53using namespace ROOT::Experimental;
54namespace REX = ROOT::Experimental;
55
56REveManager *REX::gEve = nullptr;
57
59{
60 std::vector<REveScene*> addedWatch;
61 std::vector<REveScene*> removedWatch;
62
63 void reset() {
64 addedWatch.clear();
65 removedWatch.clear();
66 }
67};
68
69thread_local std::vector<ROOT::RLogEntry> gEveLogEntries;
71
72/** \class REveManager
73\ingroup REve
74\ingroup webwidgets
75
76\brief Central application manager for web-based REve.
77
78Manages elements, GUI, GL scenes and GL viewers.
79
80Following parameters can be specified in .rootrc file
81
82WebEve.GLViewer: Three # kind of GLViewer, either Three, JSRoot or RCore
83WebEve.DisableShow: 1 # do not start new web browser when REveManager::Show is called
84WebEve.HTimeout: 200 # timeout in ms for elements highlight
85WebEve.DblClick: Off # mouse double click handling in GL viewer: Off or Reset
86WebEve.TableRowHeight: 33 # size of each row in pixels in the Table view, can be used to make design more compact
87*/
88
89////////////////////////////////////////////////////////////////////////////////
90
91REveManager::REveManager()
92 : // (Bool_t map_window, Option_t* opt) :
93 fExcHandler(nullptr), fVizDB(nullptr), fVizDBReplace(kTRUE), fVizDBUpdate(kTRUE), fGeometries(nullptr),
94 fGeometryAliases(nullptr),
95 fKeepEmptyCont(kFALSE)
96{
97 // Constructor.
98
99 static const REveException eh("REveManager::REveManager ");
100
101 if (REX::gEve)
102 throw eh + "There can be only one REve!";
103
104 REX::gEve = this;
105
107 fServerStatus.fTStart = std::time(nullptr);
108
110
111 fGeometries = new TMap;
115 fVizDB = new TMap;
117
118 fElementIdMap[0] = nullptr; // do not increase count for null element.
119
120 fWorld = new REveScene("EveWorld", "Top-level Eve Scene");
123
124 fSelectionList = new REveElement("Selection List");
125 fSelectionList->SetChildClass(TClass::GetClass<REveSelection>());
128 fSelection = new REveSelection("Global Selection", "", kRed, kViolet);
129 fSelection->SetIsMaster(true);
132 fHighlight = new REveSelection("Global Highlight", "", kGreen, kCyan);
133 fHighlight->SetIsMaster(true);
137
138 fViewers = new REveViewerList("Viewers");
141
142 fScenes = new REveSceneList("Scenes");
145
146 // --------------------------------
147 // Create camera list
148 // --------------------------------
149 fCameras = new REveElement("Cameras", "Camera list");
152
153 fGlobalScene = new REveScene("Geometry scene");
156
157 fEventScene = new REveScene("Event scene");
160
161 {
162 REveViewer *v = SpawnNewViewer("Default Viewer");
163 v->AddScene(fGlobalScene);
164 v->AddScene(fEventScene);
165 }
166
167 // !!! AMT increase threshold to enable color pick on client
169
170 // allow multiple connections
172
174 fWebWindow->UseServerThreads();
175 fWebWindow->SetDefaultPage("file:rootui5sys/eve7/index.html");
176
177 const char *gl_viewer = gEnv->GetValue("WebEve.GLViewer", "RCore");
178 const char *gl_dblclick = gEnv->GetValue("WebEve.DblClick", "Off");
179 Int_t htimeout = gEnv->GetValue("WebEve.HTimeout", 250);
180 Int_t table_row_height = gEnv->GetValue("WebEve.TableRowHeight", 0);
181 fWebWindow->SetUserArgs(Form("{ GLViewer: \"%s\", DblClick: \"%s\", HTimeout: %d, TableRowHeight: %d }", gl_viewer,
183
184 if (strcmp(gl_viewer, "RCore") == 0)
185 fIsRCore = true;
186
187 // this is call-back, invoked when message received via websocket
188 fWebWindow->SetCallBacks([this](unsigned connid) { WindowConnect(connid); },
189 [this](unsigned connid, const std::string &arg) { WindowData(connid, arg); },
190 [this](unsigned connid) { WindowDisconnect(connid); });
191 fWebWindow->SetGeometry(900, 700); // configure predefined window geometry
192 fWebWindow->SetConnLimit(100); // maximal number of connections
193 fWebWindow->SetMaxQueueLength(1000); // number of allowed entries in the window queue
194
195 fMIRExecThread = std::thread{[this] { MIRExecThread(); }};
196
197 // activate interpreter error report
198 gInterpreter->ReportDiagnosticsToErrorHandler();
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Destructor.
204
206{
207 fMIRExecThread.join();
208
209 // QQQQ How do we stop THttpServer / fWebWindow?
210
215 // Not needed - no more top-items: fScenes->Destroy();
216 fScenes = nullptr;
217
220 // Not needed - no more top-items: fViewers->Destroy();
221 fViewers = nullptr;
222
223 // fWindowManager->DestroyWindows();
224 // fWindowManager->DecDenyDestroy();
225 // fWindowManager->Destroy();
226 // fWindowManager = 0;
227
230
231 delete fGeometryAliases;
232 delete fGeometries;
233 delete fVizDB;
234 delete fExcHandler;
235}
236
237////////////////////////////////////////////////////////////////////////////////
238/// Create a new GL viewer.
239
240REveViewer *REveManager::SpawnNewViewer(const char *name, const char *title)
241{
242 REveViewer *v = new REveViewer(name, title);
244 return v;
245}
246
247////////////////////////////////////////////////////////////////////////////////
248/// Create a new scene.
249
250REveScene *REveManager::SpawnNewScene(const char *name, const char *title)
251{
252 REveScene *s = new REveScene(name, title);
254 return s;
255}
256
258{
259 printf("REveManager::RegisterRedraw3D() obsolete\n");
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Perform 3D redraw of scenes and viewers whose contents has
264/// changed.
265
267{
268 printf("REveManager::DoRedraw3D() obsolete\n");
269}
270
271////////////////////////////////////////////////////////////////////////////////
272/// Perform 3D redraw of all scenes and viewers.
273
274void REveManager::FullRedraw3D(Bool_t /*resetCameras*/, Bool_t /*dropLogicals*/)
275{
276 printf("REveManager::FullRedraw3D() obsolete\n");
277}
278
279////////////////////////////////////////////////////////////////////////////////
280/// Clear all selection objects. Can make things easier for EVE when going to
281/// the next event. Still, destruction os selected object should still work
282/// correctly as long as it is executed within a change cycle.
283
285{
286 for (auto el : fSelectionList->fChildren) {
287 dynamic_cast<REveSelection *>(el)->ClearSelection();
288 }
289}
290
291////////////////////////////////////////////////////////////////////////////////
292/// Add an element. If parent is not specified it is added into
293/// current event (which is created if does not exist).
294
296{
297 if (parent == nullptr) {
298 // XXXX
299 }
300
301 parent->AddElement(element);
302}
303
304////////////////////////////////////////////////////////////////////////////////
305/// Add a global element, i.e. one that does not change on each
306/// event, like geometry or projection manager.
307/// If parent is not specified it is added to a global scene.
308
310{
311 if (!parent)
312 parent = fGlobalScene;
313
314 parent->AddElement(element);
315}
316
317////////////////////////////////////////////////////////////////////////////////
318/// Remove element from parent.
319
324
325////////////////////////////////////////////////////////////////////////////////
326/// Lookup ElementId in element map and return corresponding REveElement*.
327/// Returns nullptr if the id is not found
328
330{
331 auto it = fElementIdMap.find(id);
332 return (it != fElementIdMap.end()) ? it->second : nullptr;
333}
334
335////////////////////////////////////////////////////////////////////////////////
336/// Assign a unique ElementId to given element.
337
339{
340 static const REveException eh("REveManager::AssignElementId ");
341
343 throw eh + "ElementId map is full.";
344
346 while (fElementIdMap.find(++fLastElementId) != fElementIdMap.end())
347 ;
348 if (fLastElementId == 0)
349 goto next_free_id;
350 // MT - alternatively, we could spawn a thread to find next thousand or so ids and
351 // put them in a vector of ranges. Or collect them when they are freed.
352 // Don't think this won't happen ... online event display can run for months
353 // and easily produce 100000 objects per minute -- about a month to use up all id space!
354
355 element->fElementId = fLastElementId;
356 fElementIdMap.insert(std::make_pair(fLastElementId, element));
358}
359
360////////////////////////////////////////////////////////////////////////////////
361/// Activate EVE browser (summary view) for specified element id
362
364{
365 nlohmann::json msg = {};
366 msg["content"] = "BrowseElement";
367 msg["id"] = id;
368
369 fWebWindow->Send(0, msg.dump());
370}
371
372////////////////////////////////////////////////////////////////////////////////
373/// Called from REveElement prior to its destruction so the
374/// framework components (like object editor) can unreference it.
375
377{
378 if (el->fImpliedSelected > 0) {
379 for (auto slc : fSelectionList->fChildren) {
380 REveSelection *sel = dynamic_cast<REveSelection *>(slc);
381 sel->RemoveImpliedSelectedReferencesTo(el);
382 }
383
384 if (el->fImpliedSelected != 0)
385 Error("REveManager::PreDeleteElement", "ImpliedSelected not zero (%d) after cleanup of selections.",
386 el->fImpliedSelected);
387 }
388 // Primary selection deregistration is handled through Niece removal from Aunts.
389
390 if (el->fElementId != 0) {
391 auto it = fElementIdMap.find(el->fElementId);
392 if (it != fElementIdMap.end()) {
393 if (it->second == el) {
394 fElementIdMap.erase(it);
396 } else
397 Error("PreDeleteElement", "element ptr in ElementIdMap does not match the argument element.");
398 } else
399 Error("PreDeleteElement", "element id %u was not registered in ElementIdMap.", el->fElementId);
400 } else
401 Error("PreDeleteElement", "element with 0 ElementId passed in.");
402}
403
404////////////////////////////////////////////////////////////////////////////////
405/// Insert a new visualization-parameter database entry. Returns
406/// true if the element is inserted successfully.
407/// If entry with the same key already exists the behaviour depends on the
408/// 'replace' flag:
409/// - true - The old model is deleted and new one is inserted (default).
410/// Clients of the old model are transferred to the new one and
411/// if 'update' flag is true (default), the new model's parameters
412/// are assigned to all clients.
413/// - false - The old model is kept, false is returned.
414///
415/// If insert is successful, the ownership of the model-element is
416/// transferred to the manager.
417
419{
420 TPair *pair = (TPair *)fVizDB->FindObject(tag);
421 if (pair) {
422 if (replace) {
423 model->IncDenyDestroy();
424 model->SetRnrChildren(kFALSE);
425
426 REveElement *old_model = dynamic_cast<REveElement *>(pair->Value());
427 if (old_model) {
428 while (old_model->HasChildren()) {
429 REveElement *el = old_model->FirstChild();
430 el->SetVizModel(model);
431 if (update) {
432 el->CopyVizParams(model);
433 el->PropagateVizParamsToProjecteds();
434 }
435 }
436 old_model->DecDenyDestroy();
437 }
438 pair->SetValue(dynamic_cast<TObject *>(model));
439 return kTRUE;
440 } else {
441 return kFALSE;
442 }
443 } else {
444 model->IncDenyDestroy();
445 model->SetRnrChildren(kFALSE);
446 fVizDB->Add(new TObjString(tag), dynamic_cast<TObject *>(model));
447 return kTRUE;
448 }
449}
450
451////////////////////////////////////////////////////////////////////////////////
452/// Insert a new visualization-parameter database entry with the default
453/// parameters for replace and update, as specified by members
454/// fVizDBReplace(default=kTRUE) and fVizDBUpdate(default=kTRUE).
455/// See docs of the above function.
456
461
462////////////////////////////////////////////////////////////////////////////////
463/// Find a visualization-parameter database entry corresponding to tag.
464/// If the entry is not found 0 is returned.
465
467{
468 return dynamic_cast<REveElement *>(fVizDB->GetValue(tag));
469}
470
471////////////////////////////////////////////////////////////////////////////////
472/// Load visualization-parameter database from file filename. The
473/// replace, update arguments replace the values of fVizDBReplace
474/// and fVizDBUpdate members for the duration of the macro
475/// execution.
476
489
490////////////////////////////////////////////////////////////////////////////////
491/// Load visualization-parameter database from file filename.
492/// State of data-members fVizDBReplace and fVizDBUpdate determine
493/// how the registered entries are handled.
494
500
501////////////////////////////////////////////////////////////////////////////////
502/// Save visualization-parameter database to file filename.
503
505{
506 TPMERegexp re("(.+)\\.\\w+");
507 if (re.Match(filename) != 2) {
508 Error("SaveVizDB", "filename does not match required format '(.+)\\.\\w+'.");
509 return;
510 }
511
514
515 std::ofstream out(exp_filename, std::ios::out | std::ios::trunc);
516 out << "void " << re[1] << "()\n";
517 out << "{\n";
518 out << " REveManager::Create();\n";
519
521
522 Int_t var_id = 0;
524 TIter next(fVizDB);
525 TObjString *key;
526 while ((key = (TObjString *)next())) {
527 REveElement *mdl = dynamic_cast<REveElement *>(fVizDB->GetValue(key));
528 if (mdl) {
529 var_name.Form("x%03d", var_id++);
530 mdl->SaveVizParams(out, key->String(), var_name);
531 } else {
532 Warning("SaveVizDB", "Saving failed for key '%s'.", key->String().Data());
533 }
534 }
535
536 out << "}\n";
537 out.close();
538}
539
540////////////////////////////////////////////////////////////////////////////////
541/// Get geometry with given filename.
542/// This is cached internally so the second time this function is
543/// called with the same argument the same geo-manager is returned.
544/// gGeoManager is set to the return value.
545
547{
548 static const REveException eh("REveManager::GetGeometry ");
549
552 printf("REveManager::GetGeometry loading: '%s' -> '%s'.\n", filename.Data(), exp_filename.Data());
553
555 if (gGeoManager) {
557 } else {
559 if (locked) {
560 Warning("REveManager::GetGeometry", "TGeoManager is locked ... unlocking it.");
562 }
563 if (TGeoManager::Import(filename) == nullptr) {
564 throw eh + "TGeoManager::Import() failed for '" + exp_filename + "'.";
565 }
566 if (locked) {
568 }
569
571
572 // Import colors exported by Gled, if they exist.
573 {
574 TFile f(exp_filename, "READ");
575 TObjArray *collist = (TObjArray *)f.Get("ColorList");
576 f.Close();
577 if (collist) {
579 TGeoVolume *vol;
580 while ((vol = (TGeoVolume *)next()) != nullptr) {
581 Int_t oldID = vol->GetLineColor();
582 TColor *col = (TColor *)collist->At(oldID);
583 Float_t r, g, b;
584 col->GetRGB(r, g, b);
586 vol->SetLineColor(newID);
587 }
588 }
589 }
590
592 }
593 return gGeoManager;
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// Get geometry with given alias.
598/// The alias must be registered via RegisterGeometryAlias().
599
601{
602 static const REveException eh("REveManager::GetGeometry ");
603
605 if (!full_name)
606 throw eh + "geometry alias '" + alias + "' not registered.";
607 return GetGeometry(full_name->String());
608}
609
610////////////////////////////////////////////////////////////////////////////////
611/// Get the default geometry.
612/// It should be registered via RegisterGeometryName("Default", `<URL>`).
613
618
619////////////////////////////////////////////////////////////////////////////////
620/// Get the default viewer.
621///
622
624{
625 return dynamic_cast<REveViewer*>(fViewers->FirstChild());
626}
627
628////////////////////////////////////////////////////////////////////////////////
629/// Utility function to allow remote RWebWindow connections.
630/// Disable loopback when use remote client.
631/// Authentification key has to be disabled in the case of multiple connections.
632/// The default arguments prevent remote connections for the security reasons.
633//
639
640////////////////////////////////////////////////////////////////////////////////
641/// Register 'name' as an alias for geometry file 'filename'.
642/// The old aliases are silently overwritten.
643/// After that the geometry can be retrieved also by calling:
644/// REX::gEve->GetGeometryByName(name);
645
650
651////////////////////////////////////////////////////////////////////////////////
652/// Work-around uber ugly hack used in SavePrimitive and co.
653
655{
656 gROOT->ResetClassSaved();
657}
658
659////////////////////////////////////////////////////////////////////////////////
660/// Register new directory to THttpServer
661// For example: AddLocation("mydir/", "/test/EveWebApp/ui5");
662//
663void REveManager::AddLocation(const std::string &locationName, const std::string &path)
664{
665 fWebWindow->GetServer()->AddLocation(locationName.c_str(), path.c_str());
666}
667
668////////////////////////////////////////////////////////////////////////////////
669/// Set content of default window HTML page
670// Got example: SetDefaultHtmlPage("file:currentdir/test.html")
671//
672void REveManager::SetDefaultHtmlPage(const std::string &path)
673{
674 fWebWindow->SetDefaultPage(path);
675}
676
677////////////////////////////////////////////////////////////////////////////////
678/// Set client version, used as prefix in scripts URL
679/// When changed, web browser will reload all related JS files while full URL will be different
680/// Default is empty value - no extra string in URL
681/// Version should be string like "1.2" or "ver1.subv2" and not contain any special symbols
683{
684 fWebWindow->SetClientVersion(version);
685}
686
687////////////////////////////////////////////////////////////////////////////////
688/// If global REveManager* REX::gEve is not set initialize it.
689/// Returns REX::gEve.
690
692{
693 static const REveException eh("REveManager::Create ");
694
695 if (!REX::gEve) {
696 // XXXX Initialize some server stuff ???
697
698 REX::gEve = new REveManager();
699 }
700 return REX::gEve;
701}
702
703////////////////////////////////////////////////////////////////////////////////
704/// Properly terminate global REveManager.
705
707{
708 if (!REX::gEve)
709 return;
710
711 delete REX::gEve;
712 REX::gEve = nullptr;
713}
714
715void REveManager::ExecuteInMainThread(std::function<void()> func)
716{
717 class XThreadTimer : public TTimer {
718 std::function<void()> foo_;
719 public:
720 XThreadTimer(std::function<void()> f) : foo_(f)
721 {
722 SetTime(0);
724 gSystem->AddTimer(this);
725 }
726 Bool_t Notify() override
727 {
728 foo_();
729 gSystem->RemoveTimer(this);
730 delete this;
731 return kTRUE;
732 }
733 };
734
735 new XThreadTimer(func);
736}
737
739{
741 // QQQQ Should call Terminate() but it needs to:
742 // - properly stop MIRExecThread;
743 // - shutdown civet/THttp/RWebWindow
745 });
746}
747
748////////////////////////////////////////////////////////////////////////////////
749/// Process new connection from web window
750
751void REveManager::WindowConnect(unsigned connid)
752{
753 std::unique_lock<std::mutex> lock(fServerState.fMutex);
754
756 {
757 fServerState.fCV.wait(lock);
758 }
759
760 fConnList.emplace_back(connid);
761 printf("connection established %u\n", connid);
762
763 // QQQQ do we want mir-time here as well? maybe set it at the end of function?
764 // Note, this is all under lock, so nobody will get state out in between.
765 fServerStatus.fTLastMir = fServerStatus.fTLastConnect = std::time(nullptr);
767
768 // This prepares core and render data buffers.
769 printf("\nEVEMNG ............. streaming the world scene.\n");
770
771 fWorld->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
773
774 printf(" sending json, len = %d\n", (int)fWorld->fOutputJson.size());
775 Send(connid, fWorld->fOutputJson);
776 printf(" for now assume world-scene has no render data, binary-size=%d\n", fWorld->fTotalBinarySize);
778
779 for (auto &c : fScenes->RefChildren()) {
780 REveScene *scene = dynamic_cast<REveScene *>(c);
781 if (!scene->GetMandatory())
782 continue;
783
784 scene->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
785 printf("\nEVEMNG ............. streaming scene %s [%s]\n", scene->GetCTitle(), scene->GetCName());
786
787 // This prepares core and render data buffers.
788 scene->StreamElements();
789
790 printf(" sending json, len = %d\n", (int)scene->fOutputJson.size());
791 Send(connid, scene->fOutputJson);
792
793 if (scene->fTotalBinarySize > 0) {
794 printf(" sending binary, len = %d\n", scene->fTotalBinarySize);
795 SendBinary(connid, &scene->fOutputBinary[0], scene->fTotalBinarySize);
796 } else {
797 printf(" NOT sending binary, len = %d\n", scene->fTotalBinarySize);
798 }
799 }
800
801 fServerState.fCV.notify_all();
802}
803
804////////////////////////////////////////////////////////////////////////////////
805/// Process disconnect of web window
806
807void REveManager::WindowDisconnect(unsigned connid)
808{
809 std::unique_lock<std::mutex> lock(fServerState.fMutex);
810 auto conn = fConnList.end();
811 for (auto i = fConnList.begin(); i != fConnList.end(); ++i) {
812 if (i->fId == connid) {
813 conn = i;
814 break;
815 }
816 }
817 // this should not happen, just check
818 if (conn == fConnList.end()) {
819 printf("error, connection not found!");
820 } else {
821 printf("connection closed %u\n", connid);
822 fConnList.erase(conn);
823 for (auto &c : fScenes->RefChildren()) {
824 REveScene *scene = dynamic_cast<REveScene *>(c);
825 scene->RemoveSubscriber(connid);
826 }
827 fWorld->RemoveSubscriber(connid);
828 }
829
830 // User case: someone can close browser tab as clients are updateding
831 // note if scene changes are in progess the new serverstate will be changes after finish those
833 {
835 }
836
837 fServerStatus.fTLastDisconnect = std::time(nullptr);
839
840 fServerState.fCV.notify_all();
841}
842
843////////////////////////////////////////////////////////////////////////////////
844/// Process data from web window
845
846void REveManager::WindowData(unsigned connid, const std::string &arg)
847{
848 static const REveException eh("REveManager::WindowData ");
849
850 // find connection object
851 bool found = false;
852 for (auto &conn : fConnList) {
853 if (conn.fId == connid) {
854 found = true;
855 break;
856 }
857 }
858
859 // this should not happen, just check
860 if (!found) {
861 R__LOG_ERROR(REveLog()) << "Internal error - no connection with id " << connid << " found";
862 return;
863 }
864
865
866 if (arg.compare("__REveDoneChanges") == 0)
867 {
868 // client status data
869 std::unique_lock<std::mutex> lock(fServerState.fMutex);
870
871 for (auto &conn : fConnList) {
872 if (conn.fId == connid) {
873 conn.fState = Conn::Free;
874 break;
875 }
876 }
877
880 fServerState.fCV.notify_all();
881 }
882
883 return;
884 }
886 {
887 if (fHttpPublic)
888 {
889 R__LOG_INFO(REveLog()) << "REveManager::WindowData, file dialog is not allowed in restriced public mode";
890 }
891 else
892 {
894 }
895 return;
896 }
897 else if (arg.compare(0, 11, "SETCHANNEL:") == 0) {
898 std::string s = arg.substr(11);
899 auto p = s.find(",");
900 int eveid = std::stoi(s.substr(0, p));
901 int chid = std::stoi(s.substr(p+1));
902
904 auto nn = dynamic_cast<REveGeoTopNodeData*>(n);
905 if (nn) nn->SetChannel(connid, chid);
906
907 return;
908 }
909
910 nlohmann::json cj = nlohmann::json::parse(arg);
911 if (gDebug > 0)
912 ::Info("REveManager::WindowData", "MIR test %s\n", cj.dump().c_str());
913
914 std::string cmd = cj["mir"];
915 int id = cj["fElementId"];
916 std::string ctype = cj["class"];
917
918 ScheduleMIR(cmd, id, ctype, connid);
919}
920
921//
922//____________________________________________________________________
923void REveManager::ScheduleMIR(const std::string &cmd, ElementId_t id, const std::string& ctype, unsigned connid)
924{
925 std::unique_lock<std::mutex> lock(fServerState.fMutex);
926 fServerStatus.fTLastMir = std::time(nullptr);
927 fMIRqueue.push(std::make_shared<MIR>(cmd, id, ctype, connid));
928
929 if (fMIRqueue.size() > 5)
930 std::cout << "Warning, REveManager::ScheduleMIR(). queue size " << fMIRqueue.size() << std::endl;
931
933 fServerState.fCV.notify_all();
934}
935
936//
937//____________________________________________________________________
938void REveManager::ExecuteMIR(std::shared_ptr<MIR> mir)
939{
940 static const REveException eh(""); // Empty -- all errors go to R__LOG
941
942 //if (gDebug > 0)
943 ::Info("REveManager::ExecuteCommand", "MIR cmd %s", mir->fCmd.c_str());
944
945 std::string tag = mir->fCtype + "::<to-be-determined>";
946
947 try {
949 if ( ! el) throw eh + "Element with id " + mir->fId + " not found";
950
951 static const std::regex cmd_re("^(\\w[\\w\\d]*)\\(\\s*(.*)\\s*\\)\\s*;?\\s*$", std::regex::optimize);
952 std::smatch m;
953 std::regex_search(mir->fCmd, m, cmd_re);
954 if (m.size() != 3)
955 throw eh + "Command string parse error: '" + mir->fCmd + "'.";
956
957 static const TClass *elem_cls = TClass::GetClass<REX::REveElement>();
958
959 TClass *call_cls = TClass::GetClass(mir->fCtype.c_str());
960 if ( ! call_cls)
961 throw eh + "Class '" + mir->fCtype + "' not found.";
962
963 void *el_casted = call_cls->DynamicCast(elem_cls, el, false);
964 if ( ! el_casted)
965 throw eh + "Dynamic cast from REveElement to '" + mir->fCtype + "' failed.";
966
967 tag = mir->fCtype + "::" + m.str(1);
968
969 std::shared_ptr<TMethodCall> mc;
970 auto mmi = fMethCallMap.find(tag);
971 if (mmi != fMethCallMap.end())
972 {
973 mc = mmi->second;
974 }
975 else
976 {
977 const TMethod *meth = call_cls->GetMethodAllAny(m.str(1).c_str());
978 if ( ! meth)
979 throw eh + "Can not find TMethod matching '" + m.str(1) + "'.";
980 mc = std::make_shared<TMethodCall>(meth);
981 fMethCallMap.insert(std::make_pair(tag, mc));
982 }
983
985
987 mc->Execute(el_casted, m.str(2).c_str());
988
990 R__LOG_ERROR(REveLog()) << eh << "error executing " << tag << ":" << REveElement::stlMirErrorString << " (code " << REveElement::stlMirError << ").";
991 }
993
994 // Alternative implementation through Cling. "Leaks" 200 kB per call.
995 // This might be needed for function calls that involve data-types TMethodCall
996 // can not handle.
997 // std::stringstream cmd;
998 // cmd << "((" << mir->fCtype << "*)" << std::hex << std::showbase << (size_t)el << ")->" << mir->fCmd << ";";
999 // std::cout << cmd.str() << std::endl;
1000 // gROOT->ProcessLine(cmd.str().c_str());
1001 } catch (std::exception &e) {
1002 R__LOG_ERROR(REveLog()) << "caught exception executing " << tag << ": " << e.what();
1003 } catch (...) {
1004 R__LOG_ERROR(REveLog()) << "caught unknown execption.";
1005 }
1006}
1007
1008// Write scene change into scenes's internal json member
1010{
1012
1013 for (auto &el : fScenes->RefChildren())
1014 {
1015 REveScene* s = dynamic_cast<REveScene*>(el);
1017 }
1018}
1019
1020// Send json and binary data to scene's connections
1022{
1023 // send begin message
1024 nlohmann::json jobj = {};
1025 jobj["content"] = "BeginChanges";
1026 SendToAllConnections(jobj.dump());
1027
1028 // send the change json
1030
1031 for (auto &el : fScenes->RefChildren())
1032 {
1033 REveScene* s = dynamic_cast<REveScene*>(el);
1035 }
1036
1037 // send end changes message and log messages
1038 jobj["content"] = "EndChanges";
1039
1040 if (!gEveLogEntries.empty()) {
1041 constexpr static int numLevels = static_cast<int>(ELogLevel::kDebug) + 1;
1042 constexpr static std::array<const char *, numLevels> sTag{
1043 {"{unset-error-level please report}", "FATAL", "Error", "Warning", "Info", "Debug"}};
1044
1045 jobj["log"] = nlohmann::json::array();
1046 std::stringstream strm;
1047 for (auto entry : gEveLogEntries) {
1048 strm.str("");
1049 nlohmann::json item = {};
1050 item["lvl"] = entry.fLevel;
1051 int cappedLevel = std::min(static_cast<int>(entry.fLevel), numLevels - 1);
1052 strm << "Server " << sTag[cappedLevel] << ":";
1053
1054 if (!entry.fLocation.fFuncName.empty())
1055 strm << " " << entry.fLocation.fFuncName;
1056 strm << " " << entry.fMessage;
1057 item["msg"] = strm.str();
1058 jobj["log"].push_back(item);
1059 }
1060 gEveLogEntries.clear();
1061 }
1062 SendToAllConnections(jobj.dump());
1063}
1064
1065//
1066//____________________________________________________________________
1068{
1069#if defined(R__LINUX)
1070 pthread_setname_np(pthread_self(), "mir_exec");
1071#endif
1072 while (true)
1073 {
1074 std::unique_lock<std::mutex> lock(fServerState.fMutex);
1075 underlock:
1077 {
1078 fServerState.fCV.wait(lock);
1079 goto underlock;
1080 }
1081 else
1082 {
1083 // set server state and update the queue under lock
1084 //
1086 std::shared_ptr<MIR> mir = fMIRqueue.front();
1087
1088 // reset local thread related data
1089 gMIRData.reset();
1090 fMIRqueue.pop();
1091
1092 lock.unlock();
1093
1094 // Ideally, as in gled, MIR execution would be steered by scenes themselves.
1095 // But this requires alpha/beta/gamma MIR elements and scene dependenices,
1096 // so dependent scenes can be locked, too.
1097 // On top of that, one could also implements authorization framework, as in gled.
1098
1101
1102 ExecuteMIR(mir);
1103
1106
1108
1109 // send changes (need to access client connection list) and set the state under lock
1110 //
1111 lock.lock();
1112
1113 // disconnect requested scene from clients
1114 for (auto &scene : gMIRData.removedWatch)
1115 scene->RemoveSubscriber(mir->fConnId);
1116
1117
1118 // connect and stream scenes to new clients
1119 for (auto &scene : gMIRData.addedWatch) {
1120 scene->AddSubscriber(std::make_unique<REveClient>(mir->fConnId, fWebWindow));
1121 scene->StreamElements();
1122 Send(mir->fConnId, scene->fOutputJson);
1123 if (scene->fTotalBinarySize > 0)
1124 SendBinary(mir->fConnId, &scene->fOutputBinary[0], scene->fTotalBinarySize);
1125 }
1126
1128
1130 fServerState.fCV.notify_all();
1131 }
1132 }
1133}
1134
1135//____________________________________________________________________
1137{
1138 for (auto &c : view->RefChildren()) {
1139 REveSceneInfo *sinfo = dynamic_cast<REveSceneInfo *>(c);
1140 std::cout << "Disconnect scee " << sinfo->GetScene()->GetName();
1141 gMIRData.removedWatch.push_back(sinfo->GetScene());
1142 }
1143}
1144//____________________________________________________________________
1146{
1147 view->StampObjProps();
1148 for (auto &c : view->RefChildren()) {
1149 REveSceneInfo *sinfo = dynamic_cast<REveSceneInfo *>(c);
1150 std::cout << "Connect scene " << sinfo->GetScene()->GetName();
1151 gMIRData.addedWatch.push_back(sinfo->GetScene());
1152 }
1153}
1154
1155//____________________________________________________________________
1157{
1158 for (auto &conn : fConnList) {
1159 fWebWindow->Send(conn.fId, data);
1160 }
1161}
1162
1163void REveManager::Send(unsigned connid, const std::string &data)
1164{
1165 fWebWindow->Send(connid, data);
1166}
1167
1168void REveManager::SendBinary(unsigned connid, const void *data, std::size_t len)
1169{
1170 fWebWindow->SendBinary(connid, data, len);
1171}
1172
1174{
1175 for (auto &conn : fConnList) {
1176 if (conn.fState != Conn::Free)
1177 return false;
1178 }
1179
1180 return true;
1181}
1182
1183// called from REveScene::SendChangesToSubscribers
1185{
1186 for (auto &conn : fConnList) {
1187 if (conn.fId == cinnId)
1188 {
1189 conn.fState = Conn::WaitingResponse;
1190 break;
1191 }
1192 }
1193}
1194
1195//////////////////////////////////////////////////////////////////
1196/// Show eve manager in specified browser.
1197
1198/// If rootrc variable WebEve.DisableShow is set, HTTP server will be
1199/// started and access URL printed on stdout.
1200
1202{
1203 if (gEnv->GetValue("WebEve.DisableShow", 0) != 0) {
1204 std::string url = fWebWindow->GetUrl(true);
1205 printf("EVE URL %s\n", url.c_str());
1206 } else {
1207 fWebWindow->Show(args);
1208 }
1209}
1210
1211
1212//____________________________________________________________________
1214{
1215 // set server state and tag scenes to begin accepting changees
1216 {
1217 std::unique_lock<std::mutex> lock(fServerState.fMutex);
1219 fServerState.fCV.wait(lock);
1220 }
1222 }
1225}
1226
1227//____________________________________________________________________
1229{
1230 // tag scene to disable accepting chages, write the change json
1233
1235
1236 // set new server state under lock
1237 std::unique_lock<std::mutex> lock(fServerState.fMutex);
1240 fServerState.fCV.notify_all();
1241}
1242
1243//____________________________________________________________________
1245{
1246 std::unique_lock<std::mutex> lock(fServerState.fMutex);
1248#if defined(_MSC_VER)
1249 std::timespec_get(&fServerStatus.fTReport, TIME_UTC);
1250#else
1251 fServerStatus.fTReport = std::time_t(nullptr);
1252#endif
1253 st = fServerStatus;
1254}
1255
1256/** \class REveManager::ChangeGuard
1257\ingroup REve
1258RAII guard for locking Eve manager (ctor) and processing changes (dtor).
1259*/
1260
1261//////////////////////////////////////////////////////////////////////
1262//
1263// Helper struct to guard update mechanism
1264//
1269
1274
1275// gInterpreter error handlder
1276void REveManager::ErrorHandler(Int_t level, Bool_t abort, const char * location, const char *msg)
1277{
1278 if (level >= kError)
1279 {
1281 entry.fMessage = msg;
1282 gEveLogEntries.emplace_back(entry);
1283 }
1284 ::DefaultErrorHandler(level, abort, location, msg);
1285}
1286
1287/** \class REveManager::RExceptionHandler
1288\ingroup REve
1289Exception handler for Eve exceptions.
1290*/
1291
1292////////////////////////////////////////////////////////////////////////////////
1293/// Handle exceptions deriving from REveException.
1294
1296{
1297 REveException *ex = dynamic_cast<REveException *>(&exc);
1298 if (ex) {
1299 Info("Handle", "Exception %s", ex->what());
1300 // REX::gEve->SetStatusLine(ex->Data());
1301 gSystem->Beep();
1302 return kSEHandled;
1303 }
1304 return kSEProceed;
1305}
1306
1307
1308////////////////////////////////////////////////////////////////////////////////
1309/// Utility to stream loggs to client.
1310/// Return false to supress further emission
1311
1313{
1314 gEveLogEntries.emplace_back(entry);
1315 return false;
1316}
1317
1318
1319////////////////////////////////////////////////////////////////////////////////
1320/// Restrict functionality for this server when open to public
1321
1323{
1324 R__LOG_INFO(REveLog()) << "Set public mode to " << x <<".";
1325 fHttpPublic = x;
1326}
thread_local std::vector< ROOT::RLogEntry > gEveLogEntries
thread_local MIR_TL_Data_t gMIRData
#define R__LOG_ERROR(...)
Definition RLogger.hxx:356
#define R__LOG_INFO(...)
Definition RLogger.hxx:358
#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:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
@ kRed
Definition Rtypes.h:67
@ kGreen
Definition Rtypes.h:67
@ kCyan
Definition Rtypes.h:67
@ kViolet
Definition Rtypes.h:68
R__EXTERN TApplication * gApplication
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
R__EXTERN TEnv * gEnv
Definition TEnv.h:126
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:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition TError.cxx:92
winID h TVirtualViewer3D TVirtualGLPainter p
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:148
R__EXTERN TGeoManager * gGeoManager
R__EXTERN TGeoIdentity * gGeoIdentity
Definition TGeoMatrix.h:538
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
#define gInterpreter
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:777
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2570
R__EXTERN TVirtualMutex * gSystemMutex
Definition TSystem.h:254
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
#define R__LOCKGUARD2(mutex)
void DecDenyDestroy()
Decreases the deny-destroy count of the element.
virtual void AddElement(REveElement *el)
Add el to the list of children.
static thread_local int stlMirError
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.
static void SetMirContext(REveElement *el)
void IncDenyDestroy()
Increases the deny-destroy count of the element.
static thread_local std::string stlMirErrorString
virtual void RemoveElement(REveElement *el)
Remove el from the list of children.
REveException Exception-type thrown by Eve classes.
Definition REveTypes.hxx:42
bool Emit(const RLogEntry &entry) override
Utility to stream loggs to client.
EStatus Handle(std::exception &exc) override
Handle exceptions deriving from REveException.
void DisconnectEveViewer(REveViewer *)
void ScheduleMIR(const std::string &cmd, ElementId_t i, const std::string &ctype, unsigned connid)
void ClearROOTClassSaved()
Work-around uber ugly hack used in SavePrimitive and co.
void SendToAllConnections(const std::string &data)
std::shared_ptr< ROOT::RWebWindow > fWebWindow
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.
void AllowMultipleRemoteConnections(bool loopBack=true, bool useAuthKey=true)
Utility function to allow remote RWebWindow connections.
REveElement * FindVizDBEntry(const TString &tag)
Find a visualization-parameter database entry corresponding to tag.
TGeoManager * GetGeometry(const TString &filename)
Get geometry with given filename.
void ConnectEveViewer(REveViewer *)
static void ErrorHandler(Int_t level, Bool_t abort, const char *location, const char *msg)
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 SetHttpPublic(bool)
Restrict functionality for this server when open to public.
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.
REveViewer * GetDefaultViewer() const
Get the default viewer.
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.
REveSceneInfo Scene in a viewer.
void BeginAcceptingChanges()
Loop-wrapers over Scene children, element type checked on insertion.
void DestroyScenes()
Destroy all scenes and their contents.
void AddSubscriber(std::unique_ptr< REveClient > &&sub)
Definition REveScene.cxx:69
void StreamRepresentationChanges()
Prepare data for sending element changes.
void RemoveSubscriber(unsigned int)
Definition REveScene.cxx:80
REveSelection Container for selected and highlighted elements.
static void Macro(const char *mac)
Execute macro 'mac'. Do not reload the macro.
Definition REveUtil.cxx:95
REveViewerList List of Viewers providing common operations on REveViewer collections.
void AddElement(REveElement *el) override
Call base-class implementation.
REveViewer Reve representation of TGLViewer.
A diagnostic that can be emitted by the RLogManager.
Definition RLogger.hxx:174
Holds different arguments for starting browser with RWebDisplayHandle::Display() method.
static std::shared_ptr< RWebWindow > Create()
Create new RWebWindow Using default RWebWindowsManager.
static bool EmbedFileDialog(const std::shared_ptr< RWebWindow > &window, unsigned connid, const std::string &args)
Create dialog instance to use as embedded dialog inside provided widget Loads libROOTBrowserv7 and tr...
static bool IsFileDialogMessage(const std::string &msg)
Check if this could be the message send by client to start new file dialog If returns true,...
static void SetSingleConnMode(bool on=true)
Enable or disable single connection mode (default on) If enabled, one connection only with any web wi...
static void SetLoopbackMode(bool on=true)
Set loopback mode for THttpServer used for web widgets By default is on.
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:36
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
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:2994
The color creation and management class.
Definition TColor.h:22
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition TColor.h:55
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:1926
static void SetColorThreshold(Float_t t)
This method specifies the color threshold used by GetColor to retrieve a color.
Definition TColor.cxx:1995
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:511
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
An identity transformation.
Definition TGeoMatrix.h:407
The manager class for any TGeo geometry.
Definition TGeoManager.h:46
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:43
void VisibleDaughters(Bool_t vis=kTRUE)
set visibility for daughters
void SetLineColor(Color_t lcolor) override
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:53
virtual void SetOwnerKeyValue(Bool_t ownkeys=kTRUE, Bool_t ownvals=kTRUE)
Set ownership for keys and values.
Definition TMap.cxx:351
TObject * FindObject(const char *keyname) const override
Check if a (key,value) pair exists with keyname as name of the key.
Definition TMap.cxx:214
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition TMap.cxx:235
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:170
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:42
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition TPRegexp.h:97
Class used by TMap to store (key,value) pairs.
Definition TMap.h:103
void SetValue(TObject *val)
Definition TMap.h:123
TObject * Value() const
Definition TMap.h:122
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:386
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:326
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1289
virtual int GetPid()
Get process id.
Definition TSystem.cxx:720
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition TSystem.cxx:473
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2504
virtual TTimer * RemoveTimer(TTimer *t)
Remove timer from list of system timers.
Definition TSystem.cxx:483
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
Namespace for ROOT features in testing.
Definition TROOT.h:100
ROOT::RLogChannel & REveLog()
Log channel for Eve diagnostics.
Definition REveTypes.cxx:52
R__EXTERN REveManager * gEve
@ kDebug
Debug information; only useful for developers; can have added verbosity up to 255-kDebug.
@ kError
An error.
std::vector< REveScene * > removedWatch
std::vector< REveScene * > addedWatch
TMarker m
Definition textangle.C:8