Skip to content

Commit 31175f1

Browse files
committed
Fix problem with serializing dynamic ports
Part of #445
1 parent 29bc3b8 commit 31175f1

File tree

11 files changed

+424
-29
lines changed

11 files changed

+424
-29
lines changed

src/Dataflow/Network/Module.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ OutputPortHandle Module::getOutputPort(const PortId& id) const
105105
return oports_[id];
106106
}
107107

108-
InputPortHandle Module::getInputPort(const PortId& id) const
108+
InputPortHandle Module::getInputPort(const PortId& id)
109109
{
110110
return iports_[id];
111111
}

src/Dataflow/Network/Module.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ namespace Networks {
8080

8181
virtual bool hasInputPort(const PortId& id) const;
8282
virtual bool hasOutputPort(const PortId& id) const;
83-
virtual InputPortHandle getInputPort(const PortId& id) const;
83+
virtual InputPortHandle getInputPort(const PortId& id);
8484
virtual OutputPortHandle getOutputPort(const PortId& id) const;
8585
virtual std::vector<InputPortHandle> findInputPortsWithName(const std::string& name) const;
8686
virtual std::vector<OutputPortHandle> findOutputPortsWithName(const std::string& name) const;

src/Dataflow/Network/ModuleInterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ namespace Networks {
6868
virtual std::vector<OutputPortHandle> outputPorts() const = 0;
6969

7070
virtual bool hasInputPort(const PortId& id) const = 0;
71-
virtual InputPortHandle getInputPort(const PortId& id) const = 0;
71+
virtual InputPortHandle getInputPort(const PortId& id) = 0;
7272
virtual std::vector<InputPortHandle> findInputPortsWithName(const std::string& name) const = 0;
7373
virtual size_t num_input_ports() const = 0;
7474
virtual std::vector<InputPortHandle> inputPorts() const = 0;

src/Dataflow/Network/Port.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ using namespace SCIRun::Dataflow::Networks;
4242
using namespace SCIRun::Core::Datatypes;
4343

4444
Port::Port(ModuleInterface* module, const ConstructionParams& params)
45-
: module_(module), id_(params.id_), typeName_(params.type_name), portName_(params.port_name), colorName_(PortColorLookup::toColor(params.type_name))
45+
: module_(module), index_(0), id_(params.id_), typeName_(params.type_name), portName_(params.port_name), colorName_(PortColorLookup::toColor(params.type_name))
4646
{
4747
ENSURE_NOT_NULL(module_, "port cannot have null module");
4848
if (typeName_.empty() || portName_.empty() || colorName_.empty())

src/Dataflow/Network/Port.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class SCISHARE Port : virtual public PortInterface, boost::noncopyable
6262
const Connection* connection(size_t) const;
6363

6464
virtual PortId id() const { return id_; }
65+
virtual void setId(const PortId& id) { id_ = id; }
6566
std::string get_typename() const { return typeName_; }
6667
std::string get_colorname() const { return colorName_; }
6768
std::string get_portname() const { return portName_; }

src/Dataflow/Network/PortInterface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ namespace Networks {
8989
virtual ~OutputPortInterface();
9090
virtual void sendData(Core::Datatypes::DatatypeHandle data) = 0;
9191
virtual bool hasData() const = 0;
92+
virtual OutputPortInterface* clone() const { return 0; } // TODO
9293
};
9394

9495
class SCISHARE PortConnectionDeterminer

src/Dataflow/Network/PortManager.h

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <boost/range/algorithm/copy.hpp>
4141
#include <string>
4242
#include <map>
43+
#include <Dataflow/Network/share.h>
4344

4445
namespace SCIRun {
4546
namespace Dataflow {
@@ -54,13 +55,17 @@ class PortManager : boost::noncopyable
5455
PortMap ports_;
5556
DynamicMap isDynamic_;
5657
ModuleInterface* module_;
57-
58+
void checkDynamicPortInvariant(const std::string& name);
59+
void throwForPortNotFound(const PortId& id) const;
60+
std::vector<T> findAllByName(const std::string& name) const;
61+
5862
public:
5963
PortManager();
6064
size_t size() const;
6165
size_t add(const T& item);
6266
void remove(const PortId& id);
6367
T operator[](const PortId& id);
68+
T operator[](const PortId& id) const;
6469
std::vector<T> operator[](const std::string& name) const;
6570
bool hasPort(const PortId& id) const;
6671
void set_module(ModuleInterface* mod) { module_ = mod; }
@@ -88,12 +93,33 @@ PortManager<T>::add(const T& item)
8893
{
8994
ports_[item->id()] = item;
9095
isDynamic_[item->id().name] = item->isDynamic();
96+
97+
if (item->isDynamic())
98+
checkDynamicPortInvariant(item->id().name);
99+
91100
/// @todo: who should manage port indexes?
92101
//item->setIndex(size() - 1);
93102
auto index = size() - 1;
94103
return index;
95104
}
96105

106+
template<class T>
107+
void
108+
PortManager<T>::checkDynamicPortInvariant(const std::string& name)
109+
{
110+
auto byName = findAllByName(name);
111+
const size_t lastIndex = byName.size() - 1;
112+
std::vector<PortId> toRemove;
113+
for (int i = 0; i < byName.size(); ++i)
114+
{
115+
auto port = byName[i];
116+
if (0 == port->nconnections() && i != lastIndex)
117+
toRemove.push_back(port->id());
118+
}
119+
BOOST_FOREACH(const PortId& id, toRemove)
120+
remove(id);
121+
}
122+
97123
template<class T>
98124
void
99125
PortManager<T>::remove(const PortId& id)
@@ -120,40 +146,55 @@ PortManager<T>::operator[](const PortId& id)
120146
{
121147
if (isDynamic_[id.name])
122148
{
123-
auto byName = this->operator[](id.name);
149+
auto byName = findAllByName(id.name);
124150
if (byName.empty())
125151
{
126-
std::ostringstream ostr;
127-
ostr << "PortManager tried to access a port that does not exist: " << id;
128-
BOOST_THROW_EXCEPTION(PortOutOfBoundsException() << Core::ErrorMessage(ostr.str()));
152+
throwForPortNotFound(id);
129153
}
130-
auto newPort = byName[0]->clone();
154+
auto newPort = boost::shared_ptr<typename T::element_type>(byName[0]->clone());
131155
newPort->setId(id);
132-
add(newPort);
156+
newPort->setIndex(add(newPort));
133157
return newPort;
134158
}
159+
}
160+
return it->second;
161+
}
135162

163+
template<class T>
164+
void
165+
PortManager<T>::throwForPortNotFound(const PortId& id) const
166+
{
167+
std::ostringstream ostr;
168+
ostr << "PortManager tried to access a port that does not exist: " << id;
169+
BOOST_THROW_EXCEPTION(PortOutOfBoundsException() << Core::ErrorMessage(ostr.str()));
170+
}
136171

137-
/// @todo: need a way to detect and create arbitrary dynamic ports from serialized files.
138-
//if (id.dynamic)
139-
// std::cout << "DYNAMIC PORT NEEDS TO INSERT ITSELF HERE SOMEHOW" << std::endl;
140-
//else
141-
// std::cout << "NOT SETTING PORT FLAGS CORRECT" << std::endl;
142-
//std::ostringstream ostr;
143-
//ostr << "PortManager tried to access a port that does not exist: " << id;
144-
//BOOST_THROW_EXCEPTION(PortOutOfBoundsException() << Core::ErrorMessage(ostr.str()));
172+
template<class T>
173+
T
174+
PortManager<T>::operator[](const PortId& id) const
175+
{
176+
auto it = ports_.find(id);
177+
if (it == ports_.end())
178+
{
179+
throwForPortNotFound(id);
145180
}
146181
return it->second;
147182
}
148183

149184
template<class T>
150185
std::vector<T> PortManager<T>::operator[](const std::string& name) const
186+
{
187+
return findAllByName(name);
188+
}
189+
190+
template<class T>
191+
std::vector<T> PortManager<T>::findAllByName(const std::string& name) const
151192
{
152193
std::vector<T> portsWithName;
153194

154195
boost::copy(
155196
ports_ | boost::adaptors::map_values
156-
| boost::adaptors::filtered([&](const T& port) { return port->get_portname() == name; }), std::back_inserter(portsWithName));
197+
| boost::adaptors::filtered([&](const T& port) { return port->get_portname() == name; }), std::back_inserter(portsWithName));
157198

158199
if (portsWithName.empty())
159200
{

src/Dataflow/Network/Tests/MockModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace SCIRun {
5656
MOCK_CONST_METHOD1(findOutputPortsWithName, std::vector<OutputPortHandle>(const std::string&));
5757
MOCK_CONST_METHOD0(outputPorts, std::vector<OutputPortHandle>());
5858
MOCK_CONST_METHOD1(hasInputPort, bool(const PortId&));
59-
MOCK_CONST_METHOD1(getInputPort, InputPortHandle(const PortId&));
59+
MOCK_METHOD1(getInputPort, InputPortHandle(const PortId&));
6060
MOCK_CONST_METHOD1(findInputPortsWithName, std::vector<InputPortHandle>(const std::string&));
6161
MOCK_CONST_METHOD0(inputPorts, std::vector<InputPortHandle>());
6262
MOCK_CONST_METHOD0(num_input_ports, size_t());

src/Dataflow/Network/Tests/MockPorts.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ namespace SCIRun {
7070
MOCK_CONST_METHOD0(getIndex, size_t());
7171
MOCK_CONST_METHOD0(clone, InputPortInterface*());
7272
MOCK_CONST_METHOD0(id, PortId());
73+
MOCK_METHOD1(setId, void(const PortId&));
7374
MOCK_CONST_METHOD0(hasChanged, bool());
7475
MOCK_METHOD1(setIndex, void(size_t));
7576
MOCK_METHOD1(connectDataOnPortHasChanged, boost::signals2::connection(const DataOnPortHasChangedSignalType::slot_type&));
@@ -92,6 +93,7 @@ namespace SCIRun {
9293
MOCK_CONST_METHOD0(getUnderlyingModuleId, ModuleId());
9394
MOCK_CONST_METHOD0(getIndex, size_t());
9495
MOCK_CONST_METHOD0(id, PortId());
96+
MOCK_METHOD1(setId, void(const PortId&));
9597
MOCK_METHOD1(setIndex, void(size_t));
9698
MOCK_CONST_METHOD0(hasData, bool());
9799
};

src/ExampleNets/regression/dynamicPortsSerialization.srn5

Lines changed: 115 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<networkFile class_id="0" tracking_level="0" version="2">
55
<networkInfo class_id="1" tracking_level="0" version="0">
66
<modules class_id="2" tracking_level="0" version="0">
7-
<count>3</count>
7+
<count>4</count>
88
<item_version>0</item_version>
99
<item class_id="3" tracking_level="0" version="0">
1010
<first>CreateLatVol:0</first>
@@ -182,6 +182,94 @@
182182
</state>
183183
</second>
184184
</item>
185+
<item>
186+
<first>CreateLatVol:3</first>
187+
<second>
188+
<module>
189+
<package_name_>SCIRun</package_name_>
190+
<category_name_>NewField</category_name_>
191+
<module_name_>CreateLatVol</module_name_>
192+
</module>
193+
<state>
194+
<stateMap>
195+
<count>6</count>
196+
<item_version>0</item_version>
197+
<item>
198+
<first>
199+
<name>DataAtLocation</name>
200+
</first>
201+
<second>
202+
<name>DataAtLocation</name>
203+
<value>
204+
<which>2</which>
205+
<value>Nodes</value>
206+
</value>
207+
</second>
208+
</item>
209+
<item>
210+
<first>
211+
<name>ElementSizeNormalized</name>
212+
</first>
213+
<second>
214+
<name>ElementSizeNormalized</name>
215+
<value>
216+
<which>3</which>
217+
<value>1</value>
218+
</value>
219+
</second>
220+
</item>
221+
<item>
222+
<first>
223+
<name>PadPercent</name>
224+
</first>
225+
<second>
226+
<name>PadPercent</name>
227+
<value>
228+
<which>1</which>
229+
<value>0</value>
230+
</value>
231+
</second>
232+
</item>
233+
<item>
234+
<first>
235+
<name>XSize</name>
236+
</first>
237+
<second>
238+
<name>XSize</name>
239+
<value>
240+
<which>0</which>
241+
<value>16</value>
242+
</value>
243+
</second>
244+
</item>
245+
<item>
246+
<first>
247+
<name>YSize</name>
248+
</first>
249+
<second>
250+
<name>YSize</name>
251+
<value>
252+
<which>0</which>
253+
<value>16</value>
254+
</value>
255+
</second>
256+
</item>
257+
<item>
258+
<first>
259+
<name>ZSize</name>
260+
</first>
261+
<second>
262+
<name>ZSize</name>
263+
<value>
264+
<which>0</which>
265+
<value>16</value>
266+
</value>
267+
</second>
268+
</item>
269+
</stateMap>
270+
</state>
271+
</second>
272+
</item>
185273
<item>
186274
<first>JoinFields:2</first>
187275
<second>
@@ -272,7 +360,7 @@
272360
</item>
273361
</modules>
274362
<connections class_id="12" tracking_level="0" version="0">
275-
<count>2</count>
363+
<count>3</count>
276364
<item_version>0</item_version>
277365
<item class_id="13" tracking_level="0" version="0">
278366
<moduleId1_>CreateLatVol:0</moduleId1_>
@@ -283,7 +371,7 @@
283371
<moduleId2_>JoinFields:2</moduleId2_>
284372
<port2_>
285373
<name>InputFields</name>
286-
<id>2</id>
374+
<id>5</id>
287375
</port2_>
288376
</item>
289377
<item>
@@ -295,19 +383,31 @@
295383
<moduleId2_>JoinFields:2</moduleId2_>
296384
<port2_>
297385
<name>InputFields</name>
298-
<id>1</id>
386+
<id>4</id>
387+
</port2_>
388+
</item>
389+
<item>
390+
<moduleId1_>CreateLatVol:3</moduleId1_>
391+
<port1_>
392+
<name>OutputField</name>
393+
<id>0</id>
394+
</port1_>
395+
<moduleId2_>JoinFields:2</moduleId2_>
396+
<port2_>
397+
<name>InputFields</name>
398+
<id>3</id>
299399
</port2_>
300400
</item>
301401
</connections>
302402
</networkInfo>
303403
<modulePositions class_id="15" tracking_level="0" version="0">
304-
<count>3</count>
404+
<count>4</count>
305405
<item_version>0</item_version>
306406
<item class_id="16" tracking_level="0" version="0">
307407
<first>CreateLatVol:0</first>
308408
<second class_id="17" tracking_level="0" version="0">
309-
<first>-2052</first>
310-
<second>-988</second>
409+
<first>-2128</first>
410+
<second>-1064</second>
311411
</second>
312412
</item>
313413
<item>
@@ -317,10 +417,17 @@
317417
<second>-988</second>
318418
</second>
319419
</item>
420+
<item>
421+
<first>CreateLatVol:3</first>
422+
<second>
423+
<first>-2508</first>
424+
<second>-1216</second>
425+
</second>
426+
</item>
320427
<item>
321428
<first>JoinFields:2</first>
322429
<second>
323-
<first>-2052</first>
430+
<first>-1976</first>
324431
<second>-760</second>
325432
</second>
326433
</item>

0 commit comments

Comments
 (0)