Tips   >   Misc   >   Multiple Libraries

Multiple Libraries

I recommend that you build your application using multiple libraries. It makes your code a lot easier to view because the code is broken into logical groups (libraries). Instead of looking at a list of all the schemas, or all the file classes, or all the window classes, or all the report classes, in your entire application, using multiple libraries you just view the classes in, for example, the Accounts Payable library.

There are just a few things to get used to/do differently with multiple libraries, but once you get those things set up, it's very easy to work with.

You need a main library which the users double-click on to open your application. In the $construct of the Startup_Task of the main library, you call a method ie. openLibraries, which the automatically opens your sub-libraries.

See the topic Directory Structure for a recommended way of organizing your sub-libaries in subfolders.

In my app, the main library only contains generic code. Superclass tables, superclass windows, superclass objects are all stored in the main library. That way if there is a problem with a superclass, I go straight to the main library and can always find it there. Commonly used menus, toolbars, and objects are also stored in the main library.

There's a couple things you have to watch with multiple libraries.

  1. Set the $defaultname property of every library. If the $defaultname is not set, the library name will change if you or the user changes the file name. Changing the library name will break multi-library dependent code.
  2. If you create a subclass in one library and then drag the class to another library, you must prefix the $superclass property of the class with the name of the library which contains the superclass. A better way to handle superclasses is to set the $issupercomponent property to kTrue and create the subclass through the Class Wizard. See the Super Components topic for more information.
  3. Set the $designtaskname property in all your windows, reports, objects to the main library startup task. In my application, the main library default name is 'CSP', so all my Window, Report, Table, Schema, object classes have the $designtaskname property set to "CSP.Startup_Task".
  4. If you need to access a window, report, or object class in a different library, the $external property of the class must be set to kTrue, otherwise it won't be visible in design mode and won't be accessible in runtime mode. Omnis Studio defaults new classes to $external=kTrue. You can set $external to kFalse if you don't want the class to be visible or accessible from outside of the library.
  5. Be aware of the current task instance ($ctask). Unless you need multiple tasks, just run your application under the main library's Startup_Task task instance... the one that automatically opens when the main library is opened.
  6. When you open sub-libraries from your main library check the Do not close others and Do not open startup task options. This will prevent the sub-libraries from having their own tasks. You can even go so far as to delete the Startup_Task class from your sub-libraries. To make my life easier for the developer I put a modified copy of the main library Startup_Task in each sub-library so that the main library Startup_Task task variables are visible to all the classes in each sub-library in design mode. In the sub-libraries I delete all of the Startup_Task methods and then add a $construct method with a single line of code which immediately closes the task instance. Do $cinst.$close()

Think of the task instance as a container of instances. When you open your main library it automatically opens up a task instance. When you install a menu from the task instance, the menu instance is contained in the task instance. When you use that menu to open a window (in the same library, or another library), that window instance is now also contained in the task instance. Being part of the task instance gives anything within the task access to the task variables. They are said to be in scope of the task.

If you are working in development mode on a window in a sub library and you Ctrl/Cmnd+T to open the window instance, you will find if you step through code that is run by the window, the task variables in the main library's startup task instance are out of scope. You can't access them. That is because the window instance was not opened by something which was contained in to the main library startup task instance. When you did a Ctrl/Cmnd+T to open the window instance the window instance was probably opened in the default task. Runtime users don't get the chance to do this, it's more when you are developing that you run into this.

Multi-libraries, I strongly recommend them! There's lots of advantages, very few disadvantages. Easy to do. See the sample code and demo in this section for Open Sub-Libraries.

Directory Structure

There are many ways to set up your directory structure for multiple libraries.

Here is a sample multi-library file structure which I use for my applications.

(> character is used for indenting)


MyApp (folder)

> open_MyApp.lbs

> libraries (folder)

> > MainLibrary.lbs

> > modules (folder)

> > > SubLibrary1.lbs
> > > SubLibrary2.lbs

The user double-clicks open_MyApp.lbs, its Startup_Task $construct method looks for a libraries folder within the same parent folder and then opens any libraries directly contained in the libraries folder. In this case, there is only one library, MainLibrary.lbs. The Startup_Task of MainLibrary looks for a modules folder within the same parent folder and then opens any libraries directly contained in the modules folder.

You could have other folders within the libraries folder that contain special utilities or demo libraries.

When the main library is closed, the $destruct method of its Startup_Task closes any libraries who's $pathname is within the main library's parent folder.

In the studiotips/demos folder there is a multi_library folder which gives you an idea of how you can set it up. Double-clicking on open_MyApp.lbs opens /libraries/MainLib.lbs which then opens a main window. The main window has an Open Sub-Libraries button which opens the modules and a window in each of the modules.

Click the Run Demo button in the StudioTips Browser window to open the multi-library demo. Feel free to experiment with the multi-library demo.

Open Sub-Libraries

This method is in the main library and is used to open all the sub-libraries. The sub-libraries are located in the modules folder which is located within the same parent folder as the main library.

Click the Run Demo method in the StudioTips Browser window and then look at the oOpenLibraries object class in the MainLib.

AutoUpdater

Tired of manually uploading new versions of your software to the server, telling users to download the updates, and then having users mess up on the relatively simply job of dragging the updated version from the server to their computer?

Here's a strategy that I use with my multi-library applications, that has relieved me of all of the above.

Rather than having the users directly open the main library of your application have them double-click on an AutoUpdater library. Place your application's libraries in a libraries subfolder. See the Directory Structure topic for a suggested folder structure.

When the user opens the AutoUpdater library on their local computer, it first checks a files server for any newer version libraries, downloads them to the local computer, and then proceeds with opening the main library. The main library's Startup_Task then automatically opens all the sub-libraries on the user's local computer.

I developed a utility called AutoUpdater which does all of the above plus the following extra features:

  1. Each time AutoUpdater is opened it compares the subfolder structure and files specified on the files server to its own subfolder structure and files and automatically creates any new subfolders and downloads any new files. Initially all you need on the user's computer is the AutoUpdater.lbs file in an empty folder. The first time AutoUpdater is opened it will automatically download all the subfolders and files from the files server.
  2. Allows the developer to easily upload newer version libraries to the files server as stable or beta release libraries.
  3. Allows the runtime user to switch from stable to beta release versions of the libraries.
  4. Support using FTP or a database as the files server.
  5. Users can be given a Check for Updates... menu option.
For more information visit
http://www.studiotips.net/docs/autoupdater/autoupdater.html