2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 An object archiving system for SuperCollider.
27 #ifndef _PyrDeepCopier_
28 #define _PyrDeepCopier_
30 #include "PyrObject.h"
31 #include "SC_AllocPool.h"
33 #include "PyrKernel.h"
34 #include "PyrPrimitive.h"
35 #include "VMGlobals.h"
38 const int32 kDeepCopierObjectArrayInitialCapacity
= 32;
43 PyrDeepCopier(VMGlobals
*inG
)
44 : g(inG
), objectArray(initialObjectArray
), numObjects(0),
45 objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity
)
50 if (objectArrayCapacity
> kDeepCopierObjectArrayInitialCapacity
) {
51 g
->allocPool
->Free(objectArray
);
55 long doDeepCopy(PyrSlot
*objectSlot
)
60 if (IsObj(objectSlot
)) {
61 constructObjectArray(slotRawObject(objectSlot
));
62 for (int i
=0; i
<numObjects
; ++i
) {
63 fixSlots(objectArray
[i
]);
65 fixObjSlot(objectSlot
);
66 for (int i
=0; i
<numObjects
; ++i
) {
67 objectArray
[i
]->ClearMark();
71 } catch (std::exception
&ex
) {
80 void recurse(PyrObject
*obj
, int n
)
82 //post("->recurse %s %08X\n", obj->classptr->name.us->name, obj);
83 PyrSlot
*slot
= obj
->slots
;
84 for (int i
=0; i
<n
; ++i
, ++slot
) {
85 if (IsObj(slot
)) constructObjectArray(slotRawObject(slot
));
87 //post("<-recurse %s %08X\n", obj->classptr->name.us->name, obj);
90 void growObjectArray()
92 int32 newObjectArrayCapacity
= objectArrayCapacity
<< 1;
94 int32 newSize
= newObjectArrayCapacity
* sizeof(PyrObject
*);
95 PyrObject
** newArray
= (PyrObject
**)g
->allocPool
->Alloc(newSize
);
96 memcpy(newArray
, objectArray
, numObjects
* sizeof(PyrObject
*));
97 if (objectArrayCapacity
> kDeepCopierObjectArrayInitialCapacity
) {
98 g
->allocPool
->Free(objectArray
);
100 objectArrayCapacity
= newObjectArrayCapacity
;
101 objectArray
= newArray
;
104 void putSelf(PyrObject
*obj
)
107 obj
->scratch1
= numObjects
;
109 // expand array if needed
110 if (numObjects
>= objectArrayCapacity
) growObjectArray();
112 //post("putSelf %d %08X\n", numObjects, obj);
114 objectArray
[numObjects
++] = obj
;
117 void putCopy(PyrObject
*obj
)
120 obj
->scratch1
= numObjects
;
122 // expand array if needed
123 if (numObjects
+2 >= objectArrayCapacity
) growObjectArray();
125 // add a shallow copy to object array
126 PyrObject
*copy
= copyObject(g
->gc
, obj
, false);
129 //post("putCopy %d %08X\n", numObjects, copy);
132 objectArray
[numObjects
++] = copy
;
133 objectArray
[numObjects
++] = obj
;
136 void constructObjectArray(PyrObject
*obj
)
138 //post("->constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
139 if (!obj
->IsMarked()) {
140 if (isKindOf(obj
, class_class
)) {
142 } else if (isKindOf(obj
, class_process
)) {
144 } else if (isKindOf(obj
, s_interpreter
->u
.classobj
)) {
146 } else if (isKindOf(obj
, class_rawarray
)) {
148 } else if (isKindOf(obj
, class_array
)) {
150 recurse(obj
, obj
->size
);
151 } else if (isKindOf(obj
, class_func
)) {
153 } else if (isKindOf(obj
, class_method
)) {
155 } else if (isKindOf(obj
, class_thread
)) {
157 } else if (isKindOf(obj
, class_server_shm_interface
)) {
161 recurse(obj
, obj
->size
);
164 //post("<-constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
167 void fixObjSlot(PyrSlot
* slot
)
169 //post("fixObjSlot %s %08X %d %08X\n", slotRawObject(slot)->classptr->name.us->name, slotRawObject(slot), slot->uo->scratch1, objectArray[slot->uo->scratch1]);
170 SetRaw(slot
, objectArray
[slotRawObject(slot
)->scratch1
]);
173 void fixSlots(PyrObject
*obj
)
175 //post("fixSlots %s %08X %d\n", obj->classptr->name.us->name, obj, obj->IsMarked());
176 if (!obj
->IsMarked() && obj
->obj_format
<= obj_slot
) { // it is a copy
177 PyrSlot
*slot
= obj
->slots
;
178 for (int i
=0; i
<obj
->size
; ++i
, ++slot
) {
179 if (IsObj(slot
)) fixObjSlot(slot
);
186 PyrObject
**objectArray
;
188 int32 objectArrayCapacity
;
190 PyrObject
*initialObjectArray
[kDeepCopierObjectArrayInitialCapacity
];