tagged release 0.6.4
[parrot.git] / src / pmc / eventhandler.pmc
blobbfff5079be251512c004d2ce17825942a1691e58
1 /*
2 Copyright (C) 2007-2008, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/eventhandler.pmc - a handler for events
9 =head1 DESCRIPTION
11 A PMC that captures the state of the interpreter to invoke when handling an
12 Event.
14 =head2 Vtable Functions
16 =over 4
18 =cut
22 #include "parrot/parrot.h"
24 pmclass EventHandler extends Sub need_ext {
26     ATTR STRING *type;          /* the type of the event to handle */
27     ATTR PMC    *code;          /* the code object to execute */
28     ATTR PMC    *interp;        /* the registered interpreter */
29     ATTR INTVAL  priority;      /* the minimum priority threshhold of events */
33 =item C<void init()>
35 Initializes an empty C<EventHandler>.  Add attributes to it if you want it to
36 do anything.
38 =cut
42     VTABLE void init() {
43         Parrot_EventHandler *e = mem_allocate_zeroed_typed(Parrot_EventHandler);
45         PObj_custom_mark_SET(SELF);
46         PObj_active_destroy_SET(SELF);
48         PMC_data(SELF) = e;
49     }
53 =item C<void init_pmc(PMC *data)>
55 Initializes a new EventHandler with either a C<Sub> PMC (or descendant) or a
56 C<Hash> PMC.  With the latter, the keys should be any or all of:
58 =over 4
60 =item C<code>
62 a C<Sub> (or descendant) PMC containing code to invoke when handling the event
64 =item C<interp>
66 a C<ParrotInterpreter> PMC in which to invoke the code PMC
68 =item C<type>
70 a STRING recording the type of event to handle
72 =item C<priority>
74 the minimum threshhold of priority which the event must meet or exceed for the
75 handler to care
77 =back
79 =cut
83     VTABLE void init_pmc(PMC *data) {
84         PMC                 *code        = NULL;
85         PMC                 *interpreter = PMCNULL;
86         STRING              *type        = NULL;
87         INTVAL               priority    = 0;
88         Parrot_EventHandler *e           = NULL;
90         if (VTABLE_isa(INTERP, data, CONST_STRING(INTERP, "Sub"))) {
91             code = data;
92         }
93         else if (VTABLE_isa(INTERP, data, CONST_STRING(INTERP, "Hash"))) {
94             code =
95                 VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "code"));
96             interpreter =
97                 VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "interp"));
98             type =
99                 VTABLE_get_string_keyed_str(INTERP, data, CONST_STRING(INTERP, "type"));
100             priority =
101                 VTABLE_get_integer_keyed_str(INTERP, data, CONST_STRING(INTERP, "priority"));
102         }
103         else {
104             real_exception(INTERP, NULL, INVALID_OPERATION,
105                 "EventHandler initializer must be Sub or Hash");
106         }
108         if (PMC_IS_NULL(interpreter))
109             interpreter = VTABLE_get_pmc_keyed_int(INTERP,
110                     INTERP->iglobals, IGLOBALS_INTERPRETER);
112         e = mem_allocate_zeroed_typed(Parrot_EventHandler);
114         PObj_custom_mark_SET(SELF);
115         PObj_active_destroy_SET(SELF);
117         PMC_data(SELF) = e;
118         e->type        = type;
119         e->code        = code;
120         e->interp      = interpreter;
121         e->priority    = priority;
122     }
126 =item C<void mark()>
128 Marks this PMC and any of its contents as live.
130 =cut
134     VTABLE void mark() {
135         Parrot_EventHandler *e = PMC_data_typed(SELF, Parrot_EventHandler *);
137         if (e) {
138             if (e->type)
139                 pobject_lives(INTERP, (PObj *)e->type);
141             if (! PMC_IS_NULL(e->interp))
142                 pobject_lives(INTERP, (PObj *)e->interp);
144             if (! PMC_IS_NULL(e->code))
145                 pobject_lives(INTERP, (PObj *)e->code);
146         }
147     }
151 =item C<void destroy()>
153 Frees any memory held by this PMC.
157     VTABLE void destroy() {
158         Parrot_EventHandler *e = PMC_data_typed(SELF, Parrot_EventHandler *);
160         if (e) {
161             mem_sys_free(e);
162             PMC_data(SELF) = NULL;
163         }
164     }
168 =item C<void set_string(STRING *type)>
170 Sets the C<type> attribute of this event handler to the passed-in string.
172 =cut
176     void set_string(STRING *type) {
177         Parrot_EventHandler *e = PMC_data_typed(SELF, Parrot_EventHandler *);
179         if (e)
180             e->type = type;
181     }
185 =item C<STRING *get_string()>
187 Retrieves the C<type> attribute of this event handler.
189 =cut
193     VTABLE STRING *get_string() {
194         Parrot_EventHandler *e = PMC_data_typed(SELF, Parrot_EventHandler *);
196         if (e)
197             return string_copy(INTERP, e->type);
199         return CONST_STRING(INTERP, "");
200     }
204 =item C<void set_integer_native(INTVAL priority)>
206 Sets the minimum interesting priority for this event handler.
208 =cut
211     VTABLE void set_integer_native(INTVAL priority) {
212         Parrot_EventHandler *e = PMC_data_typed(SELF, Parrot_EventHandler *);
214         if (e)
215             e->priority = priority;
216     }
220 =item C<void set_pmc(PMC *interpreter)>
222 Sets the passed-in C<ParrotInterpreter> as the active interpreter in which to
223 handle the registered events.
225 =cut
228     VTABLE void set_pmc(PMC *interpreter) {
229         Parrot_EventHandler *e = PMC_data_typed(SELF, Parrot_EventHandler *);
231         if (e)
232             e->interp = interpreter;
233     }
237 =item C<PMC *get_attr_str(STRING *name)>
239 =cut
243     VTABLE PMC *get_attr_str(STRING *name) {
244         Parrot_EventHandler *core_struct  = PMC_data_typed(SELF, Parrot_EventHandler *);
245         PMC *value = PMCNULL;
247         if (string_equal(interp, name, CONST_STRING(interp, "code")) == 0) {
248             value = core_struct->code;
249         }
251         return value;
252     }
256 =item C<opcode_t *invoke(void *next)>
258 Runs the contained code, if any; this is what handles the event.
260 =cut
263     VTABLE opcode_t *invoke(void *next) {
264         Parrot_EventHandler *e = PMC_data_typed(SELF, Parrot_EventHandler *);
265         void                *unused;
267         /* can't invoke on INTERP and can't return its result; this may not be
268          * the right interpreter */
269         if (e) {
270             unused = VTABLE_invoke(PMC_data_typed(e->interp, Parrot_Interp),
271                     e->code, next);
272             UNUSED(unused);
273         }
275         return (opcode_t *)next;
276     }
280 =back
282 =head2 Methods
284 =over 4
286 =cut
292 =item C<METHOD can_handle(PMC *event)>
294 Report whether the event handler can handle a particular type of event.
296 =cut
300     METHOD can_handle(PMC *event) {
301         Parrot_EventHandler *handler_struct = PMC_data_typed(SELF, Parrot_EventHandler *);
302         if (event->vtable->base_type == enum_class_Task) {
303             PMC *type = VTABLE_get_attr_str(interp, event, CONST_STRING(interp, "type"));
304             STRING *type_str = VTABLE_get_string(interp, type);
306             if (string_equal(interp, type_str, CONST_STRING(interp, "event")) == 0) {
307                 PMC *subtype = VTABLE_get_attr_str(interp, event, CONST_STRING(interp, "subtype"));
308                 STRING *subtype_str = VTABLE_get_string(interp, subtype);
310                 if (string_equal(interp, subtype_str, handler_struct->type) == 0) {
311                     RETURN(INTVAL 1);
312                 }
313             }
314         }
316         RETURN(INTVAL 0);
317     }
323 =back
325 =cut
330  * Local variables:
331  *   c-file-style: "parrot"
332  * End:
333  * vim: expandtab shiftwidth=4:
334  */