Skip to content

Commit

Permalink
Merge branch 'master' into hiddenAdd
Browse files Browse the repository at this point in the history
  • Loading branch information
mhroth committed Feb 16, 2012
2 parents 5db1810 + b303d47 commit 6c16013
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/MessageMessageBox.cpp
Expand Up @@ -116,7 +116,7 @@ void MessageMessageBox::processMessage(int inletIndex, PdMessage *message) {
char *buffer = (char *) alloca(RES_BUFFER_LENGTH * sizeof(char));
// TODO(mhroth): resolve string, but may be in stack buffer
PdMessage::resolveString(messageTemplate->getSymbol(i), message, 1, buffer, RES_BUFFER_LENGTH);
outgoingMessage->setFloatOrSymbol(i, buffer); // buffer is resolved to float or string
outgoingMessage->parseAndSetMessageElement(i, buffer); // buffer is resolved to float or string
}
}
sendMessage(0, outgoingMessage);
Expand Down
15 changes: 15 additions & 0 deletions src/PdContext.cpp
Expand Up @@ -463,6 +463,21 @@ void PdContext::scheduleExternalMessage(const char *receiverName, PdMessage *mes
unlock();
}

void PdContext::scheduleExternalMessage(const char *receiverName, double timestamp, const char *initString) {
// do the heavy lifting of string parsing before the lock (minimise the critical section)
int maxElements = (strlen(initString)/2)+1;
PdMessage *message = PD_MESSAGE_ON_STACK(maxElements);
char str[strlen(initString)+1]; strcpy(str, initString);
message->initWithString(timestamp, maxElements, str);

lock(); // lock and load
int receiverNameIndex = sendController->getNameIndex(receiverName);
if (receiverNameIndex >= 0) { // if the receiver exists
scheduleMessage(sendController, receiverNameIndex, message);
}
unlock();
}

PdMessage *PdContext::scheduleMessage(MessageObject *messageObject, unsigned int outletIndex, PdMessage *message) {
// basic argument checking. It may happen that the message is NULL in case a cancel message
// is sent multiple times to a particular object, when no message is pending
Expand Down
7 changes: 7 additions & 0 deletions src/PdContext.h
Expand Up @@ -134,6 +134,13 @@ class PdContext {
/** Schedules a message to be sent to all receivers at the start of the next block. */
void scheduleExternalMessage(const char *receiverName, PdMessage *message);

/**
* Schedules a message described by the given string to be sent to named receivers at the
* given timestamp.
*/
void scheduleExternalMessage(const char *receiverName, double timestamp,
const char *initString);

/**
* Schedules a <code>PdMessage</code> to be sent by the <code>MessageObject</code> from the
* <code>outletIndex</code> at the specified <code>time</code>. The message will be copied
Expand Down
44 changes: 14 additions & 30 deletions src/PdMessage.cpp
Expand Up @@ -36,20 +36,22 @@ void PdMessage::initWithString(double ts, unsigned int maxElements, char *initSt
if (token == NULL || strlen(initString) == 0) {
initWithTimestampAndBang(0.0); // just in case, there is always at least one element in a message
} else {
int i = 0;
unsigned int i = 0;
do {
setFloatOrSymbol(i++, token);
parseAndSetMessageElement(i++, token);
} while (((token = strtok(NULL, " ;")) != NULL) && (i < maxElements));

numElements = i;
}
}

void PdMessage::setFloatOrSymbol(unsigned int index, char *initString) {
if (StaticUtils::isNumeric(initString)) {
setFloat(index, atof(initString));
void PdMessage::parseAndSetMessageElement(unsigned int index, char *token) {
if (StaticUtils::isNumeric(token)) {
setFloat(index, atof(token)); // element is a float
} else if (!strcmp("!", token)) {
setBang(index); // element is a bang
} else {
setSymbol(index, initString); // element is symbolic
setSymbol(index, token); // element is symbolic
}
}

Expand Down Expand Up @@ -347,18 +349,9 @@ char *PdMessage::toString() {
for (int i = 0; i < numElements; i++) {
lengths[i] = 0;
switch (getType(i)) {
case FLOAT: {
lengths[i] = snprintf(NULL, 0, "%g", getFloat(i));
break;
}
case BANG: {
lengths[i] = snprintf(NULL, 0, "%s", "bang");
break;
}
case SYMBOL: {
lengths[i] = snprintf(NULL, 0, "%s", getSymbol(i));
break;
}
case FLOAT: lengths[i] = snprintf(NULL, 0, "%g", getFloat(i)); break;
case BANG: lengths[i] = snprintf(NULL, 0, "%s", "bang"); break;
case SYMBOL:lengths[i] = snprintf(NULL, 0, "%s", getSymbol(i)); break;
default: break;
}
// total length of our string is each atom plus a space, or \0 on the end
Expand All @@ -375,18 +368,9 @@ char *PdMessage::toString() {
}
// put a string representation of each atom into the final string
switch (getType(i)) {
case FLOAT: {
snprintf(&finalString[pos], lengths[i] + 1, "%g", getFloat(i));
break;
}
case BANG: {
snprintf(&finalString[pos], lengths[i] + 1, "%s", "bang");
break;
}
case SYMBOL: {
snprintf(&finalString[pos], lengths[i] + 1, "%s", getSymbol(i));
break;
}
case FLOAT: snprintf(&finalString[pos], lengths[i] + 1, "%g", getFloat(i)); break;
case BANG: snprintf(&finalString[pos], lengths[i] + 1, "%s", "bang"); break;
case SYMBOL: snprintf(&finalString[pos], lengths[i] + 1, "%s", getSymbol(i)); break;
default: break;
}
pos += lengths[i];
Expand Down
2 changes: 1 addition & 1 deletion src/PdMessage.h
Expand Up @@ -86,7 +86,7 @@ class PdMessage {
void initWithString(double timestamp, unsigned int maxElements, char *initString);

/** Sets the given message element to a FLOAT or SYMBOL depending on contents of string. */
void setFloatOrSymbol(unsigned int index, char *initString);
void parseAndSetMessageElement(unsigned int index, char *initString);

MessageAtom *getElement(unsigned int index);

Expand Down
5 changes: 5 additions & 0 deletions src/ZenGarden.cpp
Expand Up @@ -332,6 +332,11 @@ void zg_context_send_message(ZGContext *context, const char *receiverName, ZGMes
context->scheduleExternalMessage(receiverName, message);
}

void zg_context_send_message_from_string(ZGContext *context, const char *receiverName,
double timestamp, const char *initString) {
context->scheduleExternalMessage(receiverName, timestamp, initString);
}

void zg_context_send_messageV(PdContext *context, const char *receiverName, double timestamp,
const char *messageFormat, ...) {
va_list ap;
Expand Down
4 changes: 4 additions & 0 deletions src/ZenGarden.h
Expand Up @@ -179,6 +179,10 @@ typedef enum ZGConnectionType {
/** Send a message to the named receiver. */
void zg_context_send_message(ZGContext *context, const char *receiverName, ZGMessage *message);

/** Send a message described by the <code>initString</code> to the named receiver at the given timestamp. */
void zg_context_send_message_from_string(ZGContext *context, const char *receiverName,
double timestamp, const char *initString);

/**
* Send a message to the named receiver with the given format at the beginning of the next audio block.
* If no receiver exists with the given name, then this funtion does nothing.
Expand Down

0 comments on commit 6c16013

Please sign in to comment.