The timeline API is used to create, manage, and communicate the lifecycle of entities with finite lifespan within the RIP and SDK. More...
Files | |
file | timelineapi.h |
Header file defining the Timeline API. | |
file | timelineerrors.h |
Header file defining the Timeline API result translation. | |
Data Structures | |
struct | SWMSG_TIMELINE |
Common timeline event message. More... | |
struct | sw_tl_options |
Options for SwTimelineStartEx(). More... | |
struct | sw_timeline_api_20110623 |
Timeline API struct for version 20110623. More... | |
struct | sw_timeline_api_20170413 |
Timeline API struct for version 20170413. More... | |
Macros | |
#define | SW_TL_EXTENT_INDETERMINATE DBL_MAX |
A timeline extent value representing an indeterminate value. More... | |
#define | SW_TL_OPTIONS_INIT { sizeof(sw_tl_options), SW_TL_PROLONG_AUTO, FALSE, FALSE, 0u, SW_TL_PROGRESS_SUPPRESS, } |
Explicit auto/static initialiser for sw_tl_options structure. | |
Typedefs | |
typedef HqnIdent | sw_tl_ref |
A unique identifier for a Timeline. | |
typedef int | sw_tl_state |
Type of variables in which timeline state values TL_STATES are stored. | |
typedef HqnIdent | sw_tl_type |
Timeline types. More... | |
typedef HqnIdent | sw_tl_unit |
Timeline units. More... | |
typedef int | sw_tl_priority |
Timeline priorities. More... | |
typedef double | sw_tl_extent |
Timeline extents and progress. More... | |
typedef HqnResult | sw_tl_result |
A type used to communicate return values from timeline API calls. More... | |
typedef HqnIdent | sw_tl_context |
Timeline context identifiers. More... | |
typedef struct sw_tl_options | sw_tl_options |
Options for SwTimelineStartEx(). More... | |
Enumerations | |
enum | { SW_TL_REF_INVALID = 0 } |
Well-known identifiers for timelines. More... | |
enum | TL_STATES { TL_STATE_START = 0 , TL_STATE_TITLE , TL_STATE_EXTEND , TL_STATE_PROGRESS , TL_STATE_END = 32 , TL_STATE_ABORT , TL_STATE_ENDING , TL_STATE_ABORTING , TL_STATE_ENDED , TL_STATE_ABORTED , TL_STATE_UNKNOWN = 64 } |
Timeline states. More... | |
enum | { EVENT_TIMELINE_START = EVENT_TIMELINE+TL_STATE_START , EVENT_TIMELINE_TITLE = EVENT_TIMELINE+TL_STATE_TITLE , EVENT_TIMELINE_EXTEND = EVENT_TIMELINE+TL_STATE_EXTEND , EVENT_TIMELINE_PROGRESS = EVENT_TIMELINE+TL_STATE_PROGRESS , EVENT_TIMELINE_ENDING = EVENT_TIMELINE+TL_STATE_ENDING , EVENT_TIMELINE_ENDED = EVENT_TIMELINE+TL_STATE_ENDED , EVENT_TIMELINE_ABORTING = EVENT_TIMELINE+TL_STATE_ABORTING , EVENT_TIMELINE_ABORTED = EVENT_TIMELINE+TL_STATE_ABORTED } |
Timeline event numbers. More... | |
enum | { TL_SKIN = 0x4000 , TL_SKIN_PRIVATE = 0x5000 , TL_PLUGAPI = 0x6000 , TL_PLUGAPI_PRIVATE = 0x7000 , TL_CORE = 0x8000 , TL_CORE_PRIVATE = 0x9000 , SW_TL_TYPE_ANY = 0 , SW_TL_TYPE_NONE = 0 } |
enum | { SW_TL_UNIT_INVALID = 0 , SW_TL_UNIT_NONE , SW_TL_UNIT_BYTES , SW_TL_UNIT_JOBS , SW_TL_UNIT_PAGES , SW_TL_UNIT_BANDS , SW_TL_UNIT_LINES } |
Pre-defined units for timelines. More... | |
enum | { SW_TL_PRIORITY_UNKNOWN = INT_MIN , SW_TL_PRIORITY_AUTO = SW_TL_PRIORITY_UNKNOWN , SW_TL_PRIORITY_BLOCKING = SW_TL_PRIORITY_UNKNOWN+1 , SW_TL_PRIORITY_NORMAL = 0 } |
enum | TL_RESULT { SW_TL_SUCCESS = HQN_RESULT_SUCCESS , SW_TL_ERROR , SW_TL_ERROR_UNKNOWN , SW_TL_ERROR_SYNTAX , SW_TL_ERROR_IN_USE , SW_TL_ERROR_MEMORY } |
enum | { SW_TL_CONTEXT_OWNER = 0 } |
Well-known context identifiers for timelines. More... | |
enum | { SW_TL_PROLONG_FALSE = 0 , SW_TL_PROLONG_TRUE = 1 , SW_TL_PROLONG_AUTO = 2 } |
Values for the sw_tl_options::can_prolong options field. More... | |
enum | { SW_TL_PROGRESS_SUPPRESS = 0 , SW_TL_PROGRESS_START = 1 , SW_TL_PROGRESS_END = 2 , SW_TL_PROGRESS_MID = 4 , SW_TL_PROGRESS_FIRST = 8 } |
A bitmask of flags used to control which progress messages are not suppressed. These values may be combined in the sw_tl_options::progress_not_suppressed options field. These options do not affect changes to the extent. More... | |
Functions | |
sw_tl_ref | SwTimelineStart (sw_tl_type type, sw_tl_ref parent, sw_tl_extent start, sw_tl_extent end, sw_tl_unit unit, sw_tl_priority priority, void *context, const uint8 *title, size_t length) |
Create a Timeline, issuing a Start Event immediately. More... | |
sw_tl_ref | SwTimelineStartEx (sw_tl_type type, sw_tl_ref parent, sw_tl_extent start, sw_tl_extent end, sw_tl_unit unit, sw_tl_priority priority, void *context, const uint8 *title, size_t length, const sw_tl_options *options) |
Create a Timeline with a specified set of options, issuing a Start Event immediately. More... | |
sw_tl_result | SwTimelineEnd (sw_tl_ref ref) |
Potentially end a Timeline. More... | |
sw_tl_result | SwTimelineAbort (sw_tl_ref ref, int reason) |
Potentially abort a Timeline. More... | |
sw_tl_result | SwTimelineSetTitle (sw_tl_ref ref, const uint8 *title, size_t length) |
Change the title of a Timeline. Issues an Event before changing the title. More... | |
size_t | SwTimelineGetTitle (sw_tl_ref ref, uint8 *buffer, size_t size) |
Return the Timeline's title and length. More... | |
sw_tl_result | SwTimelineSetExtent (sw_tl_ref ref, sw_tl_extent start, sw_tl_extent end) |
Extend the length of the Timeline. Issues an Event for a nonzero change. More... | |
sw_tl_result | SwTimelineSetProgress (sw_tl_ref ref, sw_tl_extent progress) |
Update the progress of the Timeline, in the units given when the Timeline was started. Issues an Event if the current value changes. More... | |
sw_tl_result | SwTimelineGetProgress (sw_tl_ref ref, sw_tl_extent *start, sw_tl_extent *end, sw_tl_extent *progress, sw_tl_unit *unit) |
Return the extent, unit and progress through a Timeline. More... | |
sw_tl_ref | SwTimelineGetAncestor (sw_tl_ref ref, sw_tl_type type) |
Return the nearest ancestor of the Timeline of the specified type. More... | |
sw_tl_ref | SwTimelineOfType (sw_tl_ref ref, sw_tl_type type) |
Ensure the Timeline or an ancestor is of the given type. More... | |
sw_tl_type | SwTimelineGetType (sw_tl_ref ref) |
Return the Timeline type if known. More... | |
sw_tl_priority | SwTimelineGetPriority (sw_tl_ref ref) |
Return the Timeline priority if known. More... | |
sw_tl_result | SwTimelineSetContext (sw_tl_ref ref, sw_tl_context id, void *context) |
Attach a secondary context to a Timeline. More... | |
void * | SwTimelineGetContext (sw_tl_ref ref, sw_tl_context id) |
Return a context from the Timeline. More... | |
static HqnResult | timeline_result_translate (sw_tl_result result) |
Translate a timeline-specific error code to a generic HqnResult error code. More... | |
The timeline API is used to create, manage, and communicate the lifecycle of entities with finite lifespan within the RIP and SDK.
The timeline API allows entities with a finite lifespan to be uniquely identified, with a type and human-readable title. The resulting reference can then be used to identify the entity, associate contextual information with it, and detect when it no longer exists. Additionally, the lifespan of such entities can be managed, communicated to interested parties and negotiated. They can be linked to related superior or subordinate entities. Related information can be attached to a timeline and retrieved later, even after the timeline has ended. Timelines can be used to report state and monitor progress of a timeline through its lifecycle.
The timeline API makes extensive use of the events and is independent of the RIP core.
A timeline is a way of representing any entity within software that has a finite life; that is, a start, an existence, and an end. Anything that has finite life associated with it that you need to refer in some kind of unique way could be represented by a timeline. It is of no use to anything which is hard-wired into the program which exists from the moment the program starts and continues until the program ends.
Timelines are mainly used in the RIP to represent internal RIP processes, for lifespan or status monitoring. They could also be used to represent physical entities or resources. Some use cases for timelines are:
A timeline has:
Timelines are created using SwTimelineStartEx() or SwTimelineStart(). They are ended using SwTimelineEnd() or SwTimelineAbort(). The timeline hierarchy can be navigated using SwTimelineGetAncestor() and SwTimelineOfType(). Progress for a timeline may be determined or set using SwTimelineGetProgress(), SwTimelineSetProgress(), and SwTimelineSetExtent(). The timeline title can be queried using SwTimelineGetTitle() and modified using SwTimelineSetTitle(). Context data for a timeline can be retrieved using SwTimelineGetContext() and set using SwTimelineSetContext(). The type of a timeline may be discovered using SwTimelineGetType(), and the priority may be discovered using SwTimelineGetPriority(), though both of these operations are rarely necessary.
The timeline system provides a method of uniquely identifying an entity with a non-pointer reference of type sw_tl_ref. Timeline references are 32-bit integers, and could eventually be re-used, but that is not likely within the lifetime of a RIP. A reference can be retained once that entity has stopped existing. References should not be used as keys for persistent storage, since each RIP instantiation will re-start the timeline reference sequence.
The invalid timeline reference, SW_TL_REF_INVALID, should be used to initialize timeline reference variables. This is defined to have value zero.
Each timeline has a type, of type sw_tl_type. This is an identifier indicating the type of entity that the timeline represents. The meaning and type of context data attached to the timeline, the progress units and indications, and the representation and use of the timeline title are all defined by the timeline type. The documentation for each timeline type should indicate how these are used. In some cases, there may be more than one instance of a timeline type present in the system at a time: the parent reference, title, and context data may be used to discriminate between individual instances.
Timeline type numbers are split into ranges, defined in timelineapi.h and sub-divided in core and skin headers elsewhere. Timeline type numbering follows the numbering conventions for DEVICETYPE numbers.
Timelines naturally form a hierarchy. When a timeline is created it can be defined with a parent timeline reference. A timeline is either a child of another timeline or an autonomous timeline in its own right. The reason for this hierarchy is that in a multithreaded and more especially a pipelined RIP (in fact any program that has to deal with more than one thing at a time), you can have a number of distinct elements of the same type all of which will have their own lifetime. The RIP may be interpreting one page while rendering a different page: each page may have its own timeline references simultaneously. If you have an open dialog associated with a particular page, there is no point in closing that dialog when an unrelated page finishes. The timeline system provides a method of unique identification which is retained even if the entity has ceased to exist, and if you do try to use it you will get a safe error result.
The timeline hierarchy allows a single reference to a specific entity within the system to be used to navigate to more general entities. Given a timeline reference, you can ask for ancestor timelines, and you can also as for ancestor timelines with a particular type. In the case of the RIP, with a timeline reference, you can ask for a core job timeline that is part of a hierarchy. From a reference to a very specific entity, one call will give you the reference for that overall job.
As any sub-system is free to attach child timelines to any other timeline, no assumption should be made of the topography of a timeline hierarchy unless explicitly documented. Calls are provided to find the type and title of a timeline, and ancestors of any or a particular type. This allows clients to discover if timeline events relate to the timeline it is most interested in, even if only distantly related.
Some of the entities that a timeline can represent may not have a meaningful notion of progress: only the starting and ending of the timeline are meaningful events. Other entities may be able to indicate progress, but not be able to measure it against a known end point. Finally, some entities have a meaningful notion of progress, and can measure it against well-defined limits. What progress means is documented for separately for each timeline type.
Timelines represent these differing notions of progress using a start position, an end position, a current position, and a unit of progress. The start, end, and current position are measured using values of the sw_tl_extent type. The start does not have to be zero, it could be any value defined by the timeline type. The start value may be larger than the end value, indicating a depleting resource or a progress indicator that counts down. The special value SW_TL_EXTENT_INDETERMINATE is used to indicate that the end position is indeterminate. You should not attempt to indicate a proportion of completion for a process when its timeline has an indeterminate end, but you may indicate that the process is making progress by monitoring changes to its current position.
Timelines also have a unit in which these extents and progress are measured, represented by values of the sw_tl_unit type. The SDK defines a number of different units of progress including a number of bytes, jobs, pages, bands, and lines, but you can also introduce your own units as required (e.g., if you wish to represent volts or degrees Celsius). If the timeline unit type is SW_TL_UNIT_NONE, the timeline should not indicate progress.
The creator of a timeline may manage how progress is updated by passing a sw_tl_options structure to SwTimelineStartEx(). Progress may be defined to be monotonic (it only ever moves in the direction from the start to end position), it may be clamped to the start and end positions rather than being allowed to exceed those limits, and progress update events may be rate-limited, so they don't swamp the system. Some significant progress update events (such as the first and last updates) may be explicitly permitted even if they would otherwise be suppressed or rate-limited.
When a timeline is created, as well as specifying the extent, the units and the title of the timeline, a context pointer is also provided. This context has a wide range of uses. Every handler that gets called with an event on that timeline immediately has access to the contextual information for that timeline. It is possible to attach any number of separate pieces of context information to a timeline, and third parties can attach their own information to timelines. For example, third party code that wants to keep track of an object associated with page interpretation could use a handler that gets called when the page interpretation timeline is started. Rather than having to keep track of that timeline and its memory structures, it can create and attach those structures to that timeline in the start event and then forget about it. The next time there is an event for that timeline it can use the SwTimelineGetContext() call from the timeline API to get its context back. This means that it doesn't have to do any of its own context management, and that disparate systems can share the same workspace and information without actually having any connection between them.
Context data attached to the timeline can be manipulated by any client, with one exception: the creator of a timeline may attach a "primary" context to a timeline on creation. This context cannot be removed or changed by any client, and should have a lifetime at least as long as the timeline is active. If the primary context is not documented for a timeline type, you should not attempt to dereference or manipulate it.
Context data is attached and retrieved from a timeline using context identifier of type sw_tl_context. Context data identifiers are specific to the timeline type, though the RIP and SDK do no re-use content identifiers for different timeline types to avoid confusion. The context identifier numbering scheme is extensible, you may define your own context identifiers in a manner that will avoid conflict with other uses.
Timelines have a priority of type sw_tl_priority, which is used to determine how timelines interact with their parent and child timelines in the timeline hierarchy.
When a timeline is created an event is issued to indicate that it has started. When the timeline ends, another event is issued to indicate that it has ended. However, it is possible that other parties have created timelines that are children of the timeline. When an attempt is made to end a timeline, the children of the timeline may wish to continue. Timelines may be created with dynamic scope, meaning they can be prolonged, or static scope, meaning they cannot be prolonged. If created with dynamic scope, the priority of a child timeline may be higher than its parent. If a child of a dynamically scoped timeline has the same or higher priority as its parent, ending the parent timeline may not cause it to end yet, it will be automatically prolonged until its child has ended. If the child is a lower priority, ending the parent timeline will automatically end the child timeline.
Assuming there are no child timelines with the same or higher priority that are going to prolong a timeline, when SwTimelineEnd() or SwTimelineAbort() are used the timeline system issues an EVENT_TIMELINE_ENDING or EVENT_TIMELINE_ABORTING event. In response to this event, other systems may object to the timeline ending and possibly to prolong it. If an event handler successfully negotiates to prevent the timeline from ending, the event handler takes responsibility for ending or aborting the timeline. Only timelines with dynamic scope may be prolonged in this manner: timelines with static scope will always be terminated regardless of objections to ending. When a timeline is actually ended or aborted, the timeline system issues an EVENT_TIMELINE_ENDED or EVENT_TIMELINE_ABORTED event.
The default behavior for timelines is to disallow children to prolong a parent timeline. This is the normal case when the lifetime of the timeline represents the scope of an object, which will be destroyed at the end of that scope regardless of any objections. In this normal case, even if handlers object to ending the timeline, or if child timelines are attached with a higher priority, the timeline will end. The ending event will be sent to the handlers first, followed by an ended event.
Timelines may be started with optional behavior specified. Amongst the options supported is an option to prolong the timeline, in which case the timeline can be extended by a higher-priority child or a handler objecting, as described above. A timeline with a dynamic scope (one that can be prolonged) can be created as a child of a timeline with a static scope, but not the other way around. An error will be returned if an attempt is made to create a static timeline as a child of a dynamic timeline.
The normal behavior when creating timelines is to use priority SW_TL_PRIORITY_AUTO, which will select a lower priority than the parent timeline.
All significant timeline state changes issue events. This allows interested parties to be informed immediately of the change, and in many cases allows event handlers to modify or prevent the change from happening. For example, the interpreter can communicate the job title as it is discovered, or the core could object to a font cartridge being ejected if it is currently in use. Events are issued for:
There are no events for changes to context data attached to timelines. It is normal to register event handlers for the EVENT_TIMELINE_ENDED and EVENT_TIMELINE_ABORTED events, rather than the EVENT_TIMELINE_ENDING and EVENT_TIMELINE_ABORTING events. It is also common to register the same handler for both the EVENT_TIMELINE_ENDED and EVENT_TIMELINE_ABORTED events, and use the event type to distinguish between them.
The SWMSG_TIMELINE message associated with all timeline events contains most of the information you will need when manipulating a timeline, including the timeline type, reference, parent, state, progress, priority, title, and the primary context of the timeline.
A number of operations in the RIP and SDK API may use or require a timeline reference, to discriminate between jobs, or to attach or extract contextually relevant data on the timeline. A common pattern used is to capture a timeline reference when a timeline is started, and invalidate the reference when a timeline is ended. This is performed using event handlers to capture the timeline reference, either into a global reference or an allocated structure. For example, to capture the core job timeline, which can be used to interrupt a specific job in the RIP, this code installs start and end event handlers, and sets the tl_ref
field of a context structure to the current job in progress:
Any code that has access to the my_context
structure in the example above could use the timeline reference safely, even while there is no job in progress. The timeline reference captured will be reset to the invalid value after a job completes, but the timeline API functions are also safe for use with expired timeline references.
The RIP and SDK uses timelines to represent the overall lifetime of the RIP, jobs, and the stages of processing jobs. The timelines defined and used by the RIP and the SDK are defined and documented in the header file swtimelines.h. The timelines that are probably of most interest for progress monitoring are described in section SDK and Core library Timelines. Some other timelines that may be of interest are:
Consider a printer that can take a font cartridge which contains fonts the printer can use. As far as the printer is concerned, before the cartridge is plugged in the cartridge does not exist. When it is plugged in it has a finite lifetime: from the time it is plugged in to the time it is removed. Once the cartridge is in the printer, the printer might start using some of the fonts. So consider what would happen when the printer is halfway through a job which is using fonts from the cartridge and you try to eject the cartridge using the eject button.
When you plug in the font cartridge you create a timeline of type "font cartridge" and immediately anything in the system that has registered an interest in font cartridges gets an event callback to inform it that the font cartridge is plugged in. Any timeline can have a context associated with it. So in this case it could be the information required to access the font cartridge.
When the eject button is pressed the application could attempt to end the font cartridge timeline. An event is issued, but if the printer is still using one of the fonts it can object to the timeline ending and the cartridge being ejected. At that point, the responsibility for that entity, in this case the font cartridge, passes to whatever objected (the printer).
So the objector (the printer) now owns it and the core can continue to use the fonts. At the end of the job, when the fonts are no longer needed, an event is issued stating that the fonts are no longer required, and at that point, if nothing else objects, the timeline for the font cartridge would actually end.
In this particular scenario the skin would have a handler for the EVENT_TIMELINE_ENDED event for the font cartridge and would then physically eject it. As far as the skin is concerned the action of ejecting is to end the timeline. The code to actually eject it is in the default handler for the "ended" event for that timeline.
Timelines automatically provide functionality that something else can object to the cartridge being ejected, can manage the lifetime of the timeline and then can finally cause it to be ejected when it is finished with. This process applies to anything that can be represented with a timeline.
A further example is of a print head containing ink cartridges. These would have some concept of progress: if you represented an ink cartridge with a timeline you could represent how much ink is left in the cartridge by progress along the ink cartridge timeline. You might also want to have some kind of control over the removal of a particular ink cartridge. Also, if the whole print head is removable then the concept of a hierarchy; with a print head parent timeline of which the ink cartridge timelines are children. This would mean all interested parties are automatically informed if he ink cartridges are being removed by the fact that you have removed the print head.
The timeline system is multi-thread and multi-client system. Timelines can appear and disappear at unpredictable times. In particular, this means a timeline can disappear after a call that returns some state from that timeline, but before the caller uses that state. Care must be taken that no assumption is made of timeline continuance where such timelines could end unexpectedly.
The timeline hierarchy is not fully documented at the moment. This is deliberate, there are some structural changes that Global Graphics intends to do to the hierarchy. Global Graphics recommends only using documented relationships between timelines to navigate the hierarchy, in case future changes invalidate your assumptions.
A timeline API pointer must be discovered using RDR using class RDR_CLASS_API and type RDR_API_TIMELINE and assigned to a suitably-named API pointer variable before the API macros are used. The timeline system is automatically started when the Harlequin RIP SDK is started. It remains active until the Harlequin RIP SDK is shutdown.
#define SW_TL_EXTENT_INDETERMINATE DBL_MAX |
A timeline extent value representing an indeterminate value.
This is used for extents that are unknown or unset.
typedef HqnIdent sw_tl_context |
Timeline context identifiers.
Any producer or consumer of timelines may attach a void pointer to the timeline, so it can associate its own data with the timeline. Contexts are identified by a number, used by the SwTimelineGetContext() and SwTimelineSetContext() calls to identify the particular piece of data. Timeline context identifier numbering follows the numbering conventions for DEVICETYPE numbers.
The value 0 is reserved for the creator of the timeline type, regardless of whether it is Global Graphics or a customer.
These ranges are sub-allocated here and elsewhere.
The owner context (ID SW_TL_CONTEXT_OWNER, defined to be zero) may only be associated with the timeline by the creator of the timeline, as an argument to the SwTimelineStart() call.
Callers that associate data with a timeline must also take responsibility for managing the lifetime of that data. In particular, callers should be aware that timelines may be prolonged beyond their normal scope, if a child timeline with higher priority defers ending. The caller should either detach context references from the timeline when it sees an EVENT_TIMELINE_ENDING, or use reference counting or another liveness management technique to ensure the context can survive until EVENT_TIMELINE_ENDED is issued.
typedef double sw_tl_extent |
Timeline extents and progress.
A Timeline can have an extent, measured in a unit. Progress along the Timeline is measured as a fraction of that extent.
A Timeline for which there is no way of knowing its extent can have an indeterminate extent.
typedef struct sw_tl_options sw_tl_options |
Options for SwTimelineStartEx().
Option values are arranged where possible so that the default behaviour happens with a zero value. It is still advisable to initialise auto/static options variables using the SW_TL_OPTIONS_INIT initialiser, and then override the fields of interest.
typedef int sw_tl_priority |
Timeline priorities.
Timelines within a hierarchy can have different priorities. These decide whether ending a Timeline automatically ends its children or waits for children to end.
Higher priority Timelines outrank lower priority Timelines. The priority of the Timeline being Ended or Aborted is compared with its immediate children, to determine whether the timeline can terminate automatically, or should wait for the child to terminate. Timelines will only end or abort children if they are strictly greater priority than the child. If any child has an equal or higher priority than its parent, ending or aborting the parent will wait for the child to be terminated by another thread. If the programmer creates a timeline with an equal or higher priority than its parent, it is the programmer's responsibility to ensure that SwTimelineEnd() or SwTimelineAbort() is called. This is most suitable for creating timelines in a static program scope, especially where the timeline context refers to an object with the same or higher static scope.
See SwTimelineEnd() and SwTimelineAbort() for details.
typedef HqnResult sw_tl_result |
A type used to communicate return values from timeline API calls.
This is a subclass of HqnResult that also supports some specific extra error codes generated by timelines (declared as the TL_RESULT enumeration). Before assigning to values of HqnResult type or any of its other subclasses, sw_tl_result values must be converted to change the timeline specific values to HQN_RESULT_SUCCESS or a monitor UID error code greater than MON_CLASS_ERROR. This can be done by including the file timelineerrors.h and calling the function timeline_result_translate().
If the Timeline reference passed in a call is not recognised, usually because that Timeline has ended, SW_TL_ERROR_UNKNOWN is returned.
SwTimelineEnd() and SwTimelineAbort() may not immediately end the Timeline, either because the Timeline has a higher priority child or a Handler has Handled the Timeline End/Abort Event. In such a case, SW_TL_ERROR_IN_USE is returned. Note that this is purely informational - the caller does not need to do anything else, responsibility for the Timeline is taken by the Handler or the Timeline system.
typedef HqnIdent sw_tl_type |
Timeline types.
Timeline numbering follows the numbering conventions for DEVICETYPE numbers.
These ranges are sub-allocated here and elsewhere.
typedef HqnIdent sw_tl_unit |
Timeline units.
Each Timeline has an associated unit in which extent and progress is measured, if meaningful for that Timeline Type.
Timeline units follow the numbering conventions for DEVICETYPE numbers.
These ranges are sub-allocated here and elsewhere. Other clients may use the values of the Global Graphics units defined contiguously from zero. These units will not change in future releases.
anonymous enum |
anonymous enum |
Timeline event numbers.
The Timeline system issues many Events. Authors must be careful to attach their Handlers to the appropriate Events and return the correct return codes.
All timeline events are associated with a SWMSG_TIMELINE message. The message contains full details of the current timeline state for all events.
Enumerator | |
---|---|
EVENT_TIMELINE_START | The Timeline has started. The Timeline reference is now valid, and children can be attached. Handlers should return SW_EVENT_CONTINUE. However, if a Handler returns SW_EVENT_HANDLED the Timeline will be ended immediately and the caller of SwTimelineStart() will get a SW_TL_REF_INVALID reference returned. |
EVENT_TIMELINE_TITLE | The Timeline is about to be renamed. Handlers can change the title pointer and length in the Event message if they wish to modify the title change. They can remove the title by setting the pointer or length to zero, or retain the existing title by returning SW_EVENT_HANDLED. Normally they should return SW_EVENT_CONTINUE. |
EVENT_TIMELINE_EXTEND | The extent of the Timeline has changed. Handlers should return SW_EVENT_CONTINUE. Returning anything else will merely prevent other Handlers getting the Event - the change has already occured. |
EVENT_TIMELINE_PROGRESS | The Timeline progress has changed. Handlers should return SW_EVENT_CONTINUE. Returning anything else will merely prevent other Handlers getting the Event - the change has already occured. |
EVENT_TIMELINE_ENDING | The Timeline may be about to end, if there are no objections. Handlers should return SW_EVENT_CONTINUE normally to signal that that they do not object. If a Handler returns SW_EVENT_HANDLED and the Timeline has the sw_tl_options::can_prolong option set to SW_TL_PROLONG_TRUE, the Timeline will be prolonged. It is then that Handler's responsibility to arrange for the Timeline to end or abort. If a Handler returns SW_EVENT_HANDLED and the Timeline has the sw_tl_options::can_prolong option set to anything except SW_TL_PROLONG_TRUE, the call to SwTimelineEnd() will wait for the timeline to be ended or aborted by another thread. It is the Handler's responsibility to arrange for the Timeline to end or abort. Note that multiple EVENT_TIMELINE_ENDING Events may be issued for a Timeline before all Handlers agree to the end. The default behavior for timelines started with default options is to disable explicit prolonging. |
EVENT_TIMELINE_ENDED | The Timeline has ended. The Timeline reference will only continue to be valid for the duration of the Event and will be unknown thereafter. There will only be one EVENT_TIMELINE_ENDED or EVENT_TIMELINE_ABORTED Event issued for a Timeline. |
EVENT_TIMELINE_ABORTING | The Timeline may be about to abort, if there are no objections. Handlers should return SW_EVENT_CONTINUE normally to signal that that they do not object. If a Handler returns SW_EVENT_HANDLED and the Timeline has the sw_tl_options::can_prolong option set to SW_TL_PROLONG_TRUE, the Timeline will be prolonged. It is then that Handler's responsibility to arrange for the Timeline to end or abort. If a Handler returns SW_EVENT_HANDLED and the Timeline has the sw_tl_options::can_prolong option set to anything except SW_TL_PROLONG_TRUE, the call to SwTimelineAbort() will wait for the timeline to be ended or aborted by another thread. It is the Handler's responsibility to arrange for the Timeline to end or abort. Note that multiple EVENT_TIMELINE_ABORTING Events may be issued for a Timeline before all Handlers agree to the end. The default behavior for timelines started with default options is to disable explicit prolonging. |
EVENT_TIMELINE_ABORTED | The Timeline has aborted. The Timeline reference will only continue to be valid for the duration of the Event and will be unknown thereafter. There will only be one EVENT_TIMELINE_ENDED or EVENT_TIMELINE_ABORTED Event issued for a Timeline. |
anonymous enum |
Enumeration of Timeline types reflecting the partition of type definitions for RIP components.
Enumerator | |
---|---|
TL_SKIN | 4096 types for published Skin use |
TL_SKIN_PRIVATE | 4096 types for private Skin use |
TL_PLUGAPI | 4096 types for published Plugin use |
TL_PLUGAPI_PRIVATE | 4096 types for private Plugin use |
TL_CORE | 4096 types for published Core use |
TL_CORE_PRIVATE | 4096 types for private Core use |
SW_TL_TYPE_ANY | Wildcard passed to SwTimelineGetAncestor() |
SW_TL_TYPE_NONE | Empty return from SwTimelineGetType() |
anonymous enum |
Pre-defined units for timelines.
anonymous enum |
Well-known timeline priority values.
Enumerator | |
---|---|
SW_TL_PRIORITY_UNKNOWN | Unknown priority from SwTimelineGetPriority(). |
SW_TL_PRIORITY_AUTO | Automatically select a lower priority than the parent for SwTimelineStart() and SwTimelineStartEx(). |
SW_TL_PRIORITY_BLOCKING | Automatically select the same priority as the parent for SwTimelineStart() and SwTimelineStartEx(). The name is chosen to reflect that the timeline will block its parent from terminating until explicitly ended or aborted. |
SW_TL_PRIORITY_NORMAL | Normal priority for timeline. |
anonymous enum |
anonymous enum |
Values for the sw_tl_options::can_prolong options field.
Enumerator | |
---|---|
SW_TL_PROLONG_FALSE | Do not prolong this timeline (aka FALSE). Non-prolongable timelines may not be children of prolongable timelines. |
SW_TL_PROLONG_TRUE | Allow prolonging of this timeline (aka TRUE). If prolonged by an event handler, the handler delegates responsibility for ending or aborting the timeline. |
SW_TL_PROLONG_AUTO | Allow the timeline to be created under either prolongable or non-prolongable timelines. This is equivalent to SW_TL_PROLONG_FALSE if there is no parent timeline. Timelines created with this option cannot be explicitly objected to by timeline end event handlers. Timelines created with this option should have dynamic scope. |
anonymous enum |
A bitmask of flags used to control which progress messages are not suppressed. These values may be combined in the sw_tl_options::progress_not_suppressed options field. These options do not affect changes to the extent.
enum TL_RESULT |
Return values from timeline API calls.
enum TL_STATES |
Timeline states.
The existing state numbers will not change between releases.
sw_tl_result SwTimelineAbort | ( | sw_tl_ref | ref, |
int | reason | ||
) |
Potentially abort a Timeline.
Whether the Timeline Abort Event is issued immediately depends on whether there are ongoing descendant Timelines of the same or higher priority, whether the timeline was created with the sw_tl_options::can_prolong option SW_TL_PROLONG_TRUE, and whether any event handlers objected to aborting the timeline.
ref | Timeline reference to abort |
reason | A reason code for the abort, defined per Timeline type |
SW_TL_SUCCESS | if the Timeline has ended |
SW_TL_ERROR_UNKNOWN | if the Timeline is not known |
SW_TL_ERROR_IN_USE | if the Timeline is being kept alive by an event Handler |
SW_TL_ERROR_SYNTAX | if an event handler incorrectly tries to end a timeline from the same thread that a descendent is already ending or aborting it, potentially causing a deadlock. This is a programming error, and will also cause an assert. |
SwTimelineAbort() will only return SW_TL_SUCCESS when the timeline has been ended or aborted, and all of the timeline and its descendents' have been the subject of EVENT_TIMELINE_ABORTED or EVENT_TIMELINE_ENDED events.
SwTimelineAbort() will only return SW_TL_ERROR_IN_USE if the timeline was created with the sw_tl_options::can_prolong option SW_TL_PROLONG_TRUE.
If there are priority inversions in the descendent hierarchy, or a timeline in the descendent hierarchy is prolonged using an event handler objection, the thread calling SwTimelineEnd() may be blocked waiting for a descendent to end. It is the programmer's responsibility to ensure that all priority inversions and objections are handled, by ending or aborting higher priority children explicitly, and by removing event handler objections.
Note that if SW_TL_ERROR_IN_USE is returned, the timeline is being prolonged by an event handler. It is the event handler's responsibility to remove the objection at a suitable point, and also to delegate calling of SwTimelineEnd() or SwTimelineAbort() on the timeline. Failing to remove the objection or end or abort the timeline may result in threads being blocked indefinitely.
If SW_TL_ERROR_IN_USE is returned, it also means that the attached primary context must also continue to exist. For such contexts that must be discarded, it may be best to discard them in a default priority EVENT_TIMELINE_ABORTED Handler for that Timeline reference.
sw_tl_result SwTimelineEnd | ( | sw_tl_ref | ref | ) |
Potentially end a Timeline.
Whether the Timeline End Event is issued immediately depends on whether there are ongoing descendant Timelines of the same or higher priority, whether the timeline was created with the sw_tl_options::can_prolong option SW_TL_PROLONG_TRUE, and whether any event handlers objected to ending the timeline.
ref | Timeline reference to end |
SW_TL_SUCCESS | if the Timeline has ended |
SW_TL_ERROR_UNKNOWN | if the Timeline is not known |
SW_TL_ERROR_IN_USE | if the Timeline is being kept alive by an event handler |
SW_TL_ERROR_SYNTAX | if an event handler incorrectly tries to end a timeline from the same thread that a descendent is already ending or aborting it, potentially causing a deadlock. This is a programming error, and will also cause an assert. |
SwTimelineEnd() will only return SW_TL_SUCCESS when the timeline has been ended or aborted, and all of the timeline and its descendents have been the subject of EVENT_TIMELINE_ENDED or EVENT_TIMELINE_ABORTED events.
SwTimelineEnd() will only return SW_TL_ERROR_IN_USE if the timeline was created with the sw_tl_options::can_prolong option SW_TL_PROLONG_TRUE.
If there are priority inversions in the descendent hierarchy, or a timeline in the descendent hierarchy is prolonged using an event handler objection, the thread calling SwTimelineEnd() may be blocked waiting for a descendent to end. It is the programmer's responsibility to ensure that all priority inversions and objections are handled, by ending or aborting higher priority children explicitly, and by removing event handler objections.
Note that if SW_TL_ERROR_IN_USE is returned, the timeline is being prolonged by an event handler. It is the event handler's responsibility to remove the objection at a suitable point, and also to delegate calling of SwTimelineEnd() or SwTimelineAbort() on the timeline. Failing to remove the objection or end or abort the timeline may result in threads being blocked indefinitely.
If SW_TL_ERROR_IN_USE is returned, it also means that the attached primary context must also continue to exist. For such contexts that must be discarded, it may be best to discard them in a default priority EVENT_TIMELINE_ABORTED Handler for that Timeline reference.
sw_tl_ref SwTimelineGetAncestor | ( | sw_tl_ref | ref, |
sw_tl_type | type | ||
) |
Return the nearest ancestor of the Timeline of the specified type.
ref | Timeline reference |
type | Type of ancestor to find, or SW_TL_TYPE_ANY to find immediate parent. |
This can be used to find the immediate parent of a Timeline, if it has one, or to find a Timeline's ancestor of a particular known type.
This allows something that cares about Job Timelines, for example, to find out whether a particular message Event belongs to its job. Note however that it may in principle be possible for there to be multiple nested Job Timelines, so the first Job parent found may itself be a child of the Job Timeline in question.
This call does not issue an Event.
void* SwTimelineGetContext | ( | sw_tl_ref | ref, |
sw_tl_context | id | ||
) |
Return a context from the Timeline.
ref | Timeline reference | |
[in] | id | Unique identifier for context. Zero for Timeline creator's primary context |
The Timeline system places no interpretation on these contexts, they are for client use. Note that NULL is returned if the Timeline reference or context id is not known.
This call does not issue an Event.
sw_tl_priority SwTimelineGetPriority | ( | sw_tl_ref | ref | ) |
Return the Timeline priority if known.
ref | Timeline reference |
This call does not issue an Event.
sw_tl_result SwTimelineGetProgress | ( | sw_tl_ref | ref, |
sw_tl_extent * | start, | ||
sw_tl_extent * | end, | ||
sw_tl_extent * | progress, | ||
sw_tl_unit * | unit | ||
) |
Return the extent, unit and progress through a Timeline.
ref | Timeline reference | |
[out] | start | If not null, this is filled in with the extent start |
[out] | end | If not null, this is filled in with the extent end |
[out] | progress | If not null, this is filled in with the progress |
[out] | unit | If not null, this is filled in with the unit |
SW_TL_SUCCESS | normally |
SW_TL_ERROR_UNKNOWN | if the Timeline is not known |
An extent end of SW_TL_EXTENT_INDETERMINATE means the Timeline is not of a known length. The progress and unit may still be informational.
This call does not issue an Event.
Return the Timeline's title and length.
ref | Timeline reference | |
[out] | buffer | If not null, this is filled in with the title, space permitting |
size | The size of the supplied buffer |
This call allows the Timeline's title to be retrieved. It can be called with a null buffer pointer to find the length of the title so a suitable buffer can be allocated before calling this function again, but be prepared for the title to be changed by another thread between the calls.
If the returned title length is greater than the buffer size passed in, the title returned will have been truncated.
This call does not issue an Event.
sw_tl_type SwTimelineGetType | ( | sw_tl_ref | ref | ) |
Return the Timeline type if known.
ref | Timeline reference |
This call does not issue an Event.
sw_tl_ref SwTimelineOfType | ( | sw_tl_ref | ref, |
sw_tl_type | type | ||
) |
Ensure the Timeline or an ancestor is of the given type.
ref | Timeline reference |
type | Type of Timeline to find |
This is similar to SwTimelineGetAncestor(), but can return the Timeline passed in and does not accept SW_TL_TYPE_ANY as a parameter.
If the Timeline passed in and none of its ancestors are of the required type, SW_TL_REF_INVALID is returned.
It is equivalent to an atomic version of:
This call does not issue an Event.
sw_tl_result SwTimelineSetContext | ( | sw_tl_ref | ref, |
sw_tl_context | id, | ||
void * | context | ||
) |
Attach a secondary context to a Timeline.
ref | Timeline reference | |
id | Unique identifier for context. | |
[in] | context | The context pointer to attach to the Timeline, or null |
SW_TL_SUCCESS | The context was attached to the timeline. |
SW_TL_ERROR_UNKNOWN | If the Timeline is not known |
SW_TL_ERROR_SYNTAX | If an attempt was made to change the owner context (identifier zero). |
SW_TL_ERROR_MEMORY | If memory allocation fails |
The Timeline system places no interpretation on these contexts, they are for client use. Context management is not performed by the Timeline system, and these contexts can only be retrieved using this call while the Timeline continues to exist.
Note: Entities that wish to associate a context with a Timeline that will outlive the Timeline itself should register the context with RDR using a Class of RDR_CLASS_TIMELINE, the Timeline reference as the RDR Type, and their context identifier as the RDR ID. Such an RDR will have to be manually deregistered when the Timeline ends (though not necessarily immediately).
This call does not issue an Event.
sw_tl_result SwTimelineSetExtent | ( | sw_tl_ref | ref, |
sw_tl_extent | start, | ||
sw_tl_extent | end | ||
) |
Extend the length of the Timeline. Issues an Event for a nonzero change.
ref | Timeline reference |
start | New start of the Timeline extent |
end | New end of the Timeline extent, or SW_TL_EXTENT_INDETERMINATE |
SW_TL_SUCCESS | normally |
SW_TL_ERROR_UNKNOWN | if the Timeline is not known |
A Timeline created with an end of SW_TL_EXTENT_INDETERMINATE should not be represented by a GUI as having a known length.
An EVENT_TIMELINE_EXTEND event will be issued. The Timeline system ignores the return code from this event.
Timeline extents can have the start value greater than the end value, for example to represent a countdown timer or remaining resource items. The caller can determine if this is the case by comparing the extent boundaries returned by SwTimelineGetProgress().
If the timeline was originally created with the sw_tl_options::progress_monotonic option TRUE, then the extents can only be increased if the original extent order was positive, or decreased if the original extent order was negative.
sw_tl_result SwTimelineSetProgress | ( | sw_tl_ref | ref, |
sw_tl_extent | progress | ||
) |
Update the progress of the Timeline, in the units given when the Timeline was started. Issues an Event if the current value changes.
ref | Timeline reference |
progress | Current progress value. |
SW_TL_SUCCESS | normally |
SW_TL_ERROR_UNKNOWN | if the Timeline is not known |
If the timeline was created with the sw_tl_options::progress_monotonic option TRUE, then retrograde progress updates will be silently ignored, and an event will not be issued.
If the timeline was created with the default options, then progressing beyond the current Timeline extent automatically extends the extent. If the timeline was created with the sw_tl_options::progress_clamped option TRUE, then attempts to progress beyond the extent will be clamped. If the progress is already at the timeline extent, then an event will not be issued.
A Handler may choose to reflect the progress of a child Timeline in the parent Timeline, eg by reducing the parent's extent start by some amount, and then updating the parent's progress accordingly.
An EVENT_TIMELINE_PROGRESS event is issued. The Timeline system ignores the return code from this event.
sw_tl_result SwTimelineSetTitle | ( | sw_tl_ref | ref, |
const uint8 * | title, | ||
size_t | length | ||
) |
Change the title of a Timeline. Issues an Event before changing the title.
ref | Timeline reference to rename | |
[in] | title | Pointer to a string, or null to remove the name |
length | Length of the unterminated string |
SW_TL_SUCCESS | normally |
SW_TL_ERROR_UNKNOWN | if the Timeline is not known |
SW_TL_ERROR_MEMORY | if memory allocation fails |
The title will be copied so does not need to be maintained.
An EVENT_TIMELINE_TITLE event is issued. A Handler may choose to modify the title or suppress it by changing the pointer and length in the Event Message. If a Handler returns SW_EVENT_HANDLED, no title change occurs at all.
sw_tl_ref SwTimelineStart | ( | sw_tl_type | type, |
sw_tl_ref | parent, | ||
sw_tl_extent | start, | ||
sw_tl_extent | end, | ||
sw_tl_unit | unit, | ||
sw_tl_priority | priority, | ||
void * | context, | ||
const uint8 * | title, | ||
size_t | length | ||
) |
Create a Timeline, issuing a Start Event immediately.
type | Timeline type, such as Job, Document, Interpret, Render | |
parent | ID of parent Timeline, or SW_TL_REF_INVALID for an autonomous Timeline | |
start | Start of the Timeline extent in some units, eg total bytes, number of pages. Often zero. | |
end | End of the Timeline extent, or SW_TL_EXTENT_INDETERMINATE | |
unit | Unit of the above extent, eg Bytes, Pages, Lines | |
priority | Used to resolve Ending a Timeline with ongoing child Timelines | |
[in] | context | The primary context supplied by the Timeline owner |
[in] | title | A title for the Timeline. Could be leafname, page title or job phase |
length | The length of the title |
The timeline created has the default options (no negotiation, non-monotonic progress, no progress limiting). If a timeline is desired with non-default options, call SwTimelineStartEx() instead.
A Timeline that has no concept of length, for which progress has no real meaning, should have an extent end of SW_TL_EXTENT_INDETERMINATE. A GUI may represent this as an indeterminate progress bar instead of a standard progress bar.
A EVENT_TIMELINE_START event is issued immediately after creating the Timeline. If a Handler returns SW_EVENT_HANDLED the Timeline is immediately ended and SW_TL_REF_INVALID will be returned to the creator.
See SwTimelineEnd() for usage of the priority parameter.
The title is copied so need not be maintained.
The supplied context is delivered in Timeline Events and is identified by context id zero. It can be retrieved with SwTimelineGetContext() but cannot be changed - Timeline events can occur at any time and in other threads, so changing this primary context would invalidate events currently in flow.
sw_tl_ref SwTimelineStartEx | ( | sw_tl_type | type, |
sw_tl_ref | parent, | ||
sw_tl_extent | start, | ||
sw_tl_extent | end, | ||
sw_tl_unit | unit, | ||
sw_tl_priority | priority, | ||
void * | context, | ||
const uint8 * | title, | ||
size_t | length, | ||
const sw_tl_options * | options | ||
) |
Create a Timeline with a specified set of options, issuing a Start Event immediately.
type | Timeline type, such as Job, Document, Interpret, Render | |
parent | ID of parent Timeline, or SW_TL_REF_INVALID for an autonomous Timeline | |
start | Start of the Timeline extent in some units, eg total bytes, number of pages. Often zero. | |
end | End of the Timeline extent, or SW_TL_EXTENT_INDETERMINATE | |
unit | Unit of the above extent, eg Bytes, Pages, Lines | |
priority | Used to resolve Ending a Timeline with ongoing child Timelines | |
[in] | context | The primary context supplied by the Timeline owner |
[in] | title | A title for the Timeline. Could be leafname, page title or job phase |
length | The length of the title | |
[in] | options | A pointer to the options structure for this timeline. |
The options structure affects the behaviour of the new timeline. If the options pointer is NULL, or the size field in the options structure) is shorter than expected for a particular API version, then the default values of the options for that API version will be used.
A Timeline that has no concept of length, for which progress has no real meaning, should have an extent end of SW_TL_EXTENT_INDETERMINATE. A GUI may represent this as an indeterminate progress bar instead of a standard progress bar.
A EVENT_TIMELINE_START event is issued immediately after creating the Timeline. If a Handler returns SW_EVENT_HANDLED the Timeline is immediately ended and SW_TL_REF_INVALID will be returned to the creator.
See SwTimelineEnd() for usage of the priority parameter.
The title is copied so need not be maintained.
The supplied context is delivered in Timeline Events and is identified by context id zero. It can be retrieved with SwTimelineGetContext() but cannot be changed - Timeline events can occur at any time and in other threads, so changing this primary context would invalidate events currently in flow.
|
inlinestatic |
Translate a timeline-specific error code to a generic HqnResult error code.
[in] | result | One of the TL_RESULT values, or an error value greater than MON_CLASS_ERROR. |
The header file defining this function should be included explicitly in every C or C++ file that calls it.