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
, size_t n
)
82 //post("->recurse %s %08X\n", obj->classptr->name.us->name, obj);
83 PyrSlot
*slot
= obj
->slots
;
84 for (size_t i
=0; i
<n
; ++i
, ++slot
) {
86 constructObjectArray(slotRawObject(slot
));
88 //post("<-recurse %s %08X\n", obj->classptr->name.us->name, obj);
91 void growObjectArray()
93 int32 newObjectArrayCapacity
= objectArrayCapacity
<< 1;
95 int32 newSize
= newObjectArrayCapacity
* sizeof(PyrObject
*);
96 PyrObject
** newArray
= (PyrObject
**)g
->allocPool
->Alloc(newSize
);
97 memcpy(newArray
, objectArray
, numObjects
* sizeof(PyrObject
*));
98 if (objectArrayCapacity
> kDeepCopierObjectArrayInitialCapacity
) {
99 g
->allocPool
->Free(objectArray
);
101 objectArrayCapacity
= newObjectArrayCapacity
;
102 objectArray
= newArray
;
105 void putSelf(PyrObject
*obj
)
108 obj
->scratch1
= numObjects
;
110 // expand array if needed
111 if (numObjects
>= objectArrayCapacity
) growObjectArray();
113 //post("putSelf %d %08X\n", numObjects, obj);
115 objectArray
[numObjects
++] = obj
;
118 void putCopy(PyrObject
*obj
)
121 obj
->scratch1
= numObjects
;
123 // expand array if needed
124 if (numObjects
+2 >= objectArrayCapacity
) growObjectArray();
126 // add a shallow copy to object array
127 PyrObject
*copy
= copyObject(g
->gc
, obj
, false);
130 //post("putCopy %d %08X\n", numObjects, copy);
133 objectArray
[numObjects
++] = copy
;
134 objectArray
[numObjects
++] = obj
;
137 void constructObjectArray(PyrObject
*obj
)
139 //post("->constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
140 if (!obj
->IsMarked()) {
141 if (isKindOf(obj
, class_class
)) {
143 } else if (isKindOf(obj
, class_process
)) {
145 } else if (isKindOf(obj
, s_interpreter
->u
.classobj
)) {
147 } else if (isKindOf(obj
, class_rawarray
)) {
149 } else if (isKindOf(obj
, class_array
)) {
151 recurse(obj
, obj
->size
);
152 } else if (isKindOf(obj
, class_func
)) {
154 } else if (isKindOf(obj
, class_method
)) {
156 } else if (isKindOf(obj
, class_thread
)) {
158 } else if (isKindOf(obj
, class_server_shm_interface
)) {
162 recurse(obj
, obj
->size
);
165 //post("<-constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
168 void fixObjSlot(PyrSlot
* slot
)
170 //post("fixObjSlot %s %08X %d %08X\n", slotRawObject(slot)->classptr->name.us->name, slotRawObject(slot), slot->uo->scratch1, objectArray[slot->uo->scratch1]);
171 SetRaw(slot
, objectArray
[slotRawObject(slot
)->scratch1
]);
174 void fixSlots(PyrObject
*obj
)
176 //post("fixSlots %s %08X %d\n", obj->classptr->name.us->name, obj, obj->IsMarked());
177 if (!obj
->IsMarked() && obj
->obj_format
<= obj_slot
) { // it is a copy
178 PyrSlot
*slot
= obj
->slots
;
179 for (int i
=0; i
<obj
->size
; ++i
, ++slot
) {
180 if (IsObj(slot
)) fixObjSlot(slot
);
187 PyrObject
**objectArray
;
189 int32 objectArrayCapacity
;
191 PyrObject
*initialObjectArray
[kDeepCopierObjectArrayInitialCapacity
];