diff --git a/spark/core.py b/spark/core.py index ee07ad1..b6d9dee 100644 --- a/spark/core.py +++ b/spark/core.py @@ -41,12 +41,19 @@ def __init__(self, globals_dict): self._globals_dict = globals_dict self._methods = {} + # Supports the print function. + self.current_step = 'presetup' + self.print_outputs = { 'setup': '', 'draw': '' } + self.draw_output_tracker = '' + self.draw_output_frame = 0 + + self.frame_count = 0 + self.stop_button = Button(description="Stop") self.stop_button.on_click(self.on_stop_button_clicked) self._globals_dict["canvas"] = Canvas() self.kb_mon = Event(source=self.canvas, watched_events=['keydown', 'keyup'], wait=1000 // FRAME_RATE, prevent_default_actions=True) - self.output_text = "" self.color_strings = { "default": "#888888" } @@ -83,6 +90,16 @@ def __init__(self, globals_dict): def canvas(self) -> Canvas: return self._globals_dict["canvas"] + @property + @ignite_global + def frame_count(self): + return self._globals_dict["frame_count"] + + @frame_count.setter + def frame_count(self, val): + self._globals_dict["frame_count"] = val + + @property @ignite_global def mouse_x(self): @@ -158,7 +175,10 @@ def start(self, methods): display(self.canvas) - self.output_text_code = display(Code(self.output_text), display_id=True) + self.print_output_display = { + 'handle': display(Code(''), display_id=True), + 'value': '' + } self.canvas.on_mouse_down(self.on_mouse_down) self.canvas.on_mouse_up(self.on_mouse_up) @@ -203,12 +223,16 @@ def loop(self): setup = self._methods.get("setup", None) if setup: + self.current_step = 'setup' try: setup() except Exception as e: + self.update_print_output_display() self.stop("Error in setup() function: " + str(e)) return + self.update_print_output_display() + while _sparkplug_running: if _sparkplug_active_thread_id != current_thread_id \ or time.time() - _sparkplug_last_activity > NO_ACTIVITY_THRESHOLD: @@ -219,12 +243,16 @@ def loop(self): self.stop("Done drawing.") return + self.current_step = 'draw' with hold_canvas(self.canvas): try: draw() + self.frame_count += 1 except Exception as e: + self.update_print_output_display() self.stop("Error in draw() function: " + str(e)) return + self.update_print_output_display() time.sleep(1 / FRAME_RATE) @@ -236,11 +264,25 @@ def print_status(self, msg): # Can't use @validate_args decorator for functions actually accepting variable arguments @ignite_global def print(self, *args, sep=' ', end='\n', flush=True): - global _sparkplug_running - self.output_text += sep.join([str(arg) for arg in args]) + end + if self.current_step == 'presetup': + print(*args) # Use built-in print outside of setup and draw methods. + return - if _sparkplug_running and flush: - self.output_text_code.update(Code(self.output_text)) + if self.current_step == 'draw': + # If printing from the draw method, clear values from the previous frame. + if self.draw_output_frame != self.frame_count: + self.draw_output_frame = self.frame_count + self.print_outputs['draw'] = '' + + msg = sep.join([str(arg) for arg in args]) + end + self.print_outputs[self.current_step] += msg + + def update_print_output_display(self): + vals = [self.print_outputs['setup'], self.print_outputs['draw']] + new_text = ''.join(filter(None, vals)) # Filter out empty values. + if self.print_output_display['value'] != new_text: + self.print_output_display['value'] = new_text + self.print_output_display['handle'].update(Code(new_text)) # Update mouse_x, mouse_y, and call mouse_down handler def on_mouse_down(self, x, y): diff --git a/test/KeyEventsUnits.ipynb b/test/KeyEventsUnits.ipynb index bce14d1..4bf0aa5 100644 --- a/test/KeyEventsUnits.ipynb +++ b/test/KeyEventsUnits.ipynb @@ -1598,7 +1598,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.6" } }, "nbformat": 4, diff --git a/test/PrintTest.ipynb b/test/PrintTest.ipynb new file mode 100644 index 0000000..a2911a8 --- /dev/null +++ b/test/PrintTest.ipynb @@ -0,0 +1,499 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import spark\n", + "%reload_ext spark" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Stopped\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Stopped" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "acd511e6d1664663a5f33819b319c666", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ce52e55f431d4b02ba6c27edb7ead3c2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
0\n",
+       "21 65 1\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{0}\n", + "\\PY{err}{2}\\PY{err}{1}\\PY{err}{ }\\PY{err}{6}\\PY{err}{5}\\PY{err}{ }\\PY{err}{1}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "0\n", + "21 65 1" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Prints out a variable x that is constantly incrementing and mouse_x and mouse_y on-the-spot inside draw()\n", + "\n", + "x = 0\n", + "\n", + "def setup():\n", + " print(x)\n", + "\n", + "def draw():\n", + " global x\n", + " x += 1\n", + " print(x, mouse_x, mouse_y)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Stopped\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Stopped" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4e749ac0b6b649c89c9db61e37491e3c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "cb6f158f70a84fdf93857ba85ac1e63a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
23\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{2}\\PY{err}{3}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "23" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Print out the variable frame_count\n", + "\n", + "def setup():\n", + " size(100, 100)\n", + " background(\"aqua\")\n", + " \n", + "def draw():\n", + " print(frame_count)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}