Skip to content

Commit

Permalink
Merge pull request #10 from SpectralVectors/docstrings
Browse files Browse the repository at this point in the history
Docstrings
  • Loading branch information
SpectralVectors authored Sep 8, 2024
2 parents 3cce7a6 + 22895bb commit a1ca039
Show file tree
Hide file tree
Showing 36 changed files with 9,451 additions and 3,259 deletions.
99 changes: 98 additions & 1 deletion scripts/addons/cam/async_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,23 @@

@types.coroutine
def progress_async(text, n=None, value_type='%'):
"""Function for Reporting During the Script, Works for Background Operations in the Header."""
"""Report progress during script execution for background operations.
This function is designed to provide progress updates while a script is
running, particularly for background operations. It yields a dictionary
containing the progress information, which includes the text description
of the progress, an optional numeric value, and the type of value being
reported. If an exception is thrown during the operation, it will be
raised for handling.
Args:
text (str): A message indicating the current progress.
n (optional): An optional numeric value representing the progress.
value_type (str?): A string indicating the type of value being reported (default is '%').
Raises:
Exception: If an exception is thrown during the operation.
"""
throw_exception = yield ('progress', {'text': text, 'n': n, "value_type": value_type})
if throw_exception is not None:
raise throw_exception
Expand All @@ -30,6 +46,22 @@ def __init__(self):
self._is_cancelled = False

def modal(self, context, event):
"""Handle modal operations for a Blender event.
This function processes events in a modal operator. It checks for
specific event types, such as TIMER and ESC, and performs actions
accordingly. If the event type is TIMER, it attempts to execute a tick
function, managing the timer and status text in the Blender workspace.
If an exception occurs during the tick execution, it handles the error
gracefully by removing the timer and reporting the error. The function
also allows for cancellation of the operation when the ESC key is
pressed.
Args:
context (bpy.context): The current Blender context.
event (bpy.types.Event): The event being processed.
"""

if bpy.app.background:
return {'PASS_THROUGH'}

Expand Down Expand Up @@ -58,6 +90,24 @@ def modal(self, context, event):
return {'PASS_THROUGH'}

def show_progress(self, context, text, n, value_type):
"""Display the progress of a task in the workspace and console.
This function updates the status text in the Blender workspace to show
the current progress of a task. It formats the progress message based on
the provided parameters and outputs it to both the Blender interface and
the standard output. If the value of `n` is not None, it includes the
formatted number and value type in the progress message; otherwise, it
simply displays the provided text.
Args:
context: The context in which the progress is displayed (typically
the Blender context).
text (str): A message indicating the task being performed.
n (float or None): The current progress value to be displayed.
value_type (str): A string representing the type of value (e.g.,
percentage, units).
"""

if n is not None:
progress_text = f"{text}: {n:.2f}{value_type}"
else:
Expand All @@ -67,6 +117,27 @@ def show_progress(self, context, text, n, value_type):
sys.stdout.flush()

def tick(self, context):
"""Execute a tick of the coroutine and handle its progress.
This method checks if the coroutine is initialized; if not, it
initializes it by calling `execute_async` with the provided context. It
then attempts to send a signal to the coroutine to either continue its
execution or handle cancellation. If the coroutine is cancelled, it
raises a `StopIteration` exception. The method also processes messages
from the coroutine, displaying progress or other messages as needed.
Args:
context: The context in which the coroutine is executed.
Returns:
bool: True if the tick was processed successfully, False if the coroutine has
completed.
Raises:
StopIteration: If the coroutine has completed its execution.
Exception: If an unexpected error occurs during the execution of the tick.
"""

if self.coroutine == None:
self.coroutine = self.execute_async(context)
try:
Expand All @@ -86,6 +157,21 @@ def tick(self, context):
print("Exception Thrown in Tick:", e)

def execute(self, context):
"""Execute the modal operation based on the context.
This function checks if the application is running in the background. If
it is, it continuously ticks until the operation is complete. If not, it
sets up a timer for the modal operation and adds the modal handler to
the window manager, allowing the operation to run in a modal state.
Args:
context (bpy.types.Context): The context in which the operation is executed.
Returns:
dict: A dictionary indicating the status of the operation, either
{'FINISHED'} if completed or {'RUNNING_MODAL'} if running in modal.
"""

if bpy.app.background:
# running in background - don't run as modal,
# otherwise tests all fail
Expand All @@ -105,6 +191,17 @@ class AsyncTestOperator(bpy.types.Operator, AsyncOperatorMixin):
bl_options = {'REGISTER', 'UNDO', 'BLOCKING'}

async def execute_async(self, context):
"""Execute an asynchronous operation with a progress indicator.
This function runs a loop 100 times, calling an asynchronous function to
report progress for each iteration. It is designed to be used in an
asynchronous context where the progress of a task needs to be tracked
and reported.
Args:
context: The context in which the asynchronous operation is executed.
"""

for x in range(100):
await progress_async("Async test:", x)

Expand Down
Loading

0 comments on commit a1ca039

Please sign in to comment.