Programming Conventions
From RISC OS
This article is a collaborative attempt to summarise some RISC OS programming conventions. It may not represent every programmer's opinion however. Use the discussion page to disagree/comment on it.
Contents |
Introduction
This guide will introduce some of the conventions and techniques associated with writing a "well-behaving" RISC OS program. It does not address the technical aspects of programming under RISC OS (which it is assumed the reader is already familiar with) but deals with some of the "softer" issues. Where possible, further resources and references are given. In particular, "PRM" refers to the Programmer's Reference Manual and "SG" refers to the Style Guide.
The guidance given in this article is not cast in stone, but should be adherred to unless there are convincing reasons why a certain situation demands a different solution.
!Boot
Choices
It is recommended that the choices for an application are stored in a dedicated place on the system. This makes it easy for a user to upgrade the program whithout changing their settings, allows the application to run from a read only medium and on modern, multi-user OSes means each user can easily have different saved choices. Choices and settings should not, therefore, be stored within the application directory.
To achieve this, user choices should be written to <Choices$Write>.AppName
and read from Choices:AppName
. (This is a general rule: where reading takes place from Example:Path
, the corresponding write location is <Example$Write>.Path
.) For a more detailed explanation, take a look here. AppName
should be registered with the allocation service.
(PRM5a:530-531,539)
While it is generally good practice to write (and read) choices to the locations referenced by the variables outlined above, there is one caveat. It is entirely possible for a user to be running on a system where they have no write access to most of the hard drive. (Consider FSLock in Configure.) For example, this may be in a school or office situation where the system administrator wants to prevent users from altering too much on the machines. As a minimum, therefore, programs should fail gracefully if they find they can't write to <Choices$Write>
and ideally, should also provide some mechanism whereby the location of the application's choices can be chosen by the user.
Modifications
Great care must be taken when modifying a user's boot sequence. If this is absolutely necessary, the user should be informed (and given a choice) about what the application intends to do. The application should keep a log of what happened and, ideally, provide a means to roll back the changes.
To install a stand-alone program in the boot sequence, use the system variable Boot$ToBeTasks
(unless the program is necessary for the completion of the boot sequence, in which case it should go in Boot$ToBeLoaded
).
Scrap usage
To make use of the Scrap directory, programs should read and write to <Wimp$ScrapDir>.AppName
. (Where AppName
is the name of the program, and/or has been allocated specifically.)
Distribution of Modules
In the majority of cases modules should be distributed inside the applications which use them. However, if a module is likely to be used by other programs, it might be worth considering distributing it for installation into !System
. This has two benefits: it means that each program which uses it does not have to supply it separately and also makes keeping the module up to date (when newer versions are released) much easier for the user.
Modules which are destined for !System
should be supplied in a dummy !System
application which the user can then use with their computer's in-built "System Merge" utility. The structure of
the dummy application will be:
!System.Modules.<minOS>.YourModule
where <minOS>
is the minimum version of the OS which is required to run the module. So, for example, if a module is only suitable for an Iyonix, <minOS>
will be 500.
UniBoot
Most end-users ought to be using the UniBoot distribution for their boot sequence, but this should not be assumed. If the use of the nested window manager is required, an application should check for version 3.80 of WindowManager. If it's not present the application should direct users to the RISCOS Ltd website where it can be downloaded and installed.
Sprites
As a minimum, applications should have a !Sprites
file which includes a mode 12 sprite called !AppName
. Note that sprite names are limited to 12 characters so, if a program has a long name, and the first 12 characters match another program, the sprites may get confused.
!Sprites
can also contain sm!AppName
which should be half the size of the main sprite, for use when the user has "small icons" showing in their directory viewer. There's no point in just shrinking the sprite without touching it up, however, as the filer will automatically scale the large version of the sprite if sm!AppName
is not present. If present, and if the user's screen mode supports it, !Sprites22
will be used in preference to !Sprites
. It should contain a mode 20 sprite. Likewise, a !Sprites11
file may be included which has a 180dpi sprite. From RISC OS 4 onwards, 256 colour sprites may be used. If ic_taskname
is present, it will be used when the application windows are iconised to the pinboard or iconbar. (taskname
is the string given in Wimp_Initialise
.)
Application sprites should be irregularly shaped, with transparent backgrounds and document sprites should have a solid outline, preferably with the curled corner present in many default sprite sets. This helps the user distinguish easily and quickly between the two types of object.
(SG:17,89,93)
Icons should not attempt to be photographic quality pictures. They should be clear, iconic representations of whatever it is they are trying to communicate.
Application icons should go on the right of the icon bar and not have text under them, unless they are for devices. They should only be animated with good reason.
To avoid cluttering up the Wimp sprite pool, only application sprites, iconised icon and any filetype sprites should be *IconSprites
ed. The command is always *IconSprites <YourApp$Dir>.!Sprites
: the Wimp will itself add the numeric suffix for the appropriate resolution and colour depth. If an application requires the use of further sprites, they should be loaded into its own workspace. (For instance, by using the OS_SpriteOp,