home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: FuturesDemo.cp
- Project: Sample code for Sprocket Framework 1.1 (DR2), released 6/15/96
- Contains: A demo of AE Futures functionality
- To Do: ?
-
- Sprocket Major Contributors:
- ----------------------------
- Dave Falkenburg, producer of Sprocket 1.0
- Bill Hayden, producer of Sprocket 1.1
- Steve Sisak, producer of the upcoming Sprocket 2.0
-
- Pete Alexander Steve Falkenburg Randy Thelen
- Eric Berdahl Nitin Ganatra Chris K. Thomas
- Marshall Clow Dave Hershey Leonard Rosenthal
- Tim Craycroft Dave Mark Dean Yu
- David denBoer Gary Powell
- Cameron Esfahani Jon Summers Apple Computer, Inc.
-
- Comments, Additions, or Corrections:
- ------------------------------------
- Bill Hayden, Nikol Software <nikol@codewell.com>
-
- */
-
-
- #include "FuturesDemo.h"
- #include "AEFutures.h"
- #include "AEThreads.h"
-
- #include <Threads.h>
- #include <PPCToolBox.h>
- #include <EPPC.h>
- #include <AppleEvents.h>
-
- #include "UString.h"
-
-
- AEDesc gNullDesc; // A null descriptor record
- AEAddressDesc gSelfAddress; // A self-addressed address descriptor record
- ProcessSerialNumber gSelfPSN; // This application's psn
-
- #pragma segment handlers
-
- pascal OSErr HandlePing(AppleEvent question, AppleEvent answer, long /*handlerRefcon*/)
- {
- char* stringPtr;
- char stringBuffer[100];
- long actualSize;
- DescType actualType;
- OSErr theErr;
- EventRecord evt;
-
- // Beep to indicate that the question was received
-
- while (EventAvail(everyEvent, &evt))
- {
- YieldToAnyThread();
- }
-
- SysBeep(1);
-
- // Extract a string from the question.
-
- theErr = AEGetParamPtr(&question, 'qstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
-
- // Load a string into the answer.
-
- stringPtr = "I’m just fine.";
- theErr = AEPutParamPtr(&answer, 'rstr', 'TEXT', stringPtr, clen(stringPtr));
-
- return(noErr);
- }
-
- pascal OSErr HandlePing1(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
- {
- OSErr theErr;
- TargetID theTargetID;
- PortInfoRec thePortInfo;
- AEAddressDesc theAddressDesc;
- AppleEvent question;
- AppleEvent answer;
- char* stringPtr;
- char stringBuffer[100];
- long actualSize;
- DescType actualType;
- long i;
-
- // Get the target address of the other process
-
- theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
- theTargetID.name = thePortInfo.name;
- theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
-
- // Start the thread that pings
-
- for (i=0; i<30; i++)
- {
- YieldToAnyThread();
-
- // Build an AppleEvent question that is addressed to the user selected target
-
- theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
-
- // Load a string into the question.
-
- stringPtr = "Hello server, how are you doing?";
- theErr = AEPutParamPtr(&question, 'qstr', 'TEXT', stringPtr, clen(stringPtr));
-
- // Ask the question
-
- theErr = AskForFuture(&question, &answer);
-
- // If the answer is not a future so soon after ask, something is probably wrong.
-
- // if (!IsFuture(&answer)) Debugger();
-
- // Extract a string from the answer. This will cause the thread to block until the answer is received.
-
- theErr = AEGetParamPtr(&answer, 'rstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
-
- // If the answer is still a future after retrieving a string from the answer, something is definitely wrong.
-
- // if (IsFuture(&answer)) Debugger();
-
- // Dispose of the answer and the question.
-
- theErr = AEDisposeDesc(&answer);
- theErr = AEDisposeDesc(&question);
- }
-
- // Dispose of the address descriptor now that the thread no longer needs it.
-
- theErr = AEDisposeDesc(&theAddressDesc);
-
- return theErr;
- }
-
- pascal OSErr HandlePing2(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
- {
-
- OSErr theErr;
- TargetID theTargetID;
- PortInfoRec thePortInfo;
- AEAddressDesc theAddressDesc;
- AEAddressDesc theAddressDesc2;
- AppleEvent question;
- AppleEvent question2;
- AppleEvent answer;
- AppleEvent answer2;
- long i;
-
- // Get the target addresses of the two processes
-
- theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
- theTargetID.name = thePortInfo.name;
- theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
-
- theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
- theTargetID.name = thePortInfo.name;
- theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc2);
-
- // Start the thread that pings
-
- for (i=0; i<30; i++)
- {
- YieldToAnyThread();
-
- // Build the questions.
-
- theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
- theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc2, kAutoGenerateReturnID, kAnyTransactionID, &question2);
-
- // Ask the questions.
-
- theErr = AskForFuture(&question, &answer);
- theErr = AskForFuture(&question2, &answer2);
-
- // Block until the answers become real.
-
- BlockUntilReal(&answer);
- BlockUntilReal(&answer2);
-
- // Dispose of the answers and the questions.
-
- theErr = AEDisposeDesc(&answer);
- theErr = AEDisposeDesc(&answer2);
- theErr = AEDisposeDesc(&question);
- theErr = AEDisposeDesc(&question2);
- }
-
- // Dispose of the address descriptor now that the thread no longer needs it.
-
- theErr = AEDisposeDesc(&theAddressDesc);
- theErr = AEDisposeDesc(&theAddressDesc2);
-
- return noErr;
- }
-
- #pragma segment Main
-
-
- void SendSimpleAEvt(AEEventClass theAEEventClass, AEEventID theAEEventID)
- {
- AppleEvent myAppleEvent, reply;
-
- // Create the Apple Event.
- AECreateAppleEvent(theAEEventClass, theAEEventID, &gSelfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
- // Send the Apple Event.
- AESend(&myAppleEvent, &reply, kAENoReply, kAENormalPriority,
- kAEDefaultTimeout, nil, nil);
-
- AEDisposeDesc(&myAppleEvent); // Dispose of the Apple Event.
- }
-
-
- pascal void InitFuturesDemo(void)
- {
- gSelfPSN.highLongOfPSN = 0;
- gSelfPSN.lowLongOfPSN = kCurrentProcess; //* Use this instead of GetCurrentProcess *//
- AECreateDesc(typeProcessSerialNumber,(Ptr)&gSelfPSN,sizeof(ProcessSerialNumber),&gSelfAddress);
- gNullDesc.descriptorType = typeNull; // Initialize the global null descriptor record.
- gNullDesc.dataHandle = nil;
-
- // Initialize the futures package
-
- InitFutures();
-
- // Install a handler for the ping messages in AppleEvents, so that when we receive these events, this routine will be called
-
- #if 0
- AEInstallEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0, false);
- #else
- AEInstallThreadedEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0,
- kCreateIfNeeded+kFPUNotNeeded, 0);
- #endif
- AEInstallThreadedEventHandler(kSillyEventClass, kPing1Event, NewAEEventHandlerProc(HandlePing1), 0,
- kCreateIfNeeded+kFPUNotNeeded, 0);
- AEInstallThreadedEventHandler(kSillyEventClass, kPing2Event, NewAEEventHandlerProc(HandlePing2), 0,
- kCreateIfNeeded+kFPUNotNeeded, 0);
-
- }
-
-
- pascal void CleanupFuturesDemo(void)
- {
- AEDisposeDesc(&gSelfAddress); // Dispose of my self-addressed descriptor.
- }
-
-