Line data Source code
1 :
2 : /* Copyright (c) 2010-2013, Stefan Eilemann <eile@eyescale.ch>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #ifndef EQSERVER_CONFIGUPDATEVISITOR_H
19 : #define EQSERVER_CONFIGUPDATEVISITOR_H
20 :
21 : #include "configVisitor.h" // base class
22 :
23 : namespace eq
24 : {
25 : namespace server
26 : {
27 : namespace
28 : {
29 : class ConfigUpdateVisitor : public ConfigVisitor
30 : {
31 : public:
32 4 : ConfigUpdateVisitor(const uint128_t& initID, const uint32_t frameNumber)
33 4 : : _initID(initID)
34 4 : , _frameNumber(frameNumber)
35 : {
36 4 : }
37 4 : virtual ~ConfigUpdateVisitor() {}
38 4 : virtual VisitorResult visitPre(Node* node) { return _updateDown(node); }
39 4 : virtual VisitorResult visitPost(Node* node)
40 : {
41 4 : const VisitorResult result = _updateUp(node);
42 4 : if (result == TRAVERSE_CONTINUE)
43 4 : node->flushSendBuffer();
44 4 : return result;
45 : }
46 :
47 8 : virtual VisitorResult visitPre(Pipe* pipe) { return _updateDown(pipe); }
48 8 : virtual VisitorResult visitPost(Pipe* pipe) { return _updateUp(pipe); }
49 8 : virtual VisitorResult visitPre(Window* window)
50 : {
51 8 : return _updateDown(window);
52 : }
53 8 : virtual VisitorResult visitPost(Window* window)
54 : {
55 8 : return _updateUp(window);
56 : }
57 :
58 36 : virtual VisitorResult visit(Channel* channel)
59 : {
60 36 : if (_updateDown(channel) == TRAVERSE_CONTINUE)
61 8 : return _updateUp(channel);
62 28 : return TRAVERSE_CONTINUE;
63 : }
64 :
65 : private:
66 : const uint128_t _initID;
67 : const uint32_t _frameNumber;
68 :
69 : template <class T>
70 56 : VisitorResult _updateDown(T* entity) const
71 : {
72 56 : const uint32_t state = entity->getState() & ~STATE_DELETE;
73 :
74 56 : switch (state)
75 : {
76 : case STATE_STOPPED:
77 42 : if (entity->isActive())
78 : {
79 14 : entity->configInit(_initID, _frameNumber);
80 14 : return TRAVERSE_CONTINUE;
81 : }
82 28 : return TRAVERSE_PRUNE;
83 :
84 : case STATE_RUNNING:
85 14 : return TRAVERSE_CONTINUE;
86 : case STATE_FAILED:
87 0 : if (entity->isActive())
88 0 : return TRAVERSE_PRUNE;
89 0 : return TRAVERSE_CONTINUE;
90 : }
91 0 : LBUNREACHABLE;
92 0 : return TRAVERSE_PRUNE;
93 : }
94 :
95 : template <class T>
96 28 : VisitorResult _updateUp(T* entity) const
97 : {
98 28 : const uint32_t state = entity->getState() & ~STATE_DELETE;
99 28 : switch (state)
100 : {
101 : case STATE_INITIALIZING:
102 : case STATE_INIT_FAILED:
103 : case STATE_INIT_SUCCESS:
104 14 : return TRAVERSE_CONTINUE;
105 :
106 : case STATE_RUNNING:
107 14 : if (!entity->isActive())
108 14 : entity->configExit();
109 14 : return TRAVERSE_CONTINUE;
110 :
111 : case STATE_FAILED:
112 0 : LBASSERT(!entity->isActive());
113 0 : if (!entity->isActive())
114 : {
115 0 : entity->setState(STATE_STOPPED);
116 0 : return TRAVERSE_PRUNE;
117 : }
118 0 : return TRAVERSE_CONTINUE;
119 : }
120 0 : LBASSERTINFO(false, State(state));
121 0 : return TRAVERSE_PRUNE;
122 : }
123 : };
124 : }
125 : }
126 : }
127 :
128 : #endif // EQSERVER_CONFIGUPDATEVISITOR_H
|