/
Genesis-1.0p36-DEV/
Genesis-1.0p36-DEV/bin/
Genesis-1.0p36-DEV/doc/
Genesis-1.0p36-DEV/etc/
Genesis-1.0p36-DEV/src/data/
/*
// Full copyright information is available in the file ../doc/CREDITS
*/

#include "defs.h"

#include "lookup.h"
#include "execute.h"
#include "grammar.h"
#include "opcodes.h"

/* ----------------------------------------------------------------- */
/* cancel a suspended task                                           */
COLDC_FUNC(task_info) {
    cList * list;
    cData *args;
 
    if (!func_init_1(&args, INTEGER))
        return;

    list = task_info(INT1);

    if (!list)
        THROW((type_id, "No task %d.", INT1))
    pop(1);
    push_list(list);
    list_discard(list);
}

/* ----------------------------------------------------------------- */
/* cancel a suspended task                                           */
COLDC_FUNC(cancel) {
    cData *args;
 
    if (!func_init_1(&args, INTEGER))
        return;


    if (!task_lookup(args[0].u.val)) {
        cthrow(type_id, "No task %d.", args[0].u.val);
    } else {
        task_cancel(args[0].u.val);
        pop(1);
        push_int(1);
    }
}

/* ----------------------------------------------------------------- */
/* suspend a task                                                    */
void func_suspend(void) {

    if (!func_init_0())
        return;

    if (atomic) {
        cthrow(atomic_id, "Attempt to suspend while executing atomically.");
        return;
    }

    task_suspend();

    /* we'll let task_resume push something onto the stack for us */
}

/* ----------------------------------------------------------------- */
void func_resume(void) {
    cData *args;
    Int nargs;
    Long tid;

    if (!func_init_1_or_2(&args, &nargs, INTEGER, 0))
        return;

    tid = args[0].u.val;

    if (!task_lookup(tid)) {
        cthrow(type_id, "No task %d.", args[0].u.val);
    } else {
        if (nargs == 1)
            task_resume(tid, NULL);
        else
            task_resume(tid, &args[1]);
        pop(nargs);
        push_int(1);
    }
}

/* ----------------------------------------------------------------- */
void func_pause(void) {
    if (!func_init_0())
        return;

    push_int(1);

    if (atomic) {
        if (cur_frame->ticks <= REFRESH_METHOD_THRESHOLD)
            cur_frame->ticks = PAUSED_METHOD_TICKS;
    } else {
        task_pause();
    }
}

/* ----------------------------------------------------------------- */
void func_atomic(void) {
    cData * args;

    if (!func_init_1(&args, INTEGER))
        return;

    if (!coldcc)
        atomic = (Bool) (args[0].u.val ? YES : NO);

    pop(1);
    push_int(atomic ? 1 : 0);
}

/* ----------------------------------------------------------------- */
void func_refresh(void) {

    if (!func_init_0())
        return;

    push_int(1);

    if (cur_frame->ticks <= REFRESH_METHOD_THRESHOLD) {
        if (atomic) {
            cur_frame->ticks = PAUSED_METHOD_TICKS;
        } else {
            task_pause();
        }
    }
}

/* ----------------------------------------------------------------- */
void func_tasks(void) {
    cList * list;

    if (!func_init_0())
        return;

    list = task_list();

    push_list(list);
    list_discard(list);
}

/* ----------------------------------------------------------------- */
void func_tick(void) {
    if (!func_init_0())
        return;
    push_int(tick);
}

/* ----------------------------------------------------------------- */
void func_stack(void) {
    cList * list;

    if (!func_init_0())
        return;

    list = task_stack();

    push_list(list);
    list_discard(list);
}

void func_method(void) {
    if (!func_init_0())
        return;

    push_symbol(cur_frame->method->name);
}

void func_this(void) {
    /* Accept no arguments, and push the objnum of the current object. */
    if (!func_init_0())
        return;
    push_objnum(cur_frame->object->objnum);
}

void func_definer(void) {
    /* Accept no arguments, and push the objnum of the method definer. */
    if (!func_init_0())
        return;
    push_objnum(cur_frame->method->object->objnum);
}

void func_sender(void) {
    /* Accept no arguments, and push the objnum of the sending object. */
    if (!func_init_0())
        return;
    if (cur_frame->sender == NOT_AN_IDENT)
        push_int(0);
    else
        push_objnum(cur_frame->sender);
}

void func_caller(void) {
    /* Accept no arguments, and push the objnum of the calling method's
     * definer. */
    if (!func_init_0())
        return;
    if (cur_frame->caller == NOT_AN_IDENT)
        push_int(0);
    else
        push_objnum(cur_frame->caller);
}

void func_task_id(void) {
    /* Accept no arguments, and push the task ID. */
    if (!func_init_0())
        return;
    push_int(task_id);
}

void func_ticks_left(void) {
    if (!func_init_0())
      return;

    push_int(cur_frame->ticks);
}

COLDC_FUNC(user) {
    if (!func_init_0())
        return;
    if (cur_frame->user == NOT_AN_IDENT)
        push_int(0);
    else
        push_objnum(cur_frame->user);
}

COLDC_FUNC(set_user) {
    if (!func_init_0())
        return;
    cur_frame->user = cur_frame->object->objnum;
    push_objnum(cur_frame->user);
}