Timer Workshop
This workshop provides a tool for monitoring timers and testing timer configurations. To open this workshop, first open a procedure window and then choose Program>Timer Workshop. This workshop contains two panels, Monitor Running Timers and Create Timer.

A special thank you to Gary Yonaites for the idea of this workshop, and for writing most of the Create Timer panel.

### The Monitor Running Timers Panel

This panel displays any timers that are currently running. For example, suppose you have created two timers with this code (see starttimer).

    starttimer "timer one", "code",{nslog "The time is "+longtimestr(now())}
    starttimer "timer two", "interval",60, "code",{nsnotify "It's "+timestr(now())}

If no other timers are running, the Timer Workshop display will look like this:

The monitor spans six columns:

- Name – This is the name of the timer. Each timer must have a unique name.
- Interval – This indicates how often the timer will run. In this case, timer one runs once per second, and timer two runs once per minute (60 seconds).
- Count – This is how many times the timer has run so far.
- Max – This indicates how many times the timer will run before automatically stopping. If this is ∞ then the timer will never stop (unless the scope it is attached to closes, or it is explicitly stopped by a program).
- Next Runtime – This is the next time this timer can run. Note that if the scope of the timer is not active (for example the database or window is not frontmost), the timer will not run until that scope is active.
- Scope – Indicates the scope when the timer can run, which can be global (always runs), a particular database, or a particular window.

The Count and Next Runtime values will update live as the timer runs. (Keep in mind, however, that a timer only runs when its scope is active. If a timer appears to be stuck, that means its scope is inactive.)

#### Pop-Up Context Menu

When you click on a timer (you can click anywhere on the line) a pop-up menu appears:

You can display more detail about the timer, suspend it, or stop it. (Or, if the timer is already suspended, you will have the choice to resume it.) If you stop the timer it will be removed from the list.

If you chose Timer Detail a separate window will appear:

You can view the timer code, pause/resume, or stop the timer (which closes the window). The count and next runtime values will update as the timer runs. You can open as many timer detail windows as you like (one per timer). If the timer stops on its own (for example the scope it is attached to closes) you will have to close the window manually.

#### Password Protected Timers

The monitor panel normally doesn’t display timers that are password protected (see starttimer). You can create your own password protected timers, but Panorama also creates these timers for its own internal use and it’s best if you don’t mess with these. But if you create your own password protected timers and want to monitor them, go to the Advanced panel in the Preferences dialog (in the PanoramaX menu) and enable the Display Password Protected Timers option. (Note: Clicking on the clock icon next to this option is another way to open the Timer Workshop.)

After a warning, the option will be enabled. At the time this screen shot was taken, there were two password protected timers running.

When you try to suspend or stop a password protected timer, Panorama will ask you for the password before proceeding. There is also an explicit Unlock option in the context menu:

Once a timer is unlocked, it will stay unlocked until it stops running. You won’t have to enter the password over and over again (for example if you are suspending then resuming).

### The Create Timer Panel

This panel allows you to create and test the code for a timer mostly using pop-up menus and stepper controls. The only items you have to type in are the timer name and the code for the timer (see the starttimer page to learn more about the options on this panel). This example is an annoying timer will beep every ten seconds, no matter what Panorama window is in front (and even if Panorama is in the background).

To try out this timer you can simply press the play button.

As the timer is running, the workshop will display the run count, which will increment each time the timer runs. You can press the stop button at any time to stop the timer.

Of course you can also switch to the monitor panel to view and control your timer there:

Once you have the timer code working the way you want it to, you can copy it to your own procedure. There are three ways to do this: 1) Press the Copy Code button, 2) Drag the share icon to your procedure window, or 3) Directly select code in the window and copy it.

See Also

- Automatic Field Code -- running a short program when data is entered into a field.
- changetimer -- modifies a repeating task that will be performed periodically when Panorama is not otherwise busy.
- endnoshow -- resumes the output of text and graphics after it has been disabled with the noshow statement.
- executeasap -- executes the specified code at the first possible opportunity, non-atomically.
- Implicitly Triggered Procedures -- Procedures that are triggered automatically when the user performs some normal Panorama action are said to be "implicitly triggered."
- info("computername") -- returns the name of the computer (as set up in the System Preferences Sharing panel).
- info("noshow") -- returns true if noshow is currently turned on, false if it is not.
- info("runningatomic") -- returns true if the current procedure is running as a "atomic" procedure.
- info("timerinfo") -- returns a dictionary that contains all of the properties of the currently running timer.
- info("timers") -- returns a carriage return separated list of all active timers.
- noshow -- temporarily disables the output of text and graphics.
- resumeaftertask -- resumes after a waitfortask statement.
- setwaitinglocal -- assigns a value to a local variable in the parent procedure of an asynchronous task, allowing the asynchronouse code to pass a value back to the code that spawned it.
- starttimer -- sets up and starts a repeating task that will be performed periodically when Panorama is not otherwise busy.
- stoptimer -- stops and deletes a timer that was set up with the StartTimer statement.
- timerexists( -- checks to see whether a timer exists.
- timerinfo( -- returns a dictionary that contains all of the properties of a timer.
- Timers -- executing recurring periodic background code at fixed intervals.
- Understanding the Run Loop -- explanation of how Panorama code interacts with the run loop to respond to mouse clicks, keyboard presses, display updates and other events that require attention.
- wait -- pauses the program for a specified period of time.
- waitfortask -- temporarily pauses a procedure until the specified task is complete.

History

Version | Status | Notes
10.2 | New | New in this version.