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 <pression/plugins/compressorTypes.h>
27 :
28 : namespace co
29 : {
30 : namespace detail
31 : {
32 6098934 : class ICommand
33 : {
34 : public:
35 1163623 : ICommand()
36 : : func( 0, 0 )
37 : , buffer( 0 )
38 : , size( 0 )
39 : , type( COMMANDTYPE_INVALID )
40 : , cmd( CMD_INVALID )
41 1163623 : , consumed( false )
42 1163612 : {}
43 :
44 120296 : 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 120296 : , consumed( false )
53 120296 : {}
54 :
55 358965 : void clear()
56 : {
57 358965 : *this = ICommand();
58 358965 : }
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 804637 : ICommand::ICommand()
72 : : DataIStream( false )
73 804637 : , _impl( new detail::ICommand )
74 : {
75 804647 : }
76 :
77 120296 : ICommand::ICommand( LocalNodePtr local, NodePtr remote, ConstBufferPtr buffer,
78 : const bool swap_ )
79 : : DataIStream( swap_ )
80 120296 : , _impl( new detail::ICommand( local, remote, buffer ))
81 : {
82 120296 : if( _impl->buffer )
83 : {
84 120295 : LBASSERT( buffer->getSize() >= sizeof( _impl->size ) +
85 : sizeof( _impl->type ) + sizeof( _impl->cmd ));
86 :
87 120295 : *this >> _impl->size >> _impl->type >> _impl->cmd;
88 : }
89 120296 : }
90 :
91 1917471 : ICommand::ICommand( const ICommand& rhs )
92 : : DataIStream( rhs )
93 1917471 : , _impl( new detail::ICommand( *rhs._impl ))
94 : {
95 1917473 : _impl->consumed = false;
96 1917473 : _skipHeader();
97 1917473 : }
98 :
99 625424 : ICommand& ICommand::operator = ( const ICommand& rhs )
100 : {
101 625424 : if( this != &rhs )
102 : {
103 625428 : DataIStream::operator = ( rhs );
104 625420 : *_impl = *rhs._impl;
105 625433 : _impl->consumed = false;
106 625433 : _skipHeader();
107 : }
108 625404 : return *this;
109 : }
110 :
111 5680359 : ICommand::~ICommand()
112 : {
113 2838071 : delete _impl;
114 2842158 : }
115 :
116 358965 : void ICommand::clear()
117 : {
118 358965 : _impl->clear();
119 358965 : }
120 :
121 2518481 : void ICommand::_skipHeader()
122 : {
123 : const size_t headerSize = sizeof( _impl->size ) + sizeof( _impl->type ) +
124 2518481 : sizeof( _impl->cmd );
125 2518481 : if( isValid() && getRemainingBufferSize() >= headerSize )
126 2496548 : getRemainingBuffer( headerSize );
127 2499980 : }
128 :
129 72273 : uint32_t ICommand::getType() const
130 : {
131 72273 : return _impl->type;
132 : }
133 :
134 699300 : uint32_t ICommand::getCommand() const
135 : {
136 699300 : return _impl->cmd;
137 : }
138 :
139 619898 : uint64_t ICommand::getSize() const
140 : {
141 619898 : return _impl->size;
142 : }
143 :
144 48154 : void ICommand::setType( const CommandType type )
145 : {
146 48154 : _impl->type = type;
147 48154 : }
148 :
149 48284 : void ICommand::setCommand( const uint32_t cmd )
150 : {
151 48284 : _impl->cmd = cmd;
152 48284 : }
153 :
154 676913 : void ICommand::setDispatchFunction( const Dispatcher::Func& func )
155 : {
156 676913 : _impl->func = func;
157 676913 : }
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 2618795 : bool ICommand::getNextBuffer( uint32_t& compressor, uint32_t& nChunks,
176 : const void** chunkData, uint64_t& size )
177 : {
178 2618795 : if( _impl->consumed ) // 2nd call
179 0 : _impl->buffer = 0;
180 :
181 2618795 : if( !_impl->buffer )
182 0 : return false;
183 :
184 2617798 : _impl->consumed = true;
185 2617798 : *chunkData = _impl->buffer->getData();
186 2612015 : size = reinterpret_cast< const uint64_t* >( *chunkData )[ 0 ];
187 2612015 : compressor = EQ_COMPRESSOR_NONE;
188 2612015 : nChunks = 1;
189 2612015 : return true;
190 : }
191 :
192 210222 : NodePtr ICommand::getRemoteNode() const
193 : {
194 210222 : return _impl->remote;
195 : }
196 :
197 0 : LocalNodePtr ICommand::getLocalNode() const
198 : {
199 0 : return _impl->local;
200 : }
201 :
202 4245851 : bool ICommand::isValid() const
203 : {
204 12724819 : return _impl->buffer && !_impl->buffer->isEmpty() &&
205 16956851 : _impl->type != COMMANDTYPE_INVALID && _impl->cmd != CMD_INVALID &&
206 8477670 : _impl->size > 0;
207 : }
208 :
209 676888 : bool ICommand::operator()()
210 : {
211 676888 : LBASSERT( _impl->func.isValid( ));
212 676880 : Dispatcher::Func func = _impl->func;
213 676880 : _impl->func.clear();
214 676878 : 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 66 : }
|