Skip to content

Commit

Permalink
Make the tolerance class a singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
tomvanmele committed Apr 29, 2024
1 parent c2516e9 commit ceb1469
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `compas.colors.Color.contrast`.
* Added `compas.geometry.Brep.from_plane`.
* Added `compas.tolerance.Tolerance.angulardeflection`.
* Added `compas.tolerance.Tolerance.update_from_dict`.

### Changed

Expand All @@ -34,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Changed use of `compas.geometry.allclose` to `compas.tolerance.TOL.is_allclose`.
* Changed use of `compas.geometry.close` to `compas.tolerance.TOL.is_close`.
* Changed imports of itertools to `compas.itertools` instead of `compas.utilities`.
* Changed `compas.tolerance.Tolerance` to a singleton, to ensure having only library-wide tolerance values.

### Removed

Expand Down
72 changes: 54 additions & 18 deletions src/compas/tolerance.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class Tolerance(Data):
This value is called the "true value".
By convention, the second value is considered the "true value" by the comparison functions of this class.
The :class:`compas.tolerance.Tolerance` class is implemented using a "singleton" pattern and can therefore have only 1 (one) instance per context.
Usage of :attr:`compas.tolerance.TOL` outside of :mod:`compas` internals is therefore deprecated.
Examples
--------
>>> tol = Tolerance()
Expand All @@ -67,6 +70,9 @@ class Tolerance(Data):
"""

_instance = None
_is_inited = False

ABSOLUTE = 1e-9
"""float: Determines when a number is small enough to be considered zero.
"""
Expand Down Expand Up @@ -108,8 +114,9 @@ class Tolerance(Data):
"""

def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
cls._instance = super(Tolerance, cls).__new__(cls)
if not isinstance(cls._instance, cls):
cls._instance = object.__new__(cls, *args, **kwargs)
cls._inited = False
return cls._instance

@property
Expand Down Expand Up @@ -151,22 +158,34 @@ def __init__(
name=None,
):
super(Tolerance, self).__init__(name=name)
self._unit = None
self._absolute = None
self._relative = None
self._angular = None
self._approximation = None
self._precision = None
self._lineardeflection = None
self._angulardeflection = None
self.unit = unit
self.absolute = absolute
self.relative = relative
self.angular = angular
self.approximation = approximation
self.precision = precision
self.lineardeflection = lineardflection
self.angulardeflection = angulardflection
if not self._is_inited:
self._unit = None
self._absolute = None
self._relative = None
self._angular = None
self._approximation = None
self._precision = None
self._lineardeflection = None
self._angulardeflection = None

self._is_inited = True

if unit is not None:
self.unit = unit
if absolute is not None:
self.absolute = absolute
if relative is not None:
self.relative = relative
if angular is not None:
self.angular = angular
if approximation is not None:
self.approximation = approximation
if precision is not None:
self.precision = precision
if lineardflection is not None:
self.lineardeflection = lineardflection
if angulardflection is not None:
self.angulardeflection = angulardflection

# this can be autogenerated if we use slots
# __repr__: return f"{__class__.__name__}({', '.join(f'{k}={v!r}' for k, v in self.__dict__.items())})}"
Expand All @@ -193,6 +212,23 @@ def reset(self):
self._lineardeflection = None
self._angulardeflection = None

def update_from_dict(self, tolerance):
"""Update the tolerance singleton from the key-value pairs found in a dict.
Parameters
----------
tolerance : dict
A dictionary containing named tolerance values.
Returns
-------
None
"""
for name in tolerance:
if hasattr(self, name):
setattr(self, name, tolerance[name])

@property
def units(self):
return self._unit
Expand Down

0 comments on commit ceb1469

Please sign in to comment.