Permalink
Browse files

Fixing up Receiver for arbitrary ports

  • Loading branch information...
1 parent 3ffcfbb commit 122a1353ed8bc02f3fc54fee977d67b1454fb01e Jonathan del Strother committed Sep 9, 2009
Showing with 230 additions and 89 deletions.
  1. +12 −6 BBOSC.xcodeproj/project.pbxproj
  2. +1 −46 BBOSCPlugInSender.m
  3. +9 −5 BBOSCPluginReceiver.h
  4. +97 −32 BBOSCPluginReceiver.m
  5. +2 −0 NSArrayExtensions.h
  6. +9 −0 NSArrayExtensions.m
  7. +16 −0 OSCExtensions.h
  8. +84 −0 OSCExtensions.m
@@ -33,6 +33,7 @@
FC520B0A1056B90000FE3004 /* BBOSCSettings.xib in Resources */ = {isa = PBXBuildFile; fileRef = FC520AC11056B56400FE3004 /* BBOSCSettings.xib */; };
FC520BFC1057E69B00FE3004 /* NSArrayExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = FC520BFB1057E69B00FE3004 /* NSArrayExtensions.m */; };
FC520CFB1058085100FE3004 /* BBOSCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC520CFA1058085100FE3004 /* BBOSCViewController.m */; };
+ FC520D301058137600FE3004 /* OSCExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = FC520D2F1058137600FE3004 /* OSCExtensions.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -47,42 +48,42 @@
isa = PBXContainerItemProxy;
containerPortal = FC5208BF10567BED00FE3004 /* VVOSC.xcodeproj */;
proxyType = 2;
- remoteGlobalIDString = 963E71D00E993BB9007CF9D8 /* VVOSCTester.app */;
+ remoteGlobalIDString = 963E71D00E993BB9007CF9D8;
remoteInfo = VVOSCTester;
};
FC5208CF10567BED00FE3004 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FC5208BF10567BED00FE3004 /* VVOSC.xcodeproj */;
proxyType = 2;
- remoteGlobalIDString = 8DC2EF5B0486A6940098B216 /* VVOSC.framework */;
+ remoteGlobalIDString = 8DC2EF5B0486A6940098B216;
remoteInfo = "VVOSC framework";
};
FC5208D110567BED00FE3004 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FC5208BF10567BED00FE3004 /* VVOSC.xcodeproj */;
proxyType = 2;
- remoteGlobalIDString = 96EB122C0EFAA64300B2D581 /* libVVOSC.a */;
+ remoteGlobalIDString = 96EB122C0EFAA64300B2D581;
remoteInfo = "VVOSC-iPhone sim";
};
FC5208D310567BED00FE3004 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FC5208BF10567BED00FE3004 /* VVOSC.xcodeproj */;
proxyType = 2;
- remoteGlobalIDString = 967FDE3C0EFAA6A600BCF87E /* libVVOSC.a */;
+ remoteGlobalIDString = 967FDE3C0EFAA6A600BCF87E;
remoteInfo = "VVOSC-iPhone dev";
};
FC5208D510567BED00FE3004 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FC5208BF10567BED00FE3004 /* VVOSC.xcodeproj */;
proxyType = 2;
- remoteGlobalIDString = 96A059B40EFACDDB00E82377 /* libVVOSC.a */;
+ remoteGlobalIDString = 96A059B40EFACDDB00E82377;
remoteInfo = "VVOSC-os x";
};
FC5208EC10567C6C00FE3004 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FC5208BF10567BED00FE3004 /* VVOSC.xcodeproj */;
proxyType = 1;
- remoteGlobalIDString = 8DC2EF4F0486A6940098B216 /* VVOSC framework */;
+ remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
remoteInfo = "VVOSC framework";
};
/* End PBXContainerItemProxy section */
@@ -123,6 +124,8 @@
FC520BFB1057E69B00FE3004 /* NSArrayExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSArrayExtensions.m; sourceTree = "<group>"; };
FC520CF91058085100FE3004 /* BBOSCViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BBOSCViewController.h; sourceTree = "<group>"; };
FC520CFA1058085100FE3004 /* BBOSCViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BBOSCViewController.m; sourceTree = "<group>"; };
+ FC520D2E1058137600FE3004 /* OSCExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSCExtensions.h; sourceTree = "<group>"; };
+ FC520D2F1058137600FE3004 /* OSCExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSCExtensions.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -184,6 +187,8 @@
FC520BFB1057E69B00FE3004 /* NSArrayExtensions.m */,
FC520CF91058085100FE3004 /* BBOSCViewController.h */,
FC520CFA1058085100FE3004 /* BBOSCViewController.m */,
+ FC520D2E1058137600FE3004 /* OSCExtensions.h */,
+ FC520D2F1058137600FE3004 /* OSCExtensions.m */,
);
name = Classes;
sourceTree = "<group>";
@@ -349,6 +354,7 @@
FC5209AC1056853800FE3004 /* BBOSCPluginReceiver.m in Sources */,
FC520BFC1057E69B00FE3004 /* NSArrayExtensions.m in Sources */,
FC520CFB1058085100FE3004 /* BBOSCViewController.m in Sources */,
+ FC520D301058137600FE3004 /* OSCExtensions.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
@@ -8,8 +8,7 @@
/* It's highly recommended to use CGL macros instead of changing the current context for plug-ins that perform OpenGL rendering */
#import <OpenGL/CGLMacro.h>
-#import "vvosc/FrameworkSrc/VVOSC.h"
-
+#import "OSCExtensions.h"
#import "BBOSCViewController.h"
#import "BBOSCPlugInSender.h"
#import "NSArrayExtensions.h"
@@ -18,50 +17,10 @@
#define kQCPlugIn_Description @"Best Before Open Sound Control sender plugin"
-@interface OSCMessage(BBExtensions)
--(void)addNSValue:(id)newValue withBias:(BBOSCType)bias;
-@end
-@implementation OSCMessage(BBExtensions)
--(void)addNSValue:(id)newValue withBias:(BBOSCType)bias {
-
- if ([newValue isKindOfClass:[NSString class]]) {
- [self addString:newValue];
-
- } else if ([newValue isKindOfClass:[NSNumber class]]) {
- switch(bias) {
- case BBOSCTypeBool:
- [self addBOOL:[newValue boolValue]];
- break;
- case BBOSCTypeInt:
- [self addInt:[newValue intValue]];
- break;
- case BBOSCTypeFloat:
- [self addFloat:[newValue floatValue]];
- break;
- default:
- NSAssert2(NO, @"Bad type %d for %@", bias, newValue);
- }
-
- } else if ([newValue isKindOfClass:[NSArray class]]) {
- NSAssert2(bias>=BBOSCTypeArrayOfInt && bias<=BBOSCTypeArrayOfBool, @"Unexpected value %@ for type %d", newValue, bias);
- // We've got an array - add all the subvalues into the message, using the appropriate type (eg if we're using BBOSCTypeArrayOfFloat, subvalues should use BBOSCTypeFloat)
- for(id subvalue in newValue) {
- [self addNSValue:subvalue withBias:bias-4];
- }
-
- } else {
- [self addBOOL:!!newValue];
- }
-}
-@end
-
-
-
@interface BBOSCPlugInSender ()
@property (nonatomic, readwrite, retain) OSCManager *oscManager;
@property (nonatomic, readwrite, retain) OSCOutPort *oscPort;
@property (nonatomic, readwrite, retain) NSArray* oscParameters;
-
@end
@implementation BBOSCPlugInSender
@@ -171,10 +130,6 @@ -(void)setOscParameters:(NSArray*)params {
}
}
--(NSArray*)oscParameters {
- return oscParameters;
-}
-
@end
@implementation BBOSCPlugInSender (Execution)
View
@@ -9,14 +9,18 @@
#import <Quartz/Quartz.h>
@class OSCManager, OSCInPort;
-@interface BBOSCPluginReceiver : QCPlugIn
-{
- OSCManager *oscManager;
- OSCInPort *oscPort;
+@interface BBOSCPluginReceiver : QCPlugIn {
NSMutableArray* messages;
NSLock* messageLock;
}
+@property (nonatomic, readonly, retain) NSString* listeningPath;
-@property (nonatomic, readwrite, assign) NSArray* outputStructure;
+@property (nonatomic, readonly, retain) NSArray* oscParameters;
+@property (nonatomic, readonly, retain) OSCManager *oscManager;
+@property (nonatomic, readonly, retain) OSCInPort *oscPort;
+
+@property (nonatomic, readwrite, assign) NSUInteger inputReceivingPort;
+@property (nonatomic, readwrite, assign) NSString* inputReceivingPath;
+@property (nonatomic, readwrite, assign) BOOL outputMessageReceived;
@end
View
@@ -8,14 +8,24 @@
/* It's highly recommended to use CGL macros instead of changing the current context for plug-ins that perform OpenGL rendering */
#import <OpenGL/CGLMacro.h>
-#import "vvosc/FrameworkSrc/VVOSC.h"
#import "BBOSCPluginReceiver.h"
+#import "BBOSCViewController.h"
+#import "NSArrayExtensions.h"
+#import "OSCExtensions.h"
#define kQCPlugIn_Name @"BBOSC Receiver"
#define kQCPlugIn_Description @"Best Before Open Sound Control receiver plugin"
+@interface BBOSCPluginReceiver ()
+@property (nonatomic, readwrite, retain) OSCManager *oscManager;
+@property (nonatomic, readwrite, retain) OSCOutPort *oscPort;
+@property (nonatomic, readwrite, retain) NSArray* oscParameters;
+@property (nonatomic, readwrite, retain) NSString* listeningPath;
+@end
+
@implementation BBOSCPluginReceiver
-@dynamic outputStructure;
+@dynamic inputReceivingPort, inputReceivingPath, outputMessageReceived;
+@synthesize oscManager, oscPort, oscParameters, listeningPath;
+ (NSDictionary*) attributes
{
@@ -31,6 +41,17 @@ + (NSDictionary*) attributesForPropertyPortWithKey:(NSString*)key
/*
Specify the optional attributes for property based ports (QCPortAttributeNameKey, QCPortAttributeDefaultValueKey...).
*/
+ if ([key isEqualToString:@"inputReceivingPort"]) {
+ return [NSDictionary dictionaryWithObjectsAndKeys:@"Receiving Port", QCPortAttributeNameKey,
+ [NSNumber numberWithInt:60000], QCPortAttributeDefaultValueKey, nil];
+ }
+ if ([key isEqualToString:@"inputReceivingPath"]) {
+ return [NSDictionary dictionaryWithObjectsAndKeys:@"Receiving Path", QCPortAttributeNameKey,
+ @"", QCPortAttributeDefaultValueKey, nil];
+ }
+ if ([key isEqualToString:@"outputMessageReceived"]) {
+ return [NSDictionary dictionaryWithObjectsAndKeys:@"Message Received", QCPortAttributeNameKey, nil];
+ }
return nil;
}
@@ -56,10 +77,11 @@ + (QCPlugInTimeMode) timeMode
- (id) init
{
if(self = [super init]) {
- oscManager = [[OSCManager alloc] init];
- oscManager.delegate = self;
+ self.oscManager = [[[OSCManager alloc] init] autorelease];
+ self.oscManager.delegate = self;
+ self.oscParameters = [NSArray array];
messages = [[NSMutableArray alloc] init];
- messageLock = [[NSLock alloc] init];
+ messageLock = [[NSLock alloc] init];
}
return self;
@@ -81,16 +103,51 @@ - (void) dealloc
[oscManager release];
[messages release];
[messageLock release];
+ [listeningPath release];
+ [oscParameters release];
[super dealloc];
}
+- (QCPlugInViewController*) createViewController
+{
+ return [[BBOSCViewController alloc] initWithPlugIn:self
+ viewNibName:@"BBOSCSettings"];
+}
+
++ (NSArray*) plugInKeys {
+ return [NSArray arrayWithObjects:@"oscParameters", nil];
+}
+
+-(void)setOscParameters:(NSArray*)params {
+ NSArray* originalPortKeys = [oscParameters map:^(id port){ return [port objectForKey:BBOSCPortKey]; }];
+
+ [self willChangeValueForKey:@"oscParameters"];
+ [oscParameters release];
+ oscParameters = [params retain];
+ [self didChangeValueForKey:@"oscParameters"];
+
+ // Bleh, just trash all the original input ports
+ for(NSString* portKey in originalPortKeys) {
+ [self removeOutputPortForKey:portKey];
+ }
+
+ for(NSDictionary* port in oscParameters) {
+ NSString* key = [port objectForKey:BBOSCPortKey];
+ NSNumber* oscType = [port objectForKey:BBOSCTypeKey];
+ NSString* name = [NSString stringWithFormat:@"OSC-%@", [[BBOSCTypeToStringTransformer transformer] transformedValue:oscType]];
+ NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:name, QCPortAttributeNameKey, nil];
+
+ [self addOutputPortWithType:QCTypeForOSCType([oscType intValue]) forKey:key withAttributes:attributes];
+ }
+}
+
+
- (void) receivedOSCMessage:(OSCMessage *)m {
- // TODO : Needs to be thread safe
- if ([[m address] isEqualToString:@"/test"]) {
- [messageLock lock];
+ [messageLock lock];
+ if ([[m address] hasPrefix:self.listeningPath]) {
[messages addObject:m];
- [messageLock unlock];
}
+ [messageLock unlock];
}
@end
@@ -102,7 +159,6 @@ - (BOOL) startExecution:(id<QCPlugInContext>)context
Called by Quartz Composer when rendering of the composition starts: perform any required setup for the plug-in.
Return NO in case of fatal failure (this will prevent rendering of the composition to start).
*/
- oscPort = [[oscManager createNewInputForPort:60000 withLabel:@"BB OSC"] retain];
return YES;
}
@@ -124,31 +180,40 @@ Return NO in case of failure during the execution (this will prevent rendering o
CGLContextObj cgl_ctx = [context CGLContextObj];
*/
+ if ([self didValueForInputKeyChange:@"inputReceivingPort"]) {
+ if (self.oscPort)
+ [self.oscManager removeInput:self.oscPort];
+ self.oscPort = [self.oscManager createNewInputForPort:self.inputReceivingPort withLabel:@"BB OSC"];
+ }
+
+ if ([self didValueForInputKeyChange:@"inputReceivingPath"]) {
+ [messageLock lock];
+ self.listeningPath = self.inputReceivingPath;
+ [messages removeAllObjects];
+ [messageLock unlock];
+ }
+
[messageLock lock];
- if ([messages count]>0) {
+ if ([messages count]==0) {
+ self.outputMessageReceived = NO;
+ } else {
+ self.outputMessageReceived = YES;
+
OSCMessage* message = [messages objectAtIndex:0];
- NSLog(@"Yay %@", message);
- NSMutableArray* messageContent = [NSMutableArray array];
- for(OSCValue* oscValue in [message valueArray]) {
- switch (oscValue.type) {
- case OSCValInt:
- [messageContent addObject:[NSNumber numberWithInt:[oscValue intValue]]];
- break;
- case OSCValFloat:
- [messageContent addObject:[NSNumber numberWithFloat:[oscValue floatValue]]];
- break;
- case OSCValString:
- [messageContent addObject:[oscValue stringValue]];
- break;
- case OSCValBool:
- [messageContent addObject:[NSNumber numberWithBool:[oscValue boolValue]]];
- break;
- default:
- NSLog(@"Ignoring object value %@", oscValue);
- break;
- }
+
+ NSUInteger valueIndex=0;
+ for(NSDictionary* port in oscParameters) {
+ BBOSCType expectedType = [[port objectForKey:BBOSCTypeKey] intValue];
+ NSString* portKey = [port objectForKey:BBOSCPortKey];
+
+ id outputValue = [message readNSValueFromPosition:&valueIndex withBias:expectedType];
+ // Grr, no assigning arrays to QCStructures. rdar://5672284
+ if ([outputValue isKindOfClass:[NSArray class]])
+ outputValue = [outputValue qcStructure];
+
+ [self setValue:outputValue forOutputKey:portKey];
}
- self.outputStructure = messageContent;
+
[messages removeObjectAtIndex:0];
}
[messageLock unlock];
View
@@ -11,4 +11,6 @@
@interface NSArray(BBExtensions)
- (NSArray *)map: (id (^)(id obj))block;
+- (NSArray *)select: (BOOL (^)(id obj))block;
+-(NSDictionary*)qcStructure;
@end
View
@@ -33,4 +33,13 @@ - (NSArray *)select: (BOOL (^)(id obj))block
}
return new;
}
+
+-(NSDictionary*)qcStructure {
+ int i=0;
+ NSMutableDictionary* result = [NSMutableDictionary dictionary];
+ for(id object in self) {
+ [result setObject:object forKey:[NSNumber numberWithInt:i++]];
+ }
+ return result;
+}
@end
Oops, something went wrong.

0 comments on commit 122a135

Please sign in to comment.