Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
303 lines (196 sloc) 6.44 KB
/*
Copyright (C) 2007-2009, Parrot Foundation.
$Id$
=head1 NAME
src/pmc/eventhandler.pmc - a handler for events
=head1 DESCRIPTION
A PMC that captures the state of the interpreter to invoke when handling an
Event.
=head2 Vtable Functions
=over 4
=cut
*/
pmclass EventHandler extends Sub auto_attrs {
ATTR STRING *type; /* the type of the event to handle */
ATTR PMC *code; /* the code object to execute */
ATTR PMC *interp; /* the registered interpreter */
ATTR INTVAL priority; /* the minimum priority threshhold of events */
/*
=item C<void init()>
Initializes an empty C<EventHandler>. Add attributes to it if you want it to
do anything.
=cut
*/
VTABLE void init() {
PObj_custom_mark_SET(SELF);
PObj_custom_destroy_SET(SELF);
}
/*
=item C<void init_pmc(PMC *data)>
Initializes a new EventHandler with either a C<Sub> PMC (or descendant) or a
C<Hash> PMC. With the latter, the keys should be any or all of:
=over 4
=item C<code>
a C<Sub> (or descendant) PMC containing code to invoke when handling the event
=item C<interp>
a C<ParrotInterpreter> PMC in which to invoke the code PMC
=item C<type>
a STRING recording the type of event to handle
=item C<priority>
the minimum threshhold of priority which the event must meet or exceed for the
handler to care
=back
=cut
*/
VTABLE void init_pmc(PMC *data) {
PMC *code = NULL;
PMC *interpreter = PMCNULL;
STRING *type = NULL;
INTVAL priority = 0;
Parrot_EventHandler_attributes *e =
(Parrot_EventHandler_attributes *) PMC_data(SELF);
if (VTABLE_isa(INTERP, data, CONST_STRING(INTERP, "Sub"))) {
code = data;
}
else if (VTABLE_isa(INTERP, data, CONST_STRING(INTERP, "Hash"))) {
code = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "code"));
interpreter = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "interp"));
type = VTABLE_get_string_keyed_str(INTERP, data, CONST_STRING(INTERP, "type"));
priority = VTABLE_get_integer_keyed_str(INTERP, data, CONST_STRING(INTERP, "priority"));
}
else {
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"EventHandler initializer must be Sub or Hash");
}
if (PMC_IS_NULL(interpreter))
interpreter = VTABLE_get_pmc_keyed_int(INTERP,
INTERP->iglobals, IGLOBALS_INTERPRETER);
PObj_custom_mark_SET(SELF);
PObj_custom_destroy_SET(SELF);
e->type = type;
e->code = code;
e->interp = interpreter;
e->priority = priority;
}
/*
=item C<void mark()>
Marks this PMC and any of its contents as live.
=cut
*/
VTABLE void mark() {
Parrot_EventHandler_attributes * const e = PARROT_EVENTHANDLER(SELF);
if (e) {
Parrot_gc_mark_STRING_alive(INTERP, e->type);
Parrot_gc_mark_PMC_alive(INTERP, e->interp);
Parrot_gc_mark_PMC_alive(INTERP, e->code);
SUPER();
}
}
/*
=item C<void set_string(STRING *type)>
Sets the C<type> attribute of this event handler to the passed-in string.
=cut
*/
VTABLE void set_string(STRING *type) {
Parrot_EventHandler_attributes * const e = PARROT_EVENTHANDLER(SELF);
if (e)
e->type = type;
}
/*
=item C<STRING *get_string()>
Retrieves the C<type> attribute of this event handler.
=cut
*/
VTABLE STRING *get_string() {
Parrot_EventHandler_attributes * const e = PARROT_EVENTHANDLER(SELF);
if (e)
return Parrot_str_copy(INTERP, e->type);
return string_from_literal(INTERP, "");
}
/*
=item C<void set_integer_native(INTVAL priority)>
Sets the minimum interesting priority for this event handler.
=cut
*/
VTABLE void set_integer_native(INTVAL priority) {
Parrot_EventHandler_attributes * const e = PARROT_EVENTHANDLER(SELF);
if (e)
e->priority = priority;
}
/*
=item C<void set_pmc(PMC *interpreter)>
Sets the passed-in C<ParrotInterpreter> as the active interpreter in which to
handle the registered events.
=cut
*/
VTABLE void set_pmc(PMC *interpreter) {
Parrot_EventHandler_attributes * const e = PARROT_EVENTHANDLER(SELF);
if (e)
e->interp = interpreter;
}
/*
=item C<PMC *get_attr_str(STRING *name)>
=cut
*/
VTABLE PMC *get_attr_str(STRING *name) {
Parrot_EventHandler_attributes * const e = PARROT_EVENTHANDLER(SELF);
PMC *value = PMCNULL;
if (Parrot_str_equal(interp, name, CONST_STRING(interp, "code"))) {
value = e->code;
}
return value;
}
/*
=item C<opcode_t *invoke(void *next)>
Runs the contained code, if any; this is what handles the event.
=cut
*/
VTABLE opcode_t *invoke(void *next) {
Parrot_EventHandler_attributes * const e = PARROT_EVENTHANDLER(SELF);
void *unused;
/* can't invoke on INTERP and can't return its result; this may not be
* the right interpreter */
if (e) {
unused = VTABLE_invoke(PMC_data_typed(e->interp, Parrot_Interp),
e->code, next);
UNUSED(unused);
}
return (opcode_t *)next;
}
/*
=back
=head2 Methods
=over 4
=cut
*/
/*
=item C<METHOD can_handle(PMC *event)>
Report whether the event handler can handle a particular type of event.
=cut
*/
METHOD can_handle(PMC *event) {
Parrot_EventHandler_attributes * const handler_struct = PARROT_EVENTHANDLER(SELF);
if (event->vtable->base_type == enum_class_Task) {
PMC *type = VTABLE_get_attr_str(interp, event, CONST_STRING(interp, "type"));
STRING *type_str = VTABLE_get_string(interp, type);
if (Parrot_str_equal(interp, type_str, CONST_STRING(interp, "event"))) {
PMC *subtype = VTABLE_get_attr_str(interp, event, CONST_STRING(interp, "subtype"));
STRING *subtype_str = VTABLE_get_string(interp, subtype);
if (Parrot_str_equal(interp, subtype_str, handler_struct->type)) {
RETURN(INTVAL 1);
}
}
}
RETURN(INTVAL 0);
}
}
/*
=back
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4:
*/
Something went wrong with that request. Please try again.