50#include <nlohmann/json.hpp>
101 throw eh +
"There can be only one REve!";
115 fVizDB->SetOwnerKeyValue();
167 fWebWindow->SetDefaultPage(
"file:rootui5sys/eve7/index.html");
169 const char *gl_viewer =
gEnv->GetValue(
"WebEve.GLViewer",
"RCore");
170 const char *gl_dblclick =
gEnv->GetValue(
"WebEve.DblClick",
"Off");
171 Int_t htimeout =
gEnv->GetValue(
"WebEve.HTimeout", 250);
172 Int_t table_row_height =
gEnv->GetValue(
"WebEve.TableRowHeight", 0);
173 fWebWindow->SetUserArgs(
Form(
"{ GLViewer: \"%s\", DblClick: \"%s\", HTimeout: %d, TableRowHeight: %d }", gl_viewer,
174 gl_dblclick, htimeout, table_row_height));
176 if (strcmp(gl_viewer,
"RCore") == 0)
181 [
this](
unsigned connid,
const std::string &arg) {
WindowData(connid, arg); },
251 printf(
"REveManager::RegisterRedraw3D() obsolete\n");
260 printf(
"REveManager::DoRedraw3D() obsolete\n");
268 printf(
"REveManager::FullRedraw3D() obsolete\n");
289 if (parent ==
nullptr) {
332 static const REveException eh(
"REveManager::AssignElementId ");
335 throw eh +
"ElementId map is full.";
357 nlohmann::json msg = {};
358 msg[
"content"] =
"BrowseElement";
377 Error(
"REveManager::PreDeleteElement",
"ImpliedSelected not zero (%d) after cleanup of selections.",
385 if (it->second == el) {
389 Error(
"PreDeleteElement",
"element ptr in ElementIdMap does not match the argument element.");
391 Error(
"PreDeleteElement",
"element id %u was not registered in ElementIdMap.", el->
fElementId);
393 Error(
"PreDeleteElement",
"element with 0 ElementId passed in.");
415 model->IncDenyDestroy();
416 model->SetRnrChildren(
kFALSE);
436 model->IncDenyDestroy();
437 model->SetRnrChildren(
kFALSE);
499 if (re.
Match(filename) != 2) {
500 Error(
"SaveVizDB",
"filename does not match required format '(.+)\\.\\w+'.");
504 TString exp_filename(filename);
505 gSystem->ExpandPathName(exp_filename);
507 std::ofstream out(exp_filename, std::ios::out | std::ios::trunc);
508 out <<
"void " << re[1] <<
"()\n";
510 out <<
" REveManager::Create();\n";
521 var_name.
Form(
"x%03d", var_id++);
542 TString exp_filename = filename;
543 gSystem->ExpandPathName(exp_filename);
544 printf(
"REveManager::GetGeometry loading: '%s' -> '%s'.\n", filename.
Data(), exp_filename.
Data());
552 Warning(
"REveManager::GetGeometry",
"TGeoManager is locked ... unlocking it.");
556 throw eh +
"TGeoManager::Import() failed for '" + exp_filename +
"'.";
562 gGeoManager->GetTopVolume()->VisibleDaughters(
true);
566 TFile f(exp_filename,
"READ");
572 while ((vol = (
TGeoVolume *)next()) !=
nullptr) {
598 throw eh +
"geometry alias '" + alias +
"' not registered.";
629 fWebWindow->SetRequireAuthKey(requireAuthKey);
648 gROOT->ResetClassSaved();
657 fWebWindow->GetServer()->AddLocation(locationName.c_str(), path.c_str());
709 class XThreadTimer :
public TTimer {
710 std::function<void()> foo_;
712 XThreadTimer(std::function<
void()>
f) : foo_(
f)
727 new XThreadTimer(func);
753 printf(
"connection established %u\n", connid);
761 printf(
"\nEVEMNG ............. streaming the world scene.\n");
766 printf(
" sending json, len = %d\n", (
int)
fWorld->fOutputJson.size());
768 printf(
" for now assume world-scene has no render data, binary-size=%d\n",
fWorld->fTotalBinarySize);
769 assert(
fWorld->fTotalBinarySize == 0);
771 for (
auto &
c :
fScenes->RefChildren()) {
777 printf(
"\nEVEMNG ............. streaming scene %s [%s]\n", scene->
GetCTitle(), scene->
GetCName());
782 printf(
" sending json, len = %d\n", (
int)scene->
fOutputJson.size());
804 if (i->fId == connid) {
811 printf(
"error, connection not found!");
813 printf(
"connection closed %u\n", connid);
815 for (
auto &
c :
fScenes->RefChildren()) {
819 fWorld->RemoveSubscriber(connid);
845 if (conn.fId == connid) {
853 R__LOG_ERROR(
REveLog()) <<
"Internal error - no connection with id " << connid <<
" found";
858 if (arg.compare(
"__REveDoneChanges") == 0)
864 if (conn.fId == connid) {
881 R__LOG_INFO(
REveLog()) <<
"REveManager::WindowData, file dialog is not allowed in restriced public mode";
889 else if (arg.compare(0, 11,
"SETCHANNEL:") == 0) {
890 std::string s = arg.substr(11);
891 auto p = s.find(
",");
892 int eveid = std::stoi(s.substr(0, p));
893 int chid = std::stoi(s.substr(p+1));
902 nlohmann::json cj = nlohmann::json::parse(arg);
904 ::Info(
"REveManager::WindowData",
"MIR test %s\n", cj.dump().c_str());
906 std::string cmd = cj[
"mir"];
907 int id = cj[
"fElementId"];
908 std::string ctype = cj[
"class"];
919 fMIRqueue.push(std::make_shared<MIR>(cmd,
id, ctype, connid));
922 std::cout <<
"Warning, REveManager::ScheduleMIR(). queue size " <<
fMIRqueue.size() << std::endl;
935 ::Info(
"REveManager::ExecuteCommand",
"MIR cmd %s", mir->fCmd.c_str());
937 std::string tag = mir->fCtype +
"::<to-be-determined>";
941 if ( ! el)
throw eh +
"Element with id " + mir->fId +
" not found";
943 static const std::regex cmd_re(
"^(\\w[\\w\\d]*)\\(\\s*(.*)\\s*\\)\\s*;?\\s*$", std::regex::optimize);
945 std::regex_search(mir->fCmd,
m, cmd_re);
947 throw eh +
"Command string parse error: '" + mir->fCmd +
"'.";
953 throw eh +
"Class '" + mir->fCtype +
"' not found.";
955 void *el_casted = call_cls->
DynamicCast(elem_cls, el,
false);
957 throw eh +
"Dynamic cast from REveElement to '" + mir->fCtype +
"' failed.";
959 tag = mir->fCtype +
"::" +
m.str(1);
961 std::shared_ptr<TMethodCall> mc;
971 throw eh +
"Can not find TMethod matching '" +
m.str(1) +
"'.";
972 mc = std::make_shared<TMethodCall>(meth);
979 mc->Execute(el_casted,
m.str(2).c_str());
993 }
catch (std::exception &
e) {
1003 if (
fWorld->IsChanged())
fWorld->StreamRepresentationChanges();
1005 for (
auto &el :
fScenes->RefChildren())
1016 nlohmann::json jobj = {};
1017 jobj[
"content"] =
"BeginChanges";
1021 fWorld->SendChangesToSubscribers();
1023 for (
auto &el :
fScenes->RefChildren())
1030 jobj[
"content"] =
"EndChanges";
1034 constexpr static std::array<const char *, numLevels> sTag{
1035 {
"{unset-error-level please report}",
"FATAL",
"Error",
"Warning",
"Info",
"Debug"}};
1037 jobj[
"log"] = nlohmann::json::array();
1038 std::stringstream strm;
1041 nlohmann::json item = {};
1042 item[
"lvl"] = entry.fLevel;
1043 int cappedLevel = std::min(
static_cast<int>(entry.fLevel), numLevels - 1);
1044 strm <<
"Server " << sTag[cappedLevel] <<
":";
1046 if (!entry.fLocation.fFuncName.empty())
1047 strm <<
" " << entry.fLocation.fFuncName;
1048 strm <<
" " << entry.fMessage;
1049 item[
"msg"] = strm.str();
1050 jobj[
"log"].push_back(item);
1061#if defined(R__LINUX)
1062 pthread_setname_np(pthread_self(),
"mir_exec");
1066 std::unique_lock<std::mutex> lock(
fServerState.fMutex);
1078 std::shared_ptr<MIR> mir =
fMIRqueue.front();
1091 gEve->GetWorld()->BeginAcceptingChanges();
1092 gEve->GetScenes()->BeginAcceptingChanges();
1096 gEve->GetScenes()->EndAcceptingChanges();
1097 gEve->GetWorld()->EndAcceptingChanges();
1106 for (
auto &scene :
gMIRData.removedWatch)
1107 scene->RemoveSubscriber(mir->fConnId);
1111 for (
auto &scene :
gMIRData.addedWatch) {
1112 scene->AddSubscriber(std::make_unique<REveClient>(mir->fConnId,
fWebWindow));
1113 scene->StreamElements();
1114 Send(mir->fConnId, scene->fOutputJson);
1115 if (scene->fTotalBinarySize > 0)
1116 SendBinary(mir->fConnId, &scene->fOutputBinary[0], scene->fTotalBinarySize);
1179 if (conn.fId == cinnId)
1195 if (
gEnv->GetValue(
"WebEve.DisableShow", 0) != 0) {
1197 printf(
"EVE URL %s\n", url.c_str());
1209 std::unique_lock<std::mutex> lock(
fServerState.fMutex);
1229 std::unique_lock<std::mutex> lock(
fServerState.fMutex);
1238 std::unique_lock<std::mutex> lock(
fServerState.fMutex);
1240#if defined(_MSC_VER)
1259 gEve->BeginChange();
1291 Info(
"Handle",
"Exception %s",
ex->what());
std::vector< ROOT::RLogEntry > gEveLogEntries
#define R__LOG_ERROR(...)
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
int Int_t
Signed integer 4 bytes (int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
externTApplication * gApplication
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
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.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
externTGeoManager * gGeoManager
externTGeoIdentity * gGeoIdentity
#define R__LOCKGUARD_CLING(mutex)
externTVirtualMutex * gInterpreterMutex
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
externTVirtualMutex * gSystemMutex
#define R__LOCKGUARD2(mutex)
void DecDenyDestroy()
Decreases the deny-destroy count of the element.
const std::string & GetName() const
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.
static std::string stlMirErrorString
REveElement * FirstChild() const
Returns the first child element or 0 if the list is empty.
static void ClearMirContext()
Bool_t HasChildren() const
static void SetMirContext(REveElement *el)
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.
void SetChannel(unsigned connid, int chid)
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.
REveManager(const REveManager &)=delete
ElementId_t fMaxElementIds
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)
ElementId_t fNumElementIds
REveSceneList * GetScenes() const
std::thread fMIRExecThread
void ClearAllSelections()
Clear all selection objects.
RExceptionHandler * fExcHandler
!< exception handler
REveSelection * fSelection
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)
bool ClientConnectionsFree() const
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.
std::vector< Conn > fConnList
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.
ElementId_t fLastElementId
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)
REveSelection * fHighlight
std::queue< std::shared_ptr< MIR > > fMIRqueue
REveViewerList * fViewers
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.
REveServerStatus fServerStatus
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.
REveElement * fSelectionList
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 StreamSceneChangesToJson()
REveViewer * GetDefaultViewer() const
Get the default viewer.
REveScene * GetWorld() const
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.
REveScene * GetScene() const
void EndAcceptingChanges()
void BeginAcceptingChanges()
Loop-wrapers over Scene children, element type checked on insertion.
void AddSubscriber(std::unique_ptr< REveClient > &&sub)
std::vector< char > fOutputBinary
!
void StreamRepresentationChanges()
Prepare data for sending element changes.
void SendChangesToSubscribers()
void BeginAcceptingChanges()
void EndAcceptingChanges()
void RemoveSubscriber(unsigned int)
REveSelection Container for selected and highlighted elements.
int RemoveImpliedSelectedReferencesTo(REveElement *el)
Remove pointers to el from implied selected sets.
static void Macro(const char *mac)
Execute macro 'mac'. Do not reload the macro.
REveViewerList List of Viewers providing common operations on REveViewer collections.
REveViewer Reve representation of TGLViewer.
A diagnostic that can be emitted by the RLogManager.
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 Color_t GetLineColor() const
Return the line color.
TClass instances represent classes, structs and namespaces in the ROOT type system.
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.
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
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.
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
static Int_t GetColor(const char *hexcolor)
static void SetColorThreshold(Float_t t)
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
An identity transformation.
The manager class for any TGeo geometry.
static void UnlockGeometry()
Unlock current geometry.
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, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
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 ...
Each ROOT class (see TClass) has a linked list of methods.
TObject * At(Int_t idx) const override
Collectable string class.
Mother of all ROOT objects.
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Class used by TMap to store (key,value) pairs.
const char * Data() const
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Handles synchronous and a-synchronous timer events.
Namespace for ROOT features in testing.
ROOT::RLogChannel & REveLog()
Log channel for Eve diagnostics.
@ kDebug
Debug information; only useful for developers; can have added verbosity up to 255-kDebug.
std::vector< REveScene * > removedWatch
std::vector< REveScene * > addedWatch