Skip to content

Commit

Permalink
release 0.10.1a1
Browse files Browse the repository at this point in the history
  • Loading branch information
hx2A committed Mar 30, 2024
1 parent db0b48a commit 9f6024e
Show file tree
Hide file tree
Showing 17 changed files with 915 additions and 843 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Have a comment or question? We'd love to hear from you! The best ways to reach o
* github [discussions](https://github.com/py5coding/py5generator/discussions) and [issues](https://github.com/py5coding/py5generator/issues)
* Mastodon <a rel="me" href="https://fosstodon.org/@py5coding">fosstodon.org/@py5coding</a>
* twitter [@py5coding](https://twitter.com/py5coding)
* [processing foundation discourse](https://discourse.processing.org/)
* [processing foundation discourse](https://discourse.processing.org/c/28)

[processing]: https://github.com/processing/processing4
[jpype]: https://github.com/jpype-project/jpype
Expand Down
1,508 changes: 760 additions & 748 deletions py5/__init__.py

Large diffs are not rendered by default.

Binary file modified py5/jars/py5.jar
Binary file not shown.
38 changes: 22 additions & 16 deletions py5/mixins/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ def load_strings(
) -> list[str]:
"""Load a list of strings from a file or URL.
Underlying Processing method: Sketch.loadStrings
Parameters
----------
Expand Down Expand Up @@ -189,8 +187,6 @@ def save_strings(
) -> None:
"""Save a list of strings to a file.
Underlying Processing method: Sketch.saveStrings
Parameters
----------
Expand Down Expand Up @@ -229,8 +225,6 @@ def load_bytes(
) -> bytearray:
"""Load byte data from a file or URL.
Underlying Processing method: Sketch.loadBytes
Parameters
----------
Expand Down Expand Up @@ -277,8 +271,6 @@ def save_bytes(
) -> None:
"""Save byte data to a file.
Underlying Processing method: Sketch.saveBytes
Parameters
----------
Expand All @@ -305,8 +297,6 @@ def save_bytes(
def load_pickle(self, pickle_path: Union[str, Path]) -> Any:
"""Load a pickled Python object from a file.
Underlying Processing method: Sketch.loadPickle
Parameters
----------
Expand All @@ -321,7 +311,16 @@ def load_pickle(self, pickle_path: Union[str, Path]) -> Any:
path.
There are security risks associated with Python pickle files. A pickle file can
contain malicious code, so never load a pickle file from an untrusted source."""
contain malicious code, so never load a pickle file from an untrusted source.
When using py5 in imported mode, pickling will not work on objects instantiated
from new classes you have defined yourself on the main sketch file. This applies
to py5's `save_pickle()` and `load_pickle()` methods, as well as the Python's
standard library pickle module methods they depend upon. If you need to pickle
objects from classes you defined, move the class definitions to a different .py
file that you import as a module or import the classes from. Otherwise, you
could also try using module mode if you want to use pickle with your classes and
keep all the sketch code in a single file."""
path = Path(pickle_path)
if not path.is_absolute():
cwd = self.sketch_path()
Expand All @@ -338,8 +337,6 @@ def load_pickle(self, pickle_path: Union[str, Path]) -> Any:
def save_pickle(self, obj: Any, filename: Union[str, Path]) -> None:
"""Pickle a Python object to a file.
Underlying Processing method: Sketch.savePickle
Parameters
----------
Expand All @@ -356,10 +353,19 @@ def save_pickle(self, obj: Any, filename: Union[str, Path]) -> None:
be saved relative to the current working directory (`sketch_path()`). The saved
file can be reloaded with `load_pickle()`.
Object "pickling" is a method for serializing objects and saving them to a file
for later retrieval. The recreated objects will be clones of the original
Object "pickling" is a technique for serializing objects and saving them to a
file for later retrieval. The recreated objects will be clones of the original
objects. Not all Python objects can be saved to a Python pickle file. This
limitation prevents any py5 object from being pickled."""
limitation prevents any py5 object from being pickled.
When using py5 in imported mode, pickling will not work on objects instantiated
from new classes you have defined yourself on the main sketch file. This applies
to py5's `save_pickle()` and `load_pickle()` methods, as well as the Python's
standard library pickle module methods they depend upon. If you need to pickle
objects from classes you defined, move the class definitions to a different .py
file that you import as a module or import the classes from. Otherwise, you
could also try using module mode if you want to use pickle with your classes and
keep all the sketch code in a single file."""
path = Path(filename)
if not path.is_absolute():
path = self.sketch_path() / filename
Expand Down
12 changes: 6 additions & 6 deletions py5/mixins/math.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def constrain(
low: Union[float, npt.NDArray],
high: Union[float, npt.NDArray],
) -> Union[float, npt.NDArray]:
"""Constrains a value to not exceed a maximum and minimum value.
"""Constrains a value between a minimum and maximum value.
Parameters
----------
Expand All @@ -286,15 +286,15 @@ def constrain(
the value to constrain
high: Union[float, npt.NDArray]
minimum limit
maximum limit
low: Union[float, npt.NDArray]
maximum limit
minimum limit
Notes
-----
Constrains a value to not exceed a maximum and minimum value."""
Constrains a value between a minimum and maximum value."""
return np.where(amt < low, low, np.where(amt > high, high, amt))

@classmethod
Expand Down Expand Up @@ -733,7 +733,7 @@ def floor(cls, value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]:
parameter.
This function makes a call to the numpy `floor()` function."""
return np.floor(value).astype(np.int_)
return np.floor(value).astype(np.int64)

@classmethod
def ceil(cls, value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]:
Expand All @@ -753,7 +753,7 @@ def ceil(cls, value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]:
the parameter.
This function makes a call to the numpy `ceil()` function."""
return np.ceil(value).astype(np.int_)
return np.ceil(value).astype(np.int64)

@classmethod
def exp(cls, value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]:
Expand Down
40 changes: 32 additions & 8 deletions py5/mixins/pixels.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# *****************************************************************************
from __future__ import annotations

import tempfile
import threading
from io import BytesIO
from pathlib import Path
Expand All @@ -30,6 +31,7 @@
from PIL import Image
from PIL.Image import Image as PIL_Image

from .. import bridge
from ..decorators import _hex_converter

_Sketch = jpype.JClass("py5.core.Sketch")
Expand Down Expand Up @@ -679,14 +681,36 @@ def save(
if isinstance(self._instance, _Sketch)
else self._instance.parent
)
if not isinstance(filename, BytesIO):
filename = Path(str(sketch_instance.savePath(str(filename))))
self.load_np_pixels()
arr = (
self.np_pixels[:, :, 1:]
if drop_alpha
else np.roll(self.np_pixels, -1, axis=2)
)
if (
isinstance(self._instance, _Sketch)
and bridge.check_run_method_callstack()
and self._py5_bridge.current_running_method not in ["setup", "draw"]
):
if (
drop_alpha
# and not use_thread # ignore use_thread because the alternative is always slower
and format is None
and isinstance((filename_param := Path(str(filename))), (str, Path))
and filename_param.suffix.lower() in [".jpg", ".jpeg", ".png"]
):
self._instance.save(filename)
return

with tempfile.TemporaryDirectory() as td:
temp_filename = Path(td) / "temp.png"
self._instance.save(temp_filename)
arr = np.asarray(Image.open(temp_filename))
if not drop_alpha:
arr = np.dstack([arr, np.full(arr.shape[:2], 255, dtype=np.uint8)])
else:
if not isinstance(filename, BytesIO):
filename = Path(str(sketch_instance.savePath(str(filename))))
self.load_np_pixels()
arr = (
self.np_pixels[:, :, 1:]
if drop_alpha
else np.roll(self.np_pixels, -1, axis=2)
)

if use_thread:

Expand Down
3 changes: 3 additions & 0 deletions py5/mouseevent.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ def get_count(self) -> int:
Get the number of mouse clicks. This will be 1 for a single mouse click and 2
for a double click. The value can be much higher if the user clicks fast enough.
This method also responds to the mouse wheel. It will be 1 when the mouse wheel
is rotating down and -1 when the mouse wheel is rotating up.
"""
return self._instance.getCount()

Expand Down
29 changes: 15 additions & 14 deletions py5/reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
settings=[0],
setup=[0],
draw=[0],
predraw_update=[0],
pre_draw=[0],
post_draw=[0],
key_pressed=[0, 1],
Expand Down Expand Up @@ -246,14 +247,22 @@
(('Sketch', 'save_bytes'), ['(bytes_data: Union[bytes, bytearray], filename: Union[str, Path]) -> None']),
(('Sketch', 'load_pickle'), ['(pickle_path: Union[str, Path]) -> Any']),
(('Sketch', 'save_pickle'), ['(obj: Any, filename: Union[str, Path]) -> None']),
(('Sketch', 'set_println_stream'), ['(println_stream: Any) -> None']),
(('Sketch', 'println'), ['(*args, sep: str = " ", end: str = "\\n", stderr: bool = False) -> None']),
(('Sketch', 'launch_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None, ) -> str']),
(('Sketch', 'launch_promise_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None, ) -> Py5Promise']),
(('Sketch', 'launch_repeating_thread'), ['(f: Callable, name: str = None, *, time_delay: float = 0, daemon: bool = True, args: tuple = None, kwargs: dict = None, ) -> str']),
(('Sketch', 'has_thread'), ['(name: str) -> None']),
(('Sketch', 'join_thread'), ['(name: str, *, timeout: float = None) -> bool']),
(('Sketch', 'stop_thread'), ['(name: str, wait: bool = False) -> None']),
(('Sketch', 'stop_all_threads'), ['(wait: bool = False) -> None']),
(('Sketch', 'list_threads'), ['() -> None']),
(('Sketch', 'load_np_pixels'), ['() -> None']),
(('Sketch', 'update_np_pixels'), ['() -> None']),
(('Sketch', 'set_np_pixels'), ['(array: npt.NDArray[np.uint8], bands: str = "ARGB") -> None']),
(('Sketch', 'get_np_pixels'), ['(*, bands: str = "ARGB", dst: npt.NDArray[np.uint8] = None) -> npt.NDArray[np.uint8]', '(x: int, y: int, w: int, h: int, /, *, bands: str = "ARGB", dst: npt.NDArray[np.uint8] = None, ) -> npt.NDArray[np.uint8]']),
(('Sketch', 'to_pil'), ['() -> PIL_Image', '(x: int, y: int, w: int, h: int, /) -> PIL_Image']),
(('Sketch', 'save'), ['(filename: Union[str, Path, BytesIO], *, format: str = None, drop_alpha: bool = True, use_thread: bool = False, **params, ) -> None']),
(('Sketch', 'set_println_stream'), ['(println_stream: Any) -> None']),
(('Sketch', 'println'), ['(*args, sep: str = " ", end: str = "\\n", stderr: bool = False) -> None']),
(('Sketch', 'hex_color'), ['(color: int) -> str']),
(('Sketch', 'sin'), ['(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]']),
(('Sketch', 'cos'), ['(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]']),
Expand Down Expand Up @@ -284,14 +293,6 @@
(('Sketch', 'random_gaussian'), ['() -> float', '(loc: float, /) -> float', '(loc: float, scale: float, /) -> float']),
(('Sketch', 'noise'), ['(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /, ) -> Union[float, npt.NDArray]']),
(('Sketch', 'os_noise'), ['(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /, ) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /, ) -> Union[float, npt.NDArray]']),
(('Sketch', 'launch_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None, ) -> str']),
(('Sketch', 'launch_promise_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None, ) -> Py5Promise']),
(('Sketch', 'launch_repeating_thread'), ['(f: Callable, name: str = None, *, time_delay: float = 0, daemon: bool = True, args: tuple = None, kwargs: dict = None, ) -> str']),
(('Sketch', 'has_thread'), ['(name: str) -> None']),
(('Sketch', 'join_thread'), ['(name: str, *, timeout: float = None) -> bool']),
(('Sketch', 'stop_thread'), ['(name: str, wait: bool = False) -> None']),
(('Sketch', 'stop_all_threads'), ['(wait: bool = False) -> None']),
(('Sketch', 'list_threads'), ['() -> None']),
(('Sketch', 'sketch_path'), ['() -> Path', '(where: str, /) -> Path']),
(('Sketch', 'hot_reload_draw'), ['(draw: Callable) -> None']),
(('Sketch', 'profile_functions'), ['(function_names: list[str]) -> None']),
Expand Down Expand Up @@ -609,8 +610,8 @@
(('Py5Vector', 'normalize'), ['() -> Py5Vector']),
(('Py5Vector', 'set_limit'), ['(max_mag: float) -> Py5Vector']),
(('Py5Vector', 'set_heading'), ['(*heading) -> Py5Vector']),
(('Py5Vector', 'from_heading'), ['(*heading, dtype: int = np.float_) -> Py5Vector']),
(('Py5Vector', 'random'), ['(dim: int, *, dtype: type = np.float_) -> Py5Vector']),
(('Py5Vector', 'from_heading'), ['(*heading, dtype: int = np.float64) -> Py5Vector']),
(('Py5Vector', 'random'), ['(dim: int, *, dtype: type = np.float64) -> Py5Vector']),
(('Py5Vector', 'rotate'), ['(angle: float) -> Py5Vector2D', '(angle: float, dim: Union[int, str]) -> Py5Vector3D']),
(('Py5Vector', 'rotate_around'), ['(angle: float, v: Py5Vector3D) -> Py5Vector3D']),
(('Py5Graphics', 'points'), ['(coordinates: npt.NDArray[np.floating], /) -> None']),
Expand All @@ -627,7 +628,7 @@
(('Py5Shape', 'bezier_vertices'), ['(coordinates: npt.NDArray[np.floating], /) -> None']),
(('Py5Shape', 'curve_vertices'), ['(coordinates: npt.NDArray[np.floating], /) -> None']),
(('Py5Shape', 'quadratic_vertices'), ['(coordinates: npt.NDArray[np.floating], /) -> None']),
(('Sketch', 'run_sketch'), ['(block: bool = None, *, py5_options: list[str] = None, sketch_args: list[str] = None, sketch_functions: dict[str, Callable] = None, jclassname: str = None) -> None']),
(('Sketch', 'run_sketch'), ['(block: bool = None, *, py5_options: list[str] = None, sketch_args: list[str] = None, sketch_functions: dict[str, Callable] = None, jclassname: str = None, jclass_params: tuple[Any] = ()) -> None']),
(('Py5Functions', 'create_font_file'), ['(font_name: str, font_size: int, filename: str = None, characters: str = None, pause: bool = True) -> None']),
(('Py5Functions', 'get_current_sketch'), ['() -> Sketch']),
(('Py5Functions', 'reset_py5'), ['(jclassname: str = None) -> bool']),
Expand All @@ -649,6 +650,6 @@
(('Py5Tools', 'screenshot'), ['(*, sketch: Sketch = None, hook_post_draw: bool = False) -> PIL_Image']),
(('Py5Tools', 'save_frames'), ['(dirname: str, *, filename: str = "frame_####.png", period: float = 0.0, start: int = None, limit: int = 0, sketch: Sketch = None, hook_post_draw: bool = False, block: bool = False, display_progress: bool = True) -> None']),
(('Py5Tools', 'animated_gif'), ['(filename: str, *, count: int = 0, period: float = 0.0, frame_numbers: Iterable = None, duration: float = 0.0, loop: int = 0, optimize: bool = True, sketch: Sketch = None, hook_post_draw: bool = False, block: bool = False) -> None']),
(('Py5Tools', 'offline_frame_processing'), ['(func: Callable[[npt.NDArray[np.uint8]], None], *, limit: int = 0, period: float = 0.0, batch_size: int = 1, complete_func: Callable[[], None] = None, stop_processing_func: Callable[[], bool] = None, sketch: Sketch = None, hook_post_draw: bool = False, queue_limit: int = None, block: bool = False) -> None']),
(('Py5Tools', 'offline_frame_processing'), ['(func: Callable[[npt.NDArray[np.uint8]], None], *, limit: int = 0, period: float = 0.0, batch_size: int = 1, complete_func: Callable[[], None] = None, stop_processing_func: Callable[[], bool] = None, sketch: Sketch = None, hook_post_draw: bool = False, queue_limit: int = None, block: bool = False, display_progress: bool = True) -> None']),
(('Py5Tools', 'capture_frames'), ['(*, count: float = 0, period: float = 0.0, frame_numbers: Iterable = None, sketch: Sketch = None, hook_post_draw: bool = False, block: bool = False) -> list[PIL_Image]']),
(('Py5Tools', 'sketch_portal'), ['(*, time_limit: float = 0.0, throttle_frame_rate: float = 30, scale: float = 1.0, quality: int = 75, portal_widget: Py5SketchPortal = None, sketch: Sketch = None, hook_post_draw: bool = False) -> None']),])
Loading

0 comments on commit 9f6024e

Please sign in to comment.