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 self._logError("Field %s not found in the used context!" % (fieldName))
81 return False
82 field = self.__ctx.field(fieldName)
83 fieldType = field.type
84 if (fieldType in ("Trigger",)) or fieldValue is None:
85 if verbose:
86 self._logInfo("Touched field %s" % (fieldName))
87 field.touch()
88 else:
89 # Store old field value.
90 oldFieldValue = getFieldValue(field)
91 if fieldName not in self.__changeDict:
92 self.__changeStack.append(fieldName)
93 self.__changeDict.setdefault(fieldName, oldFieldValue)
94 setFieldValue(field, fieldValue)
95 if verbose:
96 self._logInfo("Set field %s to value %s" % (fieldName, fieldValue))
97 return True
98
99 # -- def updateFieldValue -----------------------------------------------------------------------{{{-
100
108 def updateFieldValue(self, fieldName, fieldValue, verbose=False) -> bool:
109 if not self.__ctx.hasField(fieldName):
110 self._logError("Field %s not found in the used context!" % (fieldName))
111 return False
112 field = self.__ctx.field(fieldName)
113 fieldType = field.type
114 if (fieldType in ("Trigger",)) or fieldValue is None:
115 if verbose:
116 self._logInfo("Touched field %s" % (fieldName))
117 field.touch()
118 else:
119 # Store old field value.
120 oldFieldValue = getFieldValue(field)
121 if oldFieldValue != fieldValue:
122 if fieldName not in self.__changeDict:
123 self.__changeStack.append(fieldName)
124 self.__changeDict.setdefault(fieldName, oldFieldValue)
125 setFieldValue(field, fieldValue)
126 if verbose:
127 self._logInfo("Set field %s to value %s" % (fieldName, fieldValue))
128 else:
129 if verbose:
130 self._logInfo(
131 "Ensured field %s already has value %s, skipping field touch." % (fieldName, fieldValue)
132 )
133
134 return True
135
136 # --------------------------------------------------------------------------------------------}}}-
137
138 # -- def addField ----------------------------------------------------------------------------{{{-
139
144 def addField(self, fieldName, verbose=False):
145 if not self.__ctx.hasField(fieldName):
146 self._logError("Field %s not found in the used context!" % (fieldName))
147 return False
148 field = self.__ctx.field(fieldName)
149 self.__changeDict.setdefault(fieldName, getFieldValue(field))
150 return True
151
152 # --------------------------------------------------------------------------------------------}}}-
153
154 # -- def autoRevert --------------------------------------------------------------------------{{{-
155
156 def autoRevert(self):
157 if self.__enableAutoRevert and self.__ctx: # the module might not exist anymore, so check
158 self.revert()
159
160 # --------------------------------------------------------------------------------------------}}}-
161
162 # -- def revert ------------------------------------------------------------------------------{{{-
163
164 def revert(self):
165 # For each changed field restore the original value.
166 while len(self.__changeStack) > 0:
167 fieldName = self.__changeStack.pop(-1)
168 field = self.__ctx.field(fieldName)
169 setFieldValue(field, self.__changeDict[fieldName])
170 self.__changeDict = {}
171
172 # --------------------------------------------------------------------------------------------}}}-
173
174 def enableAutoRevert(self, enable):
175 # Enable/disable revert on destruction. Can be disabled for debugging purposes (to leave the
176 # network state as it was on error occurrence).
177 self.__enableAutoRevert = enable
178
179 # --------------------------------------------------------------------------------------------}}}-
180
181
182# ----------------------------------------------------------------------------------------------}}}-
183
184
185def getFieldValue(field):
186 if "Vector6" in field.type:
187 return field.stringValue()
188 elif "MLBase" in field.type:
189 return field.object()
190 else:
191 return field.value
192
193
194def setFieldValue(field, fieldValue):
195 if "Vector6" in field.type:
196 if isinstance(fieldValue, (str, bytes)):
197 field.setStringValue(fieldValue)
198 else:
199 field.setVectorValue(fieldValue)
200 elif "MLBase" in field.type:
201 field.setObject(fieldValue)
202 else:
203 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:144
bool updateFieldValue(self, fieldName, fieldValue, verbose=False)
Updates the value of a field.
Definition ChangeSet.py:108
revert(self)
Revert all changes made.
Definition ChangeSet.py:164
__init__(self, context)
The default constructor.
Definition ChangeSet.py:42
autoRevert(self)
Revert all changes made if auto-revert is enabled.
Definition ChangeSet.py:156
setFieldValue(field, fieldValue)
Definition ChangeSet.py:194