LCOV - code coverage report
Current view: top level - eq/fabric - config.ipp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 353 472 74.8 %
Date: 2017-12-16 05:07:20 Functions: 80 504 15.9 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2017, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Cedric Stalder <cedric Stalder@gmail.com>
       4             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify it under
       7             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       8             :  * by the Free Software Foundation.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      12             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      17             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             :  */
      19             : 
      20             : #include "config.h"
      21             : 
      22             : #include "paths.h"
      23             : 
      24             : #include "configVisitor.h"
      25             : 
      26             : #include <co/global.h>
      27             : #include <co/objectICommand.h>
      28             : 
      29             : #include "layout.ipp" // Layout::_removeObserver template impl
      30             : 
      31             : namespace eq
      32             : {
      33             : namespace fabric
      34             : {
      35             : #define MAKE_ATTR_STRING(attr) (std::string("EQ_CONFIG_") + #attr)
      36             : 
      37             : namespace
      38             : {
      39         100 : std::string _fAttributeStrings[] = {
      40         200 :     MAKE_ATTR_STRING(FATTR_EYE_BASE), MAKE_ATTR_STRING(FATTR_VERSION),
      41         250 : };
      42         100 : std::string _iAttributeStrings[] = {
      43         100 :     MAKE_ATTR_STRING(IATTR_ROBUSTNESS),
      44         150 : };
      45             : }
      46             : 
      47             : template <class S, class C, class O, class L, class CV, class N, class V>
      48         405 : Config<S, C, O, L, CV, N, V>::Config(lunchbox::RefPtr<S> server)
      49             :     : Object()
      50         405 :     , _server(server)
      51             : {
      52         405 :     server->_addConfig(static_cast<C*>(this));
      53         405 :     LBLOG(LOG_INIT) << "New " << lunchbox::className(this) << std::endl;
      54         405 : }
      55             : 
      56             : template <class S, class C, class O, class L, class CV, class N, class V>
      57         403 : Config<S, C, O, L, CV, N, V>::~Config()
      58             : {
      59         403 :     LBLOG(LOG_INIT) << "Delete " << lunchbox::className(this) << std::endl;
      60         403 :     _appNodeID = 0;
      61             : 
      62        1239 :     while (!_canvases.empty())
      63             :     {
      64         418 :         CV* canvas = _canvases.back();
      65         418 :         _removeCanvas(canvas);
      66         418 :         delete canvas;
      67             :     }
      68             : 
      69        1687 :     while (!_layouts.empty())
      70             :     {
      71         642 :         L* layout = _layouts.back();
      72         642 :         _removeLayout(layout);
      73         642 :         delete layout;
      74             :     }
      75             : 
      76        1215 :     while (!_observers.empty())
      77             :     {
      78         406 :         O* observer = _observers.back();
      79         406 :         _removeObserver(observer);
      80         406 :         delete observer;
      81             :     }
      82             : 
      83        2055 :     while (!_nodes.empty())
      84             :     {
      85         826 :         N* node = _nodes.back();
      86         826 :         _removeNode(node);
      87         826 :         delete node;
      88             :     }
      89             : 
      90         403 :     _server->_removeConfig(static_cast<C*>(this));
      91         403 :     _server = 0;
      92         806 : }
      93             : 
      94             : template <class S, class C, class O, class L, class CV, class N, class V>
      95           3 : void Config<S, C, O, L, CV, N, V>::attach(const uint128_t& id,
      96             :                                           const uint32_t instanceID)
      97             : {
      98           3 :     Object::attach(id, instanceID);
      99             : 
     100           3 :     co::CommandQueue* queue = _server->getMainThreadQueue();
     101           3 :     LBASSERT(queue);
     102             : 
     103           3 :     registerCommand(CMD_CONFIG_NEW_LAYOUT,
     104             :                     CmdFunc(this, &Config<S, C, O, L, CV, N, V>::_cmdNewLayout),
     105             :                     queue);
     106           3 :     registerCommand(CMD_CONFIG_NEW_CANVAS,
     107             :                     CmdFunc(this, &Config<S, C, O, L, CV, N, V>::_cmdNewCanvas),
     108             :                     queue);
     109           3 :     registerCommand(CMD_CONFIG_NEW_OBSERVER,
     110             :                     CmdFunc(this,
     111             :                             &Config<S, C, O, L, CV, N, V>::_cmdNewObserver),
     112             :                     queue);
     113           3 :     registerCommand(CMD_CONFIG_NEW_ENTITY_REPLY,
     114             :                     CmdFunc(this,
     115             :                             &Config<S, C, O, L, CV, N, V>::_cmdNewEntityReply),
     116             :                     0);
     117           3 : }
     118             : 
     119             : template <class C, class V>
     120       11629 : VisitorResult _acceptImpl(C* config, V& visitor)
     121             : {
     122       11629 :     VisitorResult result = visitor.visitPre(config);
     123       11629 :     if (result != TRAVERSE_CONTINUE)
     124         612 :         return result;
     125             : 
     126       11017 :     const typename C::Nodes& nodes = config->getNodes();
     127       26491 :     for (typename C::Nodes::const_iterator i = nodes.begin(); i != nodes.end();
     128             :          ++i)
     129             :     {
     130       20886 :         switch ((*i)->accept(visitor))
     131             :         {
     132             :         case TRAVERSE_TERMINATE:
     133        5412 :             return TRAVERSE_TERMINATE;
     134             : 
     135             :         case TRAVERSE_PRUNE:
     136         382 :             result = TRAVERSE_PRUNE;
     137         382 :             break;
     138             : 
     139             :         case TRAVERSE_CONTINUE:
     140             :         default:
     141       15092 :             break;
     142             :         }
     143             :     }
     144             : 
     145        5605 :     const typename C::Observers& observers = config->getObservers();
     146       31623 :     for (typename C::Observers::const_iterator i = observers.begin();
     147       21082 :          i != observers.end(); ++i)
     148             :     {
     149        5655 :         switch ((*i)->accept(visitor))
     150             :         {
     151             :         case TRAVERSE_TERMINATE:
     152         719 :             return TRAVERSE_TERMINATE;
     153             : 
     154             :         case TRAVERSE_PRUNE:
     155           0 :             result = TRAVERSE_PRUNE;
     156           0 :             break;
     157             : 
     158             :         case TRAVERSE_CONTINUE:
     159             :         default:
     160        4936 :             break;
     161             :         }
     162             :     }
     163             : 
     164        4886 :     const typename C::Layouts& layouts = config->getLayouts();
     165       69444 :     for (typename C::Layouts::const_iterator i = layouts.begin();
     166       46296 :          i != layouts.end(); ++i)
     167             :     {
     168       19947 :         switch ((*i)->accept(visitor))
     169             :         {
     170             :         case TRAVERSE_TERMINATE:
     171        1685 :             return TRAVERSE_TERMINATE;
     172             : 
     173             :         case TRAVERSE_PRUNE:
     174           0 :             result = TRAVERSE_PRUNE;
     175           0 :             break;
     176             : 
     177             :         case TRAVERSE_CONTINUE:
     178             :         default:
     179       18262 :             break;
     180             :         }
     181             :     }
     182             : 
     183        3201 :     const typename C::Canvases& canvases = config->getCanvases();
     184       17160 :     for (typename C::Canvases::const_iterator i = canvases.begin();
     185       11440 :          i != canvases.end(); ++i)
     186             :     {
     187        2551 :         switch ((*i)->accept(visitor))
     188             :         {
     189             :         case TRAVERSE_TERMINATE:
     190          32 :             return TRAVERSE_TERMINATE;
     191             : 
     192             :         case TRAVERSE_PRUNE:
     193           0 :             result = TRAVERSE_PRUNE;
     194           0 :             break;
     195             : 
     196             :         case TRAVERSE_CONTINUE:
     197             :         default:
     198        2519 :             break;
     199             :         }
     200             :     }
     201             : 
     202        3169 :     switch (config->_acceptCompounds(visitor))
     203             :     {
     204             :     case TRAVERSE_TERMINATE:
     205         422 :         return TRAVERSE_TERMINATE;
     206             : 
     207             :     case TRAVERSE_PRUNE:
     208         142 :         result = TRAVERSE_PRUNE;
     209         142 :         break;
     210             : 
     211             :     case TRAVERSE_CONTINUE:
     212             :     default:
     213        2605 :         break;
     214             :     }
     215             : 
     216        2747 :     switch (visitor.visitPost(config))
     217             :     {
     218             :     case TRAVERSE_TERMINATE:
     219           0 :         return TRAVERSE_TERMINATE;
     220             : 
     221             :     case TRAVERSE_PRUNE:
     222           0 :         result = TRAVERSE_PRUNE;
     223           0 :         break;
     224             : 
     225             :     case TRAVERSE_CONTINUE:
     226             :     default:
     227        2747 :         break;
     228             :     }
     229             : 
     230        2747 :     return result;
     231             : }
     232             : 
     233             : template <class S, class C, class O, class L, class CV, class N, class V>
     234        8639 : VisitorResult Config<S, C, O, L, CV, N, V>::accept(V& visitor)
     235             : {
     236        8639 :     return _acceptImpl(static_cast<C*>(this), visitor);
     237             : }
     238             : 
     239             : template <class S, class C, class O, class L, class CV, class N, class V>
     240        2990 : VisitorResult Config<S, C, O, L, CV, N, V>::accept(V& visitor) const
     241             : {
     242        2990 :     return _acceptImpl(static_cast<const C*>(this), visitor);
     243             : }
     244             : 
     245             : template <class S, class C, class O, class L, class CV, class N, class V>
     246        2459 : lunchbox::RefPtr<S> Config<S, C, O, L, CV, N, V>::getServer()
     247             : {
     248        2459 :     return _server;
     249             : }
     250             : 
     251             : template <class S, class C, class O, class L, class CV, class N, class V>
     252          15 : lunchbox::RefPtr<const S> Config<S, C, O, L, CV, N, V>::getServer() const
     253             : {
     254          15 :     return _server;
     255             : }
     256             : 
     257             : namespace
     258             : {
     259             : template <typename T, typename V>
     260             : class IDFinder : public V
     261             : {
     262             : public:
     263          15 :     explicit IDFinder(const uint128_t& id)
     264             :         : _id(id)
     265          15 :         , _result(0)
     266             :     {
     267          15 :     }
     268          15 :     virtual ~IDFinder() {}
     269          28 :     virtual VisitorResult visitPre(T* node) { return visit(node); }
     270          35 :     virtual VisitorResult visit(T* node)
     271             :     {
     272          35 :         if (node->getID() == _id)
     273             :         {
     274          14 :             _result = node;
     275          14 :             return TRAVERSE_TERMINATE;
     276             :         }
     277          21 :         return TRAVERSE_CONTINUE;
     278             :     }
     279             : 
     280          15 :     T* getResult() { return _result; }
     281             : private:
     282             :     const uint128_t _id;
     283             :     T* _result;
     284             : };
     285             : }
     286             : 
     287             : template <class S, class C, class O, class L, class CV, class N, class V>
     288             : template <typename T>
     289          15 : void Config<S, C, O, L, CV, N, V>::find(const uint128_t& id, T** result)
     290             : {
     291          30 :     IDFinder<T, V> finder(id);
     292          15 :     static_cast<C*>(this)->accept(finder);
     293          15 :     *result = finder.getResult();
     294          15 : }
     295             : 
     296             : template <class S, class C, class O, class L, class CV, class N, class V>
     297             : template <typename T>
     298         710 : void Config<S, C, O, L, CV, N, V>::find(const std::string& name,
     299             :                                         const T** result) const
     300             : {
     301        1420 :     NameFinder<T, V> finder(name);
     302         710 :     static_cast<const C*>(this)->accept(finder);
     303         710 :     *result = finder.getResult();
     304         710 : }
     305             : 
     306             : template <class S, class C, class O, class L, class CV, class N, class V>
     307             : template <typename T>
     308           0 : T* Config<S, C, O, L, CV, N, V>::find(const uint128_t& id)
     309             : {
     310           0 :     IDFinder<T, V> finder(id);
     311           0 :     static_cast<C*>(this)->accept(finder);
     312           0 :     return finder.getResult();
     313             : }
     314             : 
     315             : template <class S, class C, class O, class L, class CV, class N, class V>
     316             : template <typename T>
     317           0 : const T* Config<S, C, O, L, CV, N, V>::find(const uint128_t& id) const
     318             : {
     319           0 :     IDFinder<const T, V> finder(id);
     320           0 :     static_cast<const C*>(this)->accept(finder);
     321           0 :     return finder.getResult();
     322             : }
     323             : 
     324             : template <class S, class C, class O, class L, class CV, class N, class V>
     325             : template <typename T>
     326        3804 : T* Config<S, C, O, L, CV, N, V>::find(const std::string& name)
     327             : {
     328        7608 :     NameFinder<T, V> finder(name);
     329        3804 :     static_cast<C*>(this)->accept(finder);
     330        7608 :     return finder.getResult();
     331             : }
     332             : 
     333             : template <class S, class C, class O, class L, class CV, class N, class V>
     334             : template <typename T>
     335        2280 : const T* Config<S, C, O, L, CV, N, V>::find(const std::string& name) const
     336             : {
     337        4560 :     NameFinder<const T, V> finder(name);
     338        2280 :     static_cast<const C*>(this)->accept(finder);
     339        4560 :     return finder.getResult();
     340             : }
     341             : 
     342             : template <class S, class C, class O, class L, class CV, class N, class V>
     343         300 : O* Config<S, C, O, L, CV, N, V>::getObserver(const ObserverPath& path)
     344             : {
     345         300 :     LBASSERTINFO(_observers.size() > path.observerIndex,
     346             :                  _observers.size() << " <= " << path.observerIndex);
     347             : 
     348         300 :     if (_observers.size() <= path.observerIndex)
     349           0 :         return 0;
     350             : 
     351         300 :     return _observers[path.observerIndex];
     352             : }
     353             : 
     354             : template <class S, class C, class O, class L, class CV, class N, class V>
     355        1224 : const std::string& Config<S, C, O, L, CV, N, V>::getFAttributeString(
     356             :     const FAttribute attr)
     357             : {
     358        1224 :     return _fAttributeStrings[attr];
     359             : }
     360             : 
     361             : template <class S, class C, class O, class L, class CV, class N, class V>
     362         618 : const std::string& Config<S, C, O, L, CV, N, V>::getIAttributeString(
     363             :     const IAttribute attr)
     364             : {
     365         618 :     return _iAttributeStrings[attr];
     366             : }
     367             : 
     368             : template <class S, class C, class O, class L, class CV, class N, class V>
     369           3 : uint32_t Config<S, C, O, L, CV, N, V>::getTimeout() const
     370             : {
     371           3 :     if (getIAttribute(IATTR_ROBUSTNESS) == OFF)
     372           3 :         return LB_TIMEOUT_INDEFINITE;
     373           0 :     return co::Global::getIAttribute(co::Global::IATTR_TIMEOUT_DEFAULT);
     374             : }
     375             : 
     376             : template <class S, class C, class O, class L, class CV, class N, class V>
     377        1736 : L* Config<S, C, O, L, CV, N, V>::getLayout(const LayoutPath& path)
     378             : {
     379        1736 :     LBASSERTINFO(_layouts.size() > path.layoutIndex,
     380             :                  _layouts.size() << " <= " << path.layoutIndex);
     381             : 
     382        1736 :     if (_layouts.size() <= path.layoutIndex)
     383           0 :         return 0;
     384             : 
     385        1736 :     return _layouts[path.layoutIndex];
     386             : }
     387             : 
     388             : template <class S, class C, class O, class L, class CV, class N, class V>
     389        2058 : CV* Config<S, C, O, L, CV, N, V>::getCanvas(const CanvasPath& path)
     390             : {
     391        2058 :     LBASSERTINFO(_canvases.size() > path.canvasIndex,
     392             :                  _canvases.size() << " <= " << path.canvasIndex);
     393             : 
     394        2058 :     if (_canvases.size() <= path.canvasIndex)
     395           0 :         return 0;
     396             : 
     397        2058 :     return _canvases[path.canvasIndex];
     398             : }
     399             : 
     400             : template <class S, class C, class O, class L, class CV, class N, class V>
     401         409 : void Config<S, C, O, L, CV, N, V>::_addObserver(O* observer)
     402             : {
     403         409 :     LBASSERT(observer->getConfig() == this);
     404         409 :     _observers.push_back(observer);
     405         409 :     setDirty(DIRTY_OBSERVERS);
     406         409 : }
     407             : 
     408             : template <class S, class C, class O, class L, class CV, class N, class V>
     409         814 : bool Config<S, C, O, L, CV, N, V>::_removeObserver(O* observer)
     410             : {
     411             :     typename Observers::iterator i =
     412         814 :         std::find(_observers.begin(), _observers.end(), observer);
     413         814 :     if (i == _observers.end())
     414         407 :         return false;
     415             : 
     416             :     // remove from views
     417        1221 :     for (typename Layouts::const_iterator j = _layouts.begin();
     418         814 :          j != _layouts.end(); ++j)
     419             :     {
     420           0 :         (*j)->_removeObserver(observer);
     421             :     }
     422             : 
     423         407 :     LBASSERT(observer->getConfig() == this);
     424         407 :     _observers.erase(i);
     425         407 :     setDirty(DIRTY_OBSERVERS);
     426         407 :     if (!isMaster())
     427         407 :         postRemove(observer);
     428         407 :     return true;
     429             : }
     430             : 
     431             : template <class S, class C, class O, class L, class CV, class N, class V>
     432         651 : void Config<S, C, O, L, CV, N, V>::_addLayout(L* layout)
     433             : {
     434         651 :     LBASSERT(layout->getConfig() == this);
     435         651 :     _layouts.push_back(layout);
     436         651 :     setDirty(DIRTY_LAYOUTS);
     437         651 : }
     438             : 
     439             : template <class S, class C, class O, class L, class CV, class N, class V>
     440        1298 : bool Config<S, C, O, L, CV, N, V>::_removeLayout(L* layout)
     441             : {
     442             :     typename Layouts::iterator i =
     443        1298 :         std::find(_layouts.begin(), _layouts.end(), layout);
     444        1298 :     if (i == _layouts.end())
     445         649 :         return false;
     446             : 
     447             :     // remove from canvases
     448        1947 :     for (typename Canvases::const_iterator j = _canvases.begin();
     449        1298 :          j != _canvases.end(); ++j)
     450             :     {
     451           0 :         (*j)->removeLayout(layout);
     452             :     }
     453             : 
     454         649 :     LBASSERT(layout->getConfig() == this);
     455         649 :     _layouts.erase(i);
     456         649 :     setDirty(DIRTY_LAYOUTS);
     457         649 :     if (!isMaster())
     458         649 :         postRemove(layout);
     459         649 :     return true;
     460             : }
     461             : 
     462             : template <class S, class C, class O, class L, class CV, class N, class V>
     463         421 : void Config<S, C, O, L, CV, N, V>::_addCanvas(CV* canvas)
     464             : {
     465         421 :     LBASSERT(canvas->getConfig() == this);
     466         421 :     _canvases.push_back(canvas);
     467         421 :     setDirty(DIRTY_CANVASES);
     468         421 : }
     469             : 
     470             : template <class S, class C, class O, class L, class CV, class N, class V>
     471           1 : void Config<S, C, O, L, CV, N, V>::create(O** observer)
     472             : {
     473           1 :     *observer =
     474           2 :         getServer()->getNodeFactory()->createObserver(static_cast<C*>(this));
     475           1 : }
     476             : 
     477             : template <class S, class C, class O, class L, class CV, class N, class V>
     478           0 : void Config<S, C, O, L, CV, N, V>::release(O* observer)
     479             : {
     480           0 :     getServer()->getNodeFactory()->releaseObserver(observer);
     481           0 : }
     482             : 
     483             : template <class S, class C, class O, class L, class CV, class N, class V>
     484           7 : void Config<S, C, O, L, CV, N, V>::create(L** layout)
     485             : {
     486           7 :     *layout =
     487          14 :         getServer()->getNodeFactory()->createLayout(static_cast<C*>(this));
     488           7 : }
     489             : 
     490             : template <class S, class C, class O, class L, class CV, class N, class V>
     491           0 : void Config<S, C, O, L, CV, N, V>::release(L* layout)
     492             : {
     493           0 :     getServer()->getNodeFactory()->releaseLayout(layout);
     494           0 : }
     495             : 
     496             : template <class S, class C, class O, class L, class CV, class N, class V>
     497           1 : void Config<S, C, O, L, CV, N, V>::create(CV** canvas)
     498             : {
     499           1 :     *canvas =
     500           2 :         getServer()->getNodeFactory()->createCanvas(static_cast<C*>(this));
     501           1 : }
     502             : 
     503             : template <class S, class C, class O, class L, class CV, class N, class V>
     504           0 : void Config<S, C, O, L, CV, N, V>::release(CV* canvas)
     505             : {
     506           0 :     getServer()->getNodeFactory()->releaseCanvas(canvas);
     507           0 : }
     508             : 
     509             : template <class S, class C, class O, class L, class CV, class N, class V>
     510           0 : void Config<S, C, O, L, CV, N, V>::create(N** node)
     511             : {
     512           0 :     *node = getServer()->getNodeFactory()->createNode(static_cast<C*>(this));
     513           0 : }
     514             : 
     515             : template <class S, class C, class O, class L, class CV, class N, class V>
     516           0 : void Config<S, C, O, L, CV, N, V>::release(N* node)
     517             : {
     518           0 :     getServer()->getNodeFactory()->releaseNode(node);
     519           0 : }
     520             : 
     521             : template <class S, class C, class O, class L, class CV, class N, class V>
     522         838 : bool Config<S, C, O, L, CV, N, V>::_removeCanvas(CV* canvas)
     523             : {
     524             :     typename Canvases::iterator i =
     525         838 :         std::find(_canvases.begin(), _canvases.end(), canvas);
     526         838 :     if (i == _canvases.end())
     527         419 :         return false;
     528             : 
     529         419 :     LBASSERT(canvas->getConfig() == this);
     530         419 :     _canvases.erase(i);
     531         419 :     setDirty(DIRTY_CANVASES);
     532         419 :     if (!isMaster())
     533         419 :         postRemove(canvas);
     534         419 :     return true;
     535             : }
     536             : 
     537             : template <class S, class C, class O, class L, class CV, class N, class V>
     538          38 : void Config<S, C, O, L, CV, N, V>::setLatency(const uint32_t latency)
     539             : {
     540          38 :     if (_data.latency == latency)
     541           2 :         return;
     542             : 
     543          36 :     _data.latency = latency;
     544          36 :     setDirty(DIRTY_LATENCY);
     545             : }
     546             : 
     547             : template <class S, class C, class O, class L, class CV, class N, class V>
     548           2 : void Config<S, C, O, L, CV, N, V>::setAppNodeID(const co::NodeID& nodeID)
     549             : {
     550           2 :     if (_appNodeID == nodeID)
     551           0 :         return;
     552             : 
     553           2 :     _appNodeID = nodeID;
     554           2 :     setDirty(DIRTY_MEMBER);
     555             : }
     556             : 
     557             : template <class S, class C, class O, class L, class CV, class N, class V>
     558           0 : EventOCommand Config<S, C, O, L, CV, N, V>::sendError(co::NodePtr node,
     559             :                                                       const uint32_t event,
     560             :                                                       const Error& error)
     561             : {
     562             : #ifdef NDEBUG
     563             :     LBWARN << error << std::endl;
     564             : #else
     565           0 :     LBWARN << "Emit " << error << " at "
     566           0 :            << lunchbox::backtrace(2 /*cut boring stack frames*/) << std::endl;
     567             : #endif
     568           0 :     EventOCommand cmd(send(node, CMD_CONFIG_EVENT));
     569           0 :     cmd << event << error;
     570           0 :     return cmd;
     571             : }
     572             : 
     573             : template <class S, class C, class O, class L, class CV, class N, class V>
     574           0 : void Config<S, C, O, L, CV, N, V>::restore()
     575             : {
     576           0 :     Object::restore();
     577           0 :     if (_data.latency != _backup.latency)
     578             :     {
     579           0 :         _data = _backup;
     580           0 :         changeLatency(_data.latency);
     581             :     }
     582             :     else
     583           0 :         _data = _backup;
     584           0 :     setDirty(DIRTY_MEMBER | DIRTY_LATENCY);
     585           0 : }
     586             : 
     587             : template <class S, class C, class O, class L, class CV, class N, class V>
     588         829 : void Config<S, C, O, L, CV, N, V>::_addNode(N* node)
     589             : {
     590         829 :     LBASSERT(node->getConfig() == this);
     591         829 :     _nodes.push_back(node);
     592         829 : }
     593             : 
     594             : template <class S, class C, class O, class L, class CV, class N, class V>
     595        1653 : bool Config<S, C, O, L, CV, N, V>::_removeNode(N* node)
     596             : {
     597        1653 :     typename Nodes::iterator i = std::find(_nodes.begin(), _nodes.end(), node);
     598        1653 :     if (i == _nodes.end())
     599         826 :         return false;
     600             : 
     601         827 :     LBASSERT(node->getConfig() == this);
     602         827 :     _nodes.erase(i);
     603         827 :     return true;
     604             : }
     605             : 
     606             : template <class S, class C, class O, class L, class CV, class N, class V>
     607           6 : N* Config<S, C, O, L, CV, N, V>::findAppNode()
     608             : {
     609           6 :     for (typename Nodes::const_iterator i = _nodes.begin(); i != _nodes.end();
     610             :          ++i)
     611             :     {
     612           6 :         N* node = *i;
     613           6 :         if (node->isApplicationNode())
     614           6 :             return node;
     615             :     }
     616           0 :     return 0;
     617             : }
     618             : 
     619             : template <class S, class C, class O, class L, class CV, class N, class V>
     620           0 : const N* Config<S, C, O, L, CV, N, V>::findAppNode() const
     621             : {
     622           0 :     for (typename Nodes::const_iterator i = _nodes.begin(); i != _nodes.end();
     623             :          ++i)
     624             :     {
     625           0 :         const N* node = *i;
     626           0 :         if (node->isApplicationNode())
     627           0 :             return node;
     628             :     }
     629           0 :     return 0;
     630             : }
     631             : 
     632             : template <class S, class C, class O, class L, class CV, class N, class V>
     633           1 : N* Config<S, C, O, L, CV, N, V>::_findNode(const uint128_t& id)
     634             : {
     635           1 :     for (typename Nodes::const_iterator i = _nodes.begin(); i != _nodes.end();
     636             :          ++i)
     637             :     {
     638           1 :         N* node = *i;
     639           1 :         if (node->getID() == id)
     640           1 :             return node;
     641             :     }
     642           0 :     return 0;
     643             : }
     644             : 
     645             : template <class S, class C, class O, class L, class CV, class N, class V>
     646          14 : uint128_t Config<S, C, O, L, CV, N, V>::commit(const uint32_t incarnation)
     647             : {
     648          14 :     if (Serializable::isDirty(DIRTY_NODES))
     649           8 :         commitChildren<N>(_nodes, incarnation);
     650          14 :     if (Serializable::isDirty(DIRTY_OBSERVERS))
     651           3 :         commitChildren<O, C>(_observers, static_cast<C*>(this),
     652             :                              CMD_CONFIG_NEW_OBSERVER, incarnation);
     653             : 
     654             :     // Always traverse layouts and canvases: view/segment objects may be dirty
     655          14 :     commitChildren<L, C>(_layouts, static_cast<C*>(this), CMD_CONFIG_NEW_LAYOUT,
     656             :                          incarnation);
     657          14 :     commitChildren<CV, C>(_canvases, static_cast<C*>(this),
     658             :                           CMD_CONFIG_NEW_CANVAS, incarnation);
     659             : 
     660          14 :     if (Serializable::isDirty(DIRTY_CANVASES))
     661           3 :         commitChildren<CV, C>(_canvases, static_cast<C*>(this),
     662             :                               CMD_CONFIG_NEW_CANVAS, incarnation);
     663          14 :     return Object::commit(incarnation);
     664             : }
     665             : 
     666             : template <class S, class C, class O, class L, class CV, class N, class V>
     667          22 : void Config<S, C, O, L, CV, N, V>::serialize(co::DataOStream& os,
     668             :                                              const uint64_t dirtyBits)
     669             : {
     670          22 :     Object::serialize(os, dirtyBits);
     671             : 
     672          22 :     if (dirtyBits & Config::DIRTY_MEMBER)
     673          12 :         os << _appNodeID;
     674          22 :     if (dirtyBits & Config::DIRTY_ATTRIBUTES)
     675          12 :         os << co::Array<float>(_fAttributes, C::FATTR_ALL)
     676          24 :            << co::Array<int32_t>(_iAttributes, C::IATTR_ALL);
     677          22 :     if (isMaster())
     678             :     {
     679          20 :         if (dirtyBits & Config::DIRTY_NODES)
     680          20 :             os.serializeChildren(_nodes);
     681          20 :         if (dirtyBits & Config::DIRTY_OBSERVERS)
     682          14 :             os.serializeChildren(_observers);
     683          20 :         if (dirtyBits & Config::DIRTY_LAYOUTS)
     684          20 :             os.serializeChildren(_layouts);
     685          20 :         if (dirtyBits & Config::DIRTY_CANVASES)
     686          14 :             os.serializeChildren(_canvases);
     687             :     }
     688          22 :     if (dirtyBits & Config::DIRTY_LATENCY)
     689          12 :         os << _data.latency;
     690          22 : }
     691             : 
     692             : template <class S, class C, class O, class L, class CV, class N, class V>
     693           9 : void Config<S, C, O, L, CV, N, V>::deserialize(co::DataIStream& is,
     694             :                                                const uint64_t dirtyBits)
     695             : {
     696           9 :     Object::deserialize(is, dirtyBits);
     697             : 
     698           9 :     if (dirtyBits & Config::DIRTY_MEMBER)
     699           1 :         is >> _appNodeID;
     700           9 :     if (dirtyBits & Config::DIRTY_ATTRIBUTES)
     701           1 :         is >> co::Array<float>(_fAttributes, C::FATTR_ALL) >>
     702             :             co::Array<int32_t>(_iAttributes, C::IATTR_ALL);
     703           9 :     if (isMaster())
     704             :     {
     705           4 :         if (dirtyBits & Config::DIRTY_NODES)
     706           0 :             syncChildren(_nodes);
     707           4 :         if (dirtyBits & Config::DIRTY_OBSERVERS)
     708           2 :             syncChildren(_observers);
     709           4 :         if (dirtyBits & Config::DIRTY_LAYOUTS)
     710           4 :             syncChildren(_layouts);
     711           4 :         if (dirtyBits & Config::DIRTY_CANVASES)
     712           2 :             syncChildren(_canvases);
     713             :     }
     714             :     else
     715             :     {
     716           5 :         if (dirtyBits & Config::DIRTY_NODES)
     717             :         {
     718           5 :             if (mapNodeObjects())
     719             :             {
     720           0 :                 typename C::Nodes result;
     721           0 :                 is.deserializeChildren(this, _nodes, result);
     722           0 :                 _nodes.swap(result);
     723           0 :                 LBASSERT(_nodes.size() == result.size());
     724             :             }
     725             :             else // consume unused ObjectVersions
     726             :             {
     727          10 :                 co::ObjectVersions childIDs;
     728           5 :                 is >> childIDs;
     729             :             }
     730             :         }
     731             : 
     732           5 :         if (mapViewObjects()) // depends on _config._appNodeID !
     733             :         {
     734           5 :             if (dirtyBits & Config::DIRTY_OBSERVERS)
     735             :             {
     736           4 :                 typename C::Observers result;
     737           2 :                 is.deserializeChildren(this, _observers, result);
     738           2 :                 _observers.swap(result);
     739           2 :                 LBASSERT(_observers.size() == result.size());
     740             :             }
     741           5 :             if (dirtyBits & Config::DIRTY_LAYOUTS)
     742             :             {
     743          10 :                 typename C::Layouts result;
     744           5 :                 is.deserializeChildren(this, _layouts, result);
     745           5 :                 _layouts.swap(result);
     746           5 :                 LBASSERT(_layouts.size() == result.size());
     747             :             }
     748           5 :             if (dirtyBits & Config::DIRTY_CANVASES)
     749             :             {
     750           4 :                 typename C::Canvases result;
     751           2 :                 is.deserializeChildren(this, _canvases, result);
     752           2 :                 _canvases.swap(result);
     753           2 :                 LBASSERT(_canvases.size() == result.size());
     754             :             }
     755             :         }
     756             :         else // consume unused ObjectVersions
     757             :         {
     758           0 :             co::ObjectVersions childIDs;
     759           0 :             if (dirtyBits & Config::DIRTY_OBSERVERS)
     760           0 :                 is >> childIDs;
     761           0 :             if (dirtyBits & Config::DIRTY_LAYOUTS)
     762           0 :                 is >> childIDs;
     763           0 :             if (dirtyBits & Config::DIRTY_CANVASES)
     764           0 :                 is >> childIDs;
     765             :         }
     766             :     }
     767             : 
     768           9 :     if (dirtyBits & Config::DIRTY_LATENCY)
     769             :     {
     770           1 :         uint32_t latency = 0;
     771           1 :         is >> latency;
     772           1 :         if (_data.latency != latency)
     773             :         {
     774           0 :             _data.latency = latency;
     775           0 :             changeLatency(latency);
     776             :         }
     777             :     }
     778           9 : }
     779             : 
     780             : template <class S, class C, class O, class L, class CV, class N, class V>
     781           3 : void Config<S, C, O, L, CV, N, V>::notifyDetach()
     782             : {
     783           3 :     Object::notifyDetach();
     784           3 :     if (isMaster())
     785           2 :         return;
     786             : 
     787           1 :     typename S::NodeFactory* nodeFactory = getServer()->getNodeFactory();
     788             : 
     789           2 :     co::LocalNodePtr localNode = getLocalNode();
     790           1 :     while (!_nodes.empty())
     791             :     {
     792           0 :         LBASSERT(mapNodeObjects());
     793           0 :         N* node = _nodes.back();
     794           0 :         localNode->unmapObject(node);
     795           0 :         _removeNode(node);
     796           0 :         nodeFactory->releaseNode(node);
     797             :     }
     798             : 
     799           3 :     while (!_canvases.empty())
     800             :     {
     801           1 :         LBASSERT(mapViewObjects());
     802           1 :         CV* canvas = _canvases.back();
     803           1 :         localNode->unmapObject(canvas);
     804           1 :         _removeCanvas(canvas);
     805           1 :         nodeFactory->releaseCanvas(canvas);
     806             :     }
     807             : 
     808          15 :     while (!_layouts.empty())
     809             :     {
     810           7 :         LBASSERT(mapViewObjects());
     811           7 :         L* layout = _layouts.back();
     812           7 :         localNode->unmapObject(layout);
     813           7 :         _removeLayout(layout);
     814           7 :         nodeFactory->releaseLayout(layout);
     815             :     }
     816             : 
     817           3 :     while (!_observers.empty())
     818             :     {
     819           1 :         LBASSERT(mapViewObjects());
     820           1 :         O* observer = _observers.back();
     821           1 :         localNode->unmapObject(observer);
     822           1 :         _removeObserver(observer);
     823           1 :         nodeFactory->releaseObserver(observer);
     824             :     }
     825             : }
     826             : 
     827             : //----------------------------------------------------------------------
     828             : // ICommand handlers
     829             : //----------------------------------------------------------------------
     830             : template <class S, class C, class O, class L, class CV, class N, class V>
     831           0 : bool Config<S, C, O, L, CV, N, V>::_cmdNewLayout(co::ICommand& cmd)
     832             : {
     833           0 :     co::ObjectICommand command(cmd);
     834             : 
     835           0 :     L* layout = 0;
     836           0 :     create(&layout);
     837           0 :     LBASSERT(layout);
     838             : 
     839           0 :     getLocalNode()->registerObject(layout);
     840           0 :     layout->setAutoObsolete(_data.latency + 1);
     841           0 :     LBASSERT(layout->isAttached());
     842             : 
     843           0 :     send(command.getRemoteNode(), CMD_CONFIG_NEW_ENTITY_REPLY)
     844           0 :         << command.read<uint32_t>() << layout->getID();
     845           0 :     return true;
     846             : }
     847             : 
     848             : template <class S, class C, class O, class L, class CV, class N, class V>
     849           0 : bool Config<S, C, O, L, CV, N, V>::_cmdNewCanvas(co::ICommand& cmd)
     850             : {
     851           0 :     co::ObjectICommand command(cmd);
     852             : 
     853           0 :     CV* canvas = 0;
     854           0 :     create(&canvas);
     855           0 :     LBASSERT(canvas);
     856             : 
     857           0 :     getLocalNode()->registerObject(canvas);
     858           0 :     canvas->setAutoObsolete(_data.latency + 1);
     859           0 :     LBASSERT(canvas->isAttached());
     860             : 
     861           0 :     send(command.getRemoteNode(), CMD_CONFIG_NEW_ENTITY_REPLY)
     862           0 :         << command.read<uint32_t>() << canvas->getID();
     863           0 :     return true;
     864             : }
     865             : 
     866             : template <class S, class C, class O, class L, class CV, class N, class V>
     867           0 : bool Config<S, C, O, L, CV, N, V>::_cmdNewObserver(co::ICommand& cmd)
     868             : {
     869           0 :     co::ObjectICommand command(cmd);
     870             : 
     871           0 :     O* observer = 0;
     872           0 :     create(&observer);
     873           0 :     LBASSERT(observer);
     874             : 
     875           0 :     getLocalNode()->registerObject(observer);
     876           0 :     observer->setAutoObsolete(_data.latency + 1);
     877           0 :     LBASSERT(observer->isAttached());
     878             : 
     879           0 :     send(command.getRemoteNode(), CMD_CONFIG_NEW_ENTITY_REPLY)
     880           0 :         << command.read<uint32_t>() << observer->getID();
     881           0 :     return true;
     882             : }
     883             : 
     884             : template <class S, class C, class O, class L, class CV, class N, class V>
     885           0 : bool Config<S, C, O, L, CV, N, V>::_cmdNewEntityReply(co::ICommand& cmd)
     886             : {
     887           0 :     co::ObjectICommand command(cmd);
     888             : 
     889           0 :     const uint32_t requestID = command.read<uint32_t>();
     890           0 :     const uint128_t& result = command.read<uint128_t>();
     891             : 
     892           0 :     getLocalNode()->serveRequest(requestID, result);
     893             : 
     894           0 :     return true;
     895             : }
     896             : 
     897             : template <class S, class C, class O, class L, class CV, class N, class V>
     898         204 : std::ostream& operator<<(std::ostream& os,
     899             :                          const Config<S, C, O, L, CV, N, V>& config)
     900             : {
     901         204 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "config "
     902             :        << std::endl;
     903         204 :     os << "{" << std::endl << lunchbox::indent;
     904             : 
     905         204 :     if (!config.getName().empty())
     906         204 :         os << "name    \"" << config.getName() << '"' << std::endl;
     907             : 
     908         204 :     if (config.getLatency() != 1)
     909          18 :         os << "latency " << config.getLatency() << std::endl;
     910         204 :     os << std::endl;
     911             : 
     912         408 :     os << "attributes" << std::endl
     913         204 :        << "{" << std::endl
     914         204 :        << lunchbox::indent << "robustness "
     915         408 :        << IAttribute(config.getIAttribute(C::IATTR_ROBUSTNESS)) << std::endl
     916         408 :        << "eye_base   " << config.getFAttribute(C::FATTR_EYE_BASE) << std::endl
     917         204 :        << lunchbox::exdent << "}" << std::endl;
     918             : 
     919         204 :     const typename C::Nodes& nodes = config.getNodes();
     920         620 :     for (typename C::Nodes::const_iterator i = nodes.begin(); i != nodes.end();
     921             :          ++i)
     922             :     {
     923         416 :         os << **i;
     924             :     }
     925         204 :     os << std::endl;
     926             : 
     927         204 :     const typename C::Observers& observers = config.getObservers();
     928        1230 :     for (typename C::Observers::const_iterator i = observers.begin();
     929         820 :          i != observers.end(); ++i)
     930             :     {
     931         206 :         os << **i;
     932             :     }
     933         204 :     const typename C::Layouts& layouts = config.getLayouts();
     934        1638 :     for (typename C::Layouts::const_iterator i = layouts.begin();
     935        1092 :          i != layouts.end(); ++i)
     936             :     {
     937         342 :         os << **i;
     938             :     }
     939         204 :     const typename C::Canvases& canvases = config.getCanvases();
     940        1248 :     for (typename C::Canvases::const_iterator i = canvases.begin();
     941         832 :          i != canvases.end(); ++i)
     942             :     {
     943         212 :         os << **i;
     944             :     }
     945             : 
     946         204 :     config.output(os);
     947             : 
     948         408 :     os << lunchbox::exdent << "}" << std::endl
     949         204 :        << lunchbox::enableHeader << lunchbox::enableFlush;
     950             : 
     951         204 :     return os;
     952             : }
     953             : }
     954             : }

Generated by: LCOV version 1.11