From b0921e10db3b3fc0e9b6330ca9146498bc9d5a15 Mon Sep 17 00:00:00 2001 From: Alina Quereilhac Date: Tue, 5 Jul 2011 12:50:03 +0200 Subject: [PATCH] merged ConnectorTyper for design and execution --- src/nepi/core/connector.py | 80 +++++++++++++++++++++++++++++++---- src/nepi/core/design.py | 38 +++-------------- src/nepi/core/execute.py | 58 ------------------------- src/nepi/core/metadata.py | 43 +++---------------- src/nepi/core/testbed_impl.py | 22 ++++++++-- 5 files changed, 100 insertions(+), 141 deletions(-) diff --git a/src/nepi/core/connector.py b/src/nepi/core/connector.py index e85d2bfd..e8ff719f 100644 --- a/src/nepi/core/connector.py +++ b/src/nepi/core/connector.py @@ -2,31 +2,49 @@ # -*- coding: utf-8 -*- """ -Common connector base classes +Common connector class """ import sys -class ConnectorTypeBase(object): - def __init__(self, testbed_id, factory_id, name, max = -1, min = 0): - super(ConnectorTypeBase, self).__init__() +class ConnectorType(object): + def __init__(self, testbed_id, factory_id, name, help, max = -1, min = 0): + super(ConnectorType, self).__init__() + if max == -1: max = sys.maxint elif max <= 0: raise RuntimeError, "The maximum number of connections allowed need to be more than 0" if min < 0: raise RuntimeError, "The minimum number of connections allowed needs to be at least 0" + # max -- maximum amount of connections that this type support, + # -1 for no limit + self._max = max + # min -- minimum amount of connections required by this type of connector + self._min = min + # connector_type_id -- univoquely identifies a connector type # across testbeds self._connector_type_id = self.make_connector_type_id( testbed_id, factory_id, name) + # name -- display name for the connector type self._name = name - # max -- maximum amount of connections that this type support, - # -1 for no limit - self._max = max - # min -- minimum amount of connections required by this type of connector - self._min = min + + # help -- help text + self._help = help + + # from_connections -- connections where the other connector is the "From" + # to_connections -- connections where the other connector is the "To" + # keys in the dictionary correspond to the + # connector_type_id for possible connections. The value is a tuple: + # (can_cross, connect) + # can_cross: indicates if the connection is allowed accros different + # testbed instances + # code: is the connection function to be invoked when the elements + # are connected + self._from_connections = dict() + self._to_connections = dict() def __str__(self): return "ConnectorType%r" % (self._connector_type_id,) @@ -39,6 +57,10 @@ class ConnectorTypeBase(object): def name(self): return self._name + @property + def help(self): + return self._help + @property def max(self): return self._max @@ -69,4 +91,44 @@ class ConnectorTypeBase(object): if (None, None, name) != connector_type_id: yield (None, None, name) + def add_from_connection(self, testbed_id, factory_id, name, can_cross, + init_code, compl_code): + type_id = self.make_connector_type_id(testbed_id, factory_id, name) + self._from_connections[type_id] = (can_cross, init_code, compl_code) + + def add_to_connection(self, testbed_id, factory_id, name, can_cross, + init_code, compl_code): + type_id = self.make_connector_type_id(testbed_id, factory_id, name) + self._to_connections[type_id] = (can_cross, init_code, compl_code) + + def connect_to_init_code(self, testbed_id, factory_id, name, must_cross): + return self._connect_to_code(testbed_id, factory_id, name, must_cross)[0] + + def connect_to_compl_code(self, testbed_id, factory_id, name, must_cross): + return self._connect_to_code(testbed_id, factory_id, name, must_cross)[1] + + def _connect_to_code(self, testbed_id, factory_id, name, + must_cross): + connector_type_id = self.make_connector_type_id(testbed_id, factory_id, name) + for lookup_type_id in self._type_resolution_order(connector_type_id): + if lookup_type_id in self._to_connections: + (can_cross, init_code, compl_code) = self._to_connections[lookup_type_id] + if not must_cross or can_cross: + return (init_code, compl_code) + else: + return (False, False) + + def can_connect(self, testbed_id, factory_id, name, must_cross): + connector_type_id = self.make_connector_type_id(testbed_id, factory_id, name) + for lookup_type_id in self._type_resolution_order(connector_type_id): + if lookup_type_id in self._from_connections: + (can_cross, init_code, compl_code) = self._from_connections[lookup_type_id] + elif lookup_type_id in self._to_connections: + (can_cross, init_code, compl_code) = self._to_connections[lookup_type_id] + else: + # keep trying + continue + return not must_cross or can_cross + else: + return False diff --git a/src/nepi/core/design.py b/src/nepi/core/design.py index 03d63193..100fff92 100644 --- a/src/nepi/core/design.py +++ b/src/nepi/core/design.py @@ -6,7 +6,7 @@ Experiment design API """ from nepi.core.attributes import AttributesMap, Attribute -from nepi.core.connector import ConnectorTypeBase +from nepi.core.connector import ConnectorType from nepi.core.metadata import Metadata from nepi.util import validation from nepi.util.guid import GuidGenerator @@ -14,35 +14,6 @@ from nepi.util.graphical_info import GraphicalInfo from nepi.util.parser._xml import XmlExperimentParser import sys -class ConnectorType(ConnectorTypeBase): - def __init__(self, testbed_id, factory_id, name, help, max = -1, min = 0): - super(ConnectorType, self).__init__(testbed_id, factory_id, name, max, min) - - # help -- help text - self._help = help - - # allowed_connections -- keys in the dictionary correspond to the - # connector_type_id for possible connections. The value indicates if - # the connection is allowed accros different testbed instances - self._allowed_connections = dict() - - @property - def help(self): - return self._help - - def add_allowed_connection(self, testbed_id, factory_id, name, can_cross): - type_id = self.make_connector_type_id(testbed_id, factory_id, name) - self._allowed_connections[type_id] = can_cross - - def can_connect(self, connector_type_id, testbed_guid1, testbed_guid2): - for lookup_type_id in self._type_resolution_order(connector_type_id): - if lookup_type_id in self._allowed_connections: - can_cross = self._allowed_connections[lookup_type_id] - if can_cross or (testbed_guid1 == testbed_guid2): - return True - else: - return False - class Connector(object): """A Connector sepcifies the connection points in an Object""" def __init__(self, box, connector_type): @@ -100,11 +71,12 @@ class Connector(object): return False if self.is_connected(connector): return False - connector_type_id = connector.connector_type.connector_type_id + (testbed_id, factory_id, name) = connector.connector_type.connector_type_id testbed_guid1 = self.box.testbed_guid testbed_guid2 = connector.box.testbed_guid - return self.connector_type.can_connect(connector_type_id, - testbed_guid1, testbed_guid2) + must_cross = (testbed_guid1 != testbed_guid2) + return self.connector_type.can_connect(testbed_id, factory_id, name, + must_cross) def destroy(self): for connector in self.connections: diff --git a/src/nepi/core/execute.py b/src/nepi/core/execute.py index 5a191aef..8c97638c 100644 --- a/src/nepi/core/execute.py +++ b/src/nepi/core/execute.py @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- from nepi.core.attributes import Attribute, AttributesMap -from nepi.core.connector import ConnectorTypeBase from nepi.util import validation from nepi.util.constants import ApplicationStatus as AS, TIME_NOW from nepi.util.parser._xml import XmlExperimentParser @@ -18,63 +17,6 @@ ATTRIBUTE_PATTERN_BASE = re.compile(r"\{#\[(?P