int prTempoClock_Sched(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;
	double delta, beats;
	int err;

	TempoClock *clock = (TempoClock*)slotRawPtr(&slotRawObject(a)->slots[1]);
	if (!clock) {
		error("clock is not running.\n");
		return errFailed;
	}

	if (!SlotEq(&g->thread->clock, a)) {
		beats = clock->ElapsedBeats();
		//post("shouldn't call TempoClock-sched from a different clock. Use schedAbs.\n");
		//return errFailed;
	} else {
		err = slotDoubleVal(&g->thread->beats, &beats);
		if (err) return errNone; // return nil OK, just don't schedule
	}

	err = slotDoubleVal(b, &delta);
	if (err) return errNone; // return nil OK, just don't schedule
	beats += delta;
	if (beats == dInfinity)
		return errNone; // return nil OK, just don't schedule

	clock->Add(beats, c);

	return errNone;
}
Exemple #2
0
bool identDict_lookupNonNil(PyrObject *dict, PyrSlot *key, int hash, PyrSlot *result)
{
again:
	PyrSlot *dictslots = dict->slots;
	PyrSlot *arraySlot = dictslots + ivxIdentDict_array;

	if (isKindOfSlot(arraySlot, class_array)) {
		PyrObject *array = slotRawObject(arraySlot);

		int index = arrayAtIdentityHashInPairsWithHash(array, key, hash);
		if (SlotEq(key, array->slots + index)) {
			slotCopy(result,&array->slots[index + 1]);
			return true;
		}
	}

	PyrClass *identDictClass = s_identitydictionary->u.classobj;
	PyrSlot *parentSlot = dictslots + ivxIdentDict_parent;
	PyrSlot * protoSlot = dictslots + ivxIdentDict_proto;
	if (isKindOfSlot(parentSlot, identDictClass)) {
		if (isKindOfSlot(protoSlot, identDictClass)) {
			// recursive call.
			if (identDict_lookupNonNil(slotRawObject(protoSlot), key, hash, result)) return true;
		}

		dict = slotRawObject(parentSlot);
		goto again; // tail call
	} else {
		if (isKindOfSlot(protoSlot, identDictClass)) {
			dict = slotRawObject(protoSlot);
			goto again; // tail call
		}
	}
	return false;
}
Exemple #3
0
int arrayAtIdentityHashInPairsWithHash(PyrObject *array, PyrSlot *key, int hash)
{
	PyrSlot *slots, *test;
	unsigned int i, start, end, maxHash;

	maxHash = array->size >> 1;
	start = (hash % maxHash) << 1;
	end = array->size;
	slots = array->slots;
	for (i=start; i<end; i+=2) {
		test = slots + i;
		if (IsNil(test) || SlotEq(test, key))
			return i;
	}
	end = start - 2;
	for (i=0; i<=end; i+=2) {
		test = slots + i;
		if (IsNil(test) || SlotEq(test, key))
			return i;
	}
	return -2;
}
Exemple #4
0
int arrayAtIdentityHash(PyrObject *array, PyrSlot *key)
{
	PyrSlot *slots, *test;
	unsigned int i, start, end, hash, maxHash;

	hash = calcHash(key);
	maxHash = array->size;
	start = hash % maxHash;
	end = array->size;
	slots = array->slots;
	for (i=start; i<end; i++) {
		test = slots + i;
		if (IsNil(test) || SlotEq(test, key))
			return i;
	}
	end = start - 1;
	for (i=0; i<=end; i++) {
		test = slots + i;
		if (IsNil(test) ||  SlotEq(test, key))
			return i;
	}
	return -1;
}
int prTempoClock_Beats(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp;
	double beats, seconds;

	if (SlotEq(&g->thread->clock, a)) {
		int err = slotDoubleVal(&g->thread->beats, &beats);
		if (err) return errWrongType;
	} else {
		TempoClock *clock = (TempoClock*)slotRawPtr(&slotRawObject(a)->slots[1]);
		if (!clock) {
			error("clock is not running.\n");
			return errFailed;
		}

		int err = slotDoubleVal(&g->thread->seconds, &seconds);
		if (err) return errWrongType;

		beats = clock->SecsToBeats(seconds);
	}
	SetFloat(a, beats);
	return errNone;
}