<?xml version='1.0' encoding='UTF-8'?>

<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>

<chapter name="Max Basic Tutorial 15: Abstractions">

<setdocpatch name="15mAbstractions" patch="15mAbstractions.maxpat"/>
  <previous name="basicchapter14">Encapsulation</previous>
<next name="basicchapter16">Remote Messaging</next>
<parent name="00_maxindex">Max Tutorials</parent>

<indexinfo category="Basics" title="Abstractions">Creating libraries of re-usable code</indexinfo>

<h1>Tutorial 15: Abstractions</h1>

<h2>Introduction</h2>

<p>In this tutorial, we will extend the concept of encapsulation to include <i>abstraction</i> – the ability to have subpatcher logic live in a separate, reusable file that you can then use inside of any patcher you like.  Once saved outside as a separate file, abstractions can be modified to use arguments to make a generic Max patch useful to your specific application.  By using abstractions for your most-used programming tasks, you will be able to reuse that logic in future projects without any duplication of work.</p>

<p>Abstractions are key to supporting your accumulated Max knowledge and experience.  The abstraction mechanism can make your subpatches look and act like built-in Max objects, and can also accept arguments to further tune its functionality.</p>

<p>To open the tutorial patch, click on the <b>Open Tutorial</b> button in the upper right-hand corner of the documentation window.</p>

<h2>An overview</h2>

<p>In our tutorial patcher, you will see that there are three different patches.  In this case, each of them do the exact same thing, but at different levels of abstraction.  The first section (labeled <b>1</b>) is the fully visible patch.  If you turn on the <o>metro</o> with the <o>toggle</o>, we see that the patch tracks your cursor around the screen and draws a scaled version of your mouse movements in the <o>lcd</o> display.  We make use of the <o>bucket</o> object in this patch; a simple example of the object is shown on the left next to the <o>lcd</o>. In its most simple form, upon receiving a value, <o>bucket</o> always puts out the last value it received.  This makes it useful as a single-event delay object, which we use in the main patcher to construct <m>linesegment</m> messages that link the current position of the mouse to its previous position.</p>

<p>In the case of section <b>1</b>, we have a lot of logic on the screen, and it might be useful to encapsulate it into a subpatcher (as we did in the previous tutorial).  However, the patcher logic that polls the mouse and scales it based on the size of our screen looks like something that could be useful elsewhere; it would be interesting to have it available for other patches without having to copy and paste from one patch to the next.</p>

<p>This is where abstractions come into play.  An abstraction is a subpatcher that is saved as an external file, and can be used just like a standard Max object.  As long as your abstraction can be found in the Max file path, you can type its name into a new object box and it will be loaded directly into your patch.  The abstractions used in this tutorial are in the same folder as the patcher accessing them; a library of abstractions can easily be created by placing them in a folder (or a bunch of folders) inside the "patches" folder of your Max installation, or anywhere else Max looks for files.</p>

<h2>Using a simple abstraction</h2>

<p>The second section of our patch (labeled <b>2</b>) shows an abstraction at work.  Turn off the <o>metro</o> for section <b>1</b>, hit the space bar (which will <m>clear</m> the <o>lcd</o>) and turn on the <o>metro</o> for section <b>2</b>.  You will see that the program works exactly as it did before.  The “object” called <b>WTHITM</b> (for "Where The Heck Is The Mouse?") is actually an <i>abstraction</i> of the scaling logic from section <b>1</b>.  If you double-click on the <b>WTHITM</b> abstraction, a new patcher window will display the contents of this abstraction.  Notice that this looks very much like an encapsulation with one exception – you cannot unlock the window to edit the contents.  This is because <b>WTHITM</b> exists as a separate patcher <i>file</i> living in the same folder as our tutorial patch.</p>

<p>Abstractions are meant to be shared among several patches, so you would not want to edit the contents in one patcher, since this might break its functionality in other patchers. If you do want to edit an abstraction, you need to open the abstraction file itself.</p>

<p>While there are several ways to open the abstraction file, we'll mention only two: We can open a <b>New File Browser</b> (from the <b>File</b> menu) and type WTHITM into to the search window and then double-click on the patcher file that appears in response to our query, or we can click the <b>Modify read-Only</b>  (pencil) icon in the abstraction toolbar. However you choose to do it, open the <b>WTHITM</b> source file.  You will again see the abstraction contents, but now you can edit the logic.  If you change something and save the file, all patchers that use this abstraction will reflect the changes – even if the patcher is currently loaded.  You can see this in action by adding a second inlet to the <b>WTHITM</b> abstraction and saving it.  The instant that Max sees a new version of the abstraction, it reloads it and adds a new inlet to the <b>WTHITM</b> abstraction in your tutorial patch.</p>

<p>While we have the <b>WTHITM</b> patch open, let’s look at the documentation that has been added to the <o>inlet</o> and <o>outlet</o> objects. If you open the inspector for the <o>inlet</o>, you see that there are several different types of built-in documentation.  The first is called <i>Annotation</i>; any text placed in the annotation field will show up in the <b>Clue</b> window when you hover over the object. Text placed in the second documentation field, the <i>Hint</i> field, will display in a hint balloon when you hover over the <o>inlet</o> object in a <i>locked</i> patcher.  Finally, text placed in the <i>Comment</i> section doesn’t display in the patcher; rather, this text is shown as the <i>assistance</i> text when you hover over the <i>inlet</i> of the "object" in the higher-level patcher.  It is wise to document your <o>inlet</o> and <o>outlet</o> objects in often-used abstractions, since it can provide simple but effective documentation for your reusable logic.</p>

<h2>Using an abstraction with replaceable arguments</h2>

<p>In our <b>WTHITM</b> abstraction, there is no logic that needs to know about the higher level patcher.  However, what if we wanted the abstraction to properly scale the output based on our <o>lcd</o> object’s size?  In this case, we would have to inform the abstraction of the <o>lcd</o> display size, which we can do using <i>arguments</i> to the abstraction.</p>

<p>Section <b>3</b> of the tutorial patch is similar to section <b>2</b>, but the abstraction used is called <b>WTHITM_scaled</b>, and includes two <i>arguments</i> that represent the horizontal and vertical sizes of the <o>lcd</o> object. If we open and unlock the "WTHITM_scaled.maxpat" patch, we see something very interesting: the multiplication factors use <m>#1</m> and <m>#2</m> as placeholders for values to be provided as arguments.  As you might expect, <m>#1</m> is replaced with the value of the first argument, while <m>#2</m> is replaced with the value of the second.</p>

<p>The use of these replaceable values (called <i>pound-sign arguments</i>) is key to making abstractions that are flexible and reusable.  If you would have “319.” and “239.” hard-coded into the abstraction, you could only use 320x240 <o>lcd</o> objects to display the mouse movements. On the other hand, if you forced the top-level patcher to perform the final scaling (as we did in section <b>2</b>), you are forcing the top-level patch to duplicate work that could be easily abstracted into the lower-level patch.  By using replaceable values in your abstractions, it makes the high-level patcher as simple as is practical.</p>

<h2>Summary</h2>

<p>By saving your logic in an abstraction, you can create modules that can be used in future work with little or no additional programming.  This allows you to parlay your Max knowledge into more efficient work in the future, and will help you create programming systems that are modular and easier to maintain.</p>

<seealsolist>
<seealso name="bucket">An n-stage shift register</seealso>
</seealsolist>

</chapter>
