fix copying
This commit is contained in:
		
							parent
							
								
									802ba51875
								
							
						
					
					
						commit
						aa82295182
					
				
					 5 changed files with 55 additions and 36 deletions
				
			
		|  | @ -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. | ||||||
|     Line(g).vec(d, 200 - d) |         g = Group() | ||||||
|  |         for d in range(0, 180, 10): | ||||||
|  |             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 a new issue
	
	 James Turk
						James Turk