The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
/*
Copyright (C) 2001-2012, Parrot Foundation.

=head1 NAME

src/pmc/alarm.pmc - Alarm

=head1 SYNOPSIS

    .include 'alarm.pasm'

    new P0, 'Alarm'
    set P0[.PARROT_ALARM_TIME], N_time   # A FLOATVAL
    set P0[.PARROT_ALARM_SUB],  P_sub    # set handler sub PMC
    invoke P0                            # schedule the alarm

=head1 DESCRIPTION

Sometime after N_time, P_sub will be called exactly once.

=head2 Functions

=over 4

=cut

*/

#include "parrot/scheduler_private.h"

/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */

pmclass Alarm provides invokable auto_attrs {
    ATTR FLOATVAL alarm_time;
    ATTR PMC     *alarm_task;

/*

=item C<void init()>

Initializes the alarm.

=cut

*/

    VTABLE void init() {
        Parrot_Alarm_attributes * const data = PARROT_ALARM(SELF);
        UNUSED(INTERP);

        data->alarm_time = 0.0;
        data->alarm_task = PMCNULL;

        PObj_custom_mark_SET(SELF);
    }

/*

=item C<PMC *clone()>

Create a copy of the alarm.

=cut

*/

    VTABLE PMC *clone() {
        PMC * const copy = Parrot_pmc_new(INTERP, SELF->vtable->base_type);

        Parrot_Alarm_attributes * const new_struct = PARROT_ALARM(copy);
        const Parrot_Alarm_attributes * const old_struct = PARROT_ALARM(SELF);

        new_struct->alarm_time = old_struct->alarm_time;
        new_struct->alarm_task  = old_struct->alarm_task;

        return copy;
    }

/*

=item C<PMC *get_pmc_keyed_int(INTVAL key)>

Returns the PMC associated with C<key>.

=cut

*/

    VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
        UNUSED(INTERP);
        if (key == PARROT_ALARM_TASK) {
            const Parrot_Alarm_attributes * const data = PARROT_ALARM(SELF);
            return data->alarm_task;
        }

        return PMCNULL;
    }

/*

=item C<FLOATVAL get_number_keyed_int(INTVAL key)>

Returns the number associated with C<key>.

=cut

*/

    VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
        UNUSED(INTERP);
        if (key == PARROT_ALARM_TIME) {
            const Parrot_Alarm_attributes * const data = PARROT_ALARM(SELF);
            return data->alarm_time;
        }

        return 0.0;
    }

/*

=item C<FLOATVAL get_number()>

Having the alarm numify to the time is convienient for sorting.

=cut

*/

    VTABLE FLOATVAL get_number() {
        const Parrot_Alarm_attributes * const data = PARROT_ALARM(SELF);
        UNUSED(INTERP);
        return data->alarm_time;
    }

/*

=item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>

Sets the PMC associated with C<key> to C<*value>.

=cut

*/

    VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
        if (key == PARROT_ALARM_TASK) {
            SET_ATTR_alarm_task(INTERP, SELF, value);
        }
    }

/*

=item C<opcode_t *invoke(void *next)>

Schedules the alarm and adds it to the alarm queue.

=cut

*/

    VTABLE opcode_t *invoke(void *next) {
        Parrot_cx_schedule_alarm(INTERP, SELF);
        return (opcode_t *)next;
    }

/*

=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>

Sets the floating-point value associated with C<key> to C<value>.

=cut

*/

    VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
        if (key == PARROT_ALARM_TIME) {
            SET_ATTR_alarm_time(INTERP, SELF, value);
        }
    }

/*

Required functions for GC and Freeze / Thaw.

*/

    VTABLE void mark() {
        PMC *sub;
        GET_ATTR_alarm_task(INTERP, SELF, sub);
        Parrot_gc_mark_PMC_alive(INTERP, sub);
    }

    VTABLE void visit(PMC *info) {
        PMC *sub;
        GET_ATTR_alarm_task(INTERP, SELF, sub);
        VISIT_PMC(INTERP, info, sub);
        SUPER(info);
    }

    VTABLE void freeze(PMC *info) {
        SUPER(info);
        VTABLE_push_integer(INTERP, info, VTABLE_elements(INTERP, SELF));
    }

    VTABLE void thaw(PMC *info) {
        SUPER(info);
        SELF.set_integer_native(VTABLE_shift_integer(INTERP, info));
    }
}





/*

=back

=cut

*/

/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
 */