Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions py5-docs/Reference/api_en/Sketch_is_looping.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@@ meta
name = is_looping
type = field
pclass = Sketch
processing_name = isLooping
category = structure
subcategory = None

@@ description
The `is_looping` property returns whether or not the sketch is currently looping. This will be `True` by default, and `False` after [](sketch_no_loop) has been called. Calling [](sketch_loop) will set it back to `True`.

@@ example
x = 0.0


def setup():
py5.size(200, 200)


def draw():
global x
py5.background(204)
py5.line(x, 0, x, py5.height)
x = x + 1
if x > py5.width:
x = 0


def mouse_pressed():
if py5.is_looping:
py5.no_loop()
else:
py5.loop()
2 changes: 1 addition & 1 deletion py5-resources/data/sketch.csv
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ create_image,createImage,@_return_py5image,method,image,,JAVA,
image,image,@_auto_convert_to_py5image(0),method,image,loading_displaying,JAVA,
handle_draw,handleDraw,,method,,,SKIP,public methods that shouldn't be available to users
alpha,alpha,@_convert_hex_color(),method,color,creating_reading,JAVA,
is_looping,isLooping,,method,,,SKIP,methods that are not part of the processing framework
is_looping,isLooping,,dynamic variable,structure,,PYTHON,property to determine if sketch is looping
looping,looping,,unknown,,,SKIP,methods that are not part of the processing framework
post_event,postEvent,,method,,,SKIP,public methods that shouldn't be available to users
focus_gained,focusGained,,method,,,SKIP,methods that are not part of the processing framework
Expand Down
5 changes: 5 additions & 0 deletions py5-resources/py5-module/src/py5/sketch.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,11 @@ def _get_is_running(self) -> bool: # @decorator
fget=_get_is_running, doc="""$class_Sketch_is_running"""
)

@property

@ulgens ulgens Sep 16, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_ready and is_running handles similar implementations by creating a helper method, then wrapping it as a property. I checked the codebase but couldn't understand the benefit of this approach, it seems to complicate the code for no reason.

Property-wrapping approach causes a typing issue too:

Image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the codebase but couldn't understand the benefit of this approach, it seems to complicate the code for no reason.

py5generator is essentially a custom template engine that takes code templates and adds more code to them to make complete python files. The template engine needs to be able to read and parse the code in the templates and extract information from them to maintain the type signatures and compare them with the documentation files. The code that extracts information expects the code to be written in a certain way to be easily parsed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance to give some context about why template engine needs it? I couldn't see how _get... + property wrapper approach provides anything extra over the approach in this PR.

def is_looping(self) -> bool:
"""$class_Sketch_is_looping"""
return self._instance.isLooping()

def _get_is_dead(self) -> bool: # @decorator
"""$class_Sketch_is_dead"""
surface = self.get_surface()
Expand Down
4 changes: 4 additions & 0 deletions py5-resources/py5-module/src/py5_tools/live_coding/syncing.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ def mock_no_loop(self):
UserFunctionWrapper.looping_state = ANIMATION_NO_LOOPING
UserFunctionWrapper.freeze_frame_count = self.sketch.frame_count

def mock_is_looping(self):
return UserFunctionWrapper.looping_state in (ANIMATION_LOOPING, ANIMATION_REDRAW)

def mock_redraw(self):
UserFunctionWrapper.looping_state = ANIMATION_REDRAW
UserFunctionWrapper.freeze_frame_count += 1
Expand Down Expand Up @@ -347,6 +350,7 @@ def _init_hooks(self, s):
mock_methods = MockMethods(s)
s.loop = mock_methods.mock_loop
s.no_loop = mock_methods.mock_no_loop
s.is_looping = mock_methods.mock_is_looping

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is actually needed and how to handle the property. Will revisit.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is actually needed and how to handle the property. Will revisit.

Good catch. I think mocking this would be important for is_looping to work properly with live coding.

s.redraw = mock_methods.mock_redraw
s.real_exit_sketch = s.exit_sketch
s.exit_sketch = mock_methods.mock_exit_sketch
Expand Down