.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "pod::Prima::Object 3" .TH pod::Prima::Object 3 "2009-02-24" "perl v5.14.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Prima::Object \- Prima toolkit base classes .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& if ( $obj\-> isa(\*(AqPrima::Component\*(Aq)) { \& \& # set and get a property \& my $name = $obj\-> name; \& $obj\->name( \*(Aqan object\*(Aq ); \& \& # set a notification callback \& $obj\-> onPostMessage( sub { \& shift; \& print "hey! I\*(Aqve received this: @_\en"; \& }); \& \& # can set multiple properties. note, that \*(Aqname\*(Aq and \*(Aqowner\*(Aq, \& # replace the old values, while onPostMessage are aggregated. \& $obj\-> set( \& name => \*(AqAnObject\*(Aq, \& owner => $new_owner, \& onPostMessage => sub { \& shift; \& print "hey! me too!\en"; \& }, \& ); \& \& # de\-reference by name \& $new_owner\-> AnObject\-> post_message(1,2); \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Prima::Object and Prima::Component are the root objects of the Prima toolkit hierarchy. All the other objects are derived from the Component class, which in turn is the only descendant of Object class. Both of these classes are never used for spawning their instances, although this is possible using .PP .Vb 1 \& Prima::Component\-> create( .. parameters ... ); .Ve .PP call. This document describes the basic concepts of the \s-1OO\s0 programming with Prima toolkit. Although Component has wider functionality than Object, all examples will be explained on Component, since Object has no descendant classes and all the functionality of Object is present in Component. Some of the information here can be found in Prima::internals as well, the difference is that Prima::internals considers the coding tasks from a C programmer's view, whereas this document is wholly about perl programming. .SH "Object base features" .IX Header "Object base features" .SS "Creation" .IX Subsection "Creation" Object creation has fixed syntax: .PP .Vb 5 \& $new_object = Class\-> create( \& parameter => value, \& parameter => value, \& ... \& ); .Ve .PP Parameters and values form a hash, which is passed to the \fIcreate()\fR method. This hash is applied to a default parameter-value hash ( a \fIprofile\fR ), specific to every Prima class. The object creation is performed in several stages. .IP "create" 4 .IX Item "create" \&\fIcreate()\fR calls \fIprofile_default()\fR method that returns ( as its name states ) the default profile, a hash with the appropriate default values assigned to its keys. The Component class defaults are ( see Classes.pm ): .Sp .Vb 3 \& name => ref $_[ 0], \& owner => $::application, \& delegations => undef, .Ve .Sp While the exact meaning of these parameters is described later, in \&\*(L"Properties\*(R", the idea is that a newly created object will have 'owner' parameter set to '$::application' and 'delegations' to undef etc etc \- unless these parameters are explicitly passed to \fIcreate()\fR. Example: .Sp .Vb 1 \& $a1 = Prima::Component\-> create(); .Ve .Sp \&\f(CW$a1\fR's owner will be \f(CW$::application\fR .Sp .Vb 1 \& $a2 = Prima::Component\-> create( owner => $a1); .Ve .Sp \&\f(CW$a2\fR's owner will be \f(CW$a1\fR. The actual merging of the default and the parameter hashes is performed on the next stage, in \fIprofile_check_in()\fR method which is called inside \fIprofile_add()\fR method. .IP "profile_check_in" 4 .IX Item "profile_check_in" A \fIprofile_check_in()\fR method merges the default and the parameter profiles. By default all specified parameters have the ultimate precedence over the default ones, but in case the specification is incomplete or ambiguous, the \&\fIprofile_check_in()\fR's task is to determine actual parameter values. In case of Component, this method maintains a simple automatic naming of the newly created objects. If the object name was not specified with \fIcreate()\fR, it is assigned to a concatenated class name with an integer \- Component1, Component2 etc. .Sp Another example can be taken from \fIPrima::Widget::profile_check_in()\fR. Prima::Widget horizontal position can be specified by using basic \f(CW\*(C`left\*(C'\fR and \&\f(CW\*(C`width\*(C'\fR parameters, and as well by auxiliary \f(CW\*(C`right\*(C'\fR, \f(CW\*(C`size\*(C'\fR and \f(CW\*(C`rect\*(C'\fR. The default of both \f(CW\*(C`left\*(C'\fR and \f(CW\*(C`width\*(C'\fR is 100. But if only \f(CW\*(C`right\*(C'\fR parameter, for example, was passed to \fIcreate()\fR it is \fIprofile_check_in()\fR job to determine \f(CW\*(C`left\*(C'\fR value, given that \f(CW\*(C`width\*(C'\fR is still 100. .Sp After profiles gets merged, the resulting hash is passed to the third stage, \&\fIinit()\fR. .IP "init" 4 .IX Item "init" \&\fIinit()\fR duty is to map the profile content into object, e.g., assign \f(CW\*(C`name\*(C'\fR property to \f(CW\*(C`name\*(C'\fR parameter value, and so on \- for all relevant parameters. After that, it has to return the profile in order the overridden subsequent \&\fIinit()\fR methods can perform same actions. This stage along with the previous is exemplified in almost all Prima modules. .Sp Note: usually \fIinit()\fR attaches the object to its owner in order to keep the newly-created object instance from being deleted by garbage-collection mechanisms. More on that later ( see \*(L"Links between objects\*(R"). .Sp After \fIinit()\fR finishes, \fIcreate()\fR calls \fIsetup()\fR method .IP "setup" 4 .IX Item "setup" \&\fIsetup()\fR method is a convenience function, it is used when some post-init actions must be taken. It is seldom overloaded, primarily because the \&\fIComponent::setup()\fR method calls \f(CW\*(C`onCreate\*(C'\fR notification, which is more convenient to overload than \fIsetup()\fR. .PP As can be noticed from the code pieces above, a successful \fIcreate()\fR call returns a newly created object. If an error condition occurred, undef is returned. It must be noted, that only errors that were generated via \fIdie()\fR during \fIinit()\fR stage result in undef. Other errors raise an exception instead. It is not recommended to frame \fIcreate()\fR calls in an \f(CW\*(C`eval{}\*(C'\fR block, because the error conditions can only occur in two situations. The first is a system error, either inside perl or Prima guts, and not much can be done here, since that error can very probably lead to an unstable program and almost always signals an implementation bug. The second reason is a caller's error, when an unexistent parameter key or invalid value is passed; such conditions are not subject to a runtime error handling as are not the syntax errors. .PP After \fIcreate()\fR, the object is subject to the event flow. As \f(CW\*(C`onCreate\*(C'\fR event is the first event the object receives, only after that stage other events can be circulated. .SS "Destruction" .IX Subsection "Destruction" Object destruction can be caused by many conditions, but all execution flow is finally passed through \fIdestroy()\fR method. \fIdestroy()\fR, as well as \fIcreate()\fR performs several finalizing steps: .IP "cleanup" 4 .IX Item "cleanup" The first method called inside \fIdestroy()\fR is \fIcleanup()\fR. \fIcleanup()\fR is the pair to \fIsetup()\fR, as \fIdestroy()\fR is the pair to \fIcreate()\fR. \fIcleanup()\fR generates \&\f(CW\*(C`onDestroy\*(C'\fR event, which can be overridden more easily than \fIcleanup()\fR itself. .Sp \&\f(CW\*(C`onDestroy\*(C'\fR is the last event the object sees. After \fIcleanup()\fR no events are allowed to circulate. .IP "done" 4 .IX Item "done" \&\fIdone()\fR method is the pair to \fIinit()\fR, and is the place where all object resources are freed. Although it is as safe to overload \fIdone()\fR as \fIinit()\fR, it almost never gets overloaded, primarily because overloading \f(CW\*(C`onDestroy\*(C'\fR is easier. .PP The typical conditions that lead to object destructions are direct \fIdestroy()\fR call, garbage collections mechanisms, user-initiated window close ( on \f(CW\*(C`Prima::Window\*(C'\fR only ), and exception during \fIinit()\fR stage. Thus, one must be careful implementing \&\fIdone()\fR which is called after \fIinit()\fR throws an exception. .SS "Methods" .IX Subsection "Methods" The class methods are declared and used with perl \s-1OO\s0 syntax, which allow both method of object referencing: .PP .Vb 1 \& $object\-> method(); .Ve .PP and .PP .Vb 1 \& method( $object); .Ve .PP The actual code is a sub, located under the object class package. The overloaded methods that call their ancestor code use .PP .Vb 1 \& $object\-> SUPER::method(); .Ve .PP syntax. Most Prima methods have fixed number of parameters. .SS "Properties" .IX Subsection "Properties" Properties are methods that combine functionality of two ephemeral \*(L"get\*(R" and \&\*(L"set\*(R" methods. The idea behind properties is that many object parameters require two independent methods, one that returns some internal state and another that changes it. For example, for managing the object name, \fIset_name()\fR and \fIget_name()\fR methods are needed. Indeed, the early Prima implementation dealt with large amount of these get's and set's, but later these method pairs were deprecated in the favor of properties. Currently, there is only one method \&\fIname()\fR ( referred as \f(CW\*(C`::name\*(C'\fR later in the documentation ). .PP The property returns a value if no parameters ( except the object) are passed, and changes the internal data to the passed parameters otherwise. Here's a sketch code for \f(CW\*(C`::name\*(C'\fR property implementation: .PP .Vb 5 \& sub name \& { \& return $_[0]\-> {name} unless $#_; \& $_[0]\->{name} = $_[1]; \& } .Ve .PP There are many examples of properties throughout the toolkit. Not all properties deal with scalar values, some accept arrays or hashes as well. The properties can be set-called not only by name like .PP .Vb 1 \& $object\-> name( "new name"); .Ve .PP but also with \fIset()\fR method. The \fIset()\fR method accepts a hash, that is much like to \fIcreate()\fR, and assigns the values to the corresponding properties. For example, the code .PP .Vb 2 \& $object\-> name( "new name"); \& $object\-> owner( $owner); .Ve .PP can be rewritten as .PP .Vb 4 \& $object\-> set( \& name => "new name", \& owner => $owner \& ); .Ve .PP A minor positive effect of a possible speed-up is gained by eliminating C\-to-perl and perl-to-C calls, especially if the code called is implemented in C. The negative effect of such technique is that the order in which the properties are set, is undefined. Therefore, the usage of \fIset()\fR is recommended either when the property order is irrelevant, or it is known beforehand that such a call speeds up the code, or is an only way to achieve the result. An example of the latter case from Prima::internals shows that Prima::Image calls .PP .Vb 2 \& $image\-> type( $a); \& $image\-> palette( $b); .Ve .PP and .PP .Vb 2 \& $image\-> palette( $b); \& $image\-> type( $a); .Ve .PP produce different results. It is indeed the only solution to call for such a change using .PP .Vb 4 \& $image\-> set( \& type => $a, \& palette => $b \& ); .Ve .PP when it is known beforehand that \f(CW\*(C`Prima::Image::set\*(C'\fR is aware of such combinations and calls neither \f(CW\*(C`::type\*(C'\fR nor \f(CW\*(C`::palette\*(C'\fR but performs another image conversion instead. .PP Some properties are read-only and some are write-only. Some methods that might be declared as properties are not; these are declared as plain methods with get_ or set_ name prefix. There is not much certainty about what methods are better off being declared as properties and vice versa. .PP However, if get_ or set_ methods cannot be used in correspondingly write or read fashion, the R/O and W/O properties can. They raise an exception on an attempt to do so. .SS "Links between objects" .IX Subsection "Links between objects" Prima::Component descendants can be used as containers, as objects that are on a higher hierarchy level than the others. This scheme is implemented in a child-owner relationship. The 'children' objects have the \f(CW\*(C`::owner\*(C'\fR property value assigned to a reference to a 'owner' object, while the 'owner' object conducts the list of its children. It is a one-to-many hierarchy scheme, as a \&'child' object can have only one owner, but an 'owner' object can have many children. The same object can be an owner and a child at the same time, so the owner-child hierarchy can be viewed as a tree-like structure. .PP Prima::Component::owner property maintains this relation, and is writable \- the object can change its owner dynamically. There is no corresponding property that manages children objects, but is a method \fIget_components()\fR, that returns an array of the child references. .PP The owner-child relationship is used in several ways in the toolkit. For example, the widgets that are children of another widget appear ( usually, but not always ) in the geometrical interior of the owner widget. Some events ( keyboard events, for example ) are propagated automatically up and/or down the object tree. Another important feature is that when an object gets destroyed, its children are destroyed first. In a typical program the whole object tree roots in a Prima::Application object instance. When the application finishes, this feature helps cleaning up the widgets and quitting gracefully. .PP Implementation note: name 'owner' was taken instead of initial 'parent', because the 'parent' is a fixed term for widget hierarchy relationship description. Prima::Widget relationship between owner and child is not the same as \s-1GUI\s0's parent-to-child. The parent is the widget for the children widgets located in and clipped by its inferior. The owner widget is more than that, its children can be located outside its owner boundaries. .PP The special convenience variety of \fIcreate()\fR, the \fIinsert()\fR method is used to explicitly select owner of the newly created object. \fIinsert()\fR can be considered a 'constructor' in OO-terms. It makes the construct .PP .Vb 1 \& $obj = Class\-> create( owner => $owner, name => \*(Aqname); .Ve .PP more readable by introducing .PP .Vb 1 \& $obj = $owner\-> insert( \*(AqClass\*(Aq, name => \*(Aqname\*(Aq); .Ve .PP scheme. These two code blocks are identical to each other. .PP There is another type of relation, where objects can hold references to each other. Internally this link level is used to keep objects from deletion by garbage collection mechanisms. This relation is many-to-many scheme, where every object can have many links to other objects. This functionality is managed by \fIattach()\fR and \fIdetach()\fR methods. .SH "Events" .IX Header "Events" Prima::Component descendants employ a well-developed event propagation mechanism, which allows handling events using several different schemes. An event is a condition, caused by the system or the user, or an explicit \fInotify()\fR call. The formerly described events onCreate and onDestroy are triggered after a new object is created or before it gets destroyed. These two events, and the described below onPostMessage are present in namespaces of all Prima objects. New classes can register their own events and define their execution flow, using \fInotification_types()\fR method. This method returns all available information about the events registered in a class. .PP Prima defines also a non-object event dispatching and filtering mechanism, available through \*(L"event_hook\*(R" static method. .SS "Propagation" .IX Subsection "Propagation" The event propagation mechanism has three layers of user-defined callback registration, that are called in different order and contexts when an event is triggered. The examples below show the usage of these layers. It is assumed that an implicit .PP .Vb 1 \& $obj\-> notify("PostMessage", $data1, $data2); .Ve .PP call is issued for all these examples. .IP "Direct methods" 4 .IX Item "Direct methods" As it is usual in \s-1OO\s0 programming, event callback routines are declared as methods. 'Direct methods' employ such a paradigm, so if a class method with name \f(CW\*(C`on_postmessage\*(C'\fR is present, it will be called as a method ( i.e., in the object context ) when \f(CW\*(C`onPostMessage\*(C'\fR event is triggered. Example: .Sp .Vb 5 \& sub on_postmessage \& { \& my ( $self, $data1, $data2) = @_; \& ... \& } .Ve .Sp The callback name is a modified lower-case event name: the name for Create event is on_create, PostMessage \- on_postmessage etc. These methods can be overloaded in the object's class descendants. The only note on declaring these methods in the first instance is that no \f(CW\*(C`::SUPER\*(C'\fR call is needed, because these methods are not defined by default. .Sp Usually the direct methods are used for the internal object book-keeping, reacting on the events that are not designed to be passed higher. For example, a Prima::Button class catches mouse and keyboard events in such a fashion, because usually the only notification that is interesting for the code that employs push-buttons is \f(CW\*(C`Click\*(C'\fR. This scheme is convenient when an event handling routine serves the internal, implementation-specific needs. .IP "Delegated methods" 4 .IX Item "Delegated methods" The delegated methods are used when objects ( mostly widgets ) include other dependent objects, and the functionality requires interaction between these. The callback functions here are the same methods as direct methods, except that they get called in context of two, not one, objects. If, for example, a \f(CW$obj\fR's owner, \f(CW$owner\fR would be interested in \f(CW$obj\fR's PostMessage event, it would register the notification callback by .Sp .Vb 1 \& $obj\-> delegations([ $owner, \*(AqPostMessage\*(Aq]); .Ve .Sp where the actual callback sub will be .Sp .Vb 4 \& sub Obj_PostMessage \& { \& my ( $self, $obj, $data1, $data2) = @_; \& } .Ve .Sp Note that the naming style is different \- the callback name is constructed from object name ( let assume that \f(CW$obj\fR's name is 'Obj') and the event name. ( This is one of the reasons why \fIComponent::profile_check_in()\fR performs automatic naming of newly created onbjects). Note also that context objects are \f(CW$self\fR ( that equals \f(CW$owner\fR ) and \f(CW$obj\fR. .Sp The delegated methods can be used not only for the owner-child relations. Every Prima object is free to add a delegation method to every other object. However, if the objects are in other than owner-child relation, it is a good practice to add Destroy notification to the object which events are of interest, so if it gets destroyed, the partner object gets a message about that. .IP "Anonymous subroutines" 4 .IX Item "Anonymous subroutines" The two previous callback types are more relevant when a separate class is developed, but it is not necessary to declare a new class every time the event handling is needed. It is possible to use the third and the most powerful event hook method using perl anonymous subroutines ( subs ) for the easy customization. .Sp Contrary to the usual \s-1OO\s0 event implementations, when only one routine per class dispatches an event, and calls inherited handlers when it is appropriate, Prima event handling mechanism can accept many event handlers for one object ( it is greatly facilitated by the fact that perl has \fIanonymous subs\fR, however). .Sp All the callback routines are called when an event is triggered, one by one in turn. If the direct and delegated methods can only be multiplexed by the usual \&\s-1OO\s0 inheritance, the anonymous subs are allowed to be multiple by the design. There are three syntaxes for setting such a event hook; the example below sets a hook on \f(CW$obj\fR using each syntax for a different situation: .Sp \&\- during \fIcreate()\fR: .Sp .Vb 7 \& $obj = Class\-> create( \& ... \& onPostMessage => sub { \& my ( $self, $data1, $data2) = @_; \& }, \& ... \& ); .Ve .Sp \&\- after create using \fIset()\fR .Sp .Vb 3 \& $obj\-> set( onPostMessage => sub { \& my ( $self, $data1, $data2) = @_; \& }); .Ve .Sp \&\- after create using event name: .Sp .Vb 3 \& $obj\-> onPostMessage( sub { \& my ( $self, $data1, $data2) = @_; \& }); .Ve .Sp As was noted in Prima, the events can be addressed as properties, with the exception that they are not substitutive but additive. The additivity is that when the latter type of syntax is used, the subs already registered do not get overwritten or discarded but stack in queue. Thus, .Sp .Vb 3 \& $obj\-> onPostMessage( sub { print "1" }); \& $obj\-> onPostMessage( sub { print "2" }); \& $obj\-> notify( "PostMessage", 0, 0); .Ve .Sp code block would print .Sp .Vb 1 \& 21 .Ve .Sp as the execution result. .Sp This, it is a distinctive feature of a toolkit is that two objects of same class may have different set of event handlers. .SS "Flow" .IX Subsection "Flow" When there is more than one handler of a particular event type present on an object, a question is risen about what are callbacks call priorities and when does the event processing stop. One of ways to regulate the event flow is based on prototyping events, by using \fInotification_types()\fR event type description. This function returns a hash, where keys are the event names and the values are the constants that describe the event flow. The constant can be a bitwise \s-1OR\s0 combination of several basic flow constants, that control the three aspects of the event flow. .IP "Order" 4 .IX Item "Order" If both anonymous subs and direct/delegated methods are present, it must be decided which callback class must be called first. Both 'orders' are useful: for example, if it is designed that a class's default action is to be overridden, it is better to call the custom actions first. If, on the contrary, the class action is primary, and the others are supplementary, the reverse order is preferred. One of two \f(CW\*(C`nt::PrivateFirst\*(C'\fR and \f(CW\*(C`nt::CustomFirst\*(C'\fR constants defines the order. .IP "Direction" 4 .IX Item "Direction" Almost the same as order, but for finer granulation of event flow, the direction constants \f(CW\*(C`nt::FluxNormal\*(C'\fR and \f(CW\*(C`nt::FluxReverse\*(C'\fR are used. The \&'normal flux' defines \s-1FIFO\s0 ( first in first out ) direction. That means, that the sooner the callback is registered, the greater priority it would possess during the execution. The code block shown above .Sp .Vb 3 \& $obj\-> onPostMessage( sub { print "1" }); \& $obj\-> onPostMessage( sub { print "2" }); \& $obj\-> notify( "PostMessage", 0, 0); .Ve .Sp results in \f(CW21\fR, not \f(CW12\fR because PostMessage event type is prototyped \&\f(CW\*(C`nt::FluxReverse\*(C'\fR. .IP "Execution control" 4 .IX Item "Execution control" It was stated above that the events are additive, \- the callback storage is never discarded when 'set'\-syntax is used. However, the event can be told to behave like a substitutive property, e.g. to call one and only one callback. This functionality is governed by \f(CW\*(C`nt::Single\*(C'\fR bit in execution control constant set, which consists of the following constants: .Sp .Vb 3 \& nt::Single \& nt::Multiple \& nt::Event .Ve .Sp These constants are mutually exclusive, and may not appear together in an event type declaration. A \f(CW\*(C`nt::Single\*(C'\fR\-prototyped notification calls only the first ( or the last \- depending on order and direction bits ) callback. The usage of this constant is somewhat limited. .Sp In contrary of \f(CW\*(C`nt::Single\*(C'\fR, the \f(CW\*(C`nt::Multiple\*(C'\fR constant sets the execution control to call all the available callbacks, with respect to direction and order bits. .Sp The third constant, \f(CW\*(C`nt::Event\*(C'\fR, is the impact as \f(CW\*(C`nt::Multiple\*(C'\fR, except that the event flow can be stopped at any time by calling \fIclear_event()\fR method. .PP Although there are 12 possible event type combinations, a half of them are not viable. Another half were assigned to unique more-less intelligible names: .PP .Vb 6 \& nt::Default ( PrivateFirst | Multiple | FluxReverse) \& nt::Property ( PrivateFirst | Single | FluxNormal ) \& nt::Request ( PrivateFirst | Event | FluxNormal ) \& nt::Notification ( CustomFirst | Multiple | FluxReverse ) \& nt::Action ( CustomFirst | Single | FluxReverse ) \& nt::Command ( CustomFirst | Event | FluxReverse ) .Ve .SS "Success state" .IX Subsection "Success state" Events do not return values, although the event generator, the \fInotify()\fR method does \- it returns either 1 or 0, which is the value of event success state. The 0 and 1 results in general do not mean either success or failure, they simply reflect the fact whether \fIclear_event()\fR method was called during the processing \- 1 if it was not, 0 otherwise. The state is kept during the whole processing stage, and can be accessed from Component::eventFlag property. Since it is allowed to call \fInotify()\fR inside event callbacks, the object maintains a stack for those states. Component::eventFlags always works with the topmost one, and fails if is called from outside the event processing stage. Actually, \&\fIclear_event()\fR is an alias for ::\fIeventFlag\fR\|(0) call. The state stack is operated by \fIpush_event()\fR and \fIpop_event()\fR methods. .PP Implementation note: a call of \fIclear_event()\fR inside a \f(CW\*(C`nt::Event\*(C'\fR\-prototyped event call does not automatically stops the execution. The execution stops if the state value equals to 0 after the callback is finished. A ::\fIeventFlag\fR\|(1) call thus cancels the effect of \fIclear_event()\fR. .PP A particular coding style is used when the event is \f(CW\*(C`nt::Single\*(C'\fR\-prototyped and is called many times in a row, so overheads of calling \fInotify()\fR become a burden. Although \fInotify()\fR logic is somewhat complicated, it is rather simple with \f(CW\*(C`nt::Single\*(C'\fR case. The helper function \fIget_notify_sub()\fR returns the context of callback to-be-called, so it can be used to emulate \fInotify()\fR behavior. Example: .PP .Vb 3 \& for ( ... ) { \& $result = $obj\-> notify( "Measure", @parms); \& } .Ve .PP can be expressed in more cumbersome, but efficient code if \&\f(CW\*(C`nt::Single\*(C'\fR\-prototyped event is used: .PP .Vb 7 \& my ( $notifier, @notifyParms) = $obj\-> get_notify_sub( "Measure" ); \& $obj\-> push_event; \& for ( ... ) { \& $notifier\-> ( @notifyParms, @parms); \& # $result = $obj\-> eventFlag; # this is optional \& } \& $result = $obj\-> pop_event; .Ve .SH "API" .IX Header "API" .SS "Prima::Object methods" .IX Subsection "Prima::Object methods" .IP "alive" 4 .IX Item "alive" Returns the object 'vitality' state \- true if the object is alive and usable, false otherwise. This method can be used as a general checkout if the scalar passed is a Prima object, and if it is usable. The true return value can be 1 for normal and operational object state, and 2 if the object is alive but in its \fIinit()\fR stage. Example: .Sp .Vb 1 \& print $obj\-> name if Prima::Object::alive( $obj); .Ve .IP "can \s-1NAME\s0, \s-1CACHE\s0 = 1" 4 .IX Item "can NAME, CACHE = 1" Checks if an object namespace contains a \s-1NAME\s0 method. Returns the code reference to it, if found, and undef if not. If \s-1CACHE\s0 is true, caches the result to speed-up subsequent calls. .IP "cleanup" 4 .IX Item "cleanup" Called right after \fIdestroy()\fR started. Used to initiate \f(CW\*(C`cmDestroy\*(C'\fR event. Is never called directly. .ie n .IP "create \s-1CLASS\s0, %PARAMETERS" 4 .el .IP "create \s-1CLASS\s0, \f(CW%PARAMETERS\fR" 4 .IX Item "create CLASS, %PARAMETERS" Creates a new object instance of a given \s-1CLASS\s0 and sets its properties corresponding to the passed parameter hash. Examples: .Sp .Vb 2 \& $obj = Class\-> create( PARAMETERS); \& $obj = Prima::Object::create( "class" , PARAMETERS); .Ve .Sp Is never called in an object context. .Sp Alias: \fInew()\fR .IP "destroy" 4 .IX Item "destroy" Initiates the object destruction. Perform in turn \fIcleanup()\fR and \fIdone()\fR calls. \&\fIdestroy()\fR can be called several times and is the only Prima re-entrant function, therefore may not be overloaded. .IP "done" 4 .IX Item "done" Called by \fIdestroy()\fR after \fIcleanup()\fR is finished. Used to free the object resources, as a finalization stage. During \fIdone()\fR no events are allowed to circulate, and \fIalive()\fR returns 0. The object is not usable after \fIdone()\fR finishes. Is never called directly. .Sp Note: the eventual child objects are destroyed inside \fIdone()\fR call. .ie n .IP "get @PARAMETERS" 4 .el .IP "get \f(CW@PARAMETERS\fR" 4 .IX Item "get @PARAMETERS" Returns hash where keys are \f(CW@PARAMETERS\fR and values are the corresponding object properties. .ie n .IP "init %PARAMETERS" 4 .el .IP "init \f(CW%PARAMETERS\fR" 4 .IX Item "init %PARAMETERS" The most important stage of object creation process. \f(CW%PARAMETERS\fR is the modified hash that was passed to \fIcreate()\fR. The modification consists of merging with the result of \fIprofile_default()\fR class method inside \&\fIprofile_check_in()\fR method. \fIinit()\fR is responsible for applying the relevant data into \s-1PARAMETERS\s0 to the object properties. Is never called directly. .ie n .IP "insert \s-1CLASS\s0, %PARAMETERS" 4 .el .IP "insert \s-1CLASS\s0, \f(CW%PARAMETERS\fR" 4 .IX Item "insert CLASS, %PARAMETERS" A convenience wrapper for \fIcreate()\fR, that explicitly sets the owner property for a newly created object. .Sp .Vb 1 \& $obj = $owner\-> insert( \*(AqClass\*(Aq, name => \*(Aqname\*(Aq); .Ve .Sp is adequate to .Sp .Vb 1 \& $obj = Class\-> create( owner => $owner, name => \*(Aqname); .Ve .Sp code. \fIinsert()\fR has another syntax that allows simultaneous creation of several objects: .Sp .Vb 5 \& @objects = $owner\-> insert( \& [ \*(AqClass\*(Aq, %parameters], \& [ \*(AqClass\*(Aq, %parameters], \& ... \& ); .Ve .Sp With such syntax, all newly created objects would have \f(CW$owner\fR set to their 'owner' properties. .ie n .IP "new \s-1CLASS\s0, %PARAMETERS" 4 .el .IP "new \s-1CLASS\s0, \f(CW%PARAMETERS\fR" 4 .IX Item "new CLASS, %PARAMETERS" Same as create. .IP "profile_add \s-1PROFILE\s0" 4 .IX Item "profile_add PROFILE" The first stage of object creation process. \s-1PROFILE\s0 is a reference to a \&\s-1PARAMETERS\s0 hash, passed to \fIcreate()\fR. It is merged with \fIprofile_default()\fR after passing both to \fIprofile_check_in()\fR. The merge result is stored back in \s-1PROFILE\s0. Is never called directly. .IP "profile_check_in \s-1CUSTOM_PROFILE\s0, \s-1DEFAULT_PROFILE\s0" 4 .IX Item "profile_check_in CUSTOM_PROFILE, DEFAULT_PROFILE" The second stage of object creation process. Resolves eventual ambiguities in \&\s-1CUSTOM_PROFILE\s0, which is the reference to \s-1PARAMETERS\s0 passed to \fIcreate()\fR, by comparing to and using default values from \s-1DEFAULT_PROFILE\s0, which is the result of \fIprofile_default()\fR method. Is never called directly. .IP "profile_default" 4 .IX Item "profile_default" Returns hash of the appropriate default values for all properties of a class. In object creation process serves as a provider of fall-back values, and is called implicitly. This method can be used directly, contrary to the other creation process-related functions. .Sp Can be called in a context of class. .IP "raise_ro \s-1TEXT\s0" 4 .IX Item "raise_ro TEXT" Throws an exception with text \s-1TEXT\s0 when a read-only property is called in a set\- context. .IP "raise_wo \s-1TEXT\s0" 4 .IX Item "raise_wo TEXT" Throws an exception with text \s-1TEXT\s0 when a write-only property is called in a get\- context. .ie n .IP "set %PARAMETERS" 4 .el .IP "set \f(CW%PARAMETERS\fR" 4 .IX Item "set %PARAMETERS" The default behavior is an equivalent to .Sp .Vb 6 \& sub set \& { \& my $obj = shift; \& my %PARAMETERS = @_; \& $obj\-> $_( $PARAMETERS{$_}) for keys %PARAMETERS; \& } .Ve .Sp code. Assigns object properties correspondingly to \s-1PARAMETERS\s0 hash. Many Prima::Component descendants overload \fIset()\fR to make it more efficient for particular parameter key patterns. .Sp As the code above, raises an exception if the key in \s-1PARAMETERS\s0 has no correspondent object property. .IP "setup" 4 .IX Item "setup" The last stage of object creation process. Called after \fIinit()\fR finishes. Used to initiate \f(CW\*(C`cmCreate\*(C'\fR event. Is never called directly. .SS "Prima::Component methods" .IX Subsection "Prima::Component methods" .IP "add_notification \s-1NAME\s0, \s-1SUB\s0, \s-1REFERER\s0 = undef, \s-1INDEX\s0 = \-1" 4 .IX Item "add_notification NAME, SUB, REFERER = undef, INDEX = -1" Adds \s-1SUB\s0 to the list of notification of event \s-1NAME\s0. \s-1REFERER\s0 is the object reference, which is used to create a context to \s-1SUB\s0 and is passed as a parameter to it when called. If \s-1REFERER\s0 is undef ( or not specified ), the same object is assumed. \s-1REFERER\s0 also gets implicitly attached to the object, \- the implementation frees the link between objects when one of these gets destroyed. .Sp \&\s-1INDEX\s0 is a desired insert position in the notification list. By default it is \&\-1, what means 'in the start'. If the notification type contains nt::FluxNormal bit set, the newly inserted \s-1SUB\s0 will be called first. If it has nt::FluxReverse, it is called last, correspondingly. .Sp Returns positive integer value on success, 0 on failure. This value can be later used to refer to the \s-1SUB\s0 in \fIremove_notification()\fR. .Sp See also: \f(CW\*(C`remove_notification\*(C'\fR, \f(CW\*(C`get_notification\*(C'\fR. .IP "attach \s-1OBJECT\s0" 4 .IX Item "attach OBJECT" Inserts \s-1OBJECT\s0 to the attached objects list and increases \s-1OBJECT\s0's reference count. The list can not hold more than one reference to the same object. The warning is issued on such an attempt. .Sp See also: \f(CW\*(C`detach\*(C'\fR. .IP "bring \s-1NAME\s0" 4 .IX Item "bring NAME" Looks for a immediate child object that has name equals to \s-1NAME\s0. Returns its reference on success, undef otherwise. It is a convenience method, that makes possible the usage of the following constructs: .Sp .Vb 4 \& $obj\-> name( "Obj"); \& $obj\-> owner( $owner); \& ... \& $owner\-> Obj\-> destroy; .Ve .IP "can_event" 4 .IX Item "can_event" Returns true if the object event circulation is allowed. In general, the same as \f(CW\*(C`alive() == 1\*(C'\fR, except that \fIcan_event()\fR fails if an invalid object reference is passed. .IP "clear_event" 4 .IX Item "clear_event" Clears the event state, that is set to 1 when the event processing begins. Signals the event execution stop for nt::Event\-prototyped events. .Sp See also: \*(L"Events\*(R", \f(CW\*(C`push_event\*(C'\fR, \f(CW\*(C`pop_event\*(C'\fR, \f(CW\*(C`::eventFlag\*(C'\fR, \f(CW\*(C`notify\*(C'\fR. .IP "detach \s-1OBJECT\s0, \s-1KILL\s0" 4 .IX Item "detach OBJECT, KILL" Removes \s-1OBJECT\s0 from the attached objects list and decreases \s-1OBJECT\s0's reference count. If \s-1KILL\s0 is true, destroys \s-1OBJECT\s0. .Sp See also: \f(CW\*(C`attach\*(C'\fR .IP "event_error" 4 .IX Item "event_error" Issues a system-dependent warning sound signal. .IP "event_hook [ \s-1SUB\s0 ]" 4 .IX Item "event_hook [ SUB ]" Installs a \s-1SUB\s0 to receive all events on all Prima objects. \s-1SUB\s0 receives same parameters passed to notify, and must return an integer, either 1 or 0, to pass or block the event respectively. .Sp If no \s-1SUB\s0 is set, returns currently installed event hook pointer. If \s-1SUB\s0 is set, replaces the old hook sub with \s-1SUB\s0. If \s-1SUB\s0 is \f(CW\*(Aqundef\*(Aq\fR, event filtering is not used. .Sp Since the \f(CW\*(Aqevent_hook\*(Aq\fR mechanism allows only one hook routine to be installed at a time, direct usage of the method is discouraged. Instead, use Prima::EventHook for multiplexing of the hook access. .Sp The method is static, and can be called either with or without class or object as a first parameter. .IP "get_components" 4 .IX Item "get_components" Returns array of the child objects. .Sp See: \f(CW\*(C`create\*(C'\fR, \*(L"Links between objects\*(R". .IP "get_handle" 4 .IX Item "get_handle" Returns a system-dependent handle for the object. For example, Prima::Widget return its system \s-1WINDOW/HWND\s0 handles, Prima::DeviceBitmap \- its system \&\s-1PIXMAP/HBITMAP\s0 handles, etc. .Sp Can be used to pass the handle value outside the program, for an eventual interprocess communication scheme. .ie n .IP "get_notification \s-1NAME\s0, @INDEX_LIST" 4 .el .IP "get_notification \s-1NAME\s0, \f(CW@INDEX_LIST\fR" 4 .IX Item "get_notification NAME, @INDEX_LIST" For each index in \s-1INDEX_LIST\s0 return three scalars, bound at the index position in the \s-1NAME\s0 event notification list. These three scalars are \s-1REFERER\s0, \s-1SUB\s0 and \&\s-1ID\s0. \s-1REFERER\s0 and \s-1SUB\s0 are those passed to \f(CW\*(C`add_notification\*(C'\fR, and \s-1ID\s0 is its result. .Sp See also: \f(CW\*(C`remove_notification\*(C'\fR, \f(CW\*(C`add_notification\*(C'\fR. .IP "get_notify_sub \s-1NAME\s0" 4 .IX Item "get_notify_sub NAME" A convenience method for nt::Single\-prototyped events. Returns code reference and context for the first notification sub for event \s-1NAME\s0. .Sp See \*(L"Success state\*(R" for example. .IP "notification_types" 4 .IX Item "notification_types" Returns a hash, where the keys are the event names and the values are the \&\f(CW\*(C`nt::\*(C'\fR constants that describe the event flow. .Sp Can be called in a context of class. .Sp See \*(L"Events\*(R" and \*(L"Flow\*(R" for details. .ie n .IP "notify \s-1NAME\s0, @PARAMETERS" 4 .el .IP "notify \s-1NAME\s0, \f(CW@PARAMETERS\fR" 4 .IX Item "notify NAME, @PARAMETERS" Calls the subroutines bound to the event \s-1NAME\s0 with parameters \f(CW@PARAMETERS\fR in context of the object. The calling order is described by \f(CW\*(C`nt::\*(C'\fR constants, contained in the \fInotification_types()\fR result hash. .Sp \&\fInotify()\fR accepts variable number of parameters, and while it is possible, it is not recommended to call \fInotify()\fR with the exceeding number of parameters; the call with the deficient number of parameters results in an exception. .Sp Example: .Sp .Vb 1 \& $obj\-> notify( "PostMessage", 0, 1); .Ve .Sp See \*(L"Events\*(R" and \*(L"Flow\*(R" for details. .IP "pop_event" 4 .IX Item "pop_event" Closes event processing stage brackets. .Sp See \f(CW\*(C`push_event\*(C'\fR, \*(L"Events\*(R" .IP "post_message \s-1SCALAR1\s0, \s-1SCALAR2\s0" 4 .IX Item "post_message SCALAR1, SCALAR2" Calls \f(CW\*(C`PostMessage\*(C'\fR event with parameters \s-1SCALAR1\s0 and \s-1SCALAR2\s0 once during idle event loop. Returns immediately. Does not guarantee that \f(CW\*(C`PostMessage\*(C'\fR will be called, however. .Sp See also \*(L"post\*(R" in Prima::Utils .IP "push_event" 4 .IX Item "push_event" Opens event processing stage brackets. .Sp See \f(CW\*(C`pop_event\*(C'\fR, \*(L"Events\*(R" .IP "remove_notification \s-1ID\s0" 4 .IX Item "remove_notification ID" Removes a notification subroutine that was registered before with \&\f(CW\*(C`add_notification\*(C'\fR, where \s-1ID\s0 was its result. After successful removal, the eventual context object gets implicitly detached from the storage object. .Sp See also: \f(CW\*(C`add_notification\*(C'\fR, \f(CW\*(C`get_notification\*(C'\fR. .IP "set_notification \s-1NAME\s0, \s-1SUB\s0" 4 .IX Item "set_notification NAME, SUB" Adds \s-1SUB\s0 to the event \s-1NAME\s0 notification list. Almost never used directly, but is a key point in enabling the following notification add syntax .Sp .Vb 1 \& $obj\-> onPostMessage( sub { ... }); .Ve .Sp or .Sp .Vb 1 \& $obj\-> set( onPostMessage => sub { ... }); .Ve .Sp that are shortcuts for .Sp .Vb 1 \& $obj\-> add_notification( "PostMessage", sub { ... }); .Ve .IP "unlink_notifier \s-1REFERER\s0" 4 .IX Item "unlink_notifier REFERER" Removes all notification subs from all event lists bound to \s-1REFERER\s0 object. .SS "Prima::Component properties" .IX Subsection "Prima::Component properties" .IP "eventFlag \s-1STATE\s0" 4 .IX Item "eventFlag STATE" Provides access to the last event processing state in the object event state stack. .Sp See also: \*(L"Success state\*(R", \f(CW\*(C`clear_event\*(C'\fR, \*(L"Events\*(R". .IP "delegations [ <\s-1REFERER\s0>, \s-1NAME\s0, <\s-1NAME\s0>, < <\s-1REFERER\s0>, \s-1NAME\s0, ... > ]" 4 .IX Item "delegations [ , NAME, , < , NAME, ... > ]" Accepts an anonymous array in \fIset\-\fR context, which consists of a list of event NAMEs, that a \s-1REFERER\s0 object ( the caller object by default ) is interested in. Registers notification entries for routines if subs with naming scheme \&\s-1REFERER_NAME\s0 are present on \s-1REFERER\s0 name space. The example code .Sp .Vb 2 \& $obj\-> name("Obj"); \& $obj\-> delegations([ $owner, \*(AqPostMessage\*(Aq]); .Ve .Sp registers Obj_PostMessage callback if it is present in \f(CW$owner\fR namespace. .Sp In \fIget\-\fR context returns an array reference that reflects the object's delegated events list content. .Sp See also: \*(L"Delegated methods\*(R". .IP "name \s-1NAME\s0" 4 .IX Item "name NAME" Maintains object name. \s-1NAME\s0 can be an arbitrary string, however it is recommended against usage of special characters and spaces in \s-1NAME\s0, to facilitate the indirect object access coding style: .Sp .Vb 4 \& $obj\-> name( "Obj"); \& $obj\-> owner( $owner); \& ... \& $owner\-> Obj\-> destroy; .Ve .Sp and to prevent system-dependent issues. If the system provides capabilities that allow to predefine some object parameters by its name ( or class), then it is impossible to know beforehand the system naming restrictions. For example, in X window system the following resource string would make all Prima toolkit buttons green: .Sp .Vb 1 \& Prima*Button*backColor: green .Ve .Sp In this case, using special characters such as \f(CW\*(C`:\*(C'\fR or \f(CW\*(C`*\*(C'\fR in the name of an object would make the X resource unusable. .IP "owner \s-1OBJECT\s0" 4 .IX Item "owner OBJECT" Selects an owner of the object, which may be any Prima::Component descendant. Setting an owner to a object does not alter its reference count. Some classes allow \s-1OBJECT\s0 to be undef, while some do not. All widget objects can not exist without a valid owner; Prima::Application on the contrary can only exist with owner set to undef. Prima::Image objects are indifferent to the value of the owner property. .Sp Changing owner dynamically is allowed, but it is a main source of implementation bugs, since the whole hierarchy tree is needed to be recreated. Although this effect is not visible in perl, the results are deeply system-dependent, and the code that changes owner property should be thoroughly tested. .Sp Changes to \f(CW\*(C`owner\*(C'\fR result in up to three notifications: \f(CW\*(C`ChangeOwner\*(C'\fR, which is called to the object itself, \f(CW\*(C`ChildLeave\*(C'\fR, which notifies the previous owner that the object is about to leave, and \f(CW\*(C`ChildEnter\*(C'\fR, telling the new owner about the new child. .SS "Prima::Component events" .IX Subsection "Prima::Component events" .IP "ChangeOwner \s-1OLD_OWNER\s0" 4 .IX Item "ChangeOwner OLD_OWNER" Called at runtime when the object changes its owner. .IP "ChildEnter \s-1CHILD\s0" 4 .IX Item "ChildEnter CHILD" Triggered when a child object is attached, either as a new instance or as a result of runtime owner change. .IP "ChildLeave \s-1CHILD\s0" 4 .IX Item "ChildLeave CHILD" Triggered when a child object is detached, either because it is getting destroyed or as a result of runtime owner change. .IP "Create" 4 .IX Item "Create" The first event an event sees. Called automatically after \fIinit()\fR is finished. Is never called directly. .IP "Destroy" 4 .IX Item "Destroy" The last event an event sees. Called automatically before \fIdone()\fR is started. Is never called directly. .IP "PostMessage \s-1SCALAR1\s0, \s-1SCALAR2\s0" 4 .IX Item "PostMessage SCALAR1, SCALAR2" Called after \fIpost_message()\fR call is issued, not inside \fIpost_message()\fR but at the next idle event loop. \s-1SCALAR1\s0 and \s-1SCALAR2\s0 are the data passed to \&\fIpost_message()\fR. .SH "AUTHOR" .IX Header "AUTHOR" Dmitry Karasik, . .SH "SEE ALSO" .IX Header "SEE ALSO" Prima, Prima::internals, Prima::EventHook.