Creating Applications with Multiple Source Files


Advantages

Splitting your Goc application into multiple source files is a good thing, for several reasons:

  1. Since a code resource (memory block) is generated for each source code file, you can control the size of your code resources. Remember that in GEOS, resources should be kept between two to six kilobytes in size, for optimal paging.
  2. Class definitions (@class/@endc), if placed in .goh files, can then be accessible as a library for your own development, as well as for other developers.
  3. Compilation time can be reduced, since PMAKE only needs to recompile those files which have changed.
  4. Normal C code can be separated from Goc code, to improve code readability and organization.

The Source Files

This document outlines the guidelines for creating multi-source file GEOS applications that will compile and run correctly. The steps are divided by file type as follows:


Application Header - app.goh

This header file will declare all the #define'd constants and typedef'd data types. It will also contain all the @class/@endc Goc class definitions. In this file, place statements of the kind:


Globals Header - global.goh

This header file will declare as extern all the global variables and all the Goc objects. Any globally-used routines can have their prototype declarations here as well:


Static Objects - appUI.goc

The standard Geoworks paradigm is to put all the static object definitions in this one file. Remember that different resources will be defined within this file.

Since the Glue linker does not create links between objects if they are in separate source files, you must keep children in the same source file as their parent. In other words, all objects that are statically connected should be in the same file.

However, objects that are linked only within an object subtree, such as document or display templates, can be stored in separate .goc files. (These resources are typically duplicated at run-time, using the kernel routine ObjDuplicateResource(), and then dynamically added to the application's object tree, using MSG_GEN_ADD_CHILD().)

You can also store objects that are related to each other, say those that are part of a menu, in a separate source file. When you do this, you must then dynamically add these menu object trees to the GenPrimary in your appUI.goc file. Here is roughly how to do this:

In the process.goc file (GenProcessClass methods):

    @extern method MyProcessClass, MSG_GEN_PROCESS_OPEN_APPLICATION  { 
        if ( !( attachFlags & AAF_RESTORING_FROM_STATE ) ) { 
            /* 
             * Do only if not restoring from state. 
             * The 2 in the second parameter is the position 
             * among the primary's children. Ie. MyOptionsMenu 
             * will be the third child of the primary. 
             */ 
            @send MyPrimary::MSG_GEN_ADD_CHILD( MyOptionsMenu,
				( CCF_MARK_DIRTY | 2 ) ); 
            @call MyOptionsMenu::MSG_GEN_SET_USABLE( 
				VUM_DELAYED_VIA_APP_QUEUE );
            @callsuper(); 
        } 
    }

If you're going to be adding controllers, you'll probably have to add them to the GCN lists in the application object. Use MSG_META_GCN_LIST_ADD to do this:

    @call application::MSG_META_GCN_LIST_ADD( 
			@MyControllerObject, 
			GAGCNLT_SELF_LOAD_OPTIONS, 
			MANUFACTURER_ID_GEOWORKS );

With this taken care of, you can have your appUI.goc file contain the objects that are related to the application and primary objects. Then, you can put the sometimes large object trees related to a menu in another source file. This keeps the compile time shorter and the code easier to organize and read.

Contents of appUI.goc

  1. Include all the necessary header files:
  2. Define all the global variables (that you declared as extern in the global.goh file):
  3. Declare the classes that this file will use when defining objects, using the Goc @classdecl keyword:
  4. Declare the methods for these classes -- since these will be defined in separate .goc files, we declare the methods using the @extern keyword. If you don't do this, the code will not cause a compile error, but the code will never be executed:
  5. Define static objects in user-defined object resources. You should declare your resources using the @start and @end Goc keywords, and define your objects using the @object keyword:

Methods - method1.goc, method2.goc, etc.

These files hold the method definitions for the classes. Remember that each .goc source file becomes a code resource for your application. So it's a good idea to group related methods/routines in the same file. This can help reduce the paging that your application will generate by using locality of code reference.

Contents of method1.goc, method2.goc, etc.

  1. 1. Include the necessary files:
  2. Prototype the functions local to this file. (Remember that the prototypes for globally-used routines were declared in globals.goh.)
  3. Define your methods (using the @extern method Goc keywords) and your routines. Don't forget to define your globally-used routines somewhere.

C Code - code1.c, code2.c, etc

These files hold normal C code -- no Goc compiler directives (keywords beginning with @) exist within. Placing C code into separate files is good since they won't have to run through the Goc preprocessor which will reduce the compilation time. Remember that each .c source file becomes a code resource for your application. So it's a good idea to group related routines in the same file. This can help reduce the paging that your application will generate by using locality of code reference.


Whitepapers

Last modified: Thu Jan 8 10:37:10 PST