Skip to content

Commit 08bd8f6

Browse files
committed
prepare for callbacks on modification of ctrlpts and weights arrays
1 parent 8f4f3bd commit 08bd8f6

File tree

3 files changed

+71
-14
lines changed

3 files changed

+71
-14
lines changed

geomdl/NURBS.py

+13-12
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ def ctrlpts(self):
127127
# Populate the cache, if necessary
128128
if not self._cache['ctrlpts']:
129129
c, w = compatibility.separate_ctrlpts_weights(self._control_points)
130-
self._cache['ctrlpts'] = [crd for crd in c]
131-
self._cache['weights'] = w
130+
self._cache['ctrlpts'] = self._array_type(iter(c))
131+
self._cache['weights'] = self._array_type(iter(w))
132132
return self._cache['ctrlpts']
133133

134134
@ctrlpts.setter
@@ -159,8 +159,8 @@ def weights(self):
159159
# Populate the cache, if necessary
160160
if not self._cache['weights']:
161161
c, w = compatibility.separate_ctrlpts_weights(self._control_points)
162-
self._cache['ctrlpts'] = [crd for crd in c]
163-
self._cache['weights'] = w
162+
self._cache['ctrlpts'] = self._array_type(iter(c))
163+
self._cache['weights'] = self._array_type(iter(w))
164164
return self._cache['weights']
165165

166166
@weights.setter
@@ -192,6 +192,7 @@ def reset(self, **kwargs):
192192
if reset_ctrlpts:
193193
# Delete the caches
194194
self._cache['ctrlpts'] = self._init_array()
195+
# TODO: why is this reset differently from the initialisation?
195196
self._cache['weights'][:] = self._init_array()
196197

197198

@@ -330,8 +331,8 @@ def ctrlpts(self):
330331
"""
331332
if not self._cache['ctrlpts']:
332333
c, w = compatibility.separate_ctrlpts_weights(self._control_points)
333-
self._cache['ctrlpts'] = [crd for crd in c]
334-
self._cache['weights'] = w
334+
self._cache['ctrlpts'] = self._array_type(iter(c))
335+
self._cache['weights'] = self._array_type(iter(w))
335336
return self._cache['ctrlpts']
336337

337338
@ctrlpts.setter
@@ -361,8 +362,8 @@ def weights(self):
361362
"""
362363
if not self._cache['weights']:
363364
c, w = compatibility.separate_ctrlpts_weights(self._control_points)
364-
self._cache['ctrlpts'] = [crd for crd in c]
365-
self._cache['weights'] = w
365+
self._cache['ctrlpts'] = self._array_type(iter(c))
366+
self._cache['weights'] = self._array_type(iter(w))
366367
return self._cache['weights']
367368

368369
@weights.setter
@@ -518,8 +519,8 @@ def ctrlpts(self):
518519
"""
519520
if not self._cache['ctrlpts']:
520521
c, w = compatibility.separate_ctrlpts_weights(self._control_points)
521-
self._cache['ctrlpts'] = [crd for crd in c]
522-
self._cache['weights'] = w
522+
self._cache['ctrlpts'] = self._array_type(iter(c))
523+
self._cache['weights'] = self._array_type(iter(w))
523524
return self._cache['ctrlpts']
524525

525526
@ctrlpts.setter
@@ -549,8 +550,8 @@ def weights(self):
549550
"""
550551
if not self._cache['weights']:
551552
c, w = compatibility.separate_ctrlpts_weights(self._control_points)
552-
self._cache['ctrlpts'] = [crd for crd in c]
553-
self._cache['weights'] = w
553+
self._cache['ctrlpts'] = self._array_type(iter(c))
554+
self._cache['weights'] = self._array_type(iter(w))
554555
return self._cache['weights']
555556

556557
@weights.setter

geomdl/_collections.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# callback handlers for list modification
2+
# https://stackoverflow.com/a/13259435/1162349
3+
4+
import sys
5+
6+
_pyversion = sys.version_info[0]
7+
8+
def callback_method(func):
9+
def notify(self,*args,**kwargs):
10+
for _,callback in self._callbacks:
11+
callback()
12+
return func(self,*args,**kwargs)
13+
return notify
14+
15+
class NotifyList(list):
16+
extend = callback_method(list.extend)
17+
append = callback_method(list.append)
18+
remove = callback_method(list.remove)
19+
pop = callback_method(list.pop)
20+
__delitem__ = callback_method(list.__delitem__)
21+
__setitem__ = callback_method(list.__setitem__)
22+
__iadd__ = callback_method(list.__iadd__)
23+
__imul__ = callback_method(list.__imul__)
24+
25+
#Take care to return a new NotifyList if we slice it.
26+
if _pyversion < 3:
27+
__setslice__ = callback_method(list.__setslice__)
28+
__delslice__ = callback_method(list.__delslice__)
29+
def __getslice__(self,*args):
30+
return self.__class__(list.__getslice__(self,*args))
31+
32+
def __getitem__(self,item):
33+
if isinstance(item,slice):
34+
return self.__class__(list.__getitem__(self,item))
35+
else:
36+
return list.__getitem__(self,item)
37+
38+
def __init__(self,*args):
39+
list.__init__(self,*args)
40+
self._callbacks = []
41+
self._callback_cntr = 0
42+
43+
def register_callback(self,cb):
44+
self._callbacks.append((self._callback_cntr,cb))
45+
self._callback_cntr += 1
46+
return self._callback_cntr - 1
47+
48+
def unregister_callback(self,cbid):
49+
for idx,(i,cb) in enumerate(self._callbacks):
50+
if i == cbid:
51+
self._callbacks.pop(idx)
52+
return cb
53+
else:
54+
return None
55+

geomdl/abstract.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from .six import add_metaclass
1212
from . import vis, helpers, knotvector, voxelize, utilities, tessellate
1313
from .base import GeomdlBase, GeomdlEvaluator, GeomdlError, GeomdlWarning, GeomdlTypeSequence
14+
from ._collections import NotifyList
1415

1516

1617
@add_metaclass(abc.ABCMeta)
@@ -34,9 +35,9 @@ class Geometry(GeomdlBase):
3435
# __slots__ = ('_iter_index', '_array_type', '_eval_points')
3536

3637
def __init__(self, *args, **kwargs):
37-
self._geometry_type = "default" if not hasattr(self, '_geometry_type') else self._geometry_type # geometry type
3838
super(Geometry, self).__init__(*args, **kwargs)
39-
self._array_type = list if not hasattr(self, '_array_type') else self._array_type # array storage type
39+
self._geometry_type = getattr(self, '_geometry_type', 'default') # geometry type
40+
self._array_type = getattr(self, '_array_type', NotifyList) # array storage type
4041
self._eval_points = self._init_array() # evaluated points
4142

4243
def __iter__(self):

0 commit comments

Comments
 (0)