fix copying
This commit is contained in:
parent
802ba51875
commit
aa82295182
@ -36,7 +36,11 @@ class Doodle(ABC):
|
|||||||
# All references to _pos_vec are internal to the class,
|
# All references to _pos_vec are internal to the class,
|
||||||
# so it will be trivial to swap this out later.
|
# so it will be trivial to swap this out later.
|
||||||
self._pos_vec = (0, 0)
|
self._pos_vec = (0, 0)
|
||||||
if parent:
|
self._register()
|
||||||
|
|
||||||
|
def _register(self):
|
||||||
|
""" register with parent and world """
|
||||||
|
if self._parent:
|
||||||
# register with parent for updates
|
# register with parent for updates
|
||||||
self._parent.add(self)
|
self._parent.add(self)
|
||||||
world.add(self)
|
world.add(self)
|
||||||
@ -63,20 +67,20 @@ class Doodle(ABC):
|
|||||||
|
|
||||||
Additionally, while a shallow copy is enough for most
|
Additionally, while a shallow copy is enough for most
|
||||||
cases, it will be possible for child classes to override
|
cases, it will be possible for child classes to override
|
||||||
this to opt for a deepcopy or other logic.
|
this.
|
||||||
"""
|
"""
|
||||||
new = copy.copy(self)
|
new = copy.copy(self)
|
||||||
world.add(new)
|
new._register()
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def color(self, r: int, g: int, b: int) -> "Doodle":
|
def color(self, color: tuple[int, int, int]) -> "Doodle":
|
||||||
"""
|
"""
|
||||||
Color works as a kind of setter function.
|
Color works as a kind of setter function.
|
||||||
|
|
||||||
The only unique part is that it returns self, accomodating the
|
The only unique part is that it returns self, accomodating the
|
||||||
chained object pattern.
|
chained object pattern.
|
||||||
"""
|
"""
|
||||||
self._color = (r, g, b)
|
self._color = color
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def pos(self, x: float, y: float) -> "Doodle":
|
def pos(self, x: float, y: float) -> "Doodle":
|
||||||
@ -111,11 +115,11 @@ class Doodle(ABC):
|
|||||||
"""
|
"""
|
||||||
x = random.random() * world.WIDTH
|
x = random.random() * world.WIDTH
|
||||||
y = random.random() * world.HEIGHT
|
y = random.random() * world.HEIGHT
|
||||||
r, g, b = Color.random()
|
color = Color.random()
|
||||||
# again here, we opt to use the setters so that
|
# again here, we opt to use the setters so that
|
||||||
# future extensions to their behavior will be
|
# future extensions to their behavior will be
|
||||||
# used by all downstream functions
|
# used by all downstream functions
|
||||||
return self.pos(x, y).color(r, g, b)
|
return self.pos(x, y).color(color)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def x(self) -> float:
|
def x(self) -> float:
|
||||||
@ -265,10 +269,13 @@ class Group(Doodle):
|
|||||||
in some languages would be much trickier to pull off.
|
in some languages would be much trickier to pull off.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, parent=None):
|
||||||
super().__init__()
|
super().__init__(parent)
|
||||||
self._doodles = []
|
self._doodles = []
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"Group(pos={self.pos_vec}, doodles={len(self._doodles)})"
|
||||||
|
|
||||||
def draw(self, screen):
|
def draw(self, screen):
|
||||||
"""
|
"""
|
||||||
Groups, despite being an abstract concept, are drawable.
|
Groups, despite being an abstract concept, are drawable.
|
||||||
@ -285,11 +292,16 @@ class Group(Doodle):
|
|||||||
|
|
||||||
We are storing a list, so deep copies are necessary.
|
We are storing a list, so deep copies are necessary.
|
||||||
"""
|
"""
|
||||||
new = copy.deepcopy(self)
|
new = copy.copy(self)
|
||||||
world.add(new)
|
new._register()
|
||||||
|
new._doodles = []
|
||||||
|
for child in self._doodles:
|
||||||
|
child = copy.copy(child)
|
||||||
|
child._parent = new
|
||||||
|
child._register()
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def color(self, r: int, g: int, b: int) -> "Doodle":
|
def color(self, color: tuple[int, int, int]) -> "Doodle":
|
||||||
"""
|
"""
|
||||||
Another override.
|
Another override.
|
||||||
|
|
||||||
@ -299,9 +311,9 @@ class Group(Doodle):
|
|||||||
|
|
||||||
We don't cascade pos() calls, why not?
|
We don't cascade pos() calls, why not?
|
||||||
"""
|
"""
|
||||||
super().color(r, g, b)
|
super().color(color)
|
||||||
for d in self._doodles:
|
for d in self._doodles:
|
||||||
d.color(r, g, b)
|
d.color(color)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def add(self, doodle: "Doodle") -> "Group":
|
def add(self, doodle: "Doodle") -> "Group":
|
||||||
@ -338,7 +350,7 @@ class Circle(Doodle):
|
|||||||
self._radius = 0
|
self._radius = 0
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"Circle(pos={self.pos_vec}, radius={self._radius}, {self._color})"
|
return f"Circle(pos={self.pos_vec}, radius={self._radius}, {self._color}, parent={self._parent}))"
|
||||||
|
|
||||||
def draw(self, screen):
|
def draw(self, screen):
|
||||||
pygame.draw.circle(screen, self._color, self.pos_vec, self._radius)
|
pygame.draw.circle(screen, self._color, self.pos_vec, self._radius)
|
||||||
@ -359,4 +371,4 @@ class Circle(Doodle):
|
|||||||
def random(self) -> "Doodle":
|
def random(self) -> "Doodle":
|
||||||
super().random()
|
super().random()
|
||||||
# constrain to 10-100
|
# constrain to 10-100
|
||||||
return self.radius(random.random*90 + 10)
|
return self.radius(random.random()*90 + 10)
|
||||||
|
16
src/doodles/examples/copies.py
Normal file
16
src/doodles/examples/copies.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from doodles.doodles import Group, Line, Circle, Color
|
||||||
|
|
||||||
|
def original():
|
||||||
|
g = Group()
|
||||||
|
c = Circle(g).radius(80).color(Color.RED).pos(0, 0)
|
||||||
|
for _ in range(15):
|
||||||
|
c = c.copy().move(45, 45)
|
||||||
|
return g
|
||||||
|
|
||||||
|
r = original()
|
||||||
|
r.copy().move(200, 0).color(Color.GREEN)
|
||||||
|
r.copy().move(400, 0).color(Color.BLUE)
|
||||||
|
|
||||||
|
# from doodles.world import world
|
||||||
|
# for d in world._drawables:
|
||||||
|
# print(" >", d)
|
@ -1,10 +1,13 @@
|
|||||||
from doodles.doodles import Group, Line
|
from doodles.doodles import Group, Line
|
||||||
from doodles.layouts import make_grid, copies
|
from doodles.layouts import make_grid
|
||||||
|
|
||||||
# Create a group of lines all with same origin, different angles.
|
def same_spiral():
|
||||||
g = Group()
|
while True:
|
||||||
for d in range(0, 180, 10):
|
# Create a group of lines all with same origin, different angles.
|
||||||
|
g = Group()
|
||||||
|
for d in range(0, 180, 10):
|
||||||
Line(g).vec(d, 200 - d)
|
Line(g).vec(d, 200 - d)
|
||||||
|
yield g
|
||||||
|
|
||||||
# Make copies, moving each one and modifying the color
|
# Make copies, moving each one and modifying the color
|
||||||
make_grid(copies(g), 3, 4, 250, 140, x_offset=70, y_offset=20)
|
make_grid(same_spiral(), 3, 4, 250, 140, x_offset=70, y_offset=20)
|
||||||
|
@ -5,21 +5,9 @@ def make_grid(iterable, cols, rows, width, height, *, x_offset=0, y_offset=0):
|
|||||||
Arranges the objects in iterable in a grid with the given parameters.
|
Arranges the objects in iterable in a grid with the given parameters.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
doodle = next(iterable)
|
|
||||||
for c in range(cols):
|
for c in range(cols):
|
||||||
for r in range(rows):
|
for r in range(rows):
|
||||||
doodle.pos(width * c + x_offset, height * r + y_offset)
|
|
||||||
doodle = next(iterable)
|
doodle = next(iterable)
|
||||||
|
doodle.pos(width * c + x_offset, height * r + y_offset)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def copies(doodle):
|
|
||||||
"""
|
|
||||||
Lazily makes an infinite number of copies of a given doodle.
|
|
||||||
|
|
||||||
Can be combined with things like `make_grid` that require
|
|
||||||
an iterable of doodles to repeat.
|
|
||||||
"""
|
|
||||||
while True:
|
|
||||||
yield doodle.copy()
|
|
||||||
|
@ -29,7 +29,7 @@ def main(modname: str):
|
|||||||
pygame.quit()
|
pygame.quit()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
world.render()
|
world.render()
|
||||||
# print(f"world contains {world._drawables}")
|
#print(f"world contains {len(world._drawables)}")
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user