source: trunk/Cocoa/F-Script Anywhere/Source/SCPatch/Common/SCPatchMessenger.h@ 645

Last change on this file since 645 was 153, checked in by Nicholas Riley, 21 years ago

Integrates SCPatch and mach_inject; unfinished, buggy.

File size: 3.1 KB
Line 
1#pragma once
2
3extern "C"
4{
5#include <pthread.h>
6}
7
8#include <CoreFoundation/CoreFoundation.h>
9#include "SCPatchCommon.h"
10#include "SCPatchMessages.h"
11
12#define DEFAULT_MESSAGE_RETRY_LIMIT 100 // Give up after 5 seconds
13#define DEFAULT_MESSAGE_RETRY_INTERVAL .05
14
15// These AppleEvents get sent to ReceiveMessage after StartListening and
16// before StopListening, respectively.
17const OSType kEventClassSCPatchMessenger = 'SCPm';
18const OSType kEventSCPatchStart = 'strt';
19const OSType kEventSCPatchStop = 'stop';
20
21typedef struct
22{
23 Boolean threaded;
24 UInt32 retryCount;
25 Ptr descData;
26 UInt32 descSize;
27 CFStringRef portName;
28} AEMessageInfo;
29
30
31class SCPatchMessenger
32{
33
34 public:
35 SCPatchMessenger(void);
36 virtual ~SCPatchMessenger(void);
37
38 void SetMessageRetryInterval(float interval) { mMessageRetryInterval = interval; }
39 float GetMessageRetryInterval(void) { return mMessageRetryInterval; }
40
41 void SetMessageRetryLimit(UInt32 limit) { mMessageRetryLimit = limit; }
42 UInt32 GetMessageRetryLimit(void) { return mMessageRetryLimit; }
43
44 // Start listening for messages. If called from a patch, a PSN must be supplied.
45 // When called from a controller, pass NULL for the PSN.
46 OSErr StartListening(CFStringRef myBundleIdentifier,
47 Boolean isPatch, Boolean threaded);
48 OSErr StopListening(void);
49
50 // When sending from controller to patch, you have to include the PSN to disambiguate
51 // the bundleID (because the same bundle is loaded into multiple apps), but when
52 // sending from patch back to controller, the PSN can be null, since there's only one
53 // controller running.
54 OSErr SendPing(CFStringRef bundleIdentifier, ProcessSerialNumber *psn);
55
56 OSErr SendMessage(CFStringRef bundleIdentifier,
57 ProcessSerialNumber *psn,
58 AEEventClass evtClass, AEEventID evtID,
59 const char *paramsFmt, ...);
60
61 OSErr SendMessage(CFStringRef bundleIdentifier,
62 ProcessSerialNumber *psn,
63 const AppleEvent *theAE,
64 Boolean threaded);
65
66 // Override this to receive messages.
67 virtual void ReceiveMessage(const AppleEvent *theAE) = 0;
68
69 protected:
70 virtual OSErr HandleMessage(const AppleEvent *) { return eventNotHandledErr; }
71
72 private:
73 // Info for the listening port
74 CFMessagePortRef mMessagePort;
75 CFRunLoopSourceRef mMessageSource;
76
77 // Flags for whether we queue outgoing messages, and whether sending is threaded.
78 Boolean mThreaded;
79
80 // We have named send queues, where the key is the port name.
81 // Each queue is a CFArray of messages.
82 CFMutableDictionaryRef mMessageQueueDict;
83 CFMutableDictionaryRef mMessageThreadDict;
84
85 pthread_mutex_t mMessageQueueMutex;
86 float mMessageRetryInterval;
87 UInt32 mMessageRetryLimit;
88
89 OSErr SendMessage(AEMessageInfo *info);
90 static void *SendThreadEntryPoint(void *infoPtr);
91 OSErr QueueMessage(AEMessageInfo *info);
92 AEMessageInfo *GetNextMessage(pthread_t threadID);
93 AEMessageInfo *DequeueMessage(pthread_t threadID);
94
95 static CFDataRef ReceiveCallback(CFMessagePortRef local, SInt32 message, CFDataRef dataRef, void *info);
96};
Note: See TracBrowser for help on using the repository browser.