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 644 : 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 324 : Dispatcher::Dispatcher()
45 324 : : _impl( new detail::Dispatcher )
46 324 : {}
47 :
48 0 : Dispatcher::Dispatcher( const Dispatcher& )
49 0 : : _impl( new detail::Dispatcher )
50 0 : {}
51 :
52 320 : Dispatcher::~Dispatcher()
53 : {
54 320 : delete _impl;
55 320 : }
56 :
57 : //===========================================================================
58 : // command handling
59 : //===========================================================================
60 2522 : void Dispatcher::_registerCommand( const uint32_t command, const Func& func,
61 : CommandQueue* destinationQueue )
62 : {
63 2522 : LBASSERT( _impl->fTable.size() == _impl->qTable.size( ));
64 :
65 2522 : if( _impl->fTable.size() <= command )
66 : {
67 4148 : while( _impl->fTable.size() < command )
68 : {
69 1558 : _impl->fTable.push_back( Func( this, &Dispatcher::_cmdUnknown ));
70 1558 : _impl->qTable.push_back( 0 );
71 : }
72 :
73 1295 : _impl->fTable.push_back( func );
74 1295 : _impl->qTable.push_back( destinationQueue );
75 :
76 1295 : LBASSERT( _impl->fTable.size() == command + 1 );
77 : }
78 : else
79 : {
80 1227 : _impl->fTable[command] = func;
81 1227 : _impl->qTable[command] = destinationQueue;
82 : }
83 2522 : }
84 :
85 :
86 1135372 : bool Dispatcher::dispatchCommand( ICommand& command )
87 : {
88 1135372 : LBASSERT( command.isValid( ));
89 :
90 2270744 : LBVERB << "dispatch " << command << " on " << lunchbox::className( this )
91 3406116 : << std::endl;
92 :
93 1135372 : const uint32_t which = command.getCommand();
94 : #ifndef NDEBUG
95 1135372 : if( which >= _impl->qTable.size( ))
96 : {
97 0 : LBABORT( "ICommand " << command
98 : << " higher than number of registered command handlers ("
99 : << _impl->qTable.size() << ") for object of type "
100 : << lunchbox::className( this ) << std::endl );
101 0 : return false;
102 : }
103 : #endif
104 :
105 1135372 : CommandQueue* queue = _impl->qTable[ which ];
106 1135372 : if( queue )
107 : {
108 1114766 : command.setDispatchFunction( _impl->fTable[ which ] );
109 1114766 : queue->push( command );
110 1114766 : return true;
111 : }
112 : // else
113 :
114 20606 : LBCHECK( _impl->fTable[ which ]( command ));
115 20606 : return true;
116 : }
117 :
118 0 : bool Dispatcher::_cmdUnknown( ICommand& command )
119 : {
120 0 : LBERROR << "Unknown " << command << " for " << lunchbox::className( this )
121 0 : << lunchbox::backtrace << std::endl;
122 0 : LBUNREACHABLE;
123 0 : return false;
124 : }
125 :
126 60 : }
|