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; }
int prFile_PutFile(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; PyrSlot *c = g->sp; NavDialogOptions options; int err = NavGetDefaultDialogOptions(&options); if (err) return errFailed; options.dialogOptionFlags |= kNavNoTypePopup; options.dialogOptionFlags |= kNavDontAutoTranslate; options.dialogOptionFlags |= kNavDontAddTranslateItems; options.dialogOptionFlags |= kNavSelectDefaultLocation; options.dialogOptionFlags &= ~kNavAllowPreviews; options.dialogOptionFlags &= ~kNavAllowMultipleFiles; if (isKindOfSlot(b, class_string)) { pstringFromPyrString((PyrString*)slotRawObject(b), options.message, 256); } if (isKindOfSlot(c, class_string)) { pstringFromPyrString((PyrString*)slotRawObject(c), options.savedFileName, 256); } else { //pstrncpy(options.savedFileName, "\pUntitled", 255); } NavReplyRecord reply; err = NavPutFile(0, &reply, &options, 0, 'TEXT', 'SCjm', 0); if (err == noErr && reply.validRecord) { AEKeyword keyword; DescType actualType; Size actualSize; FSSpec fsspec; err = AEGetNthPtr(&reply.selection, 1, typeFSS, &keyword, &actualType, &fsspec, sizeof(FSSpec), &actualSize); if (err == noErr) { Str255 pathname; GetFullPathname(&fsspec, pathname); p2cstr(pathname); PyrString *string = newPyrString(g->gc, (char*)pathname, 0, true); SetObject(a, string); err = NavCompleteSave(&reply, kNavTranslateInPlace); } else { SetNil(a); } err = NavDisposeReply(&reply); } else { SetNil(a); } return errNone; }
int prEvent_IsRest(struct VMGlobals *g, int numArgsPushed) { PyrSlot *dictslots = slotRawObject(g->sp)->slots; PyrSlot *arraySlot = dictslots + ivxIdentDict_array; if (isKindOfSlot(arraySlot, class_array)) { PyrSlot key, typeSlot; static PyrSymbol *s_type = getsym("type"); static PyrSymbol *s_rest = getsym("rest"); PyrSymbol *typeSym; // test 'this[\type] == \rest' first SetSymbol(&key, s_type); identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot); if(!slotSymbolVal(&typeSlot, &typeSym) && typeSym == s_rest) { SetBool(g->sp, 1); return errNone; } else { PyrObject *array = slotRawObject(arraySlot); PyrSymbol *slotSym; static PyrSymbol *s_empty = getsym(""); static PyrSymbol *s_r = getsym("r"); static PyrClass *class_rest = getsym("Rest")->u.classobj; static PyrClass *class_metarest = getsym("Meta_Rest")->u.classobj; PyrSlot *slot; int32 size = array->size; int32 i; slot = array->slots + 1; // scan only the odd items for (i = 1; i < size; i += 2, slot += 2) { if (isKindOfSlot(slot, class_rest) || isKindOfSlot(slot, class_metarest) ) { SetBool(g->sp, 1); return errNone; } else if(!slotSymbolVal(slot, &slotSym)) { if(slotSym == s_empty || slotSym == s_r || slotSym == s_rest ) { SetBool(g->sp, 1); return errNone; } } // why no 'else'? // slotSymbolVal nonzero return = not a symbol; // non-symbols don't indicate rests, so, ignore them. } } } else { return errWrongType; } SetBool(g->sp, 0); return errNone; }
int prSendSysex(VMGlobals *g, int numArgsPushed) { int err, uid, size; if( !isKindOfSlot(g->sp, s_int8array->u.classobj) ) return errWrongType; PyrInt8Array* packet = slotRawInt8Array(g->sp); size = packet->size; PyrSlot *u = g->sp - 1; err = slotIntVal(u, &uid); if (err) return err; MIDIEndpointRef dest; MIDIObjectType mtype; MIDIObjectFindByUniqueID(uid, (MIDIObjectRef*)&dest, &mtype); if (mtype != kMIDIObjectType_Destination) return errFailed; if (!dest) return errFailed; MIDISysexSendRequest *pk = (MIDISysexSendRequest*) malloc (sizeof(MIDISysexSendRequest) + size); Byte *data = (Byte *)pk + sizeof(MIDISysexSendRequest); memcpy(data,packet->b, size); pk->complete = false; pk -> destination = dest; pk -> data = data; pk -> bytesToSend = size; pk->completionProc = freeSysex; pk->completionRefCon = 0; return ((MIDISendSysex(pk) == (OSStatus)0) ? errNone : errFailed); }
int prReadArchive(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp - 1; PyrSlot *b = g->sp; if (!isKindOfSlot(b, class_string)) return errWrongType; char pathname[PATH_MAX]; memcpy(pathname, b->uos->s, b->uo->size); pathname[b->uos->size] = 0; PyrArchiver<FILE*> arch(g); FILE *file = fopen(pathname, "rb"); int err; if (file) { arch.setStream(file); err = arch.readArchive(a); fclose(file); } else { error("file open failed\n"); err = errFailed; } return err; }
int prLID_GetAbsInfo(VMGlobals *g, int numArgsPushed) { PyrSlot* args = g->sp - 2; int evtCode; int err; PyrObject* obj = SC_LID::getObject(args+0); if (!obj) return errWrongType; err = slotIntVal(args+1, &evtCode); if (err) return err; if (!isKindOfSlot(args+2, s_absInfoClass->u.classobj)) return errWrongType; PyrObject* infoObj = slotRawObject(&args[2]); SC_LID* dev = SC_LID::getDevice(obj); if (!dev) return errFailed; struct input_absinfo info; err = dev->getAbsInfo(evtCode, &info); if (err) return err; SetInt(infoObj->slots+0, info.value); SetInt(infoObj->slots+1, info.minimum); SetInt(infoObj->slots+2, info.maximum); SetInt(infoObj->slots+3, info.fuzz); SetInt(infoObj->slots+4, info.flat); slotCopy(&args[0], &args[2]); return errNone; }
int prSFWrite(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, *b; a = g->sp - 1; b = g->sp; SNDFILE *file = (SNDFILE*)slotRawPtr(&slotRawObject(a)->slots[0]); if (!isKindOfSlot(b, class_rawarray)) return errWrongType; switch (slotRawObject(b)->obj_format) { case obj_int16 : sf_write_short(file, (short*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_int32 : sf_write_int(file, (int*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_float : sf_write_float(file, (float*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_double : sf_write_double(file, (double*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; default: error("sample format not supported.\n"); return errFailed; } return errNone; }
int makeSynthBundle(big_scpacket *packet, PyrSlot *slots, int size, bool useElapsed) { double time; int err; int64 oscTime; err = slotDoubleVal(slots, &time); if (!err) { if (useElapsed) { oscTime = ElapsedTimeToOSC(time); } else { oscTime = (int64)(time * kSecondsToOSC); } } else { oscTime = 1; // immediate } packet->OpenBundle(oscTime); for (int i=1; i<size; ++i) { if (isKindOfSlot(slots+i, class_array)) { PyrObject *obj = slots[i].uo; makeSynthMsgWithTags(packet, obj->slots, obj->size); } } packet->CloseBundle(); return errNone; }
int prArray_OSCBytes(VMGlobals *g, int numArgsPushed) { PyrSlot* a = g->sp; PyrObject *array = a->uo; PyrSlot* args = array->slots; int numargs = array->size; if (numargs < 1) return errFailed; big_scpacket packet; if (IsFloat(args) || IsNil(args) || IsInt(args)) { makeSynthBundle(&packet, args, numargs, false); } else if (IsSym(args) || isKindOfSlot(args, class_string)) { makeSynthMsgWithTags(&packet, args, numargs); } else { return errWrongType; } int size = packet.size(); PyrInt8Array* obj = newPyrInt8Array(g->gc, size, 0, true); obj->size = size; memcpy(obj->b, packet.data(), size); SetObject(a, (PyrObject*)obj); //for (int i=0; i<packet.size()/4; i++) post("%d %08X\n", i, packet.buf[i]); return errNone; }
/// Returns whether the slot is considered a rest for \c Event.isRest. static bool slotIsRestlike(PyrSlot* slot) { PyrSymbol * slotSym; if (isKindOfSlot(slot, class_rest) || isKindOfSlot(slot, class_metarest)) { return true; } else if(!slotSymbolVal(slot, &slotSym)) { return slotSym == s_empty || slotSym == s_r || slotSym == s_rest; } // why no 'else'? // slotSymbolVal nonzero return = not a symbol; // non-symbols don't indicate rests, so, ignore them. return false; }
int prUnarchive(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp; if (!isKindOfSlot(a, class_int8array)) return errWrongType; PyrArchiver<char*> arch(g); arch.setStream((char*)a->uo->slots); int err = arch.readArchive(a); return err; }
void TempoClock::Add(double inBeats, PyrSlot* inTask) { double prevBeats = mQueue->size > 1 ? slotRawFloat(mQueue->slots) : -1e10; bool added = addheap(g, (PyrObject*)mQueue, inBeats, inTask); if (!added) post("scheduler queue is full.\n"); else { if (isKindOfSlot(inTask, class_thread)) { SetFloat(&slotRawThread(inTask)->nextBeat, inBeats); } if (slotRawFloat(mQueue->slots) != prevBeats) { pthread_cond_signal (&mCondition); } } }
bool QObjectProxy::invokeMethod( const char *method, PyrSlot *arg ) { qscDebugMsg("invoking method '%s'\n", method ); Slot argSlots[10]; if ( isKindOfSlot( arg, class_array ) ) { PyrSlot *slots = slotRawObject( arg )->slots; int size = slotRawObject( arg )->size; int i; for( i = 0; i<size && i<10; ++i ) { argSlots[i].setData( slots ); ++slots; } } else argSlots[0].setData( arg ); bool success = QMetaObject::invokeMethod( qObject, method, Qt::QueuedConnection, argSlots[0].asGenericArgument(), argSlots[1].asGenericArgument(), argSlots[2].asGenericArgument(), argSlots[3].asGenericArgument(), argSlots[4].asGenericArgument(), argSlots[5].asGenericArgument(), argSlots[6].asGenericArgument(), argSlots[7].asGenericArgument(), argSlots[8].asGenericArgument(), argSlots[9].asGenericArgument()); if( !success ) { success = QMetaObject::invokeMethod( this, method, Qt::QueuedConnection, argSlots[0].asGenericArgument(), argSlots[1].asGenericArgument(), argSlots[2].asGenericArgument(), argSlots[3].asGenericArgument(), argSlots[4].asGenericArgument(), argSlots[5].asGenericArgument(), argSlots[6].asGenericArgument(), argSlots[7].asGenericArgument(), argSlots[8].asGenericArgument(), argSlots[9].asGenericArgument()); } return success; }
int prFileGetcwd(struct VMGlobals *g, int numArgsPushed) { //PyrSlot* a = g->sp - 1; // File PyrSlot* string = g->sp; if (!isKindOfSlot(string, class_string)) return errWrongType; char * cwd = getcwd(slotRawString(string)->s,255); if (cwd == NULL) { error(strerror(errno)); return errFailed; } slotRawString(string)->size = (int)strlen(slotRawString(string)->s); return errNone; }
void schedAdd(VMGlobals *g, PyrObject* inQueue, double inSeconds, PyrSlot* inTask) { // gLangMutex must be locked double prevTime = inQueue->size > 1 ? slotRawFloat(inQueue->slots + 1) : -1e10; bool added = addheap(g, inQueue, inSeconds, inTask); if (!added) post("scheduler queue is full.\n"); else { if (isKindOfSlot(inTask, class_thread)) { SetFloat(&slotRawThread(inTask)->nextBeat, inSeconds); } if (slotRawFloat(inQueue->slots + 1) != prevTime) { //post("pthread_cond_signal\n"); pthread_cond_signal (&gSchedCond); } } }
int prSFOpenRead(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, *b; char filename[PATH_MAX]; SNDFILE *file; SF_INFO info; const char *headerstr; const char *sampleformatstr; a = g->sp - 1; b = g->sp; PyrObject *obj1 = slotRawObject(a); if (!isKindOfSlot(b, class_string)) return errWrongType; if (slotRawObject(b)->size > PATH_MAX - 1) return errFailed; memcpy(filename, slotRawString(b)->s, slotRawObject(b)->size); filename[slotRawString(b)->size] = 0; info.format = 0; file = sf_open(filename, SFM_READ, &info); if (file) { SetPtr(obj1->slots + 0, file); sndfileFormatInfoToStrings(&info, &headerstr, &sampleformatstr); //headerFormatToString(&info, &headerstr); PyrString *hpstr = newPyrString(g->gc, headerstr, 0, true); SetObject(obj1->slots+1, hpstr); g->gc->GCWriteNew(obj1, (PyrObjectHdr*)hpstr); // we know hpstr is white so we can use GCWriteNew PyrString *smpstr = newPyrString(g->gc, sampleformatstr, 0, true); SetObject(obj1->slots+2, smpstr); g->gc->GCWriteNew(obj1, (PyrObjectHdr*)smpstr); // we know smpstr is white so we can use GCWriteNew SetInt(obj1->slots + 3, info.frames); SetInt(obj1->slots + 4, info.channels); SetInt(obj1->slots + 5, info.samplerate); SetTrue(a); } else { SetNil(a); SetFalse(a); } return errNone; }
static int addMsgSlot(big_scpacket *packet, PyrSlot *slot) { switch (GetTag(slot)) { case tagInt : packet->addi(slotRawInt(slot)); break; case tagSym : packet->adds(slotRawSymbol(slot)->name); break; case tagObj : if (isKindOf(slotRawObject(slot), class_string)) { PyrString *stringObj = slotRawString(slot); packet->adds(stringObj->s, stringObj->size); } else if (isKindOf(slotRawObject(slot), class_int8array)) { PyrInt8Array *arrayObj = slotRawInt8Array(slot); packet->addb(arrayObj->b, arrayObj->size); } else if (isKindOf(slotRawObject(slot), class_array)) { PyrObject *arrayObj = slotRawObject(slot); big_scpacket packet2; if (arrayObj->size > 1 && isKindOfSlot(arrayObj->slots+1, class_array)) { makeSynthBundle(&packet2, arrayObj->slots, arrayObj->size, true); } else { int error = makeSynthMsgWithTags(&packet2, arrayObj->slots, arrayObj->size); if (error != errNone) return error; } packet->addb((uint8*)packet2.data(), packet2.size()); } break; case tagNil : case tagTrue : case tagFalse : case tagChar : case tagPtr : break; default : if (gUseDoubles) packet->addd(slotRawFloat(slot)); else packet->addf(slotRawFloat(slot)); break; } return errNone; }
int prString_POpen(struct VMGlobals *g, int numArgsPushed) { struct sc_process *process; PyrSlot *a = g->sp - 1; PyrSlot *b = g->sp; int err; if (!isKindOfSlot(a, class_string)) return errWrongType; char *cmdline = (char*)malloc(a->uo->size + 1); err = slotStrVal(a, cmdline, a->uo->size + 1); if(err) { free(cmdline); return errFailed; } #ifdef SC_IPHONE SetInt(a, 0); return errNone; #endif process = (struct sc_process *)malloc(sizeof(struct sc_process)); process->stream = sc_popen(cmdline, &process->pid, "r"); setvbuf(process->stream, 0, _IONBF, 0); process->postOutput = IsTrue(b); free(cmdline); if(process->stream == NULL) { free(process); return errFailed; } pthread_t thread; pthread_create(&thread, NULL, string_popen_thread_func, (void*)process); pthread_detach(thread); SetInt(a, process->pid); return errNone; }
void addMsgSlot(big_scpacket *packet, PyrSlot *slot) { switch (slot->utag) { case tagInt : packet->addi(slot->ui); break; case tagSym : packet->adds(slot->us->name); break; case tagObj : if (isKindOf(slot->uo, class_string)) { PyrString *stringObj = slot->uos; packet->adds(stringObj->s, stringObj->size); } else if (isKindOf(slot->uo, class_int8array)) { PyrInt8Array *arrayObj = slot->uob; packet->addb(arrayObj->b, arrayObj->size); } else if (isKindOf(slot->uo, class_array)) { PyrObject *arrayObj = slot->uo; big_scpacket packet2; if (arrayObj->size > 1 && isKindOfSlot(arrayObj->slots+1, class_array)) { makeSynthBundle(&packet2, arrayObj->slots, arrayObj->size, true); } else { makeSynthMsgWithTags(&packet2, arrayObj->slots, arrayObj->size); } packet->addb((uint8*)packet2.data(), packet2.size()); } break; case tagNil : case tagTrue : case tagFalse : case tagChar : case tagPtr : break; default : if (gUseDoubles) packet->addd(slot->uf); else packet->addf(slot->uf); break; } }
int prLID_GetInfo(VMGlobals* g, int numArgsPushed) { PyrSlot* args = g->sp - 1; int err; PyrObject* obj = SC_LID::getObject(args+0); if (!obj) return errWrongType; if (!isKindOfSlot(args+1, s_inputDeviceInfoClass->u.classobj)) return errWrongType; PyrObject* infoObj = slotRawObject(&args[1]); SC_LID* dev = SC_LID::getDevice(obj); if (!dev) return errFailed; char name[128]; err = dev->getName(name, sizeof(name)); if (err) return err; struct input_id info; char namePhys[128]; char nameUniq[128]; err = dev->getInfo(&info, namePhys, sizeof( namePhys ), nameUniq, sizeof( nameUniq ) ); if (err) return err; SetSymbol(infoObj->slots+0, getsym(name)); SetInt(infoObj->slots+1, info.bustype); SetInt(infoObj->slots+2, info.vendor); SetInt(infoObj->slots+3, info.product); SetInt(infoObj->slots+4, info.version); SetSymbol(infoObj->slots+5, getsym(namePhys)); SetSymbol(infoObj->slots+6, getsym(nameUniq)); slotCopy(&args[0], &args[1]); return errNone; }
int prEvent_IsRest(struct VMGlobals *g, int numArgsPushed) { PyrSlot *dictslots = slotRawObject(g->sp)->slots; PyrSlot *arraySlot = dictslots + ivxIdentDict_array; static int isRestCount = 0; if (!isKindOfSlot(arraySlot, class_array)) { return errWrongType; } PyrSlot key, typeSlot; PyrSymbol *typeSym; // easy tests first: 'this[\type] == \rest' SetSymbol(&key, s_type); identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot); if(!slotSymbolVal(&typeSlot, &typeSym) && typeSym == s_rest) { SetBool(g->sp, 1); return errNone; } // and, 'this[\isRest] == true' SetSymbol(&key, s_isRest); identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot); if(IsTrue(&typeSlot)) { if (isRestCount == 0) post("\nWARNING: Setting isRest to true in an event is deprecated. See the Rest helpfile for supported ways to specify rests.\n\n"); isRestCount = (isRestCount + 1) % 100; SetBool(g->sp, 1); return errNone; } // failing those, scan slot values for something rest-like PyrObject *array = slotRawObject(arraySlot); SetBool(g->sp, dictHasRestlikeValue(array) ? 1 : 0); return errNone; }
static PyrObject* getObject(PyrSlot* slot) { return isKindOfSlot(slot, s_inputDeviceClass->u.classobj) ? slotRawObject(slot) : 0; }
int prSFOpenWrite(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, *b; char filename[PATH_MAX]; SNDFILE *file; SF_INFO info; PyrSlot *headerSlot; PyrSlot *formatSlot; int error; a = g->sp - 1; b = g->sp; headerSlot = (slotRawObject(a)->slots + 1); formatSlot = (slotRawObject(a)->slots + 2); if (!isKindOfSlot(headerSlot, class_string)) return errWrongType; if (!isKindOfSlot(formatSlot, class_string)) return errWrongType; if (!isKindOfSlot(b, class_string)) return errWrongType; if (slotRawObject(b)->size > PATH_MAX - 1) return errFailed; memcpy(filename, slotRawString(b)->s, slotRawObject(b)->size); filename[slotRawString(b)->size] = 0; #ifdef SC_WIN32 char* headerFormat = (char *)malloc(slotRawObject(headerSlot)->size); #else char headerFormat[slotRawString(headerSlot)->size]; #endif memcpy(headerFormat, slotRawString(headerSlot)->s, slotRawObject(headerSlot)->size); headerFormat[slotRawString(headerSlot)->size] = 0; #ifdef SC_WIN32 char* sampleFormat = (char *)malloc(slotRawString(formatSlot)->size); #else char sampleFormat[slotRawString(formatSlot)->size]; #endif memcpy(sampleFormat, slotRawString(formatSlot)->s, slotRawObject(formatSlot)->size); sampleFormat[slotRawString(formatSlot)->size] = 0; error = sndfileFormatInfoFromStrings(&info, headerFormat, sampleFormat); if(error) { #ifdef SC_WIN32 free(sampleFormat); free(headerFormat); #endif return errFailed; } if(error) return errFailed; //slotIntVal(slotRawObject(a)->slots + 3, &info.frames); slotIntVal(slotRawObject(a)->slots + 4, &info.channels); slotIntVal(slotRawObject(a)->slots + 5, &info.samplerate); file = sf_open(filename, SFM_WRITE, &info); sf_command(file, SFC_SET_CLIPPING, NULL, SF_TRUE); if (file) { SetPtr(slotRawObject(a)->slots+0, file); SetTrue(a); } else { SetNil(a); SetFalse(a); } return errNone; }
void* TempoClock::Run() { //printf("->TempoClock::Run\n"); pthread_mutex_lock (&gLangMutex); while (mRun) { assert(mQueue->size); //printf("tempo %g dur %g beats %g\n", mTempo, mBeatDur, mBeats); //printf("wait until there is something in scheduler\n"); // wait until there is something in scheduler while (mQueue->size == 1) { //printf("wait until there is something in scheduler\n"); pthread_cond_wait (&mCondition, &gLangMutex); //printf("mRun a %d\n", mRun); if (!mRun) goto leave; } //printf("wait until an event is ready\n"); // wait until an event is ready double elapsedBeats; do { elapsedBeats = ElapsedBeats(); if (elapsedBeats >= slotRawFloat(mQueue->slots)) break; struct timespec abstime; //doubleToTimespec(mQueue->slots->uf, &abstime); //printf("event ready at %g . elapsed beats %g\n", mQueue->slots->uf, elapsedBeats); double wakeTime = BeatsToSecs(slotRawFloat(mQueue->slots)); ElapsedTimeToTimespec(wakeTime, &abstime); //printf("wait until an event is ready. wake %g now %g\n", wakeTime, elapsedTime()); pthread_cond_timedwait (&mCondition, &gLangMutex, &abstime); //printf("mRun b %d\n", mRun); if (!mRun) goto leave; //printf("time diff %g\n", elapsedTime() - mQueue->slots->uf); } while (mQueue->size > 1); //printf("perform all events that are ready %d %.9f\n", mQueue->size, elapsedBeats); // perform all events that are ready //printf("perform all events that are ready\n"); while (mQueue->size > 1 && elapsedBeats >= slotRawFloat(mQueue->slots)) { double delta; PyrSlot task; //printf("while %.6f >= %.6f\n", elapsedBeats, mQueue->slots->uf); getheap(g, (PyrObject*)mQueue, &mBeats, &task); if (isKindOfSlot(&task, class_thread)) { SetNil(&slotRawThread(&task)->nextBeat); } slotCopy((++g->sp), &task); SetFloat(++g->sp, mBeats); SetFloat(++g->sp, BeatsToSecs(mBeats)); ++g->sp; SetObject(g->sp, mTempoClockObj); runAwakeMessage(g); long err = slotDoubleVal(&g->result, &delta); if (!err) { // add delta time and reschedule double beats = mBeats + delta; Add(beats, &task); } } } leave: //printf("<-TempoClock::Run\n"); pthread_mutex_unlock (&gLangMutex); return 0; }
void* schedRunFunc(void* arg) { pthread_mutex_lock (&gLangMutex); VMGlobals *g = gMainVMGlobals; PyrObject* inQueue = slotRawObject(&g->process->sysSchedulerQueue); //dumpObject(inQueue); gRunSched = true; while (true) { assert(inQueue->size); //postfl("wait until there is something in scheduler\n"); // wait until there is something in scheduler while (inQueue->size == 1) { //postfl("wait until there is something in scheduler\n"); pthread_cond_wait (&gSchedCond, &gLangMutex); if (!gRunSched) goto leave; } //postfl("wait until an event is ready\n"); // wait until an event is ready double elapsed; do { elapsed = elapsedTime(); if (elapsed >= slotRawFloat(inQueue->slots + 1)) break; struct timespec abstime; //doubleToTimespec(inQueue->slots->uf, &abstime); ElapsedTimeToTimespec(slotRawFloat(inQueue->slots + 1), &abstime); //postfl("wait until an event is ready\n"); pthread_cond_timedwait (&gSchedCond, &gLangMutex, &abstime); if (!gRunSched) goto leave; //postfl("time diff %g\n", elapsedTime() - inQueue->slots->uf); } while (inQueue->size > 1); //postfl("perform all events that are ready %d %.9f\n", inQueue->size, elapsed); // perform all events that are ready //postfl("perform all events that are ready\n"); while ((inQueue->size > 1) && elapsed >= slotRawFloat(inQueue->slots + 1)) { double schedtime, delta; PyrSlot task; //postfl("while %.6f >= %.6f\n", elapsed, inQueue->slots->uf); getheap(g, inQueue, &schedtime, &task); if (isKindOfSlot(&task, class_thread)) { SetNil(&slotRawThread(&task)->nextBeat); } slotCopy((++g->sp), &task); SetFloat(++g->sp, schedtime); SetFloat(++g->sp, schedtime); ++g->sp; SetObject(g->sp, s_systemclock->u.classobj); runAwakeMessage(g); long err = slotDoubleVal(&g->result, &delta); if (!err) { // add delta time and reschedule double time = schedtime + delta; schedAdd(g, inQueue, time, &task); } } //postfl("loop\n"); } //postfl("exitloop\n"); leave: pthread_mutex_unlock (&gLangMutex); return 0; }
int prEvent_Delta(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, key, dur, stretch, delta; double fdur, fstretch; int err; PyrClass *restClass = getsym("Rest")->u.classobj; PyrSlot *slot; a = g->sp; // dict SetSymbol(&key, s_delta); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &delta); if (NotNil(&delta)) { if (isKindOfSlot(&delta, restClass)) { slot = slotRawObject(&delta)->slots; err = slotDoubleVal(slot, &fdur); } else { err = slotDoubleVal(&delta, &fdur); } if (err) { return err; } else { SetFloat(a, fdur); return errNone; } } else { SetSymbol(&key, s_dur); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &dur); err = slotDoubleVal(&dur, &fdur); if (err) { if (IsNil(&dur)) { SetNil(g->sp); return errNone; } else if (isKindOfSlot(&dur, restClass)) { slot = slotRawObject(&dur)->slots; err = slotDoubleVal(slot, &fdur); if (err) return err; } else { return errWrongType; } } SetSymbol(&key, s_stretch); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &stretch); err = slotDoubleVal(&stretch, &fstretch); if (err) { if (NotNil(&stretch)) { if (isKindOfSlot(&stretch, restClass)) { slot = slotRawObject(&stretch)->slots; err = slotDoubleVal(slot, &fstretch); if (err) return err; } else { return errWrongType; } } else { SetFloat(a, fdur); return errNone; } } SetFloat(a, fdur * fstretch); } return errNone; }
void doesNotUnderstand(VMGlobals *g, PyrSymbol *selector, long numArgsPushed) { PyrSlot *qslot, *pslot, *pend; long i, index; PyrSlot *uniqueMethodSlot, *arraySlot, *recvrSlot, *selSlot, *slot; PyrClass *classobj; PyrMethod *meth; PyrObject *array; #ifdef GC_SANITYCHECK g->gc->SanityCheck(); #endif // move args up by one to make room for selector qslot = g->sp + 1; pslot = g->sp + 2; pend = pslot - numArgsPushed + 1; while (pslot > pend) *--pslot = *--qslot; selSlot = g->sp - numArgsPushed + 2; SetSymbol(selSlot, selector); g->sp++; recvrSlot = selSlot - 1; classobj = classOfSlot(recvrSlot); index = slotRawInt(&classobj->classIndex) + s_nocomprendo->u.index; meth = gRowTable[index]; if (slotRawClass(&meth->ownerclass) == class_object) { // lookup instance specific method uniqueMethodSlot = &g->classvars->slots[cvxUniqueMethods]; if (isKindOfSlot(uniqueMethodSlot, class_identdict)) { arraySlot = slotRawObject(uniqueMethodSlot)->slots + ivxIdentDict_array; if ((IsObj(arraySlot) && (array = slotRawObject(arraySlot))->classptr == class_array)) { i = arrayAtIdentityHashInPairs(array, recvrSlot); if (i >= 0) { slot = array->slots + i; if (NotNil(slot)) { ++slot; if (isKindOfSlot(slot, class_identdict)) { arraySlot = slotRawObject(slot)->slots + ivxIdentDict_array; if ((IsObj(arraySlot) && (array = slotRawObject(arraySlot))->classptr == class_array)) { i = arrayAtIdentityHashInPairs(array, selSlot); if (i >= 0) { slot = array->slots + i; if (NotNil(slot)) { ++slot; slotCopy(selSlot, recvrSlot); slotCopy(recvrSlot, slot); blockValue(g, (int)numArgsPushed+1); return; } } } } } } } } } executeMethod(g, meth, numArgsPushed+1); #ifdef GC_SANITYCHECK g->gc->SanityCheck(); #endif }
int prFileReadRawLE(struct VMGlobals *g, int numArgsPushed) { PyrFile *pfile; FILE *file; PyrSlot* a = g->sp - 1; PyrSlot* b = g->sp; if (!isKindOfSlot(b, class_rawarray) || isKindOfSlot(b, class_symbolarray)) return errWrongType; pfile = (PyrFile*)slotRawObject(a); file = (FILE*)slotRawPtr(&pfile->fileptr); if (file == NULL) return errFailed; int elemSize = gFormatElemSize[slotRawObject(b)->obj_format]; int numElems = slotRawObject(b)->size; numElems = (int)fread(slotRawString(b)->s, elemSize, numElems, file); slotRawObject(b)->size = numElems; #if BYTE_ORDER == BIG_ENDIAN switch (elemSize) { case 1: break; case 2: { char *ptr = slotRawString(b)->s; char *ptrend = ptr + numElems*2; for (; ptr < ptrend; ptr+=2) { char temp = ptr[0]; ptr[0] = ptr[1]; ptr[1] = temp; } break; } case 4: { char *ptr = slotRawString(b)->s; char *ptrend = ptr + numElems*4; for (; ptr < ptrend; ptr+=4) { char temp = ptr[0]; ptr[0] = ptr[3]; ptr[3] = temp; temp = ptr[1]; ptr[1] = ptr[2]; ptr[2] = temp; } break; } case 8: { char *ptr = slotRawString(b)->s; char *ptrend = ptr + numElems*8; for (; ptr < ptrend; ptr+=8) { char temp = ptr[0]; ptr[0] = ptr[7]; ptr[7] = temp; temp = ptr[1]; ptr[1] = ptr[6]; ptr[6] = temp; temp = ptr[2]; ptr[2] = ptr[5]; ptr[5] = temp; temp = ptr[3]; ptr[3] = ptr[4]; ptr[4] = temp; } break; } } #endif if (slotRawObject(b)->size==0) SetNil(a); else slotCopy(a,b); return errNone; }
int prString_FindRegexp(struct VMGlobals *g, int numArgsPushed) { int err; PyrSlot *a = g->sp - 2; // source string PyrSlot *b = g->sp - 1; // pattern PyrSlot *c = g->sp; // offset if (!isKindOfSlot(b, class_string) || (NotInt(c))) return errWrongType; // post("prString_FindRegexp\n"); int maxfind = MAXREGEXFIND; int offset = slotRawInt(c); int stringsize = slotRawObject(a)->size + 1; int patternsize = slotRawObject(b)->size + 1; char *string = (char*)malloc(slotRawObject(a)->size + 1); err = slotStrVal(a, string, slotRawObject(a)->size + 1); if (err){ free(string); return err; } char *pattern = (char*)malloc(slotRawObject(b)->size + 1); err = slotStrVal(b, pattern, slotRawObject(b)->size + 1); if (err) return err; UParseError uerr; UErrorCode status = (UErrorCode)0; UChar *regexStr; UChar *ustring; regexStr = (UChar*)malloc((patternsize)*sizeof(UChar)); u_charsToUChars (pattern, regexStr, patternsize); ustring = (UChar*)malloc((stringsize)*sizeof(UChar)); u_charsToUChars (string+offset, ustring, stringsize-offset); unsigned flags = UREGEX_MULTILINE; int groupNumber = 0; SCRegExRegion * what; int indx = 0; int size = 0; URegularExpression *expression = uregex_open(regexStr, -1, flags, &uerr, &status); if(U_FAILURE(status)) goto nilout; if(!U_FAILURE(status)) { uregex_setText(expression, ustring, -1, &status); what = (SCRegExRegion*)malloc((maxfind)*sizeof(SCRegExRegion)); for(int i=0; i< maxfind; i++) { SCRegExRegion range; range.matched = false; what[i] = range; } int32_t groups = uregex_groupCount(expression, &status) + 1; if(U_FAILURE(status)) goto nilout; // post("groups: %i\n", groups); while (uregex_findNext(expression, &status) && size<maxfind) { if(U_FAILURE(status)) return errNone; for(int i=0; i< groups; ++i){ what[size].group = i; what[size].start = sc_clip(uregex_start(expression, i, &status), 0, stringsize) ; if(U_FAILURE(status)) goto nilout; what[size].end = sc_clip(uregex_end(expression, i, &status), 0, stringsize); what[size].matched = true; // post("index:%i, size:%i, start %i, end %i\n", i, size, what[i].start, what[i].end); size = indx++ + 1; if(U_FAILURE(status)) goto nilout; } } PyrObject *result_array = newPyrArray(g->gc, size, 0, true); result_array->size = 0; if (size>0) //(matched) { for (int i = 0; i < size; i++) { if (what[0].matched == false) { result_array->size++; SetNil(result_array->slots+i); } else { result_array->size++; int match_start = what[i].start; int match_length = what[i].end - what[i].start; // post("for i:%i, start %i, end %i\n", i, what[i].start, what[i].end); // char *match = (char*)malloc(match_length); char match[match_length]; strncpy(match, string + offset + match_start, match_length); match[match_length] = 0; PyrObject *array = newPyrArray(g->gc, 2, 0, true); array->size = 2; SetInt(array->slots, match_start + offset); PyrObject *matched_string = (PyrObject*)newPyrString(g->gc, match, 0, true); SetObject(array->slots+1, matched_string); g->gc->GCWrite(matched_string, array->slots + 1); SetObject(result_array->slots + i, array); g->gc->GCWrite(array, result_array->slots + i); } } } else { SetNil(a); } free(what); free(pattern); free(regexStr); free(ustring); free(string); SetObject(a, result_array); g->gc->GCWrite(result_array,a); //uregex_close(expression); return errNone; } nilout: free(string); free(what); free(pattern); free(regexStr); free(ustring); SetNil(a); return errNone; }
MetaType *MetaType::find( PyrSlot *slot ) { switch (GetTag(slot)) { case tagNil : return 0; case tagInt : return metaType<int>(); case tagSym : return metaType<QString>(); case tagChar : return metaType<QChar>(); case tagFalse : case tagTrue : return metaType<bool>(); case tagObj : { PyrObject *obj = slotRawObject(slot); PyrClass *klass = obj->classptr; unsigned char format = obj->obj_format; if( format == obj_double || format == obj_float ) return metaType< QVector<double> >(); else if( format == obj_int32 || format == obj_int16 || format == obj_int8 ) return metaType< QVector<int> >(); else if( isKindOfSlot( slot, class_string ) ) { return metaType<QString>(); } else if( isKindOfSlot( slot, SC_CLASS(Point) ) ) { return metaType<QPointF>(); } else if( isKindOfSlot( slot, SC_CLASS(Rect) ) ) { return metaType<QRectF>(); } else if( isKindOfSlot( slot, SC_CLASS(Size) ) ) { return metaType<QSizeF>(); } else if( klass == SC_CLASS(Color) || klass == SC_CLASS(Gradient) || klass == SC_CLASS(HiliteGradient) ) { return metaType<QColor>(); } else if( isKindOfSlot( slot, SC_CLASS(QFont) ) ) { return metaType<QFont>(); } else if( isKindOfSlot( slot, SC_CLASS(QPalette) ) ) { return metaType<QPalette>(); } else if( isKindOfSlot( slot, SC_CLASS(QObject) ) ) { return metaType<QObjectProxy*>(); } else if( isKindOfSlot( slot, class_array ) || isKindOfSlot( slot, class_symbolarray ) ) { return metaType<QVariantList>(); } else if( isKindOfSlot( slot, SC_CLASS(QTreeViewItem) ) ) { return metaType<QcTreeWidget::ItemPtr>(); } else { QString className = TypeCodec<QString>::read( &slotRawObject(slot)->classptr->name ); qcWarningMsg(QString("WARNING: Do not know how to use an instance of class '%1'").arg(className)); return 0; } } default: return metaType<double>(); } }