TestCenter Reference
ChangeSet.py
Go to the documentation of this file.
2# Copyright 2009, MeVis Medical Solutions AG
3#
4# The user may use this file in accordance with the license agreement provided with
5# the Software or, alternatively, in accordance with the terms contained in a
6# written agreement between the user and MeVis Medical Solutions AG.
7#
8# For further information use the contact form at https://www.mevislab.de/contact
9#
10
13
14# -- local imports -----------------------------------------------------------------------------{{{-
15import mevis
16
17# ----------------------------------------------------------------------------------------------}}}-
18
19
20# -- class ChangeSet ---------------------------------------------------------------------------{{{-
21
30 # -- member variables ------------------------------------------------------------------------{{{-
31
32 __changeDict = None
33
34 __changeStack = None
35
36 __ctx = None
37 # --------------------------------------------------------------------------------------------}}}-
38
39 # -- def __init__ ----------------------------------------------------------------------------{{{-
40
42 def __init__(self, context):
43 self.__changeDict = {}
44 self.__changeStack = []
45 self.__ctx = context
46 self.__enableAutoRevert = True
47
48 # --------------------------------------------------------------------------------------------}}}-
49
50 # -- def __del__ -----------------------------------------------------------------------------{{{-
51
53 def __del__(self):
54 self.autoRevert()
55
56 # --------------------------------------------------------------------------------------------}}}-
57
58 # -- def _logInfo ----------------------------------------------------------------------------{{{-
59 def _logInfo(self, message):
60 mevis.MLAB.log(message)
61
62 # --------------------------------------------------------------------------------------------}}}-
63
64 # -- def _logError ---------------------------------------------------------------------------{{{-
65 def _logError(self, message):
66 mevis.MLAB.logError(message)
67
68 # --------------------------------------------------------------------------------------------}}}-
69
70 # -- def setFieldValue -----------------------------------------------------------------------{{{-
71
78 def setFieldValue(self, fieldName, fieldValue, verbose=False) -> bool:
79 if not self.__ctx.hasField(fieldName):
80 if verbose:
81 self._logError("Field %s not found in the used context!" % (fieldName))
82 return False
83 field = self.__ctx.field(fieldName)
84 fieldType = field.type
85 if (fieldType in ("Trigger",)) or fieldValue is None:
86 if verbose:
87 self._logInfo("Touched field %s" % (fieldName))
88 field.touch()
89 else:
90 # Store old field value.
91 oldFieldValue = getFieldValue(field)
92 if fieldName not in self.__changeDict:
93 self.__changeStack.append(fieldName)
94 self.__changeDict.setdefault(fieldName, oldFieldValue)
95 setFieldValue(field, fieldValue)
96 if verbose:
97 self._logInfo("Set field %s to value %s" % (fieldName, fieldValue))
98 return True
99
100 # -- def updateFieldValue -----------------------------------------------------------------------{{{-
101
109 def updateFieldValue(self, fieldName, fieldValue, verbose=False) -> bool:
110 if not self.__ctx.hasField(fieldName):
111 if verbose:
112 self._logError("Field %s not found in the used context!" % (fieldName))
113 return False
114 field = self.__ctx.field(fieldName)
115 fieldType = field.type
116 if (fieldType in ("Trigger",)) or fieldValue is None:
117 if verbose:
118 self._logInfo("Touched field %s" % (fieldName))
119 field.touch()
120 else:
121 # Store old field value.
122 oldFieldValue = getFieldValue(field)
123 if oldFieldValue != fieldValue:
124 if fieldName not in self.__changeDict:
125 self.__changeStack.append(fieldName)
126 self.__changeDict.setdefault(fieldName, oldFieldValue)
127 setFieldValue(field, fieldValue)
128 if verbose:
129 self._logInfo("Set field %s to value %s" % (fieldName, fieldValue))
130 else:
131 if verbose:
132 self._logInfo(
133 "Ensured field %s already has value %s, skipping field touch." % (fieldName, fieldValue)
134 )
135
136 return True
137
138 # --------------------------------------------------------------------------------------------}}}-
139
140 # -- def addField ----------------------------------------------------------------------------{{{-
141
146 def addField(self, fieldName, verbose=False):
147 if not self.__ctx.hasField(fieldName):
148 if verbose:
149 self._logError("Field %s not found in the used context!" % (fieldName))
150 return False
151 field = self.__ctx.field(fieldName)
152 self.__changeDict.setdefault(fieldName, getFieldValue(field))
153 return True
154
155 # --------------------------------------------------------------------------------------------}}}-
156
157 # -- def autoRevert --------------------------------------------------------------------------{{{-
158
159 def autoRevert(self):
160 if self.__enableAutoRevert and self.__ctx: # the module might not exist anymore, so check
161 self.revert()
162
163 # --------------------------------------------------------------------------------------------}}}-
164
165 # -- def revert ------------------------------------------------------------------------------{{{-
166
167 def revert(self):
168 # For each changed field restore the original value.
169 while len(self.__changeStack) > 0:
170 fieldName = self.__changeStack.pop(-1)
171 field = self.__ctx.field(fieldName)
172 setFieldValue(field, self.__changeDict[fieldName])
173 self.__changeDict = {}
174
175 # --------------------------------------------------------------------------------------------}}}-
176
177 def enableAutoRevert(self, enable):
178 # Enable/disable revert on destruction. Can be disabled for debugging purposes (to leave the
179 # network state as it was on error occurrence).
180 self.__enableAutoRevert = enable
181
182 # --------------------------------------------------------------------------------------------}}}-
183
184
185# ----------------------------------------------------------------------------------------------}}}-
186
187
188def getFieldValue(field):
189 if "Vector6" in field.type:
190 return field.stringValue()
191 elif "MLBase" in field.type:
192 return field.object()
193 else:
194 return field.value
195
196
197def setFieldValue(field, fieldValue):
198 if "Vector6" in field.type:
199 if isinstance(fieldValue, (str, bytes)):
200 field.setStringValue(fieldValue)
201 else:
202 field.setVectorValue(fieldValue)
203 elif "MLBase" in field.type:
204 field.setObject(fieldValue)
205 else:
206 field.value = fieldValue
Class to handle field changes and make them revertable.
Definition ChangeSet.py:29
bool setFieldValue(self, fieldName, fieldValue, verbose=False)
Set the value of a field.
Definition ChangeSet.py:78
__del__(self)
The default destructor.
Definition ChangeSet.py:53
addField(self, fieldName, verbose=False)
Add a field and its value without setting it.
Definition ChangeSet.py:146
bool updateFieldValue(self, fieldName, fieldValue, verbose=False)
Updates the value of a field.
Definition ChangeSet.py:109
revert(self)
Revert all changes made.
Definition ChangeSet.py:167
__init__(self, context)
The default constructor.
Definition ChangeSet.py:42
autoRevert(self)
Revert all changes made if auto-revert is enabled.
Definition ChangeSet.py:159
setFieldValue(field, fieldValue)
Definition ChangeSet.py:197