{\rtf1\mac\deff2 {\fonttbl{\f0\fswiss Chicago;}{\f2\froman New York;}{\f3\fswiss Geneva;}{\f4\fmodern Monaco;}{\f13\fnil Zapf Dingbats;}{\f14\fnil Bookman;}{\f15\fnil N Helvetica Narrow;}{\f16\fnil Palatino;}{\f18\fnil Zapf Chancery;}{\f20\froman Times;} {\f21\fswiss Helvetica;}{\f22\fmodern Courier;}{\f23\ftech Symbol;}{\f33\fnil Avant Garde;}{\f34\fnil New Century Schlbk;}{\f55\fnil Code 3 of 9;}{\f256\fnil TaxType;}{\f257\fnil TaxTypeCondensed;}{\f258\fnil TaxType Mono;}{\f259\fnil TaxType Pi;} {\f1904\fnil AppleIcon;}{\f2029\fnil Nadianne;}{\f2052\fnil Zeal;}{\f12899\fnil AppleGaramond LtIt;}{\f12900\fnil AppleGaramond BkIt;}{\f12901\fnil AppleGaramond BdIt;}{\f12902\fnil AppleGaramond Lt;}{\f12903\fnil AppleGaramond Bk;} {\f12904\fnil AppleGaramond Bd;}{\f14003\fnil Newt Espy Plain;}{\f14004\fnil Newt Espy Bold;}}{\colortbl\red0\green0\blue0;\red0\green0\blue255;\red0\green255\b lue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\ red255\green255\blue0; \red255\green255\blue255;}{\stylesheet{\s243\qj\fi180\sa240\keep\tqc\tx43 20\tqr\tx8640 \f20 \sbasedon0\snext243 footer;}{\s254\qj\sb120\sa240\keep \b\f20 \sbasedon0\snext0 heading 2;}{\s255\qj\sb240\sa240\keep \f20\fs36 \sbasedon0\snext0 heading 1;}{ \qj\fi180\sa240\keep \f20 \sbasedon222\snext0 Normal;}{\s2\fi-360\li720\sa60\keep \f20 \sbasedon0\snext2 BulletList;}{\s3\li360\sa240\keep \f22 \sbasedon0\snext0 code;}{\s4\qc\fi180\sa240\keep \f20\fs48 \sbasedon0\snext4 Title;}{\s5\qc\fi180\sa240\keep \f20\fs28 \sbasedon0\snext5 Byline;}{\s6\qc\fi180\sa240\keep \f20 \sbasedon0\snext0 Caption;}{\s7\qj\sb240\sa240\keep \f22\fs36 \sbasedon255\snext7 CodeRef;}}\margl720\margr720\margt1080\margb720\deftab360\widowctrl\ftnbj \sectd \sbknone\linemod0\linex0\cols1\endnhere \pard\plain \s4\qc\fi180\sa240\keep \f20\fs48 Bit Parts\par \pard\plain \qc\fi180\sa240\keep \f20 {\fs36 DRAFT 6\par }\pard\plain \s5\qr\fi180\sa240\keep \f20\fs28 Michael S. Engber\line Apple Computer - Newton ToolBox Group\line Copyright \'a9 1994 - Michael S. Engber\par \pard\plain \fi180\sa240\keep \f20 This article was (will be) published in the May 1994 issue of PIE Developers magazine. For information about PIE Developers, contact Creative Digital Systems at CDS.SEM@APPLELINK.APPLE.COM or 415.621.4252.\par \pard\plain \s255\qj\sb240\sa240\keep \f20\fs36 Introduction\par \pard\plain \qj\fi180\sa240\keep \f20 Many people are unfamiliar or unclear about the terms package and part. Yet these are very basic concepts in Newton programming. This is because prior to NTK 1.0.1 final you didn't have to explicitly decide what kinds of packages and parts you produced. Th is article will try to explain these terms and discuss the possibilities introduce with NTK 1.0.1. I assume the reader has some experience using NTK to write Newton applications.\par \pard\plain \s255\qj\sb240\sa240\keep \f20\fs36 Packages and Parts\par \pard\plain \qj\fi180\sa240\keep \f20 On the Newton, a package is the basic unit of downloadable software. Newton Connection and Newton Package Installer each allow you to download packages. The Remove Software button in Prefs and the card dialog allows the user to remove a package.\par \pard \qj\fi180\sa240\keep Packages contain parts. There are a variety of different kinds of parts currently supported by Newton. Each has a four character type. Some of these types are shown in Table 1.\par \trowd \trgaph80\trleft1000 \clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrdb \clbrdrr\brdrhair \clshdng0\cellx2520\clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrdb \clbrdrr\brdrhair \clshdng0\cellx4040\clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb \brdrdb \clbrdrr\brdrhair \clshdng0\cellx9800\pard \qc\keep\intbl part type\cell part code\cell \pard \qc\keep\intbl description\cell \pard \intbl \row \trowd \trgaph80\trleft1000 \clbrdrt\brdrdb \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx2520\clbrdrt\brdrdb \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx4040\clbrdrt\brdrdb \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx9800\pard \qc\keep\intbl form\cell {\f22 form\cell }\pard \qj\keep\intbl general purpose applications created by NTK\cell \pard \intbl \row \trowd \trgaph80\trleft1000 \clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx2520\clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx4040\clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx9800\pard \qc\keep\intbl book\cell {\f22 book\cell }\pard \qj\keep\intbl books created by Newton Book Maker\cell \pard \intbl \row \pard \qc\keep\intbl auto\cell {\f22 auto\cell }\pard \qj\keep\intbl faceless background apps (or inits) of the Newton world\cell \pard \intbl \row \pard \qc\keep\intbl font\cell {\f22 font\cell }\pard \qj\keep\intbl additional fonts\cell \pard \intbl \row \pard \qc\keep\intbl dictionary\cell {\f22 dict\cell }\pard \qj\keep\intbl custom dictionaries\cell \pard \intbl \row \trowd \trgaph80\trleft1000 \clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx2520\clbrdrt \brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx4040\clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx9800\pard \qc\keep\intbl store \cell {\f22 soup\cell }\pard \qj\keep\intbl store containing read only soups\cell \pard \intbl \row \pard\plain \s6\qc\fi180\sa240\keep \f20 Table 1 - Part Types\par \pard\plain \qj\fi180\sa240\keep \f20 Prior to NTK 1.0.1 you could only create packages containing a single part \endash a form part or a book part. Using NTK 1.0.1 you can create auto parts and multi-part packages. \par \pard\plain \s255\qj\sb240\sa240\keep \f20\fs36 Auto Parts\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 How Form Parts Work\par \pard\plain \qj\fi180\sa240\keep \f20 Form parts are what you're already used to creat ing with NTK. I only mention them here to contrast them with the discussion of auto parts in the next section. When a form part is installed the following steps take place:\par \pard\plain \s2\fi-360\li720\sa60\keep \f20 1.\tab Its {\f22 partFrame} is TotalCloned (except for {\f22 theForm} slot) and then the clone's {\f22 InstallScript} is called with one parameter, the {\f22 partFrame}\par \pard \s2\fi-360\li720\sa60\keep 2.\tab A view is made using {\f22 partFrame}.theForm as the template. This view is put in a slot of the root view using the app symbol as the slot name.\par \pard \s2\fi-360\li720\sa60\keep 3.\tab An icon is added to the extras drawer for that part.\par \pard\plain \qj\fi180\sa240\keep \f20 When a form part is removed its {\f22 RemoveScript} is called. It is passed one parameter, the same {\f22 partFrame} that was passed to the {\f22 InstallScript}.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 How Auto Parts Work\par \pard\plain \qj\fi180\sa240\keep \f20 Auto parts work very differently than form parts. When an auto part is installed the following steps take place:\par \pard\plain \s2\fi-360\li720\sa60\keep \f20 0.\tab Its {\f22 partFrame} is {\b not} TotalCloned.\par \pard \s2\fi-360\li720\sa60\keep 1.\tab Its {\f22 InstallScript} is called with two parameters, the {\f22 partFrame} and the {\f22 removeFrame}. The {\f22 InstallScript} has access to other data in the package through {\f22 partFrame.partData} . There is no {\f22 partFrame.theForm} slot.\par \pard \s2\fi-360\li720\sa60\keep 2.\tab A view is {\b not} made.\par 3.\tab An icon is {\b not} added to the extras drawer.\par \pard\plain \qj\fi180\sa240\keep \f20 When an auto part is removed its {\f22 RemoveScript} is called. It is passed one parameter, the {\f22 removeFrame} that was passed to the {\f22 InstallScript}.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 Dispatch-Only Auto Parts\par \pard\plain \qj\fi180\sa240\keep \f20 There is a slight variation on an auto part called a dispatch-only auto part. It installs like a regular auto part, but then it's automatically removed. Its removal works the same as a regular auto part except for that it is triggered automatically. Dispat ch-only auto parts load, their {\f22 InstallScript} runs, their {\f22 RemoveScript} runs, then poof, they're gone.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 How To Create Auto Parts\par \pard\plain \qj\fi180\sa240\keep \f20 NTK 1.0.1 doesn't "officially" support auto parts. You won't find information on how to create them in the manual. Expect the user interface for creating auto parts to change in future versions of NTK.\par \pard \qj\fi180\sa240\keep To create an auto part project in NTK all you need to do is specify "{\f22 auto}" for your application name and symbol in the projects settings dialog ("{\f22 auto!}" if you want a dispatch-only auto part). You will n eed to create a dummy main layout so your project will compile, but this layout won't actually be put in your package. The code for your auto part all goes in {\f22 "Project Data"}. You create your {\f22 InstallScript} and {\f22 RemoveScript} in a similar fashion to form parts. You'll use code that something like the code below.\par \pard\plain \s3\li360\sa240\keep \f22 InstallScript := func(partFrame,removeFrame)\line begin\line \'c9\line end;\line \line RemoveScript := func(removeFrame)\line begin\line \'c9\line end;\par \pard\plain \qj\fi180\sa240\keep \f20 In addition, if you want your auto part to have some data you can define a {\f22 partData} global variable in the {\f22 "Project Data"} file. For example:\par \pard\plain \s3\li360\sa240\keep \f22 partData := \{s1: "moe", s2: "larry", s3: "curly"\};\par \pard\plain \qj\fi180\sa240\keep \f20 The contents of the {\f22 partData} variable will be tucked away in your part frame in a slot by the same name. You should make {\f22 partData} a frame whose slots contain the various pieces of data used by your { \f22 InstallScript}. The {\f22 partData} slot is mainly a convenience to help you organize your code. You're free to embed data in your package as literals or constants in your {\f22 InstallScript}. One situation where {\f22 partData} is especia lly useful is accessing templates you layed out graphically in NTK. This is described in the next section.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 How To Use Layouts in Auto Parts\par \pard\plain \qj\fi180\sa240\keep \f20 Of course, you can always explicitly define your templates as NewtonScript frames. (In this section I use the term template to generically mean templates, user-protos, or print formats.) However, using NTK to define your templates is easier and less error prone. Naturally, you will want to take advantage of NTK to define the templates you use in your auto parts.\par \pard \qj\fi180\sa240\keep As was mentioned before, the layouts in your project window will not be automatically included in your package. Auto part {\f22 partFrames} do not have a {\f22 theForm slot}.\par \pard \qj\fi180\sa240\keep To use templates you lay out in NTK with auto parts you should:\par \pard\plain \s2\fi-360\li720\sa60\keep \f20 \bullet create your templates in NTK as you normally would for a form part\par \bullet add them to your project\par \pard \s2\fi-360\li720\sa240\keep \bullet give each template's top-level view an {\f22 AfterScript} which tucks away the template in {\f22 partData}.\par \pard\plain \qj\fi180\sa240\keep \f20 An example {\f22 AfterScript} is shown below.\par \pard\plain \s3\li360\sa240\keep \f22 begin\line partData.fooTemplate := thisView;\line end\par \pard\plain \qj\fi180\sa240\keep \f20 You will be able to access this template from your {\f22 InstallScript} using {\f22 partFrame.partData.fooTemplate} .\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 When To Use Auto Parts\par \pard\plain \qj\fi180\sa240\keep \f20 The main thing that distinguishes auto parts from form parts is they don't have an icon in the extras drawer. For example if your package consists of a series new panels for the Formulas roll, then there is no reason to create an icon in the extras drawer. Similarly, you might use an auto part to provide a panel in the Prefs roll.\par Another use for auto parts is to provide data for another application . For example, you might have a game with various levels or screens. Rather than build all this data into one gigantic package you might break this data up into separate auto parts. This allows your users to install only the levels they need.\par Store parts might seem like a more natural part type for providing data. Apart from the fact that NTK doesn't currently support creating store parts, soups have various disadvantage and advantages as a means of storing data. This topic is discussed further in the "Lost In Space" article. (this issue of PIE Developers Magazine)\par \pard \qj\fi180\sa240\keep It's not so clear what dispatch-only auto parts are useful for. A dispatch-only auto part gets one shot at doing something. The changes a dispatch-only auto part makes are lost when the Newton is reset (except for changes made to soups). Unlike non dispatc h-only auto parts, it won't stick around so its {\f22 InstallScript} isn't run every time the Newton is reset. One possible use for dispatch-only auto parts might be to create a soup. Once the soup is cr eated there is no need for the auto part to remain installed.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 Accessing Data in Auto Parts\par \pard\plain \qj\fi180\sa240\keep \f20 Auto parts have no base view, no application name, and no app symbol. This means you can't get to their data as you would with form parts \endash {\f22 GetRoot().(kAppSymbol)}.\par \pard \qj\fi180\sa240\keep If you want the data in your auto part to be accessible then its {\f22 InstallScript} will have to have code to make it available in some way. Consider the scenario of a form part that is a game and an auto part that provides data for the game. The {\f22 InstallScript} o f the auto part can put the data into the base view of the main application as show below.\par \pard\plain \s3\li360\sa240\keep \f22 {\fs20 InstallScript := func(partFrame,removeFrame)\line begin\line local gameView := GetRoot().(kGameAppSymbol);\line if gameView then\line gameView.(EnsureInternal('Level42Data)) := partFrame.partData; \line end;\line \line RemoveScript := func(removeFrame)\line begin\line local gameView := GetRoot().(kGameAppSymbol);\line if gameView then\line RemoveSlot(gameView ,'Level42Data);\line end;\par }\pard\plain \qj\fi180\sa240\keep \f20 This assumes that the application using the data is already installed. This may or may not be a reasonable assumption. Another approach is to use a global variable. You want to keep the number of global variables to a minimum. I suggest you keep it to one \endash a frame. Below is some representative code.\par \pard\plain \s3\li360\sa240\keep \f22 {\fs20 InstallScript := func(partFrame,removeFrame)\line begin\line local gData := GetGlobals().|Game:PIEDTS|;\line if not gData then\line begin\line gData := EnsureInternal(\{\});\line GetGlobals().(EnsureInternal('|Game:PIEDTS|) := gData;\line end;\line \line gData.(EnsureInternal('Level42Data)) := partFrame.partData;\line end;\line \line RemoveScript := func(removeFrame)\line begin\line local gData := GetGlobals().|Game:PIEDTS|;\line RemoveSlot(gData,'Level42Data);\line if Length(gData) = 0 then\line RemoveSlot(GetGlobals(),'|Game:PIEDTS|);\line end;\par }\pard\plain \qj\fi180\sa240\keep \f20 In this example there is a single global variable (named using our signature to ensure its uniqueness) that holds the data for the levels that the various auto parts provide. The {\f22 InstallScript} creates this global variable if necessary. The {\f22 RemoveScript} eliminates it if we remove the last datum.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 Auto Part Warnings and Gotchas\par \pard\plain \qj\fi180\sa240\keep \f20 Remember, the {\f22 partFrame} of an auto part is not copied into internal RAM before being executed. That means the code in the {\f22 InstallScript} as well as the data in {\f22 partData} reside in your package. Remember this when you're mucking with the {\f22 removeFrame}. For example, if your {\f22 InstallScript} creates a slot in the {\f22 removeFrame} for your {\f22 RemoveScript} to use, then it had better be sure to use {\f22 EnsureInternal} on the slot name and possibly the contents of the slot as well.\par \pard\plain \s3\li360\sa240\keep \f22 removeFrame.(EnsureInternal('foo)) := EnsureInternal(\'c9);\par \pard\plain \qj\fi180\sa240\keep \f20 In some circumstances, a simple {\f22 Clone} may suffice for the contents of the slot \endash it depends on what your {\f22 RemoveScript} will be doing with the object. \par \pard \qj\fi180\sa240\keep On the other hand, the {\f22 RemoveScript} and the {\f22 removeFrame} {\b are} copied into internal RAM. They have to be because when the {\f22 RemoveScript} executes your package will no longer be available. This means you normally do not need to use {\f22 EnsureInternal} in your {\f22 RemoveScript}.\par \pard \qj\fi180\sa240\keep The topic of exactly what {\f22 EnsureInternal} does and when to use it is complex. It is explained in detail in the "Newton Still Needs the Card You Removed" article. (February 1994 issue of Double-Tap Magazine, pp. 12-18) \par \pard\plain \s255\qj\sb240\sa240\keep \f20\fs36 Other Part Types\par \pard\plain \qj\fi180\sa240\keep \f20 Book parts are thoroughly documented in the Newton Book Maker manual so I will not discuss them here. The remaining part types (font, dictionary, and store) are much more straightforward to describe since they only provide data. They do not normally contai n any NewtonScript code (only form parts and auto parts have install and remove scripts)\par \pard \qj\fi180\sa240\keep NTK 1.0.1 does not currently support the creation of any of the other part types so I will only describe them briefly.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 Font Parts\par \pard\plain \qj\fi180\sa240\keep \f20 Font parts install new fonts on Newton when they are loaded. See the latest "Monaco Test" PIE DTS sample code for an example of a font part and how to use. You may find the font part provided with this sample especially useful since it's a mono-spaced font . Currently, none of the built-in Newton fonts are mono-spaced.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 Dictionary Parts\par \pard\plain \qj\fi180\sa240\keep \f20 Dictionary parts provide a way for you to pr ovide custom dictionaries. Currently dictionaries of your own creation must reside in the NewtonScript heap. Dictionary parts will allow the dictionary data to remain in your package.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 Store Parts\par \pard\plain \qj\fi180\sa240\keep \f20 Store parts allow your package to contain a read-only store. This read-only store contains soups with the data of interest. Unfortunately, the four character code for store parts is soup. This, plus the fact that store parts are only useful in that they pr ovide soups, will undoubtedly lead to them being erroneously called "soup parts."\par \pard\plain \s255\qj\sb240\sa240\keep \f20\fs36 Multi-Part Packages\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 What Are Multi-Part Pacakges\par \pard\plain \qj\fi180\sa240\keep \f20 As their name implies, multi-part packages are packages containing more than one part. If a multi-part package contains two form parts, then when it's installed the two icons for the form parts will show up in the extras drawer. The net effect will be the same as if you had created the two form parts in separate packages and then installed both packages.\par \pard \qj\fi180\sa240\keep Creating a multi-part package only serves to bundle parts together for purposes of installation and removal. It does not link any code together. It does not give the parts any special way to access each others data.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 How To Create Multi-Part Packages\par \pard\plain \qj\fi180\sa240\keep \f20 NTK 1.0.1 creates multi-part packages by merging packages together. You specify the packages to merge by putting them in the same folder with your project and renaming them {\f22 "include.pkg"}, {\f22 "include.pkg1"}, {\f22 "include.pkg2"}, \'c9\par \pard \qj\fi180\sa240\keep NTK will create a single package containing the part from the current project followed by the parts in the various included p ackages in order by their file names. The ordering of parts in packages is not normally of interest. However, part ordering does determine the order in which the parts are installed on the Newton. For form and auto parts this determines the order in which the install and remove scripts are called.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 Package-Wide Settings\par \pard\plain \qj\fi180\sa240\keep \f20 Certain options in the NTK Settings dialog (package-name, compression, copyright, version, copy-protection) apply to a package as a whole, not to its individual parts. Therefore, w hen building a mulit-part package, the values for these options are taken from the the project being built \endash ignoring the corresponding options used when the various {\f22 "include.pkgx"} files were built.\par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 When To Create Multi-Part Packages\par \pard\plain \qj\fi180\sa240\keep \f20 I don't think we have enough experience developing Newton applications yet to give a definitive answer as to when multi-part packages are appropriate. My feeling is they'll turn out to be less frequently useful than you might initially think.\par \pard \qj\fi180\sa240\keep For example, one use that probably comes to mind immediately is to bundle together your applica tion with its documentation, a book. This has the advantage of giving your users one thing to install and one thing to remove. The disadvantage is that it takes away the flexibility of allowing experienced users to save space by installing your application without the book.\par \pard \qj\fi180\sa240\keep Another case where it makes sense to use multi-part packages is when your application is broken up into modules for development purposes. In order to speed up your build cycles, some of you with very large projects may have started break ing up your program into separate modules (packages) and compiling/downloading the individual modules separately to save time. The advent of auto parts make this strategy even more appealing because each of your modules doesn't have to have an icon in the extras drawer. During the development cycle you probably want to keep all the modules as separate packages. However, now that you can create multi-part packages you can opt to bundle all the parts together for your final build as opposed to merging the pac kages together by hand.\par \pard \qj\fi180\sa240\keep In general, I advise carefully thinking about your decision to use multi-part packages. If you are shipping your product on a floppy you might even consider providing it in various configurations and letting your users decide what is most convenient. \par \pard\plain \s254\qj\sb120\sa240\keep \b\f20 Unique Name Generation and Multi-Part Packages\par \pard\plain \qj\fi180\sa240\keep \f20 Multi-part packages throws a spin on the original DTS guidelines for generating unique names. For example, if your package contains two form parts you can't have them both use your package n ame as their app symbol. This is pretty obvious stuff. In practice, I think such conflicts will be a rare occurrence. The original guidelines should still work pretty well.\par }