Commit da53f1a
committed
Refactor: Move object version checking and migration logic to check_version.py.
Uses the onDocumentRestored() callback to check and migrate object versions when a
document is loaded, instead of doing this in the execute() method of each feature.
Pros:
- ensures that objects are updated as soon as they are loaded, and avoids
unnecessary checks during execution.
Cons:
- Forces all objects from older workbenches to be migrated when a document is
loaded, rather than only when modified.
diff --git a/freecad/gridfinity_workbench/check_version.py b/freecad/gridfinity_workbench/check_version.py
new file mode 100644
index 0000000..48ad36d
--- /dev/null
+++ b/freecad/gridfinity_workbench/check_version.py
@@ -0,0 +1,98 @@
+"""Feature modules contain bins an baseplate objects."""
+
+# ruff: noqa: D101, D102, D107
+
+import FreeCAD as fc # noqa: N813
+
+from . import const
+from .version import __version__
+
+
+def check_object_version(obj: fc.DocumentObject) -> bool:
+ """Check if the object's version matches the current version of the Gridfinity Workbench.
+
+ Returns False if the object's version is different from the current version, indicating that
+ the object needs to be updated.
+ """
+ return str(getattr(obj, "version", "")) == __version__
+
+
+def migrate_object_version(obj: fc.DocumentObject) -> None: # noqa: C901
+ """Update an object from an older version to the current version.
+
+ This function will check the version of the object against the current
+ Gridfinity Workbench version. If they are different, it will update the
+ object to the current version.
+ """
+ if check_object_version(obj):
+ return
+
+ def versiontuple(v: str) -> tuple[int, ...]:
+ return tuple(map(int, (v.split("."))))
+
+ migrated = False
+ if versiontuple(obj.version) < versiontuple("0.11.9"):
+ migrated = True
+ # v0.11.9: Changes to the magnet properties.
+ if not hasattr(obj, "CrushRibsCount"):
+ obj.addProperty(
+ "App::PropertyInteger",
+ "CrushRibsCount",
+ "GridfinityNonStandard",
+ "Number of crush ribs <br><br> default = 12",
+ ).CrushRibsCount = const.CRUSH_RIB_N
+ if not hasattr(obj, "CrushRibsWaviness"):
+ obj.addProperty(
+ "App::PropertyFloatConstraint",
+ "CrushRibsWaviness",
+ "GridfinityNonStandard",
+ "Waviness of crush ribs, from range [0, 1]",
+ ).CrushRibsWaviness = (const.CRUSH_RIB_WAVINESS, 0, 1, 0.05)
+
+ # v0.11.9: MagnetRelief property was renamed to MagnetRemoveChannel
+ if not hasattr(obj, "MagnetRemoveChannel"):
+ obj.addProperty(
+ "App::PropertyBool",
+ "MagnetRemoveChannel",
+ "GridfinityNonStandard",
+ "Toggle the magnet hole remove channel on or off, only used if magnet holes are on",
+ ).MagnetRemoveChannel = getattr(obj, "MagnetRelief", False)
+ if hasattr(obj, "MagnetRelief"):
+ obj.removeProperty("MagnetRelief")
+
+ if versiontuple(obj.version) < versiontuple("0.12.0"):
+ migrated = True
+ # v0.12.0: calculation of UsableHeight was changed to use object Expressions.
+ obj.setExpression("UsableHeight", "TotalHeight - HeightUnitValue")
+
+ # v0.12.0: xGridUnits and yGridUnits were changed from int to float properties.
+ xgridunits = getattr(obj, "xGridUnits", None)
+ if xgridunits is None or isinstance(xgridunits, int):
+ obj.removeProperty("xGridUnits")
+ obj.addProperty(
+ "App::PropertyFloat",
+ "xGridUnits",
+ "Gridfinity",
+ "Number of grid units in the x direction <br> <br> default = 2",
+ ).xGridUnits = float(xgridunits or const.X_GRID_UNITS)
+
+ ygridunits = getattr(obj, "yGridUnits", None)
+ if ygridunits is None or isinstance(ygridunits, int):
+ obj.removeProperty("yGridUnits")
+ obj.addProperty(
+ "App::PropertyFloat",
+ "yGridUnits",
+ "Gridfinity",
+ "Number of grid units in the y direction <br> <br> default = 2",
+ ).yGridUnits = float(ygridunits or const.Y_GRID_UNITS)
+
+ # Update the version property to the current version after updating the object.
+ obj.version = __version__
+
+ if migrated:
+ obj.recompute() # Force re-evaluation of expressions after updating properties.
+ fc.Console.PrintLog(
+ f"Gridfinity Workbench v{__version__}: "
+ f"updating '{obj.Name}' object properties from version v{obj.version}.\n"
+ f"'{obj.Name}' will be saved with v{__version__} properties.\n",
+ )
diff --git a/freecad/gridfinity_workbench/features.py b/freecad/gridfinity_workbench/features.py
index 95087de..dd34974 100644
--- a/freecad/gridfinity_workbench/features.py
+++ b/freecad/gridfinity_workbench/features.py
@@ -8,7 +8,7 @@ import FreeCAD as fc # noqa: N813
import Part
from . import baseplate_feature_construction as baseplate_feat
-from . import const, grid_initial_layout, label_shelf, utils
+from . import check_version, const, grid_initial_layout, label_shelf, utils
from . import feature_construction as feat
from .custom_shape_features import (
clean_up_layout,
@@ -23,58 +23,6 @@ from .version import __version__
unitmm = fc.Units.Quantity("1 mm")
-def update_object_properties_from_older_version(obj: fc.DocumentObject) -> None:
- """Update an object from an older version to the current version.
-
- This function should be called in the execute method of each feature, and will check the
- version of the object against the current Gridfinity Workbench version. If they are different,
- it will update the object to the current version.
- """
- def versiontuple(v: str) -> tuple[int, ...]:
- return tuple(map(int, (v.split("."))))
-
- if versiontuple(obj.version) < versiontuple("0.11.10"):
- # v0.11.10: MagnetRelief property was renamed to MagnetRemoveChannel
- if not hasattr(obj, "MagnetRemoveChannel"):
- obj.addProperty(
- "App::PropertyBool",
- "MagnetRemoveChannel",
- "GridfinityNonStandard",
- "Toggle the magnet hole remove channel on or off, only used if magnet holes are on",
- ).MagnetRemoveChannel = getattr(obj, "MagnetRelief", False)
- if hasattr(obj, "MagnetRelief"):
- obj.removeProperty("MagnetRelief")
-
- if versiontuple(obj.version) < versiontuple("0.12.0"):
- # v0.12.0: calculation of UsableHeight was changed to use object Expressions.
- obj.setExpression("UsableHeight", "TotalHeight - HeightUnitValue")
-
- # v0.12.0: xGridUnits and yGridUnits were changed from int to float properties.
- xgridunits = getattr(obj, "xGridUnits", None)
- if xgridunits is None or isinstance(xgridunits, int):
- obj.removeProperty("xGridUnits")
- obj.addProperty(
- "App::PropertyFloat",
- "xGridUnits",
- "Gridfinity",
- "Number of grid units in the x direction <br> <br> default = 2",
- ).xGridUnits = float(xgridunits or const.X_GRID_UNITS)
-
- ygridunits = getattr(obj, "yGridUnits", None)
- if ygridunits is None or isinstance(ygridunits, int):
- obj.removeProperty("yGridUnits")
- obj.addProperty(
- "App::PropertyFloat",
- "yGridUnits",
- "Gridfinity",
- "Number of grid units in the y direction <br> <br> default = 2",
- ).yGridUnits = float(ygridunits or const.Y_GRID_UNITS)
-
- # Update the version property to the current version after updating the object.
- obj.version = __version__
- obj.recompute() # ensure the object is recomputed after updating properties
-
-
class FoundationGridfinity:
def __init__(self, obj: fc.DocumentObject) -> None:
obj.addProperty(
@@ -87,15 +35,10 @@ class FoundationGridfinity:
obj.Proxy = self
- def execute(self, fp: Part.Feature) -> None:
- if str(getattr(fp, "version", "")) != __version__:
- fc.Console.PrintLog(
- f"Gridfinity Workbench v{__version__}: "
- f"updating '{fp.Name}' object properties from version v{fp.version}.\n"
- f"'{fp.Name}' will be saved with v{__version__} properties.\n",
- )
- update_object_properties_from_older_version(fp)
+ def onDocumentRestored(self, obj: fc.DocumentObject) -> None: # noqa: N802
+ check_version.migrate_object_version(obj)
+ def execute(self, fp: Part.Feature) -> None:
gridfinity_shape = self.generate_gridfinity_shape(fp)
if hasattr(fp, "BaseFeature") and fp.BaseFeature is not None:1 parent 6ecde77 commit da53f1a
2 files changed
Lines changed: 102 additions & 61 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | 26 | | |
79 | 27 | | |
80 | 28 | | |
| |||
87 | 35 | | |
88 | 36 | | |
89 | 37 | | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
| 38 | + | |
| 39 | + | |
98 | 40 | | |
| 41 | + | |
99 | 42 | | |
100 | 43 | | |
101 | 44 | | |
| |||
0 commit comments