Line data Source code
1 :
2 : /* Copyright (c) 2006-2016, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 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/data/CompressorInfo.h>
27 :
28 : namespace co
29 : {
30 : namespace detail
31 : {
32 6053742 : class ICommand
33 : {
34 : public:
35 1186121 : ICommand()
36 1186121 : : func( 0, 0 )
37 : , buffer( 0 )
38 : , size( 0 )
39 : , type( COMMANDTYPE_INVALID )
40 : , cmd( CMD_INVALID )
41 1186121 : , consumed( false )
42 1186042 : {}
43 :
44 117863 : ICommand( LocalNodePtr local_, NodePtr remote_, ConstBufferPtr buffer_ )
45 117863 : : local( local_ )
46 : , remote( remote_ )
47 : , func( 0, 0 )
48 : , buffer( buffer_ )
49 : , size( 0 )
50 : , type( COMMANDTYPE_INVALID )
51 : , cmd( CMD_INVALID )
52 117863 : , consumed( false )
53 117863 : {}
54 :
55 395045 : void clear()
56 : {
57 395045 : *this = ICommand();
58 395045 : }
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 791074 : ICommand::ICommand()
72 : : DataIStream( false )
73 791074 : , _impl( new detail::ICommand )
74 : {
75 790997 : }
76 :
77 117863 : ICommand::ICommand( LocalNodePtr local, NodePtr remote, ConstBufferPtr buffer,
78 117863 : const bool swap_ )
79 : : DataIStream( swap_ )
80 117863 : , _impl( new detail::ICommand( local, remote, buffer ))
81 : {
82 117863 : if( _impl->buffer )
83 : {
84 117862 : LBASSERT( buffer->getSize() >= sizeof( _impl->size ) +
85 : sizeof( _impl->type ) + sizeof( _impl->cmd ));
86 :
87 117862 : *this >> _impl->size >> _impl->type >> _impl->cmd;
88 : }
89 117863 : }
90 :
91 1910764 : ICommand::ICommand( const ICommand& rhs )
92 : : DataIStream( rhs )
93 1910764 : , _impl( new detail::ICommand( *rhs._impl ))
94 : {
95 1910768 : _impl->consumed = false;
96 1910768 : _skipHeader();
97 1910766 : }
98 :
99 593794 : ICommand& ICommand::operator = ( const ICommand& rhs )
100 : {
101 593794 : if( this != &rhs )
102 : {
103 593799 : DataIStream::operator = ( rhs );
104 593800 : *_impl = *rhs._impl;
105 593802 : _impl->consumed = false;
106 593802 : _skipHeader();
107 : }
108 593739 : return *this;
109 : }
110 :
111 5568373 : ICommand::~ICommand()
112 : {
113 2754082 : delete _impl;
114 2812347 : }
115 :
116 395045 : void ICommand::clear()
117 : {
118 395045 : _impl->clear();
119 395045 : }
120 :
121 2503122 : void ICommand::_skipHeader()
122 : {
123 : const size_t headerSize = sizeof( _impl->size ) + sizeof( _impl->type ) +
124 2503122 : sizeof( _impl->cmd );
125 2503122 : if( isValid() && getRemainingBufferSize() >= headerSize )
126 2473316 : getRemainingBuffer( headerSize );
127 2465651 : }
128 :
129 72273 : uint32_t ICommand::getType() const
130 : {
131 72273 : return _impl->type;
132 : }
133 :
134 667670 : uint32_t ICommand::getCommand() const
135 : {
136 667670 : return _impl->cmd;
137 : }
138 :
139 674018 : uint64_t ICommand::getSize() const
140 : {
141 674018 : return _impl->size;
142 : }
143 :
144 45721 : void ICommand::setType( const CommandType type )
145 : {
146 45721 : _impl->type = type;
147 45721 : }
148 :
149 45851 : void ICommand::setCommand( const uint32_t cmd )
150 : {
151 45851 : _impl->cmd = cmd;
152 45851 : }
153 :
154 645283 : void ICommand::setDispatchFunction( const Dispatcher::Func& func )
155 : {
156 645283 : _impl->func = func;
157 645283 : }
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 2555743 : bool ICommand::getNextBuffer( CompressorInfo& info, uint32_t& nChunks,
176 : const void*& chunkData, uint64_t& size )
177 : {
178 2555743 : if( _impl->consumed ) // 2nd call
179 0 : _impl->buffer = 0;
180 :
181 2555743 : if( !_impl->buffer )
182 0 : return false;
183 :
184 2555777 : _impl->consumed = true;
185 2555777 : chunkData = _impl->buffer->getData();
186 2559146 : size = reinterpret_cast< const uint64_t* >( chunkData )[ 0 ];
187 2559146 : info = CompressorInfo();
188 2598916 : nChunks = 1;
189 2598916 : return true;
190 : }
191 :
192 228262 : NodePtr ICommand::getRemoteNode() const
193 : {
194 228262 : return _impl->remote;
195 : }
196 :
197 0 : LocalNodePtr ICommand::getLocalNode() const
198 : {
199 0 : return _impl->local;
200 : }
201 :
202 4293045 : bool ICommand::isValid() const
203 : {
204 12856678 : return _impl->buffer && !_impl->buffer->isEmpty() &&
205 17113251 : _impl->type != COMMANDTYPE_INVALID && _impl->cmd != CMD_INVALID &&
206 8546015 : _impl->size > 0;
207 : }
208 :
209 645243 : bool ICommand::operator()()
210 : {
211 645243 : LBASSERT( _impl->func.isValid( ));
212 645237 : Dispatcher::Func func = _impl->func;
213 645237 : _impl->func.clear();
214 645232 : 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 : }
|