Line data Source code
1 :
2 : /* Copyright (c) 2005-2012, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2012, Daniel Nachbaur <danielnachbaur@gmail.com>
4 : *
5 : * This file is part of Collage <https://github.com/Eyescale/Collage>
6 : *
7 : * This library is free software; you can redistribute it and/or modify it under
8 : * the terms of the GNU Lesser General Public License version 2.1 as published
9 : * by the Free Software Foundation.
10 : *
11 : * This library is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 : * details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public License
17 : * along with this library; if not, write to the Free Software Foundation, Inc.,
18 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 : */
20 :
21 : #include "dispatcher.h"
22 :
23 : #include "commandQueue.h"
24 : #include "iCommand.h"
25 : #include "node.h"
26 :
27 : #include <lunchbox/log.h>
28 :
29 : namespace co
30 : {
31 : namespace detail
32 : {
33 614 : class Dispatcher
34 : {
35 : public:
36 : /** The command handler function table. */
37 : std::vector<co::Dispatcher::Func> fTable;
38 :
39 : /** Defines a queue to which commands are dispatched from the recv. */
40 : std::vector<co::CommandQueue*> qTable;
41 : };
42 : }
43 :
44 309 : Dispatcher::Dispatcher()
45 309 : : _impl(new detail::Dispatcher)
46 : {
47 309 : }
48 :
49 0 : Dispatcher::Dispatcher(const Dispatcher&)
50 0 : : _impl(new detail::Dispatcher)
51 : {
52 0 : }
53 :
54 610 : Dispatcher::~Dispatcher()
55 : {
56 305 : delete _impl;
57 305 : }
58 :
59 : //===========================================================================
60 : // command handling
61 : //===========================================================================
62 2453 : void Dispatcher::_registerCommand(const uint32_t command, const Func& func,
63 : CommandQueue* destinationQueue)
64 : {
65 2453 : LBASSERT(_impl->fTable.size() == _impl->qTable.size());
66 :
67 2453 : if (_impl->fTable.size() <= command)
68 : {
69 4271 : while (_impl->fTable.size() < command)
70 : {
71 1467 : _impl->fTable.push_back(Func(this, &Dispatcher::_cmdUnknown));
72 1467 : _impl->qTable.push_back(0);
73 : }
74 :
75 1337 : _impl->fTable.push_back(func);
76 1337 : _impl->qTable.push_back(destinationQueue);
77 :
78 1337 : LBASSERT(_impl->fTable.size() == command + 1);
79 : }
80 : else
81 : {
82 1116 : _impl->fTable[command] = func;
83 1116 : _impl->qTable[command] = destinationQueue;
84 : }
85 2453 : }
86 :
87 642084 : bool Dispatcher::dispatchCommand(ICommand& command)
88 : {
89 642084 : LBASSERT(command.isValid());
90 :
91 1284168 : LBVERB << "dispatch " << command << " on " << lunchbox::className(this)
92 1926252 : << std::endl;
93 :
94 642084 : const uint32_t which = command.getCommand();
95 : #ifndef NDEBUG
96 642084 : if (which >= _impl->qTable.size())
97 : {
98 0 : LBABORT("ICommand "
99 : << command
100 : << " higher than number of registered command handlers ("
101 : << _impl->qTable.size() << ") for object of type "
102 : << lunchbox::className(this) << std::endl);
103 0 : return false;
104 : }
105 : #endif
106 :
107 642084 : CommandQueue* queue = _impl->qTable[which];
108 642084 : if (queue)
109 : {
110 621517 : command.setDispatchFunction(_impl->fTable[which]);
111 621517 : queue->push(command);
112 621517 : return true;
113 : }
114 : // else
115 :
116 20567 : LBCHECK(_impl->fTable[which](command));
117 20567 : return true;
118 : }
119 :
120 0 : bool Dispatcher::_cmdUnknown(ICommand& command)
121 : {
122 0 : LBERROR << "Unknown " << command << " for " << lunchbox::className(this)
123 0 : << lunchbox::backtrace << std::endl;
124 0 : LBUNREACHABLE;
125 0 : return false;
126 : }
127 63 : }
|