Line data Source code
1 :
2 : /* Copyright (c) 2006-2013, 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 "iCommand.h"
22 :
23 : #include "buffer.h"
24 : #include "localNode.h"
25 : #include "node.h"
26 : #include <lunchbox/plugins/compressorTypes.h>
27 :
28 : namespace co
29 : {
30 : namespace detail
31 : {
32 8656651 : class ICommand
33 : {
34 : public:
35 1565634 : ICommand()
36 : : func( 0, 0 )
37 : , buffer( 0 )
38 : , size( 0 )
39 : , type( COMMANDTYPE_INVALID )
40 : , cmd( CMD_INVALID )
41 1565634 : , consumed( false )
42 1565677 : {}
43 :
44 153956 : ICommand( LocalNodePtr local_, NodePtr remote_, ConstBufferPtr buffer_ )
45 : : local( local_ )
46 : , remote( remote_ )
47 : , func( 0, 0 )
48 : , buffer( buffer_ )
49 : , size( 0 )
50 : , type( COMMANDTYPE_INVALID )
51 : , cmd( CMD_INVALID )
52 153956 : , consumed( false )
53 153956 : {}
54 :
55 335172 : void clear()
56 : {
57 335172 : *this = ICommand();
58 335172 : }
59 :
60 : LocalNodePtr local; //!< The node receiving the command
61 : NodePtr remote; //!< The node sending the command
62 : co::Dispatcher::Func func;
63 : ConstBufferPtr buffer;
64 : uint64_t size;
65 : uint32_t type;
66 : uint32_t cmd;
67 : bool consumed;
68 : };
69 : } // detail namespace
70 :
71 1230504 : ICommand::ICommand()
72 : : DataIStream( false )
73 1230504 : , _impl( new detail::ICommand )
74 : {
75 1230495 : }
76 :
77 153956 : ICommand::ICommand( LocalNodePtr local, NodePtr remote, ConstBufferPtr buffer,
78 : const bool swap_ )
79 : : DataIStream( swap_ )
80 153956 : , _impl( new detail::ICommand( local, remote, buffer ))
81 : {
82 153956 : if( _impl->buffer )
83 : {
84 153955 : LBASSERT( buffer->getSize() >= sizeof( _impl->size ) +
85 : sizeof( _impl->type ) + sizeof( _impl->cmd ));
86 :
87 153955 : *this >> _impl->size >> _impl->type >> _impl->cmd;
88 : }
89 153956 : }
90 :
91 2775410 : ICommand::ICommand( const ICommand& rhs )
92 : : DataIStream( rhs )
93 2775410 : , _impl( new detail::ICommand( *rhs._impl ))
94 : {
95 2775417 : _impl->consumed = false;
96 2775417 : _skipHeader();
97 2775377 : }
98 :
99 1063245 : ICommand& ICommand::operator = ( const ICommand& rhs )
100 : {
101 1063245 : if( this != &rhs )
102 : {
103 1063265 : DataIStream::operator = ( rhs );
104 1063270 : *_impl = *rhs._impl;
105 1063255 : _impl->consumed = false;
106 1063255 : _skipHeader();
107 : }
108 1063153 : return *this;
109 : }
110 :
111 8288174 : ICommand::~ICommand()
112 : {
113 4136501 : delete _impl;
114 4135077 : }
115 :
116 335172 : void ICommand::clear()
117 : {
118 335172 : _impl->clear();
119 335172 : }
120 :
121 3822071 : void ICommand::_skipHeader()
122 : {
123 : const size_t headerSize = sizeof( _impl->size ) + sizeof( _impl->type ) +
124 3822071 : sizeof( _impl->cmd );
125 3822071 : if( isValid() && getRemainingBufferSize() >= headerSize )
126 3765994 : getRemainingBuffer( headerSize );
127 3762855 : }
128 :
129 72246 : uint32_t ICommand::getType() const
130 : {
131 72246 : return _impl->type;
132 : }
133 :
134 1137124 : uint32_t ICommand::getCommand() const
135 : {
136 1137124 : return _impl->cmd;
137 : }
138 :
139 584192 : uint64_t ICommand::getSize() const
140 : {
141 584192 : return _impl->size;
142 : }
143 :
144 81833 : void ICommand::setType( const CommandType type )
145 : {
146 81833 : _impl->type = type;
147 81833 : }
148 :
149 81957 : void ICommand::setCommand( const uint32_t cmd )
150 : {
151 81957 : _impl->cmd = cmd;
152 81957 : }
153 :
154 1114767 : void ICommand::setDispatchFunction( const Dispatcher::Func& func )
155 : {
156 1114767 : _impl->func = func;
157 1114767 : }
158 :
159 0 : ConstBufferPtr ICommand::getBuffer() const
160 : {
161 0 : LBASSERT( _impl->buffer );
162 0 : return _impl->buffer;
163 : }
164 :
165 0 : size_t ICommand::nRemainingBuffers() const
166 : {
167 0 : return _impl->buffer ? 1 : 0;
168 : }
169 :
170 0 : uint128_t ICommand::getVersion() const
171 : {
172 0 : return VERSION_NONE;
173 : }
174 :
175 3927316 : bool ICommand::getNextBuffer( uint32_t& compressor, uint32_t& nChunks,
176 : const void** chunkData, uint64_t& size )
177 : {
178 3927316 : if( _impl->consumed ) // 2nd call
179 0 : _impl->buffer = 0;
180 :
181 3927316 : if( !_impl->buffer )
182 0 : return false;
183 :
184 3920320 : _impl->consumed = true;
185 3920320 : *chunkData = _impl->buffer->getData();
186 3920638 : size = reinterpret_cast< const uint64_t* >( *chunkData )[ 0 ];
187 3920638 : compressor = EQ_COMPRESSOR_NONE;
188 3920638 : nChunks = 1;
189 3920638 : return true;
190 : }
191 :
192 198316 : NodePtr ICommand::getRemoteNode() const
193 : {
194 198316 : return _impl->remote;
195 : }
196 :
197 0 : LocalNodePtr ICommand::getLocalNode() const
198 : {
199 0 : return _impl->local;
200 : }
201 :
202 5933896 : bool ICommand::isValid() const
203 : {
204 17701817 : return _impl->buffer && !_impl->buffer->isEmpty() &&
205 23555085 : _impl->type != COMMANDTYPE_INVALID && _impl->cmd != CMD_INVALID &&
206 11787661 : _impl->size > 0;
207 : }
208 :
209 1114619 : bool ICommand::operator()()
210 : {
211 1114619 : LBASSERT( _impl->func.isValid( ));
212 1114656 : Dispatcher::Func func = _impl->func;
213 1114656 : _impl->func.clear();
214 1114638 : return func( *this );
215 : }
216 :
217 0 : std::ostream& operator << ( std::ostream& os, const ICommand& command )
218 : {
219 0 : ConstBufferPtr buffer = command.getBuffer();
220 0 : if( buffer )
221 0 : os << lunchbox::disableFlush << "command< type "
222 0 : << uint32_t( command.getType( )) << " cmd " << command.getCommand()
223 0 : << " size " << command.getSize() << '/' << buffer->getSize() << '/'
224 0 : << buffer->getMaxSize() << " from " << command.getNode() << " to "
225 0 : << command.getLocalNode() << " >" << lunchbox::enableFlush;
226 : else
227 0 : os << "command< empty >";
228 :
229 0 : if( command._impl->func.isValid( ))
230 0 : os << ' ' << command._impl->func << std::endl;
231 0 : return os;
232 : }
233 60 : }
|