|
|
| |
pod::Prima::Object(3) |
User Contributed Perl Documentation |
pod::Prima::Object(3) |
Prima::Object - Prima toolkit base classes
if ( $obj-> isa('Prima::Component')) {
# set and get a property
my $name = $obj-> name;
$obj->name( 'an object' );
# set a notification callback
$obj-> onPostMessage( sub {
shift;
print "hey! I've received this: @_\n";
});
# can set multiple properties. note, that 'name' and 'owner',
# replace the old values, while onPostMessage are aggregated.
$obj-> set(
name => 'AnObject',
owner => $new_owner,
onPostMessage => sub {
shift;
print "hey! me too!\n";
},
);
# de-reference by name
$new_owner-> AnObject-> post_message(1,2);
}
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
Prima::Component-> new( .. parameters ... );
call. This document describes the basic concepts of the OO
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.
Object creation has fixed syntax:
$new_object = Class-> new(
parameter => value,
parameter => value,
...
);
Parameters and values form a hash, which is passed to the
new() method. This hash is applied to a default parameter-value hash
( a profile ), specific to every Prima class. The object creation is
performed in several stages.
- new
- new() calls profile_default() 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 ):
name => ref $_[ 0],
owner => $::application,
delegations => undef,
While the exact meaning of these parameters is described
later, in "Properties", 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 new(). Example:
$a1 = Prima::Component-> new();
$a1's owner will be
$::application
$a2 = Prima::Component-> new( owner => $a1);
$a2's owner will be
$a1. The actual merging of the default and the
parameter hashes is performed on the next stage, in
profile_check_in() method which is called inside
profile_add() method.
Note: the older syntax used create() instead of
new(), which is still valid but is not preferred
- profile_check_in
- A profile_check_in() 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 profile_check_in()'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 new(), it is assigned to a concatenated class name
with an integer - Component1, Component2 etc.
Another example can be taken from
Prima::Widget::profile_check_in(). Prima::Widget horizontal
position can be specified by using basic
"left" and
"width" parameters, and as well by
auxiliary "right",
"size" and
"rect". The default of both
"left" and
"width" is 100. But if only
"right" parameter, for example, was
passed to new() it is profile_check_in() job to determine
"left" value, given that
"width" is still 100.
After profiles gets merged, the resulting hash is passed to
the third stage, init().
- init
- init() duty is to map the profile content into object, e.g., assign
"name" property to
"name" parameter value, and so on - for
all relevant parameters. After that, it has to return the profile in order
the overridden subsequent init() methods can perform same actions.
This stage along with the previous is exemplified in almost all Prima
modules.
Note: usually init() 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 "Links
between objects").
After init() finishes, new() calls
setup() method
- setup
- setup() method is a convenience function, it is used when some
post-init actions must be taken. It is seldom overloaded, primarily
because the Component::setup() method calls
"onCreate" notification, which is more
convenient to overload than setup().
As can be noticed from the code pieces above, a successful
new() 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 die() during init() stage result in undef. Other
errors raise an exception instead. It is not recommended to frame
new() calls in an "eval{}" 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.
After new(), the object is subject to the event flow. As
"onCreate" event is the first event the
object receives, only after that stage other events can be circulated.
Object destruction can be caused by many conditions, but all execution flow is
finally passed through destroy() method. destroy(), as well as
new() performs several finalizing steps:
- cleanup
- The first method called inside destroy() is cleanup().
cleanup() is the pair to setup(), as destroy() is the
pair to new(). cleanup() generates
"onDestroy" event, which can be
overridden more easily than cleanup() itself.
"onDestroy" is the last
event the object sees. After cleanup() no events are allowed to
circulate.
- done
- done() method is the pair to init(), and is the place where
all object resources are freed. Although it is as safe to overload
done() as init(), it almost never gets overloaded, primarily
because overloading "onDestroy" is
easier.
The typical conditions that lead to object destructions are direct
destroy() call, garbage collections mechanisms, user-initiated window
close ( on "Prima::Window" only ), and
exception during init() stage. Thus, one must be careful implementing
done() which is called after init() throws an exception.
The class methods are declared and used with perl OO syntax, which allow both
method of object referencing:
$object-> method();
and
method( $object);
The actual code is a sub, located under the object class package.
The overloaded methods that call their ancestor code use
$object-> SUPER::method();
syntax. Most Prima methods have fixed number of parameters.
Properties are methods that combine functionality of two ephemeral
"get" and "set" 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, set_name() and get_name() 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 name() ( referred as
"::name" later in the documentation ).
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
"::name" property implementation:
sub name
{
return $_[0]-> {name} unless $#_;
$_[0]->{name} = $_[1];
}
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
$object-> name( "new name");
but also with set() method. The set() method accepts
a hash, that is much like to new(), and assigns the values to the
corresponding properties. For example, the code
$object-> name( "new name");
$object-> owner( $owner);
can be rewritten as
$object-> set(
name => "new name",
owner => $owner
);
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
set() 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
$image-> type( $a);
$image-> palette( $b);
and
$image-> palette( $b);
$image-> type( $a);
produce different results. It is indeed the only solution to call
for such a change using
$image-> set(
type => $a,
palette => $b
);
when it is known beforehand that
"Prima::Image::set" is aware of such
combinations and calls neither "::type"
nor "::palette" but performs another image
conversion instead.
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.
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.
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
"::owner" 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.
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
get_components(), that returns an array of the child references.
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.
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 GUI'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.
The special convenience variety of new(), the
insert() method is used to explicitly select owner of the newly
created object. insert() can be considered a 'constructor' in
OO-terms. It makes the construct
$obj = Class-> new( owner => $owner, name => 'name);
more readable by introducing
$obj = $owner-> insert( 'Class', name => 'name');
scheme. These two code blocks are identical to each other.
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 attach() and
detach() methods.
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
notify() 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 notification_types() method. This method returns
all available information about the events registered in a class.
Prima defines also a non-object event dispatching and filtering
mechanism, available through "event_hook" static method.
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
$obj-> notify("PostMessage", $data1, $data2);
call is issued for all these examples.
- Direct methods
- As it is usual in OO programming, event callback routines are declared as
methods. 'Direct methods' employ such a paradigm, so if a class method
with name "on_postmessage" is present,
it will be called as a method ( i.e., in the object context ) when
"onPostMessage" event is triggered.
Example:
sub on_postmessage
{
my ( $self, $data1, $data2) = @_;
...
}
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
"::SUPER" call is needed, because
these methods are not defined by default.
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
"Click". This scheme is convenient
when an event handling routine serves the internal,
implementation-specific needs.
- 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 $obj's owner,
$owner would be interested in
$obj's PostMessage event, it would register the
notification callback by
$obj-> delegations([ $owner, 'PostMessage']);
where the actual callback sub will be
sub Obj_PostMessage
{
my ( $self, $obj, $data1, $data2) = @_;
}
Note that the naming style is different - the callback name is
constructed from object name ( let assume that
$obj's name is 'Obj') and the event name. ( This
is one of the reasons why Component::profile_check_in() performs
automatic naming of newly created onbjects). Note also that context
objects are $self ( that equals
$owner ) and $obj.
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.
- 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.
Contrary to the usual OO 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 anonymous subs, however).
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 OO 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
$obj using each syntax for a different
situation:
- during new():
$obj = Class-> new(
...
onPostMessage => sub {
my ( $self, $data1, $data2) = @_;
},
...
);
- after new using set()
$obj-> set( onPostMessage => sub {
my ( $self, $data1, $data2) = @_;
});
- after new using event name:
$obj-> onPostMessage( sub {
my ( $self, $data1, $data2) = @_;
});
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,
$obj-> onPostMessage( sub { print "1" });
$obj-> onPostMessage( sub { print "2" });
$obj-> notify( "PostMessage", 0, 0);
code block would print
21
as the execution result.
This, it is a distinctive feature of a toolkit is that two
objects of same class may have different set of event handlers.
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 notification_types() 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 OR combination of several basic flow constants, that control the
three aspects of the event flow.
- 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
"nt::PrivateFirst" and
"nt::CustomFirst" constants defines the
order.
- Direction
- Almost the same as order, but for finer granulation of event flow, the
direction constants "nt::FluxNormal" and
"nt::FluxReverse" are used. The 'normal
flux' defines FIFO ( 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
$obj-> onPostMessage( sub { print "1" });
$obj-> onPostMessage( sub { print "2" });
$obj-> notify( "PostMessage", 0, 0);
results in 21, not
12 because PostMessage event type is prototyped
"nt::FluxReverse".
- 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
"nt::Single" bit in execution control
constant set, which consists of the following constants:
nt::Single
nt::Multiple
nt::Event
These constants are mutually exclusive, and may not appear
together in an event type declaration. A
"nt::Single"-prototyped notification
calls only the first ( or the last - depending on order and direction
bits ) callback. The usage of this constant is somewhat limited.
In contrary of "nt::Single",
the "nt::Multiple" constant sets the
execution control to call all the available callbacks, with respect to
direction and order bits.
The third constant,
"nt::Event", is the impact as
"nt::Multiple", except that the event
flow can be stopped at any time by calling clear_event()
method.
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:
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 )
Events do not return values, although the event generator, the notify()
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 clear_event() 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 notify() 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, clear_event() is an alias for
::eventFlag(0) call. The state stack is operated by push_event()
and pop_event() methods.
Implementation note: a call of clear_event() inside a
"nt::Event"-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 ::eventFlag(1) call
thus cancels the effect of clear_event().
A particular coding style is used when the event is
"nt::Single"-prototyped and is called many
times in a row, so overheads of calling notify() become a burden.
Although notify() logic is somewhat complicated, it is rather simple
with "nt::Single" case. The helper
function get_notify_sub() returns the context of callback
to-be-called, so it can be used to emulate notify() behavior.
Example:
for ( ... ) {
$result = $obj-> notify( "Measure", @parms);
}
can be expressed in more cumbersome, but efficient code if
"nt::Single"-prototyped event is used:
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;
- 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 init() stage. Example:
print $obj-> name if Prima::Object::alive( $obj);
- cleanup
- Called right after destroy() started. Used to initiate
"cmDestroy" event. Is never called
directly.
- create CLASS, %PARAMETERS
- Same as new.
- destroy
- Initiates the object destruction. Perform in turn cleanup() and
done() calls. destroy() can be called several times and is
the only Prima re-entrant function, therefore may not be overloaded.
- done
- Called by destroy() after cleanup() is finished. Used to
free the object resources, as a finalization stage. During done()
no events are allowed to circulate, and alive() returns 0. The
object is not usable after done() finishes. Is never called
directly.
Note: the eventual child objects are destroyed inside
done() call.
- get @PARAMETERS
- Returns hash where keys are @PARAMETERS and values
are the corresponding object properties.
- init %PARAMETERS
- The most important stage of object creation process.
%PARAMETERS is the modified hash that was passed
to new(). The modification consists of merging with the result of
profile_default() class method inside profile_check_in()
method. init() is responsible for applying the relevant data into
PARAMETERS to the object properties. Is never called directly.
- insert CLASS, %PARAMETERS
- A convenience wrapper for new(), that explicitly sets the owner
property for a newly created object.
$obj = $owner-> insert( 'Class', name => 'name');
is adequate to
$obj = Class-> new( owner => $owner, name => 'name);
code. insert() has another syntax that allows
simultaneous creation of several objects:
@objects = $owner-> insert(
[ 'Class', %parameters],
[ 'Class', %parameters],
...
);
With such syntax, all newly created objects would have
$owner set to their 'owner' properties.
- new CLASS, %PARAMETERS
- Creates a new object instance of a given CLASS and sets its properties
corresponding to the passed parameter hash. Examples:
$obj = Class-> new( PARAMETERS);
$obj = Prima::Object::new( "class" , PARAMETERS);
Is never called in an object context.
Alias: create()
- profile_add PROFILE
- The first stage of object creation process. PROFILE is a reference to a
PARAMETERS hash, passed to new(). It is merged with
profile_default() after passing both to profile_check_in().
The merge result is stored back in PROFILE. Is never called directly.
- profile_check_in CUSTOM_PROFILE, DEFAULT_PROFILE
- The second stage of object creation process. Resolves eventual ambiguities
in CUSTOM_PROFILE, which is the reference to PARAMETERS passed to
new(), by comparing to and using default values from
DEFAULT_PROFILE, which is the result of profile_default() method.
Is never called directly.
- 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.
Can be called in a context of class.
- raise_ro TEXT
- Throws an exception with text TEXT when a read-only property is called in
a set- context.
- raise_wo TEXT
- Throws an exception with text TEXT when a write-only property is called in
a get- context.
- set %PARAMETERS
- The default behavior is an equivalent to
sub set
{
my $obj = shift;
my %PARAMETERS = @_;
$obj-> $_( $PARAMETERS{$_}) for keys %PARAMETERS;
}
code. Assigns object properties correspondingly to PARAMETERS
hash. Many Prima::Component descendants overload set() to make it
more efficient for particular parameter key patterns.
As the code above, raises an exception if the key in
PARAMETERS has no correspondent object property.
- setup
- The last stage of object creation process. Called after init()
finishes. Used to initiate "cmCreate"
event. Is never called directly.
- add_notification NAME, SUB, REFERER = undef, INDEX = -1
- Adds SUB to the list of notification of event NAME. REFERER is the object
reference, which is used to create a context to SUB and is passed as a
parameter to it when called. If REFERER is undef ( or not specified ), the
same object is assumed. REFERER also gets implicitly attached to the
object, - the implementation frees the link between objects when one of
these gets destroyed.
INDEX 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 SUB will be called
first. If it has nt::FluxReverse, it is called last,
correspondingly.
Returns positive integer value on success, 0 on failure. This
value can be later used to refer to the SUB in
remove_notification().
See also:
"remove_notification",
"get_notification".
- attach OBJECT
- Inserts OBJECT to the attached objects list and increases OBJECT's
reference count. The list can not hold more than one reference to the same
object. The warning is issued on such an attempt.
See also: "detach".
- bring NAME
- Looks for a immediate child object that has name equals to NAME. Returns
its reference on success, undef otherwise. It is a convenience method,
that makes possible the usage of the following constructs:
$obj-> name( "Obj");
$obj-> owner( $owner);
...
$owner-> Obj-> destroy;
See also:
"find_component"
- can_event
- Returns true if the object event circulation is allowed. In general, the
same as "alive() == 1", except that
can_event() fails if an invalid object reference is passed.
- 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.
See also: "Events",
"push_event",
"pop_event",
"::eventFlag",
"notify".
- detach OBJECT, KILL
- Removes OBJECT from the attached objects list and decreases OBJECT's
reference count. If KILL is true, destroys OBJECT.
See also: "attach"
- event_error
- Issues a system-dependent warning sound signal.
- event_hook [ SUB ]
- Installs a SUB to receive all events on all Prima objects. SUB receives
same parameters passed to notify, and must return an integer, either 1 or
0, to pass or block the event respectively.
If no SUB is set, returns currently installed event hook
pointer. If SUB is set, replaces the old hook sub with SUB. If SUB is
'undef', event filtering is not used.
Since the 'event_hook' 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.
The method is static, and can be called either with or without
class or object as a first parameter.
- find_component NAME
- Performs a depth-first search on children tree hierarchy, matching the
object that has name equal to NAME. Returns its reference on success,
undef otherwise.
See also: "bring"
- get_components
- Returns array of the child objects.
See: "new", "Links
between objects".
- get_handle
- Returns a system-dependent handle for the object. For example,
Prima::Widget return its system WINDOW/HWND handles, Prima::DeviceBitmap -
its system PIXMAP/HBITMAP handles, etc.
Can be used to pass the handle value outside the program, for
an eventual interprocess communication scheme.
- get_notification NAME, @INDEX_LIST
- For each index in INDEX_LIST return three scalars, bound at the index
position in the NAME event notification list. These three scalars are
REFERER, SUB and ID. REFERER and SUB are those passed to
"add_notification", and ID is its
result.
See also:
"remove_notification",
"add_notification".
- get_notify_sub NAME
- A convenience method for nt::Single-prototyped events. Returns code
reference and context for the first notification sub for event NAME.
See "Success state" for example.
- notification_types
- Returns a hash, where the keys are the event names and the values are the
"nt::" constants that describe the event
flow.
Can be called in a context of class.
See "Events" and "Flow" for details.
- notify NAME, @PARAMETERS
- Calls the subroutines bound to the event NAME with parameters
@PARAMETERS in context of the object. The calling
order is described by "nt::" constants,
contained in the notification_types() result hash.
notify() accepts variable number of parameters, and
while it is possible, it is not recommended to call notify() with
the exceeding number of parameters; the call with the deficient number
of parameters results in an exception.
Example:
$obj-> notify( "PostMessage", 0, 1);
See "Events" and "Flow" for details.
- pop_event
- Closes event processing stage brackets.
See "push_event",
"Events"
- post_message SCALAR1, SCALAR2
- Calls "PostMessage" event with
parameters SCALAR1 and SCALAR2 once during idle event loop. Returns
immediately. Does not guarantee that
"PostMessage" will be called, however.
See also "post" in Prima::Utils
- push_event
- Opens event processing stage brackets.
See "pop_event",
"Events"
- remove_notification ID
- Removes a notification subroutine that was registered before with
"add_notification", where ID was its
result. After successful removal, the eventual context object gets
implicitly detached from the storage object.
See also:
"add_notification",
"get_notification".
- set_notification NAME, SUB
- Adds SUB to the event NAME notification list. Almost never used directly,
but is a key point in enabling the following notification add syntax
$obj-> onPostMessage( sub { ... });
or
$obj-> set( onPostMessage => sub { ... });
that are shortcuts for
$obj-> add_notification( "PostMessage", sub { ... });
- unlink_notifier REFERER
- Removes all notification subs from all event lists bound to REFERER
object.
- eventFlag STATE
- Provides access to the last event processing state in the object event
state stack.
See also: "Success state",
"clear_event", "Events".
- delegations [ <REFERER>, NAME, <NAME>, < <REFERER>,
NAME, ... > ]
- Accepts an anonymous array in set- context, which consists of a
list of event NAMEs, that a REFERER object ( the caller object by default
) is interested in. Registers notification entries for routines if subs
with naming scheme REFERER_NAME are present on REFERER name space. The
example code
$obj-> name("Obj");
$obj-> delegations([ $owner, 'PostMessage']);
registers Obj_PostMessage callback if it is present in
$owner namespace.
In get- context returns an array reference that
reflects the object's delegated events list content.
See also: "Delegated methods".
- name NAME
- Maintains object name. NAME can be an arbitrary string, however it is
recommended against usage of special characters and spaces in NAME, to
facilitate the indirect object access coding style:
$obj-> name( "Obj");
$obj-> owner( $owner);
...
$owner-> Obj-> destroy;
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:
Prima*Button*backColor: green
In this case, using special characters such as
":" or
"*" in the name of an object would
make the X resource unusable.
- 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 OBJECT 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.
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.
Changes to "owner" result in
up to three notifications:
"ChangeOwner", which is called to the
object itself, "ChildLeave", which
notifies the previous owner that the object is about to leave, and
"ChildEnter", telling the new owner
about the new child.
- ChangeOwner OLD_OWNER
- Called at runtime when the object changes its owner.
- ChildEnter CHILD
- Triggered when a child object is attached, either as a new instance or as
a result of runtime owner change.
- ChildLeave CHILD
- Triggered when a child object is detached, either because it is getting
destroyed or as a result of runtime owner change.
- Create
- The first event an event sees. Called automatically after init() is
finished. Is never called directly.
- Destroy
- The last event an event sees. Called automatically before done() is
started. Is never called directly.
- PostMessage SCALAR1, SCALAR2
- Called after post_message() call is issued, not inside
post_message() but at the next idle event loop. SCALAR1 and SCALAR2
are the data passed to post_message().
- SysHandle
- Sometimes Prima needs to implicitly re-create the system handle of a
component. The re-creation is not seen on the toolkit level, except for
some repaints when widgets on screen are affected, but under the hood,
when it happens, Prima creates a whole new system resource. This happens
when the underlying system either doesn't have API to change a certain
property during the runtime, or when such a re-creation happens on one of
component's parent, leading to a downward cascade of children re-creation.
Also, it may happen when the user changes some system settings resolution,
so that some resources have to be changed accordingly.
This event will be only needed when the system handle (that
can be acquired by "get_handle" ) is
used further, or in case when Prima doesn't restore some properties
bound to the system handle.
Dmitry Karasik, <dmitry@karasik.eu.org>.
Prima, Prima::internals, Prima::EventHook.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |