25 using namespace ROOT::Experimental;
 
   26 namespace REX = ROOT::Experimental;
 
   42 REveScene::REveScene(
const std::string& n, 
const std::string& t) :
 
   51 REveScene::~REveScene()
 
   53    fDestructing = kStandard;
 
   55    REX::gEve->GetViewers()->SceneDestructing(
this);
 
   56    REX::gEve->GetScenes()->RemoveElement(
this);
 
   61 void REveScene::AddSubscriber(std::unique_ptr<REveClient> &&sub)
 
   63    assert(sub.get() != 
nullptr && fAcceptingChanges == kFALSE);
 
   65    fSubscribers.emplace_back(std::move(sub));
 
   72 void REveScene::RemoveSubscriber(
unsigned id)
 
   74    assert(fAcceptingChanges == kFALSE);
 
   76    auto pred = [&](std::unique_ptr<REveClient> &client) {
 
   77       return client->fId == id;
 
   80    fSubscribers.erase(std::remove_if(fSubscribers.begin(), fSubscribers.end(), pred), fSubscribers.end());
 
   83 void REveScene::BeginAcceptingChanges()
 
   85    if (fAcceptingChanges) 
return;
 
   87    if (HasSubscribers()) fAcceptingChanges = kTRUE;
 
   90 void REveScene::SceneElementChanged(REveElement* element)
 
   92    assert(fAcceptingChanges);
 
   94    fChangedElements.push_back(element);
 
   97 void REveScene::SceneElementRemoved(ElementId_t 
id)
 
   99    fRemovedElements.push_back(
id);
 
  102 void REveScene::EndAcceptingChanges()
 
  104    if ( ! fAcceptingChanges) 
return;
 
  106    fAcceptingChanges = kFALSE;
 
  109 void REveScene::ProcessChanges()
 
  113       StreamRepresentationChanges();
 
  114       SendChangesToSubscribers();
 
  118 void REveScene::StreamElements()
 
  121    fOutputBinary.clear();
 
  123    fElsWithBinaryData.clear();
 
  124    fTotalBinarySize = 0;
 
  126    nlohmann::json jarr = nlohmann::json::array();
 
  128    nlohmann::json jhdr = {};
 
  129    jhdr[
"content"]  = 
"REveScene::StreamElements";
 
  130    jhdr[
"fSceneId"] = fElementId;
 
  132    if (fCommands.size() > 0) {
 
  133       jhdr[
"commands"] = nlohmann::json::array();
 
  134       for (
auto &&cmd : fCommands) {
 
  135          nlohmann::json jcmd = {};
 
  136          jcmd[
"name"]  = cmd.fName;
 
  137          jcmd[
"icon"] = cmd.fIcon;
 
  138          jcmd[
"elementid"] = cmd.fElementId;
 
  139          jcmd[
"elementclass"] = cmd.fElementClass;
 
  140          jcmd[
"func"] = cmd.fAction; 
 
  141          jhdr[
"commands"].push_back(jcmd);
 
  145    jarr.push_back(jhdr);
 
  147    StreamJsonRecurse(
this, jarr);
 
  153    fOutputBinary.resize(fTotalBinarySize);
 
  156    for (
auto &&e : fElsWithBinaryData)
 
  158       auto rd_size = e->fRenderData->Write(&fOutputBinary[off], fOutputBinary.size() - off);
 
  161    assert(off == fTotalBinarySize);
 
  163    jarr.front()[
"fTotalBinarySize"] = fTotalBinarySize;
 
  165    fOutputJson = jarr.dump();
 
  168 void REveScene::StreamJsonRecurse(REveElement *el, nlohmann::json &jarr)
 
  170    nlohmann::json jobj = {};
 
  171    Int_t rd_size = el->WriteCoreJson(jobj, fTotalBinarySize);
 
  172    jarr.push_back(jobj);
 
  177    if (el->fScene == el && el != 
this)
 
  184       assert (rd_size % 4 == 0);
 
  186       fTotalBinarySize += rd_size;
 
  187       fElsWithBinaryData.push_back(el);
 
  190    for (
auto &&c : el->fChildren)
 
  205       if (c->GetMother() == el)
 
  207          StreamJsonRecurse(c, jarr);
 
  218 void REveScene::StreamRepresentationChanges()
 
  221    fOutputBinary.clear();
 
  223    fElsWithBinaryData.clear();
 
  224    fTotalBinarySize = 0;
 
  226    nlohmann::json jarr = nlohmann::json::array();
 
  228    nlohmann::json jhdr = {};
 
  229    jhdr[
"content"]  = 
"ElementsRepresentaionChanges";
 
  230    jhdr[
"fSceneId"] = fElementId;
 
  232    jhdr[
"removedElements"] = nlohmann::json::array();
 
  233    for (
auto &re : fRemovedElements)
 
  234       jhdr[
"removedElements"].push_back(re);
 
  236    jhdr[
"numRepresentationChanged"] = fChangedElements.size();
 
  240    for (
auto &el: fChangedElements)
 
  242       UChar_t bits = el->GetChangeBits();
 
  244       nlohmann::json jobj = {};
 
  245       jobj[
"fElementId"] = el->GetElementId();
 
  246       jobj[
"changeBit"]  = bits;
 
  248       if (bits & kCBElementAdded || bits & kCBObjProps)
 
  250          if (gDebug > 0 && bits & kCBElementAdded)
 
  252             Info(
"REveScene::StreamRepresentationChanges", 
"new element change %s %d\n",
 
  253                  el->GetCName(), bits);
 
  256          Int_t rd_size = el->WriteCoreJson(jobj, fTotalBinarySize);
 
  258             assert (rd_size % 4 == 0);
 
  259             fTotalBinarySize += rd_size;
 
  260             fElsWithBinaryData.push_back(el);
 
  265         if (bits & kCBVisibility)
 
  267           jobj[
"fRnrSelf"]     = el->GetRnrSelf();
 
  268           jobj[
"fRnrChildren"] = el->GetRnrChildren();
 
  271         if (bits & kCBColorSelection)
 
  273           el->WriteCoreJson(jobj, -1);
 
  276         if (bits & kCBTransBBox)
 
  281       jarr.push_back(jobj);
 
  286    fChangedElements.clear();
 
  287    fRemovedElements.clear();
 
  290    fOutputBinary.resize(fTotalBinarySize);
 
  293    for (
auto &e : fElsWithBinaryData) {
 
  294       auto rd_size = e->fRenderData->Write(&fOutputBinary[off], fOutputBinary.size() - off);
 
  298    assert(off == fTotalBinarySize);
 
  300    jhdr[
"fTotalBinarySize"] = fTotalBinarySize;
 
  302    nlohmann::json msg = { {
"header", jhdr}, {
"arr", jarr}};
 
  303    fOutputJson = msg.dump();
 
  306       Info(
"REveScene::StreamRepresentationChanges", 
"class: %s  changes %s ...", GetCName(),  msg.dump(1).c_str() );
 
  309 void REveScene::SendChangesToSubscribers()
 
  311    for (
auto && client : fSubscribers) {
 
  313          printf(
"   sending json, len = %d --> to conn_id = %d\n", (
int) fOutputJson.size(), client->fId);
 
  314       client->fWebWindow->Send(client->fId, fOutputJson);
 
  315       if (fTotalBinarySize) {
 
  317             printf(
"   sending binary, len = %d --> to conn_id = %d\n", fTotalBinarySize, client->fId);
 
  318          client->fWebWindow->SendBinary(client->fId, &fOutputBinary[0], fTotalBinarySize);
 
  323 Bool_t REveScene::IsChanged()
 const 
  326      ::Info(
"REveScene::IsChanged",
"%s (changed_or_added=%d, removed=%d)", GetCName(),
 
  327           (
int) fChangedElements.size(), (int) fRemovedElements.size());
 
  329    return ! (fChangedElements.empty() && fRemovedElements.empty());
 
  337 void REveScene::Repaint(Bool_t dropLogicals)
 
  339    if (dropLogicals) fGLScene->SetSmartRefresh(kFALSE);
 
  340    fGLScene->PadPaint(fPad);
 
  341    if (dropLogicals) fGLScene->SetSmartRefresh(kTRUE);
 
  344    // Hack to propagate selection state to physical shapes.
 
  346    // Should actually be published in PadPaint() following a direct
 
  347    // AddObject() call, but would need some other stuff for that.
 
  348    // Optionally, this could be exported via the TAtt3D and everything
 
  351    TGLScene::LogicalShapeMap_t& logs = fGLScene->RefLogicalShapes();
 
  353    for (TGLScene::LogicalShapeMapIt_t li = logs.begin(); li != logs.end(); ++li)
 
  355       elm = dynamic_cast<REveElement*>(li->first);
 
  356       if (elm && li->second->Ref() == 1)
 
  358          TGLPhysicalShape* pshp = const_cast<TGLPhysicalShape*>(li->second->GetFirstPhysical());
 
  359          pshp->Select(elm->GetSelectedLevel());
 
  363    // Fix positions for hierarchical scenes.
 
  366       RetransHierarchically();
 
  374 void REveScene::RetransHierarchically()
 
  376    fGLScene->BeginUpdate();
 
  378    RetransHierarchicallyRecurse(this, RefMainTrans());
 
  380    fGLScene->EndUpdate();
 
  387 void REveScene::RetransHierarchicallyRecurse(REveElement* el, const REveTrans& tp)
 
  389    static const REveException eh("REveScene::RetransHierarchicallyRecurse ");
 
  392    if (el->HasMainTrans())
 
  393       t *= el->RefMainTrans();
 
  395    if (el->GetRnrSelf() && el != this)
 
  397       fGLScene->UpdatePhysioLogical(el->GetRenderObject(eh), t.Array(), 0);
 
  400    if (el->GetRnrChildren())
 
  402       for (auto &c: el->RefChildren())
 
  404          if (c->GetRnrAnything())
 
  405             RetransHierarchicallyRecurse(c, t);
 
  416 void REveScene::Paint(Option_t* option)
 
  420       for (auto &c: fChildren)
 
  422          // c->PadPaint(option);
 
  431 void REveScene::DestroyElementRenderers(REveElement* element)
 
  433    static const REveException eh("REveScene::DestroyElementRenderers ");
 
  435    fGLScene->BeginUpdate();
 
  436    Bool_t changed = fGLScene->DestroyLogical(element->GetRenderObject(eh), kFALSE);
 
  437    fGLScene->EndUpdate(changed, changed);
 
  444 void REveScene::DestroyElementRenderers(TObject* rnrObj)
 
  446    fGLScene->BeginUpdate();
 
  447    Bool_t changed = fGLScene->DestroyLogical(rnrObj, kFALSE);
 
  448    fGLScene->EndUpdate(changed, changed);
 
  461 REveSceneList::REveSceneList(
const std::string& n, 
const std::string& t) :
 
  464    SetChildClass(TClass::GetClass<REveScene>());
 
  471 void REveSceneList::DestroyScenes()
 
  473    auto i = fChildren.begin();
 
  474    while (i != fChildren.end())
 
  476       REveScene* s = (REveScene*) *(i++);
 
  477       s->DestroyElements();
 
  485 void REveSceneList::AcceptChanges(
bool on)
 
  487    for (
auto &c: fChildren)
 
  489       REveScene *s = (REveScene *)c;
 
  491          s->BeginAcceptingChanges();
 
  493          s->EndAcceptingChanges();
 
  500 void REveSceneList::RepaintChangedScenes(Bool_t dropLogicals)
 
  502    for (auto &c: fChildren)
 
  504       REveScene* s = (REveScene*) c;
 
  507          s->Repaint(dropLogicals);
 
  515 void REveSceneList::RepaintAllScenes(Bool_t dropLogicals)
 
  517    for (auto &c: fChildren)
 
  519       ((REveScene *)c)->Repaint(dropLogicals);
 
  526 void REveSceneList::DestroyElementRenderers(REveElement* element)
 
  528    static const REveException eh("REveSceneList::DestroyElementRenderers ");
 
  530    TObject* obj = element->GetRenderObject(eh);
 
  531    for (auto &c: fChildren)
 
  533       ((REveScene *)c)->DestroyElementRenderers(obj);
 
  545 void REveSceneList::ProcessSceneChanges()
 
  548       ::Info(
"REveSceneList::ProcessSceneChanges",
"processing");
 
  550    for (
auto &el : fChildren)
 
  552       ((REveScene*) el)->ProcessChanges();