<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Hi Facundo,<br>
<br>
On 11/13/2023 8:16 PM, Facundo Javier Gelatti via Cuis-dev wrote:
<blockquote
cite="mid:CAC1UKnaWcxOP4J259Z3RagsqpDoTuYuYxZAxrPO319H0eGos3A@mail.gmail.com"
type="cite">
<div dir="ltr">Hello folks!<br>
I include some code to add an option to debug the action of <font
face="monospace">MenuItemMorph</font>s and <font
face="monospace">PluggableButtonMorph</font>s. See <a
moz-do-not-send="true"
href="https://drive.google.com/file/d/1cVMwcMS56EgpYOiQg5MawVF6W_RaEzX3/view">demo
video</a> and screenshot below:
<div><br>
</div>
<div style="text-align: center;"><img
src="cid:part1.05040108.03060806@cuis.st" alt="image.png"
class="gmail-CToWUd gmail-a6T" tabindex="0" style="cursor:
pointer; outline: 0px none; margin-right: 0px;" height="178"
width="395"><br>
</div>
<div>Cheers!<br>
Facu.<br>
<br>
PS: I leave additional details about the implementation, that
could be useful during code-review 👇<br>
<br>
</div>
<div>
<hr style="color: rgb(0, 0, 0); font-family: "Times New
Roman"; font-size: medium;"></div>
<div>📝 The changes include support for <font face="monospace">MenuItemMorph</font>s
and <font face="monospace">PluggableButtonMorph</font>s (for
convenience, in this email, I'll refer to both of them as
"buttons").<br>
It'd be nice to have a more general implementation¹, but I
started only with those because I usually debug the actions of
those kinds of morph types (manually, until now :P).<br>
<br>
The way it's implemented is by opening a debugger on the
morph's action, and making it go forward² until it reaches the
appropriate method on the morph's target/model (see <font
face="monospace">#debugAction</font>).<br>
Notice that it also shows a confirmation message in case you
try to debug —and therefore run— the action of a disabled
button³.<br>
<br>
To execute the button's action, I reused some code from <font
face="monospace">PluggableButtonMorph>>#performAction</font> and <font
face="monospace">MenuItemMorph>>#invokeWithEvent:</font>.<br>
To do that, I extracted a couple of methods; I include here
the reasons that motivated the way I chose to do it:<br>
<ol>
<li style="margin-left: 15px;">To be able to skip the check
to see if the button was enabled or not, I had to extract
the code that runs the action without making any
precondition checks.</li>
<li style="margin-left: 15px;">In the case of <font
face="monospace">MenuItemMorph</font><span
style="font-family: monospace;">>>#invokeWithEvent:</span>,
the <font face="monospace">#numArgs</font> message is sent
to the corresponding selector. During manual testing, I
discovered that this caused the <font face="monospace">String>>#numArgs</font> method
to run in the debugger (stepping through it as part of the
mechanism mentioned before), and it was <i>very slow</i>.
So, to avoid running that part of the code in the
debugger, I extracted a method that does all the
pre-processing and returns a block that's ready to run the
action (<font face="monospace">MenuItemMorph>>#actionBlockForEvent:</font>).
Then, I run <i>that</i> block on the debugger.</li>
<li style="margin-left: 15px;">The issue mentioned in point
(2) did not happen for <font face="monospace">PluggableButtonMorph</font><span
style="font-family: monospace;">>>#performAction</span>.
Nonetheless, I made a similar implementation, just for
consistency's sake (<font face="monospace">PluggableButtonMorph>>#actionBlock</font>).
The different name has to do with the different vocabulary
used for the <font face="monospace">PluggableButtonMorph</font> vs.
the <font face="monospace">MenuItemMorph</font>, and with
the fact that the <font face="monospace">MenuItemMorph</font> needs
an event parameter.</li>
<li style="margin-left: 15px;">As the <font face="monospace">MenuItemMorph</font> needs
an event, we have to simulate it. I wasn't sure what was
the best way to do it, so I'm currently passing <font
face="monospace">nil</font>. While trying it out, I
noticed that all of the menu items I tested the option
with were <i>not</i> using the event object. At any rate,
if there's some menu option that uses it, it'll fail with
a "does not understand" error.</li>
</ol>
Additionally, as a refactor, to be able to open the debugger
on a block without doing anything else, I extracted the
method <font face="monospace">Debugger
class>>#openDebugging:label:</font> from <font
face="monospace">Debugger
class>>#openDebugging:to:label:</font>.</div>
<div>_____<br>
¹ e.g. detecting the events supported by any morph and letting
you simulate and debug the one of your choosing.<br>
² i.e. "step into", by sending the #send message.<br>
³ Since the action is not run by a normal interaction with the
button, and if it's disabled maybe running the action could
leave the system in an unexpected state. It does, though, let
you debug the action if you really want to do it.</div>
</div>
</blockquote>
<br>
This is very nice! Thank you.<br>
<br>
It is now at GitHub.<br>
<br>
Cheers,<br>
<pre class="moz-signature" cols="72">--
Juan Vuletich
cuis.st
github.com/jvuletich
researchgate.net/profile/Juan-Vuletich
independent.academia.edu/JuanVuletich
patents.justia.com/inventor/juan-manuel-vuletich
linkedin.com/in/juan-vuletich-75611b3
twitter.com/JuanVuletich</pre>
</body>
</html>