1 /* NAME:
2 E3Main.c
3
4 DESCRIPTION:
5 Implementation of Quesa API calls.
6
7 COPYRIGHT:
8 Copyright (c) 1999-2005, Quesa Developers. All rights reserved.
9
10 For the current release of Quesa, please see:
11
12 <http://www.quesa.org/>
13
14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions
16 are met:
17
18 o Redistributions of source code must retain the above copyright
19 notice, this list of conditions and the following disclaimer.
20
21 o Redistributions in binary form must reproduce the above
22 copyright notice, this list of conditions and the following
23 disclaimer in the documentation and/or other materials provided
24 with the distribution.
25
26 o Neither the name of Quesa nor the names of its contributors
27 may be used to endorse or promote products derived from this
28 software without specific prior written permission.
29
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
36 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
37 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
38 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
39 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 ___________________________________________________________________________
42 */
43 //=============================================================================
44 // Include files
45 //-----------------------------------------------------------------------------
46 #include <new>
47
48 #include "E3Prefix.h"
49 #include "E3Version.h"
50 #include "E3View.h"
51 #include "E3Camera.h"
52 #include "E3Geometry.h"
53 #include "E3DrawContext.h"
54 #include "E3Renderer.h"
55 #include "E3Group.h"
56 #include "E3Set.h"
57 #include "E3Light.h"
58 #include "E3Style.h"
59 #include "E3String.h"
60 #include "E3Transform.h"
61 #include "E3Main.h"
62 #include "E3Memory.h"
63 #include "E3Storage.h"
64 #include "E3Pick.h"
65 #include "E3IO.h"
66 #include "E3Shader.h"
67 #include "E3Texture.h"
68 #include "E3CustomElements.h"
69 #include "E3IOFileFormat.h"
70 #include "E3StackCrawl.h"
71
72 #if QUESA_OS_MACINTOSH
73 // Viewer supported only on Carbon/Classic now
74 #include "E3Viewer.h"
75 #endif
76
77
78
79
80
81 //=============================================================================
82 // Internal types
83 //-----------------------------------------------------------------------------
84
85
86
87
88 //=============================================================================
89 // Internal functions
90 //-----------------------------------------------------------------------------
91 // E3ShapeInfo::E3ShapeInfo : Constructor for class info of root class.
92 //-----------------------------------------------------------------------------
93
E3ShapeInfo(TQ3XMetaHandler newClassMetaHandler,E3ClassInfo * newParent)94 E3ShapeInfo::E3ShapeInfo (
95 TQ3XMetaHandler newClassMetaHandler,
96 E3ClassInfo* newParent // nil for root class of course
97 )
98 : E3SharedInfo ( newClassMetaHandler, newParent )
99 {
100 // Fill in the method data of the class
101
102 // There are (currently) no new methods in shape class
103 } ;
104
105
106 //=============================================================================
107 // e3shape_new_class_info : Method to construct a class info record.
108 //-----------------------------------------------------------------------------
109 static E3ClassInfo*
e3shape_new_class_info(TQ3XMetaHandler newClassMetaHandler,E3ClassInfo * newParent)110 e3shape_new_class_info (
111 TQ3XMetaHandler newClassMetaHandler,
112 E3ClassInfo* newParent
113 )
114 {
115 return new ( std::nothrow ) E3ShapeInfo ( newClassMetaHandler, newParent ) ;
116 }
117
118
119
120
121
122 //=============================================================================
123 // e3shape_metahandler : Shape metahandler.
124 //-----------------------------------------------------------------------------
125 static TQ3XFunctionPointer
e3shape_metahandler(TQ3XMethodType methodType)126 e3shape_metahandler(TQ3XMethodType methodType)
127 { TQ3XFunctionPointer theMethod = NULL;
128
129
130
131 // Return our methods
132 switch (methodType) {
133 case kQ3XMethodTypeNewObjectClass:
134 theMethod = (TQ3XFunctionPointer) e3shape_new_class_info;
135 break;
136
137 }
138
139 return(theMethod);
140 }
141
142
143
144
145
146 //=============================================================================
147 // E3SharedInfo::E3SharedInfo : Constructor for class info of root class.
148 //-----------------------------------------------------------------------------
149 #pragma mark -
E3SharedInfo(TQ3XMetaHandler newClassMetaHandler,E3ClassInfo * newParent)150 E3SharedInfo::E3SharedInfo (
151 TQ3XMetaHandler newClassMetaHandler,
152 E3ClassInfo* newParent // nil for root class of course
153 )
154 : E3Root ( newClassMetaHandler, newParent )
155 {
156 // Fill in the method data of the class
157
158 // disposeMethod = (TQ3XObjectDisposeMethod) Find_Method ( kQ3XMethodTypeObjectDispose , kQ3True ) ;
159 // newMethod = (TQ3XObjectNewMethod) Find_Method ( kQ3XMethodTypeObjectNew , kQ3False ) ; // N.B. False, not inherited
160 // deleteMethod = (TQ3XObjectDeleteMethod) Find_Method ( kQ3XMethodTypeObjectDelete , kQ3False ) ; // N.B. False, not inherited
161 // duplicateMethod = (TQ3XObjectDuplicateMethod) Find_Method ( kQ3XMethodTypeObjectDuplicate , kQ3False ) ; // N.B. False, not inherited
162 } ;
163
164
165 //=============================================================================
166 // e3shared_new_class_info : Method to construct a class info record.
167 //-----------------------------------------------------------------------------
168 static E3ClassInfo*
e3shared_new_class_info(TQ3XMetaHandler newClassMetaHandler,E3ClassInfo * newParent)169 e3shared_new_class_info (
170 TQ3XMetaHandler newClassMetaHandler,
171 E3ClassInfo* newParent
172 )
173 {
174 return new ( std::nothrow ) E3SharedInfo ( newClassMetaHandler, newParent ) ;
175 }
176
177
178
179
180
181 //=============================================================================
182 // e3shared_new : Shared new method.
183 //-----------------------------------------------------------------------------
184 TQ3Status
e3shared_new(E3Shared * theObject,void * privateData,void * paramData)185 e3shared_new ( E3Shared* theObject, void *privateData, void *paramData )
186 {
187 #pragma unused(privateData)
188 #pragma unused(paramData)
189
190
191
192 // Initialise our instance data
193 theObject->refCount = 1 ;
194 theObject->editIndex = 1 ;
195
196 return kQ3Success ;
197 }
198
199
200
201
202
203 //=============================================================================
204 // e3shared_dispose : Shared dispose method.
205 //-----------------------------------------------------------------------------
206 void
e3shared_dispose(E3Shared * theObject)207 e3shared_dispose ( E3Shared* theObject )
208 {
209 // Find the instance data
210 if ( theObject == NULL )
211 return ;
212
213
214
215 // Decrement the reference count
216 Q3_ASSERT(theObject->refCount >= 1);
217 theObject->refCount--;
218
219
220
221 // If the reference count falls to 0, dispose of the object
222 if ( theObject->refCount == 0 )
223 theObject->DestroyInstance () ;
224 }
225
226
227
228
229
230 //=============================================================================
231 // e3shared_duplicate : Shared duplicate method.
232 //-----------------------------------------------------------------------------
233 TQ3Status
e3shared_duplicate(TQ3Object fromObject,const void * fromPrivateData,TQ3Object toObject,void * toPrivateData)234 e3shared_duplicate(TQ3Object fromObject, const void *fromPrivateData,
235 TQ3Object toObject, void *toPrivateData)
236 { E3Shared *instanceData = (E3Shared *) toObject ;
237 #pragma unused(fromObject)
238 #pragma unused(toPrivateData)
239
240
241
242 // Validate our parameters
243 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromObject), kQ3Failure);
244 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromPrivateData), kQ3Failure);
245 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toObject), kQ3Failure);
246 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toPrivateData), kQ3Failure);
247
248
249
250 // Initialise the instance data of the new object
251 instanceData->refCount = 1;
252 instanceData->editIndex = 1;
253
254 return(kQ3Success);
255 }
256
257
258
259
260
261 //=============================================================================
262 // e3shared_write : Default write method.
263 //-----------------------------------------------------------------------------
264 static TQ3Status
e3shared_write(TQ3ViewObject theView,TQ3ObjectType objectType,TQ3Object theObject,const void * objectData)265 e3shared_write ( TQ3ViewObject theView, TQ3ObjectType objectType, TQ3Object theObject, const void *objectData )
266 {
267 // Submit the object
268 return E3FileFormat_Method_SubmitObject ( theView, theObject, objectType, objectData ) ;
269 }
270
271
272
273
274
275 //=============================================================================
276 // e3shared_metahandler : Shared metahandler.
277 //-----------------------------------------------------------------------------
278 static TQ3XFunctionPointer
e3shared_metahandler(TQ3XMethodType methodType)279 e3shared_metahandler(TQ3XMethodType methodType)
280 { TQ3XFunctionPointer theMethod = NULL;
281
282
283
284 // Return our methods
285 switch (methodType) {
286 case kQ3XMethodTypeNewObjectClass:
287 theMethod = (TQ3XFunctionPointer) e3shared_new_class_info;
288 break;
289
290 case kQ3XMethodTypeObjectNew:
291 theMethod = (TQ3XFunctionPointer) e3shared_new;
292 break;
293
294 case kQ3XMethodTypeObjectDispose:
295 theMethod = (TQ3XFunctionPointer) e3shared_dispose;
296 break;
297
298 case kQ3XMethodTypeObjectDuplicate:
299 theMethod = (TQ3XFunctionPointer) e3shared_duplicate;
300 break;
301
302 case kQ3XMethodTypeObjectSubmitWrite:
303 theMethod = (TQ3XFunctionPointer) e3shared_write;
304 break;
305 }
306
307 return(theMethod);
308 }
309
310
311
312
313
314 //=============================================================================
315 // E3Root::E3Root : Constructor for class info of root class.
316 //-----------------------------------------------------------------------------
317 #pragma mark -
318
E3Root(TQ3XMetaHandler newClassMetaHandler,E3ClassInfo * newParent)319 E3Root::E3Root (
320 TQ3XMetaHandler newClassMetaHandler,
321 E3ClassInfo* newParent // nil for root class of course
322 )
323 : E3ClassInfo ( newClassMetaHandler , newParent ) ,
324 // Fill in the method data of the class
325 disposeMethod ( (TQ3XObjectDisposeMethod) Find_Method ( kQ3XMethodTypeObjectDispose , kQ3True ) ) ,
326 newMethod ( (TQ3XObjectNewMethod) Find_Method ( kQ3XMethodTypeObjectNew , kQ3False ) ) , // N.B. False, not inherited
327 deleteMethod ( (TQ3XObjectDeleteMethod) Find_Method ( kQ3XMethodTypeObjectDelete , kQ3False ) ) , // N.B. False, not inherited
328 duplicateMethod ( (TQ3XObjectDuplicateMethod) Find_Method ( kQ3XMethodTypeObjectDuplicate , kQ3False ) ) , // N.B. False, not inherited
329 submitRenderMethod ( (TQ3XObjectSubmitMethod) Find_Method ( kQ3XMethodTypeObjectSubmitRender , kQ3True ) ) ,
330 submitPickMethod ( (TQ3XObjectSubmitMethod) Find_Method ( kQ3XMethodTypeObjectSubmitPick , kQ3True ) ) ,
331 submitBoundsMethod ( (TQ3XObjectSubmitMethod) Find_Method ( kQ3XMethodTypeObjectSubmitBounds , kQ3True ) ) ,
332 submitWriteMethod ( (TQ3XObjectSubmitMethod) Find_Method ( kQ3XMethodTypeObjectSubmitWrite , kQ3True ) )
333 {
334 if ( disposeMethod == NULL )
335 SetAbstract () ;
336 } ;
337
338
339 //=============================================================================
340 // e3root_new_class_info : Method to construct a class info record for the root class.
341 // This is necessary because applications can register their own object classes based on ours
342 //-----------------------------------------------------------------------------
343 static E3ClassInfo*
e3root_new_class_info(TQ3XMetaHandler newClassMetaHandler,E3ClassInfo * newParent)344 e3root_new_class_info (
345 TQ3XMetaHandler newClassMetaHandler,
346 E3ClassInfo* newParent // nil for root class of course
347 )
348 {
349 return new ( std::nothrow ) E3Root ( newClassMetaHandler, newParent ) ;
350 }
351
352
353
354
355
356 //=============================================================================
357 // e3root_new : Root object new method.
358 //-----------------------------------------------------------------------------
359
360 TQ3Status
e3root_new(TQ3Object theObject,void * privateData,void * paramData)361 e3root_new( TQ3Object theObject, void *privateData, void *paramData )
362 {
363 #pragma unused( paramData )
364 #pragma unused( privateData )
365
366
367 #if Q3_DEBUG
368 E3GlobalsPtr theGlobals = E3Globals_Get();
369 static TQ3Boolean sIsMakingListHead = kQ3False;
370
371 if (sIsMakingListHead == kQ3True)
372 {
373 theObject->next = theObject;
374 theObject->prev = theObject;
375 theObject->stackCrawl = NULL;
376 }
377 else
378 {
379 // initialize instance data
380 if (theGlobals->isLeakChecking == kQ3True)
381 {
382 // make sure the list has a header
383 if (theGlobals->listHead == NULL)
384 {
385 sIsMakingListHead = kQ3True; // prevent infinite recursion
386 theGlobals->listHead = E3ClassTree::CreateInstance ( kQ3ObjectTypeRoot,
387 kQ3False, NULL ) ;
388 sIsMakingListHead = kQ3False;
389 Q3_REQUIRE_OR_RESULT( theGlobals->listHead != NULL, kQ3Failure );
390 }
391 Q3_ASSERT( theGlobals->listHead->GetClass ()->GetType () == kQ3ObjectTypeRoot ) ;
392
393 // insert the new node between the list header and last normal node
394 theObject->next = theGlobals->listHead;
395 theObject->prev = PREVLINK( theGlobals->listHead );
396 NEXTLINK( PREVLINK( theGlobals->listHead ) ) = theObject;
397 PREVLINK( theGlobals->listHead ) = theObject;
398
399 // Record a stack crawl if possible
400 theObject->stackCrawl = E3StackCrawl_New();
401 }
402 else
403 {
404 theObject->next = NULL;
405 theObject->prev = NULL;
406 theObject->stackCrawl = NULL;
407 }
408 }
409 #endif
410
411 theObject->theSet = NULL;
412
413 return kQ3Success;
414 }
415
416
417
418
419
420 //=============================================================================
421 // e3root_duplicate : Root object duplicate method.
422 //-----------------------------------------------------------------------------
423 TQ3Status
e3root_duplicate(TQ3Object fromObject,const void * fromPrivateData,TQ3Object toObject,void * toPrivateData)424 e3root_duplicate(TQ3Object fromObject, const void *fromPrivateData,
425 TQ3Object toObject, void *toPrivateData)
426 {
427 #pragma unused( fromObject, fromPrivateData )
428 TQ3Status q3status;
429
430 q3status = e3root_new( toObject, toPrivateData, NULL );
431
432 if (q3status == kQ3Success)
433 {
434 OpaqueTQ3Object* fromInstanceData = (OpaqueTQ3Object*) fromPrivateData;
435 OpaqueTQ3Object* toInstanceData = (OpaqueTQ3Object*) toPrivateData;
436
437
438 if (fromInstanceData->theSet != NULL)
439 {
440 toInstanceData->theSet = Q3Object_Duplicate( fromInstanceData->theSet );
441 if (toInstanceData->theSet == NULL)
442 {
443 q3status = kQ3Failure;
444 }
445 }
446 }
447
448 return q3status;
449 }
450
451
452
453
454
455 //=============================================================================
456 // e3root_delete : Root delete method.
457 //-----------------------------------------------------------------------------
458 void
e3root_delete(TQ3Object theObject,void * privateData)459 e3root_delete( TQ3Object theObject, void *privateData )
460 {
461 OpaqueTQ3Object *instanceData = (OpaqueTQ3Object *) privateData;
462
463 Q3_ASSERT(privateData == theObject);
464 // Q3_ASSERT(privateData == theObject->FindLeafInstanceData () ) ;
465
466 Q3Object_CleanDispose( &instanceData->theSet );
467
468 #if Q3_DEBUG
469 if ( instanceData->prev != NULL )
470 {
471 NEXTLINK( instanceData->prev ) = instanceData->next;
472 PREVLINK( instanceData->next ) = instanceData->prev;
473 }
474
475 instanceData->prev = NULL;
476 instanceData->next = NULL;
477
478 E3StackCrawl_Dispose( instanceData->stackCrawl );
479 #endif
480 }
481
482
483
484
485
486 //=============================================================================
487 // e3root_dispose : Root object dispose method.
488 //-----------------------------------------------------------------------------
489 static void
e3root_dispose(TQ3Object theObject)490 e3root_dispose(TQ3Object theObject)
491 {
492 // Dispose of the object
493 theObject->DestroyInstance () ;
494 }
495
496
497
498
499
500 //=============================================================================
501 // e3root_metahandler : Root object metahandler.
502 //-----------------------------------------------------------------------------
503 static TQ3XFunctionPointer
e3root_metahandler(TQ3XMethodType methodType)504 e3root_metahandler(TQ3XMethodType methodType)
505 { TQ3XFunctionPointer theMethod = NULL;
506
507
508
509 // Return our methods
510 switch (methodType) {
511 case kQ3XMethodTypeObjectClassVersion:
512 theMethod = (TQ3XFunctionPointer) kQ3PackedVersion;
513 break;
514
515 case kQ3XMethodTypeNewObjectClass:
516 theMethod = (TQ3XFunctionPointer) e3root_new_class_info;
517 break;
518
519 case kQ3XMethodTypeObjectDispose:
520 theMethod = (TQ3XFunctionPointer) e3root_dispose;
521 break;
522
523 case kQ3XMethodTypeObjectNew:
524 theMethod = (TQ3XFunctionPointer) e3root_new;
525 break;
526
527 case kQ3XMethodTypeObjectDelete:
528 theMethod = (TQ3XFunctionPointer) e3root_delete;
529 break;
530
531 case kQ3XMethodTypeObjectDuplicate:
532 theMethod = (TQ3XFunctionPointer) e3root_duplicate;
533 break;
534 }
535
536 return(theMethod);
537 }
538
539
540
541
542
543 //=============================================================================
544 // e3main_registercoreclasses : Register the core object classes.
545 //-----------------------------------------------------------------------------
546 #pragma mark -
547 static TQ3Status
e3main_registercoreclasses(void)548 e3main_registercoreclasses(void)
549 {
550 // Register the classes
551 TQ3Status qd3dStatus = E3ClassTree::RegisterClass (
552 kQ3ObjectTypeQuesa,
553 OpaqueTQ3Object::eClassType,
554 kQ3ClassNameRoot,
555 e3root_metahandler,
556 sizeof ( OpaqueTQ3Object )
557 );
558
559 if (qd3dStatus == kQ3Success)
560 qd3dStatus = Q3_REGISTER_CLASS ( kQ3ClassNameShared,
561 e3shared_metahandler,
562 E3Shared ) ;
563
564 if (qd3dStatus == kQ3Success)
565 qd3dStatus = Q3_REGISTER_CLASS ( kQ3ClassNameShape,
566 e3shape_metahandler,
567 E3Shape ) ;
568
569 return qd3dStatus ;
570 }
571
572
573
574
575 //=============================================================================
576 // e3main_unregistercoreclasses : Unregister the core object classes.
577 //-----------------------------------------------------------------------------
578 static TQ3Status
e3main_unregistercoreclasses(void)579 e3main_unregistercoreclasses(void)
580 {
581 // Unregister the classes. Unregistering the root class will
582 // unregister everything else anchored underneath it.
583 return E3ClassTree::UnregisterClass ( kQ3ObjectTypeRoot, kQ3True ) ;
584 }
585
586
587
588
589
590 //=============================================================================
591 // Public functions
592 //-----------------------------------------------------------------------------
593 // E3Initialize : Initialise Quesa.
594 //-----------------------------------------------------------------------------
595 #pragma mark -
596 TQ3Status
E3Initialize(void)597 E3Initialize(void)
598 { E3GlobalsPtr theGlobals = E3Globals_Get();
599 TQ3Status qd3dStatus = kQ3Success;
600
601
602 // If we've not initialised Quesa yet, do so now
603 if (!theGlobals->systemInitialised)
604 {
605 // Initialise the platform
606 qd3dStatus = E3System_Initialise();
607
608
609
610 // Initialise Quesa
611 if (qd3dStatus == kQ3Success)
612 qd3dStatus = e3main_registercoreclasses();
613
614 if (qd3dStatus == kQ3Success)
615 qd3dStatus = E3Memory_RegisterClass();
616
617 if (qd3dStatus == kQ3Success)
618 qd3dStatus = E3String_RegisterClass();
619
620 if (qd3dStatus == kQ3Success)
621 qd3dStatus = E3Transform_RegisterClass();
622
623 if (qd3dStatus == kQ3Success)
624 qd3dStatus = E3Group_RegisterClass();
625
626 if (qd3dStatus == kQ3Success)
627 qd3dStatus = E3Set_RegisterClass();
628
629 if (qd3dStatus == kQ3Success)
630 qd3dStatus = E3Light_RegisterClass();
631
632 if (qd3dStatus == kQ3Success)
633 qd3dStatus = E3Style_RegisterClass();
634
635 if (qd3dStatus == kQ3Success)
636 qd3dStatus = E3View_RegisterClass();
637
638 if (qd3dStatus == kQ3Success)
639 qd3dStatus = E3DrawContext_RegisterClass();
640
641 if (qd3dStatus == kQ3Success)
642 qd3dStatus = E3Camera::RegisterClass();
643
644 if (qd3dStatus == kQ3Success)
645 qd3dStatus = E3Geometry_RegisterClass();
646
647 if (qd3dStatus == kQ3Success)
648 qd3dStatus = E3Shader_RegisterClass();
649
650 if (qd3dStatus == kQ3Success)
651 qd3dStatus = E3Texture_RegisterClass();
652
653 if (qd3dStatus == kQ3Success)
654 qd3dStatus = E3Renderer_RegisterClass();
655
656 if (qd3dStatus == kQ3Success)
657 qd3dStatus = E3Storage_RegisterClass();
658
659 if (qd3dStatus == kQ3Success)
660 qd3dStatus = E3File_RegisterClass();
661
662 if (qd3dStatus == kQ3Success)
663 qd3dStatus = E3Pick_RegisterClass();
664
665 if (qd3dStatus == kQ3Success)
666 qd3dStatus = E3CustomElements_RegisterClass();
667
668 #if QUESA_OS_MACINTOSH
669 // Viewer supported only on Carbon/Classic
670 if (qd3dStatus == kQ3Success)
671 qd3dStatus = E3Viewer_RegisterClass();
672 #endif
673
674
675
676 // Load our plug-ins
677 if (qd3dStatus == kQ3Success)
678 E3System_LoadPlugins();
679
680
681
682 // Set our flag
683 if (qd3dStatus == kQ3Success)
684 theGlobals->systemInitialised = kQ3True;
685 }
686
687
688 // Or post a notice
689 else
690 E3ErrorManager_PostNotice(kQ3NoticeSystemAlreadyInitialized);
691
692
693
694 // If all went well, increment the reference count
695 if (qd3dStatus == kQ3Success)
696 theGlobals->systemRefCount++;
697
698 return(qd3dStatus);
699 }
700
701
702
703
704
705 //=============================================================================
706 // E3Exit : Terminate Quesa.
707 //-----------------------------------------------------------------------------
708 TQ3Status
E3Exit(void)709 E3Exit(void)
710 { E3GlobalsPtr theGlobals = E3Globals_Get();
711 TQ3Status qd3dStatus;
712
713
714
715 // Make sure we've been initialised
716 if (!theGlobals->systemInitialised)
717 return(kQ3Failure);
718
719
720
721 // Decrement the instance count
722 Q3_ASSERT(theGlobals->systemRefCount > 0);
723 theGlobals->systemRefCount--;
724
725
726
727 // If this was the last instance, terminate Quesa
728 if (theGlobals->systemRefCount == 0)
729 {
730 // Dump some stats
731 #if QUESA_DUMP_STATS_ON_EXIT
732 E3ClassTree::Dump () ;
733 #endif
734
735 #if QUESA_ALLOW_QD3D_EXTENSIONS && Q3_DEBUG
736 if ( Q3Memory_IsRecording() && (Q3Memory_CountRecords() > 0) )
737 {
738 E3ErrorManager_PostError( kQ3ErrorMemoryLeak, kQ3False );
739 Q3Memory_DumpRecording( "Quesa-leaks.txt", "Q3Exit" );
740 Q3Memory_ForgetRecording();
741 }
742 #endif
743
744
745
746 // Reset leak-checking globals to initial state
747 #if Q3_DEBUG
748 Q3Object_CleanDispose(&theGlobals->listHead );
749 theGlobals->isLeakChecking = kQ3False;
750 #endif
751
752
753
754 // Unload our plug-ins
755 E3System_UnloadPlugins();
756
757
758
759 // Terminate Quesa
760 #if QUESA_OS_MACINTOSH
761 // Viewer supported only on Carbon/Classic
762 qd3dStatus = E3Viewer_UnregisterClass();
763 #endif
764 qd3dStatus = E3CustomElements_UnregisterClass();
765 qd3dStatus = E3Pick_UnregisterClass();
766 qd3dStatus = E3File_UnregisterClass();
767 qd3dStatus = E3Storage_UnregisterClass();
768 qd3dStatus = E3Renderer_UnregisterClass();
769 qd3dStatus = E3Texture_UnregisterClass();
770 qd3dStatus = E3Shader_UnregisterClass();
771 qd3dStatus = E3Geometry_UnregisterClass();
772 qd3dStatus = E3Camera::UnregisterClass();
773 qd3dStatus = E3DrawContext_UnregisterClass();
774 qd3dStatus = E3View_UnregisterClass();
775 qd3dStatus = E3Style_UnregisterClass();
776 qd3dStatus = E3Light_UnregisterClass();
777 qd3dStatus = E3Set_UnregisterClass();
778 qd3dStatus = E3Group_UnregisterClass();
779 qd3dStatus = E3Transform_UnregisterClass();
780 qd3dStatus = E3String_UnregisterClass();
781 qd3dStatus = E3Memory_UnregisterClass();
782 qd3dStatus = e3main_unregistercoreclasses();
783 E3ClassTree::Destroy () ;
784
785
786
787 // Terminate the platform
788 E3System_Terminate();
789
790
791
792 // Set our flag
793 theGlobals->systemInitialised = kQ3False;
794 }
795
796 return(kQ3Success);
797 }
798
799
800
801
802
803 //=============================================================================
804 // E3IsInitialized : Test to see if Quesa has been initialised.
805 //-----------------------------------------------------------------------------
806 TQ3Boolean
E3IsInitialized(void)807 E3IsInitialized(void)
808 { E3GlobalsPtr theGlobals = E3Globals_Get();
809
810
811
812 // Return as we've initialised Quesa
813 return(theGlobals->systemInitialised);
814 }
815
816
817
818
819
820 //=============================================================================
821 // E3GetVersion : Return the build version.
822 //-----------------------------------------------------------------------------
823 // Note : kQ3MajorVersion and kQ3MinorVersion are each in BCD format.
824 // For example, 12 is represented as 0x12.
825 //
826 // May be called outside of a Q3Initialize/Q3Exit block.
827 //-----------------------------------------------------------------------------
828 TQ3Status
E3GetVersion(TQ3Uns32 * majorRevision,TQ3Uns32 * minorRevision)829 E3GetVersion(TQ3Uns32 *majorRevision, TQ3Uns32 *minorRevision)
830 {
831
832
833 // Return the build version
834 *majorRevision = 10 * (kQ3MajorVersion >> 4) + (kQ3MajorVersion & 0x0f);
835 if (kQ3MinorVersion & 0x0f)
836 *minorRevision = 10 * (kQ3MinorVersion >> 4) + (kQ3MinorVersion & 0x0f);
837 else // single-digit minor version
838 *minorRevision = (kQ3MinorVersion >> 4);
839
840 return(kQ3Success);
841 }
842
843
844
845
846
847 //=============================================================================
848 // E3GetReleaseVersion : Return the build version in 'vers' format.
849 //-----------------------------------------------------------------------------
850 // Note : We return the version number in the format of the first four
851 // bytes of a 'vers' resource. For example, "1.23a56" is
852 // represented as 0x01234056.
853 //
854 // For more information, see the description of the 'vers'
855 // resource in "Inside Macintosh: Macintosh Toolbox Essential",
856 // p. 7-69.
857 //
858 // May be called outside of a Q3Initialize/Q3Exit block.
859 //-----------------------------------------------------------------------------
860 TQ3Status
E3GetReleaseVersion(TQ3Uns32 * releaseRevision)861 E3GetReleaseVersion(TQ3Uns32 *releaseRevision)
862 {
863
864
865 // Return the release version
866 *releaseRevision = kQ3PackedVersion;
867
868 return(kQ3Success);
869 }
870
871
872
873
874
875 //=============================================================================
876 // E3ObjectHierarchy_GetTypeFromString : Find the type for a class.
877 //-----------------------------------------------------------------------------
878 // Note : Given a class name, returns the type of the class.
879 //-----------------------------------------------------------------------------
880 #pragma mark -
881 TQ3Status
E3ObjectHierarchy_GetTypeFromString(const TQ3ObjectClassNameString objectClassString,TQ3ObjectType * objectClassType)882 E3ObjectHierarchy_GetTypeFromString(const TQ3ObjectClassNameString objectClassString, TQ3ObjectType *objectClassType)
883 {
884 // Initialise a return value
885 *objectClassType = kQ3ObjectTypeInvalid ;
886
887
888
889 // Find the class
890 E3ClassInfoPtr theClass = E3ClassTree::GetClass ( objectClassString ) ;
891 if ( theClass == NULL )
892 return kQ3Failure ;
893
894
895
896 // Return the type
897 *objectClassType = theClass->GetType () ;
898 return kQ3Success ;
899 }
900
901
902
903
904
905 //=============================================================================
906 // E3ObjectHierarchy_GetStringFromType : Find the name for a class.
907 //-----------------------------------------------------------------------------
908 // Note : Given a class type, returns the name of the class.
909 //-----------------------------------------------------------------------------
910 TQ3Status
E3ObjectHierarchy_GetStringFromType(TQ3ObjectType objectClassType,TQ3ObjectClassNameString objectClassString)911 E3ObjectHierarchy_GetStringFromType(TQ3ObjectType objectClassType, TQ3ObjectClassNameString objectClassString)
912 {
913 // Initialise a return value
914 strcpy ( objectClassString, "" ) ;
915
916
917
918 // Find the class
919 E3ClassInfoPtr theClass = E3ClassTree::GetClass ( objectClassType ) ;
920 if ( theClass == NULL )
921 return kQ3Failure ;
922
923
924
925 // Return the name
926 strcpy ( objectClassString, theClass->GetName () ) ;
927 return kQ3Success ;
928 }
929
930
931
932
933
934 //=============================================================================
935 // E3ObjectHierarchy_IsTypeRegistered : Test if a class is registered.
936 //-----------------------------------------------------------------------------
937 TQ3Boolean
E3ObjectHierarchy_IsTypeRegistered(TQ3ObjectType objectClassType)938 E3ObjectHierarchy_IsTypeRegistered(TQ3ObjectType objectClassType)
939 {
940 // Find the class
941 E3ClassInfoPtr theClass = E3ClassTree::GetClass ( objectClassType ) ;
942
943 return theClass != NULL ? kQ3True : kQ3False ;
944 }
945
946
947
948
949
950 //=============================================================================
951 // E3ObjectHierarchy_IsNameRegistered : Test if a class is registered.
952 //-----------------------------------------------------------------------------
953 TQ3Boolean
E3ObjectHierarchy_IsNameRegistered(const char * objectClassName)954 E3ObjectHierarchy_IsNameRegistered(const char *objectClassName)
955 {
956 // Find the class
957 E3ClassInfoPtr theClass = E3ClassTree::GetClass ( objectClassName ) ;
958
959 return theClass != NULL ? kQ3True : kQ3False ;
960 }
961
962
963
964
965
966 //=============================================================================
967 // E3ObjectHierarchy_GetSubClassData : Get the sub-classes of a class.
968 //-----------------------------------------------------------------------------
969 // Note : Fills in subClassData with the number and class types of all of
970 // the subclasses immediately below the specified class.
971 //-----------------------------------------------------------------------------
972 TQ3Status
E3ObjectHierarchy_GetSubClassData(TQ3ObjectType objectClassType,TQ3SubClassData * subClassData)973 E3ObjectHierarchy_GetSubClassData(TQ3ObjectType objectClassType, TQ3SubClassData *subClassData)
974 {
975 // Initialise a return value
976 subClassData->numClasses = 0;
977 subClassData->classTypes = NULL;
978
979
980
981 // Find the class
982 E3ClassInfoPtr theClass = E3ClassTree::GetClass ( objectClassType ) ;
983 if ( theClass == NULL )
984 return kQ3Failure ;
985
986
987
988 // Allocate the array for the child classes
989 Q3Memory_Clear(subClassData, sizeof(TQ3SubClassData));
990
991 TQ3Uns32 numChildren = theClass->GetNumChildren () ;
992 if (numChildren != 0)
993 {
994 subClassData->classTypes = (TQ3ObjectType *) Q3Memory_Allocate(sizeof(TQ3ObjectType) * numChildren);
995 if (subClassData->classTypes == NULL)
996 return(kQ3Failure);
997
998 subClassData->numClasses = numChildren;
999 }
1000
1001
1002
1003 // Collect the child classes
1004 for ( TQ3Uns32 n = 0 ; n < numChildren ; ++n )
1005 {
1006 // Get the child
1007 E3ClassInfoPtr theChild = theClass->GetChild ( n ) ;
1008 Q3_ASSERT_VALID_PTR(theChild);
1009
1010
1011 // Grab the type
1012 subClassData->classTypes [ n ] = theChild->GetType () ;
1013 }
1014
1015 return kQ3Success ;
1016 }
1017
1018
1019
1020
1021
1022 //=============================================================================
1023 // E3ObjectHierarchy_EmptySubClassData : Dispose of the sub-class data.
1024 //-----------------------------------------------------------------------------
1025 TQ3Status
E3ObjectHierarchy_EmptySubClassData(TQ3SubClassData * subClassData)1026 E3ObjectHierarchy_EmptySubClassData(TQ3SubClassData *subClassData)
1027 {
1028
1029
1030 // Dispose of the data
1031 Q3Memory_Free(&subClassData->classTypes);
1032
1033
1034
1035 // Reset the structure
1036 subClassData->numClasses = 0;
1037 subClassData->classTypes = NULL;
1038
1039 return(kQ3Success);
1040 }
1041
1042
1043
1044
1045
1046 //=============================================================================
1047 // E3Object_Dispose : Dispose of an object.
1048 //-----------------------------------------------------------------------------
1049 #pragma mark -
1050 TQ3Status
Dispose(void)1051 OpaqueTQ3Object::Dispose ( void )
1052 {
1053
1054 // Dispose of the object
1055 ( (E3Root*) GetClass () )->disposeMethod ( this ) ;
1056
1057 return kQ3Success ;
1058 }
1059
1060
1061
1062
1063
1064 //=============================================================================
1065 // E3Object_CleanDispose : Dispose of an object.
1066 //-----------------------------------------------------------------------------
1067 TQ3Status
E3Object_CleanDispose(TQ3Object * theObject)1068 E3Object_CleanDispose(TQ3Object *theObject)
1069 { TQ3Status qd3dStatus;
1070
1071
1072
1073 // If we have an object, dispose of it and clear the pointer
1074 if (theObject != NULL && *theObject != NULL)
1075 {
1076 qd3dStatus = Q3Object_Dispose(*theObject);
1077 *theObject = NULL;
1078 }
1079 else
1080 qd3dStatus = kQ3Success;
1081
1082 return(qd3dStatus);
1083 }
1084
1085
1086
1087
1088
1089 //=============================================================================
1090 // E3Object_Duplicate : Duplicate an object.
1091 //-----------------------------------------------------------------------------
1092 // Note : Draw context and view objects can not be duplicated, since
1093 // these refer to resources created by the application that belong
1094 // to the window system.
1095 //
1096 // If the new object is a shared object, its reference count is
1097 // set to 1.
1098 //-----------------------------------------------------------------------------
1099 TQ3Object
E3Object_Duplicate(TQ3Object theObject)1100 E3Object_Duplicate(TQ3Object theObject)
1101 {
1102 // Reject draw context and view objects
1103 //
1104 // Note - the current Quesa implementation does not support
1105 // duplicating file storage objects, as opposed to memory storage objects.
1106 //
1107 // When this is functionality is added, the kQ3SharedTypeStorage
1108 // test should be removed.
1109 //
1110 // If this causes your app problems, please contact Jose Cruanyes
1111 // or James Walker to discuss a fix.
1112 if ( E3View_IsOfMyClass ( theObject ) // Can't access E3View here as it isn't in a header file (yet)
1113 || Q3_OBJECT_IS_CLASS ( theObject, E3DrawContext )
1114 || ( Q3_OBJECT_IS_CLASS ( theObject, E3Storage ) && ! Q3_OBJECT_IS_CLASS ( theObject, E3MemoryStorage ) ) )
1115 {
1116 E3ErrorManager_PostError(kQ3ErrorInvalidObjectType, kQ3False);
1117 return(NULL);
1118 }
1119
1120
1121
1122 // Duplicate the object
1123 return theObject->DuplicateInstance () ;
1124 }
1125
1126
1127
1128
1129
1130 //=============================================================================
1131 // E3Object_Submit : Submit an object to a view.
1132 //-----------------------------------------------------------------------------
1133 TQ3Status
E3Object_Submit(TQ3Object theObject,TQ3ViewObject theView)1134 E3Object_Submit(TQ3Object theObject, TQ3ViewObject theView)
1135 { TQ3Status qd3dStatus;
1136
1137
1138
1139 // Submit the object
1140 qd3dStatus = E3View_SubmitRetained(theView, theObject);
1141 return(qd3dStatus);
1142 }
1143
1144
1145
1146
1147
1148 //=============================================================================
1149 // E3Object_IsDrawable : Determine if an object is drawable.
1150 //-----------------------------------------------------------------------------
1151 // Note : There is no is-drawable method as such, instead we interpret
1152 // the 'address' of the method as a TQ3Boolean.
1153 //-----------------------------------------------------------------------------
1154 TQ3Boolean
E3Object_IsDrawable(TQ3Object theObject)1155 E3Object_IsDrawable(TQ3Object theObject)
1156 {
1157 // Get the 'method'
1158 TQ3Boolean isDrawable = (TQ3Boolean) ( NULL != theObject->GetClass ()->GetMethod (
1159 kQ3XMethodTypeObjectIsDrawable ) ) ;
1160
1161 return isDrawable ;
1162 }
1163
1164
1165
1166
1167
1168 //=============================================================================
1169 // E3Object_IsWritable : Determine if an object is writeable.
1170 //-----------------------------------------------------------------------------
1171 // Note : We return as the object has a kQ3XMethodTypeObjectWrite method.
1172 //-----------------------------------------------------------------------------
1173 TQ3Boolean
E3Object_IsWritable(TQ3Object theObject,TQ3FileObject theFile)1174 E3Object_IsWritable(TQ3Object theObject, TQ3FileObject theFile)
1175 {
1176 #pragma unused(theFile)
1177
1178
1179
1180 // Get the method
1181 TQ3XObjectWriteMethod writeMethod = (TQ3XObjectWriteMethod) theObject->GetClass ()->GetMethod ( kQ3XMethodTypeObjectWrite ) ;
1182
1183
1184
1185 // Return as the method exists or not
1186 return (TQ3Boolean) ( writeMethod != NULL ) ;
1187 }
1188
1189
1190
1191
1192
1193 //=============================================================================
1194 // E3Object_GetType : Get the fundamental type of an object.
1195 //-----------------------------------------------------------------------------
1196 // Note : To determine the fundamental type, we walk up the object's
1197 // parents until we come to the level below the root object.
1198 //
1199 // NB - we can not filter the result, since some undocumented QD3D
1200 // objects are registered off the root object.
1201 //-----------------------------------------------------------------------------
1202 TQ3ObjectType
E3Object_GetType(TQ3Object theObject)1203 E3Object_GetType(TQ3Object theObject)
1204 {
1205 // Get the type of the object below the root object
1206 return theObject->GetObjectType ( kQ3ObjectTypeRoot ) ;
1207 }
1208
1209
1210
1211
1212
1213 //=============================================================================
1214 // E3Object_IsType : Is an object an instance of a particular type?
1215 //-----------------------------------------------------------------------------
1216 TQ3Boolean
E3Object_IsType(TQ3Object theObject,TQ3ObjectType theType)1217 E3Object_IsType(TQ3Object theObject, TQ3ObjectType theType)
1218 {
1219 // Return as the object is an instance of the type
1220 return theObject->GetClass ()->IsType ( theType ) ;
1221 }
1222
1223
1224
1225
1226
1227 //=============================================================================
1228 // E3Object_AddElement : Add an element to an object
1229 //-----------------------------------------------------------------------------
1230 TQ3Status
AddElement(TQ3ElementType theType,const void * theData)1231 OpaqueTQ3Object::AddElement ( TQ3ElementType theType, const void *theData )
1232 {
1233 // Translate public type to internal type for set elements
1234 if ( theType == kQ3ElementTypeSet )
1235 theType = kQ3ObjectTypeSetElement;
1236
1237
1238
1239 // If we've actually been passed a set, use it directly
1240 if ( Q3_OBJECT_IS_CLASS ( this, E3Set ) )
1241 return Q3Set_Add ( (TQ3SetObject) this, theType, theData ) ;
1242
1243 // otherwise use the set within the instance data
1244 if ( theSet == NULL )
1245 {
1246 theSet = Q3Set_New () ;
1247
1248 if ( theSet == NULL )
1249 return kQ3Failure ;
1250 }
1251
1252 TQ3Status qd3dStatus = Q3Set_Add ( theSet, theType, theData ) ;
1253
1254
1255 if ( ( qd3dStatus != kQ3Failure ) && Q3_OBJECT_IS_CLASS ( this, E3Shared ) )
1256 ( (E3Shared*) this )->Edited () ;
1257
1258 return qd3dStatus ;
1259 }
1260
1261
1262
1263
1264
1265 //=============================================================================
1266 // E3Object_GetElement : Get element data from an object.
1267 //-----------------------------------------------------------------------------
1268 TQ3Status
GetElement(TQ3ElementType theType,void * theData)1269 OpaqueTQ3Object::GetElement ( TQ3ElementType theType, void *theData )
1270 {
1271 // Translate public type to internal type for set elements
1272 if (theType == kQ3ElementTypeSet)
1273 theType = kQ3ObjectTypeSetElement;
1274
1275
1276
1277 // If we've actually been passed a set, use it directly
1278 if ( Q3_OBJECT_IS_CLASS ( this, E3Set ) )
1279 return Q3Set_Get ( (TQ3SetObject) this, theType, theData ) ;
1280
1281 // otherwise use the set within the instance data
1282
1283 if ( theSet == NULL )
1284 return kQ3Failure ;
1285
1286 return Q3Set_Get ( theSet, theType, (void*)theData ) ;
1287 }
1288
1289
1290
1291
1292
1293 //=============================================================================
1294 // E3Object_ContainsElement : Test whether an object contains an element.
1295 //-----------------------------------------------------------------------------
1296 TQ3Boolean
ContainsElement(TQ3ElementType theType)1297 OpaqueTQ3Object::ContainsElement ( TQ3ElementType theType )
1298 {
1299 // Translate public type to internal type for set elements
1300 if ( theType == kQ3ElementTypeSet )
1301 theType = kQ3ObjectTypeSetElement ;
1302
1303
1304
1305 // If we've actually been passed a set, use it directly
1306 if ( Q3_OBJECT_IS_CLASS ( this, E3Set ) )
1307 return Q3Set_Contains ( (TQ3SetObject) this, theType ) ;
1308
1309 // otherwise use the set within the instance data
1310
1311 if ( theSet != NULL )
1312 return Q3Set_Contains ( theSet, theType ) ;
1313
1314
1315
1316 return kQ3False ;
1317 }
1318
1319
1320
1321
1322
1323 //=============================================================================
1324 // E3Object_GetNextElementType : Get the next element type in an object.
1325 //-----------------------------------------------------------------------------
1326 TQ3Status
GetNextElementType(TQ3ElementType * theType)1327 OpaqueTQ3Object::GetNextElementType ( TQ3ElementType *theType )
1328 {
1329 TQ3Status qd3dStatus = kQ3Failure ;
1330
1331
1332
1333 // Translate public type to internal type for set elements
1334 if ( *theType == kQ3ElementTypeSet )
1335 *theType = kQ3ObjectTypeSetElement ;
1336
1337
1338
1339 // If we've actually been passed a set, use it directly
1340 if ( Q3_OBJECT_IS_CLASS ( this, E3Set ) )
1341 qd3dStatus = Q3Set_GetNextElementType ( (TQ3SetObject) this, theType ) ;
1342 else // otherwise use the set within the instance data
1343 {
1344 if ( theSet == NULL )
1345 {
1346 *theType = kQ3ElementTypeNone ;
1347 return kQ3Success ;
1348 }
1349
1350 qd3dStatus = Q3Set_GetNextElementType ( theSet, theType ) ;
1351 }
1352
1353
1354
1355 if ( *theType == kQ3ObjectTypeSetElement )
1356 *theType = kQ3ElementTypeSet ;
1357
1358
1359 return qd3dStatus ;
1360 }
1361
1362
1363
1364
1365
1366 //=============================================================================
1367 // E3Object_EmptyElements : Remove all elements from an object.
1368 //-----------------------------------------------------------------------------
1369 TQ3Status
EmptyElements(void)1370 OpaqueTQ3Object::EmptyElements ( void )
1371 {
1372 // If we've actually been passed a set, use it directly
1373 if ( Q3_OBJECT_IS_CLASS ( this, E3Set ) )
1374 return Q3Set_Empty ( (TQ3SetObject) this ) ;
1375
1376 // otherwise use the set within the instance data
1377 if ( theSet == NULL )
1378 return kQ3Success ;
1379
1380 TQ3Status qd3dStatus = Q3Set_Empty ( theSet ) ;
1381
1382
1383 if ( ( qd3dStatus != kQ3Failure ) && Q3_OBJECT_IS_CLASS ( this, E3Shared ) )
1384 ( (E3Shared*) this )->Edited () ;
1385
1386
1387 return qd3dStatus ;
1388 }
1389
1390
1391
1392
1393
1394 //=============================================================================
1395 // E3Object_ClearElement : Remove a specific type of element from an object.
1396 //-----------------------------------------------------------------------------
1397 TQ3Status
ClearElement(TQ3ElementType theType)1398 OpaqueTQ3Object::ClearElement ( TQ3ElementType theType )
1399 {
1400 // Translate public type to internal type for set elements
1401 if (theType == kQ3ElementTypeSet)
1402 theType = kQ3ObjectTypeSetElement;
1403
1404
1405
1406 // If we've actually been passed a set, use it directly
1407 if ( Q3_OBJECT_IS_CLASS ( this, E3Set ) )
1408 return Q3Set_Clear ( (TQ3SetObject) this, theType ) ;
1409
1410 // otherwise use the set within the instance data
1411 if ( theSet == NULL )
1412 return kQ3Success ;
1413
1414 TQ3Status qd3dStatus = Q3Set_Clear ( theSet, theType ) ;
1415
1416
1417 if ( ( qd3dStatus != kQ3Failure ) && Q3_OBJECT_IS_CLASS ( this, E3Shared ) )
1418 ( (E3Shared*) this )->Edited () ;
1419
1420
1421 return qd3dStatus ;
1422 }
1423
1424
1425
1426
1427
1428 //=============================================================================
1429 // E3Object_GetSet : Get the set of an object.
1430 //-----------------------------------------------------------------------------
1431 TQ3Status
GetSet(TQ3SetObject * set)1432 OpaqueTQ3Object::GetSet ( TQ3SetObject *set )
1433 {
1434 E3Shared_Acquire ( set, theSet ) ;
1435
1436 return kQ3Success ;
1437 }
1438
1439
1440
1441
1442
1443 //=============================================================================
1444 // E3Object_SetSet : Set the set of an object.
1445 //-----------------------------------------------------------------------------
1446 TQ3Status
SetSet(TQ3SetObject set)1447 OpaqueTQ3Object::SetSet ( TQ3SetObject set )
1448 {
1449 E3Shared_Replace ( &theSet, set ) ;
1450
1451 return kQ3Success ;
1452 }
1453
1454
1455
1456
1457
1458 //=============================================================================
1459 // E3Shared_IsOfMyClass : Check if object pointer is valid and of type shared
1460 //-----------------------------------------------------------------------------
1461 // Replaces Q3Object_IsType ( object, kQ3ObjectTypeShared )
1462 // but call is smaller and does not call E3System_Bottleneck
1463 // as this is (always?) done in the calling code as well
1464 //-----------------------------------------------------------------------------
1465 #pragma mark -
1466 TQ3Boolean
E3Shared_IsOfMyClass(TQ3Object object)1467 E3Shared_IsOfMyClass ( TQ3Object object )
1468 {
1469 if ( object == NULL )
1470 return kQ3False ;
1471
1472 if ( object->IsObjectValid () )
1473 return Q3_OBJECT_IS_CLASS ( object, E3Shared ) ;
1474
1475 return kQ3False ;
1476 }
1477
1478
1479
1480
1481
1482 //=============================================================================
1483 // E3Shared_GetType : Get the type of a shared object.
1484 //-----------------------------------------------------------------------------
1485 TQ3ObjectType
E3Shared_GetType(TQ3SharedObject sharedObject)1486 E3Shared_GetType(TQ3SharedObject sharedObject)
1487 {
1488 // Return the type
1489 return sharedObject->GetObjectType ( kQ3ObjectTypeShared ) ;
1490 }
1491
1492
1493
1494
1495
1496 //=============================================================================
1497 // E3Shared_GetReference : Get a reference to a shared object.
1498 //-----------------------------------------------------------------------------
1499 // Note : We increase the reference count of the shared object by 1.
1500 //
1501 // Note that other Quesa code assumes acquiring a new reference
1502 // to an object can not fail, provided the object is in fact a
1503 // shared object.
1504 //
1505 // If acquiring a new reference could ever fail, routines like
1506 // E3Shared_Replace will need to be updated.
1507 //-----------------------------------------------------------------------------
1508 E3Shared*
GetReference(void)1509 E3Shared::GetReference ( void )
1510 {
1511 // Increment the reference count and return the object. Note that we
1512 // return the object passed in: this is OK since we're not declared
1513 // to return a different object.
1514 refCount++;
1515 Q3_ASSERT(refCount >= 2);
1516
1517 return this ;
1518 }
1519
1520
1521
1522
1523
1524 //=============================================================================
1525 // E3Shared_IsReferenced : Is a reference shared?
1526 //-----------------------------------------------------------------------------
1527 // Note : We return kQ3True if there is more than one reference to the
1528 // object, and kQ3False if there is one reference to the object.
1529 //-----------------------------------------------------------------------------
1530 TQ3Boolean
IsReferenced(void)1531 E3Shared::IsReferenced ( void )
1532 {
1533 // Return as the reference count is greater than 1
1534 return ( (TQ3Boolean) ( refCount > 1 ) ) ;
1535 }
1536
1537
1538
1539
1540
1541 //=============================================================================
1542 // E3Shared_GetReferenceCount : Return the reference count.
1543 //-----------------------------------------------------------------------------
1544 TQ3Uns32
GetReferenceCount(void)1545 E3Shared::GetReferenceCount ( void )
1546 {
1547 // Return the reference count
1548 return refCount ;
1549 }
1550
1551
1552
1553
1554
1555 //=============================================================================
1556 // E3Shared_GetEditIndex : Return the edit index of a shared object.
1557 //-----------------------------------------------------------------------------
1558 TQ3Uns32
GetEditIndex(void)1559 E3Shared::GetEditIndex ( void )
1560 {
1561 // Return the edit index
1562 return editIndex ;
1563 }
1564
1565
1566
1567
1568
1569 //=============================================================================
1570 // E3Shared_Edited : Increase the edit index of an object.
1571 //-----------------------------------------------------------------------------
1572 TQ3Status
Edited(void)1573 E3Shared::Edited ( void )
1574 {
1575 // Increment the edit index
1576 ++editIndex ;
1577 return kQ3Success ;
1578 }
1579
1580
1581
1582
1583
1584 //=============================================================================
1585 // E3Shape_IsOfMyClass : Check if object pointer is valid and of type shape
1586 //-----------------------------------------------------------------------------
1587 // Replaces Q3Object_IsType ( object, kQ3SharedTypeShape )
1588 // but call is smaller and does not call E3System_Bottleneck
1589 // as this is (always?) done in the calling code as well
1590 //-----------------------------------------------------------------------------
1591 #pragma mark -
1592 TQ3Boolean
E3Shape_IsOfMyClass(TQ3Object object)1593 E3Shape_IsOfMyClass ( TQ3Object object )
1594 {
1595 if ( object == NULL )
1596 return kQ3False ;
1597
1598 if ( object->IsObjectValid () )
1599 return Q3_OBJECT_IS_CLASS ( object, E3Shape ) ;
1600
1601 return kQ3False ;
1602 }
1603
1604
1605
1606
1607
1608 //=============================================================================
1609 // E3Shape_GetType : Get the type of a shape object.
1610 //-----------------------------------------------------------------------------
1611 TQ3ObjectType
E3Shape_GetType(TQ3ShapeObject theShape)1612 E3Shape_GetType(TQ3ShapeObject theShape)
1613 {
1614 // Return the type
1615 return theShape->GetObjectType ( kQ3SharedTypeShape ) ;
1616 }
1617
1618
1619
1620
1621
1622 //=============================================================================
1623 // E3Shape_GetSet : Get the set for a shape.
1624 //-----------------------------------------------------------------------------
1625 TQ3Status
E3Shape_GetSet(TQ3ShapeObject theShape,TQ3SetObject * theSet)1626 E3Shape_GetSet(TQ3ShapeObject theShape, TQ3SetObject *theSet)
1627 {
1628 *theSet = NULL ;
1629 return theShape->GetElement ( kQ3ElementTypeSet, theSet ) ;
1630 }
1631
1632
1633
1634
1635
1636 //=============================================================================
1637 // E3Shape_SetSet : Set the set for a shape.
1638 //-----------------------------------------------------------------------------
1639 TQ3Status
E3Shape_SetSet(TQ3ShapeObject theShape,TQ3SetObject theSet)1640 E3Shape_SetSet(TQ3ShapeObject theShape, TQ3SetObject theSet)
1641 {
1642 if ( theSet == NULL )
1643 return theShape->ClearElement ( kQ3ElementTypeSet ) ;
1644
1645 return theShape->AddElement ( kQ3ElementTypeSet, &theSet ) ;
1646 }
1647
1648
1649
1650
1651
1652 //=============================================================================
1653 // E3Shape_SubmitElements : Submit custom elements of a shape.
1654 //-----------------------------------------------------------------------------
1655 // This will be called by E3FFW_3DMF_TraverseObject to submit
1656 // any custom elements that might be attached to the shape.
1657 //-----------------------------------------------------------------------------
1658 TQ3Status
SubmitElements(TQ3ViewObject inView)1659 OpaqueTQ3Object::SubmitElements ( TQ3ViewObject inView )
1660 {
1661 // Use the shape's set, if any.
1662 if ( theSet == NULL )
1663 return kQ3Success ;
1664
1665 return ( (E3Set*) theSet )->SubmitElements ( inView ) ;
1666 }
1667
1668
1669
1670
1671
1672 //=============================================================================
1673 // E3Bitmap_Empty : Dispose of the memory allocated for a bitmap.
1674 //-----------------------------------------------------------------------------
1675 #pragma mark -
1676 TQ3Status
E3Bitmap_Empty(TQ3Bitmap * theBitmap)1677 E3Bitmap_Empty(TQ3Bitmap *theBitmap)
1678 {
1679
1680
1681 // Dispose of the bitmap's image
1682 Q3Memory_Free(&theBitmap->image);
1683
1684 return(kQ3Success);
1685 }
1686
1687
1688
1689
1690
1691 //=============================================================================
1692 // E3Bitmap_GetImageSize : Get the amount of memory required for a bitmap.
1693 //-----------------------------------------------------------------------------
1694 TQ3Uns32
E3Bitmap_GetImageSize(TQ3Uns32 theWidth,TQ3Uns32 theHeight)1695 E3Bitmap_GetImageSize(TQ3Uns32 theWidth, TQ3Uns32 theHeight)
1696 { TQ3Uns32 imageSize;
1697
1698
1699
1700 // Bitmaps are 1 bit deep, so every 8 pixels requires 1 byte
1701 imageSize = ((theWidth - 1) / 8) + 1;
1702 imageSize *= theHeight;
1703
1704 return(imageSize);
1705 }
1706
1707
1708
1709
1710
1711 //=============================================================================
1712 // E3Bitmap_GetBit : Get a bit from a bitmap.
1713 //-----------------------------------------------------------------------------
1714 TQ3Boolean
E3Bitmap_GetBit(const TQ3Bitmap * theBitmap,TQ3Uns32 x,TQ3Uns32 y)1715 E3Bitmap_GetBit(const TQ3Bitmap *theBitmap, TQ3Uns32 x, TQ3Uns32 y)
1716 { TQ3Uns8 *bytePtr, theByte, bitShift;
1717 TQ3Boolean theState;
1718
1719
1720
1721 // Locate the byte we need
1722 bytePtr = theBitmap->image + (y * theBitmap->rowBytes);
1723 bytePtr += (x / 8);
1724 theByte = *bytePtr;
1725
1726
1727
1728 // Locate the bit we need
1729 bitShift = (TQ3Uns8) (x % 8);
1730 if (theBitmap->bitOrder == kQ3EndianBig)
1731 theState = ((theByte >> (7 - bitShift)) & 0x01) != 0 ? kQ3True : kQ3False;
1732 else
1733 theState = ((theByte >> ( bitShift)) & 0x01) != 0 ? kQ3True : kQ3False;
1734
1735 return(theState);
1736 }
1737
1738
1739
1740
1741
1742 //=============================================================================
1743 // E3Bitmap_SetBit : Set a bit within a bitmap.
1744 //-----------------------------------------------------------------------------
1745 TQ3Status
E3Bitmap_SetBit(TQ3Bitmap * theBitmap,TQ3Uns32 x,TQ3Uns32 y,TQ3Boolean theState)1746 E3Bitmap_SetBit(TQ3Bitmap *theBitmap, TQ3Uns32 x, TQ3Uns32 y, TQ3Boolean theState)
1747 { TQ3Uns8 *bytePtr, theByte, bitShift, byteMask;
1748
1749
1750
1751 // Locate the byte we need
1752 bytePtr = theBitmap->image + (y * theBitmap->rowBytes);
1753 bytePtr += (x / 8);
1754
1755
1756
1757 // Prepare the mask
1758 bitShift = (TQ3Uns8) (x % 8);
1759
1760 if (theBitmap->bitOrder == kQ3EndianBig)
1761 byteMask = (1 << (7 - bitShift));
1762 else
1763 byteMask = (1 << ( bitShift));
1764
1765
1766
1767 // Update the byte
1768 theByte = *bytePtr;
1769
1770 if (theState)
1771 theByte |= byteMask;
1772 else
1773 theByte &= ~byteMask;
1774
1775 *bytePtr = theByte;
1776
1777 return(kQ3Success);
1778 }
1779
1780
1781
1782
1783
1784
1785