libose
Loading...
Searching...
No Matches
Example: OSC Server that Dispatches Specific Addresses

demonstrates the use of the osevm_respondToString hook to respond to specific strings / addresses

The VM responds by default to a small number of prefixes, such as /!, /@, and /$, which mean "funcall" or "execute", "assign", and "lookup" respectively. Any string that is processed by the VM that doesn't have a prefix that the VM responds to is simply pushed onto the stack. This example shows how to implement a hook and install it in the VM to respond to messages (strings) that the VM doesn't respond to, without need for a special prefix.

#include <stdio.h>
#include <string.h>
#include "ose.h"
#include "ose_context.h"
#include "ose_stackops.h"
#include "ose_vm.h"
#include "ose_print.h"
/* The size of the bundle / VM to create. */
#define NUM_BYTES 65536
/*
* This function will print all strings found in messages on the stack.
*
* Note that it prints them in reverse order!
*
* The reason for this is that each argument of a message is pushed
* on the stack as its own message, starting from the beginning of
* the message and progressing to the end, so the last item of the
* message is the top element of the stack.
*/
static void greet(ose_bundle stack)
{
while(!ose_bundleIsEmpty(stack))
{
/* Check the type of the element on top of the stack. */
if(ose_peekType(stack) == OSETT_MESSAGE)
{
/* If this it is a message, check the type of its data. */
if(ose_peekMessageArgType(stack) == OSETT_STRING)
{
/* If it has a string, get the value, print it, and
* drop it. */
const char * const str = ose_peekString(stack);
printf("%s ", str);
ose_drop(stack);
}
else
{
/* If it's not a string, drop it. */
ose_drop(stack);
}
}
else
{
/* If it's not a message, drop it. */
ose_drop(stack);
}
}
printf("\n");
}
static void signoff(ose_bundle stack)
{
printf("Stay classy!\n");
}
/*
* This function will be installed as a hook in the VM. This is done
* using the -DOSEVM_RESPONDTOSTRING=respond_to_string compiler
* flag---see the Makefile in the examples folder.
*
* When the VM processes a string and encounters one it doesn't have
* a binding for, it will place the string on the stack and call the
* function defined by OSEVM_RESPONDTOSTRING.
*/
void respond_to_string(ose_bundle vm)
{
/* Get a reference to the VM's stack. */
ose_bundle vm_stack = OSEVM_STACK(vm);
/* Get a pointer to the string on the stack. */
const char * const str = ose_peekString(vm_stack);
if(!strcmp(str, "/greet"))
{
/* Drop the message that contains the address, and call the
* greet function, passing it the stack which contains the
* arguments. */
ose_drop(vm_stack);
greet(vm_stack);
}
else if(!strcmp(str, "/signoff"))
{
/* Drop the message that contains the address and call the
* signoff function. */
signoff(vm_stack);
}
else
{
/* Not for us. */
}
}
int main(int ac, char **av)
{
/* Allocate memory for the VM. */
char bytes[NUM_BYTES];
/* First, we turn the bytes into a bundle. */
ose_bundle bundle = ose_newBundleFromCBytes(NUM_BYTES, bytes);
/* Now initialize the bundle as a VM. */
ose_bundle vm = osevm_init(bundle,
1024, 1024, 1024, 1024, 1024);
/* Get references to the input and environment bundles. */
ose_bundle vm_input = OSEVM_INPUT(vm);
ose_pushMessage(vm_input, "/greet", strlen("/greet"), 2,
OSETT_STRING, "Hello",
OSETT_STRING, "World!");
osevm_run(vm);
ose_pushMessage(vm_input, "/signoff", strlen("/signoff"), 0);
osevm_run(vm);
return 0;
}
provides global definitions and types
contains functions that structure an OSC bundle for use with other parts of this library
contains functions that manipulate the structure and contents of an OSE bundle and its elements
the OSE virtual machine
#define OSEVM_INPUT(osevm)
Get the input bundle.
Definition ose_vm.h:362
#define OSEVM_STACK(osevm)
Get the stack bundle.
Definition ose_vm.h:368
Definition ose.h:374