Creating Your Own Protocols

cwright's picture

Recently on the list, there was a question regarding creating your own protocols for QC. This is perhaps a 3+ part problem, and I've only addressed 1. Never the less, it's a good start I think :)

The Parts:

  • The Edit Conformance Information menu (I've addressed this one)
  • The Composition Repository patch (not addressed)
  • The New From Template Dialog (not addressed)

Making a new protocol is actually really simple. Using our "Skanky SDK" template makes it a snap.

Create a new project. Remove the CustomPatch.h, CustomPatch.m, CustomPatchUI.h, and CustomPatch.m files in the Patches directory (we don't need them for this exercise). The function we'll be working on is registerNodesWithManager:, located in CustomPatchPrincipal.m. Remove references and #imports of these files too.

Add these following lines before the @implementation line:

@interface QCCompositionRepository: NSObject

This tells the compiler a bit about the Compo Repo that we're working with (actually, it doesn't say much at all, just that it's an extant class).

Next, clear out the registerNodesWithManager function. We're not adding patches, so we don't need any of the auto-generated stuff in there.

Next, the protocol dictionary construction!:

  1. NSMutableDictionary *infoDict =
  2. [[NSMutableDictionary alloc] init];
  3. NSMutableDictionary *optionalInputDict =
  4. [[NSMutableDictionary alloc] init];
  5. NSMutableDictionary *requiredInputDict =
  6. [[NSMutableDictionary alloc] init];
  7. NSMutableDictionary *optionalOutputDict =
  8. [[NSMutableDictionary alloc] init];
  9. NSMutableDictionary *requiredOutputDict =
  10. [[NSMutableDictionary alloc] init];
  12. // add and remove your specific keys to the
  13. // appropriate structs -- Use the port's class
  14. // as the object, and a name that follows the pattern
  15. [optionalInputDict setObject:[QCStructurePort class]
  16. forKey:@"_protocolInput_OptionalInputStruct"];
  17. [requiredInputDict setObject:[QCStructurePort class]
  18. forKey:@"_protocolInput_RequiredInputStruct"];
  19. [optionalOutputDict setObject:[QCStructurePort class]
  20. forKey:@"_protocolInput_OptionalOutputStruct"];
  21. [requiredOutputDict setObject:[QCStructurePort class]
  22. forKey:@"_protocolInput_RequiredOutputStruct"];
  24. // here we set some metadata about the protocol:
  25. // the display name (in the conformance dialog),
  26. // and whether or not we allow consumer patches.
  27. // (True in this example)
  28. [infoDict
  29. setObject:@"My Protocol's Display Name"
  30. forKey:@"name"];
  31. [infoDict
  32. setObject:[NSNumber numberWithBool:TRUE]
  33. forKey:@"allowConsumers"];
  35. // We add the required and optional inputs
  36. // to the protocol dictionary...
  37. [infoDict setObject:optionalInputDict
  38. forKey:@"optionalInputKeys"];
  39. [infoDict setObject:requiredInputDict
  40. forKey:@"requiredInputKeys"];
  41. [infoDict setObject:optionalOutputDict
  42. forKey:@"optionalOutputKeys"];
  43. [infoDict setObject:requiredOutputDict
  44. forKey:@"requiredOutputKeys"];
  46. // the we register it!
  47. [[QCCompositionRepository sharedCompositionRepository]
  48. registerProtocol:@"com.MyCompanyName.My-Protocol-Name"
  49. withDescription:infoDict];
  51. // here you should release all the dictionaries.
  52. // I'm lazy though, so you'll have to write that
  53. // yourself.

Feel free to use this code however you want. If you do though, please drop me a line or comment on this post, so I know I didn't waste all this time for nothing :)

multimedial's picture
Re: Creating Your Own Protocols

Hi Chris,

I am not sure if this is what I think it is - would it be possible with this to write a custom protocol to export image data from Quartz Composer over the network, for instance?

Let's say, to play out a visual composition onto a LED wall? :-)

I would be interested in getting in touch with you, yet I can't seem to find any email address for you...

you can join me at info at multimedial dot de.

Looking forward to your answer,

C. Leske

smokris's picture
Re: Creating Your Own Protocols

@multimedial: @cwright wrote that post 4.5 years ago; he no longer works for Kosada/Kineme.

If you want to send image data over the network, your best option is probably to use the Render In Image patch to produce image data (instead of rendering it to screen), and either send it over the network by writing a consumer node, or by converting the image to a data stream using Kineme DataTools and POSTing it to an HTTP server using Kineme NetworkTools.

To send an image to an LED wall, you can either:

  • Use an LED wall controller that receives Art-Net or DMX, and use Render In Image connected to Image PixelS connected to Kineme ArtNetTools.
  • Use an LED wall controller that takes DVI input, and simply display QC Viewer window on that second video output.

gtoledo3's picture
Re: Creating Your Own Protocols

To add some clarification to what Chris means by custom protocols, he's not referring to a custom data type that happens at the port/noodle level.

What he's referring to are the built in "composition types" (templates) that QC has. You can access most of them via the Templates option in the QC Editor.

Protocols suggest:

-Certain execution modes. For instance, Image Filters have no consumers, and are basically processors. Graphic Animation compositions always have consumers.

-Getting info from specific sources, to serve a niche purpose. Music Visualizers can get audio info, Graphic Animations can receive Pace and X/Y mouse position info, etc.

-Certain patches being loaded on the associated template compositions. Usually the patches loaded on the templates are optional, but there may be embargoes on adding patches with certain processor modes (a Consumer patch can't be on the root level of an Image Filter, for example).

Compositions that are placed in any of the Composition folders (in any of the three Libraries), can be queried by protocol type, and loaded by custom apps you make. So, you could have an app that filters images, and query the Composition Repository for compositions that only conform to the Image Filter protocol. Since you know that every Image Filter protocol composition has an image out, you can make certain assumptions about execution mode, and your ability to pass an image through. This is really a pretty handy function of QC, and is somewhat analogous with the way one can load Core Image filters by calling certain categories.