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"
37 #include "ReadWriteMacros.h"
39 const int32 kDeepCopierObjectArrayInitialCapacity
= 32;
44 PyrDeepCopier(VMGlobals
*inG
)
45 : g(inG
), objectArray(initialObjectArray
), numObjects(0),
46 objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity
)
52 if (objectArrayCapacity
> kDeepCopierObjectArrayInitialCapacity
) {
53 g
->allocPool
->Free(objectArray
);
57 long doDeepCopy(PyrSlot
*objectSlot
)
62 if (IsObj(objectSlot
)) {
63 constructObjectArray(slotRawObject(objectSlot
));
64 for (int i
=0; i
<numObjects
; ++i
) {
65 fixSlots(objectArray
[i
]);
67 fixObjSlot(objectSlot
);
68 for (int i
=0; i
<numObjects
; ++i
) {
69 objectArray
[i
]->ClearMark();
73 } catch (std::exception
&ex
) {
82 void recurse(PyrObject
*obj
, int n
)
84 //post("->recurse %s %08X\n", obj->classptr->name.us->name, obj);
85 PyrSlot
*slot
= obj
->slots
;
86 for (int i
=0; i
<n
; ++i
, ++slot
) {
87 if (IsObj(slot
)) constructObjectArray(slotRawObject(slot
));
89 //post("<-recurse %s %08X\n", obj->classptr->name.us->name, obj);
92 void growObjectArray()
94 int32 newObjectArrayCapacity
= objectArrayCapacity
<< 1;
96 int32 newSize
= newObjectArrayCapacity
* sizeof(PyrObject
*);
97 PyrObject
** newArray
= (PyrObject
**)g
->allocPool
->Alloc(newSize
);
98 memcpy(newArray
, objectArray
, numObjects
* sizeof(PyrObject
*));
99 if (objectArrayCapacity
> kDeepCopierObjectArrayInitialCapacity
) {
100 g
->allocPool
->Free(objectArray
);
102 objectArrayCapacity
= newObjectArrayCapacity
;
103 objectArray
= newArray
;
106 void putSelf(PyrObject
*obj
)
109 obj
->scratch1
= numObjects
;
111 // expand array if needed
112 if (numObjects
>= objectArrayCapacity
) growObjectArray();
114 //post("putSelf %d %08X\n", numObjects, obj);
116 objectArray
[numObjects
++] = obj
;
119 void putCopy(PyrObject
*obj
)
122 obj
->scratch1
= numObjects
;
124 // expand array if needed
125 if (numObjects
+2 >= objectArrayCapacity
) growObjectArray();
127 // add a shallow copy to object array
128 PyrObject
*copy
= copyObject(g
->gc
, obj
, false);
131 //post("putCopy %d %08X\n", numObjects, copy);
134 objectArray
[numObjects
++] = copy
;
135 objectArray
[numObjects
++] = obj
;
138 void constructObjectArray(PyrObject
*obj
)
140 //post("->constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
141 if (!obj
->IsMarked()) {
142 if (isKindOf(obj
, class_class
)) {
144 } else if (isKindOf(obj
, class_process
)) {
146 } else if (isKindOf(obj
, s_interpreter
->u
.classobj
)) {
148 } else if (isKindOf(obj
, class_rawarray
)) {
150 } else if (isKindOf(obj
, class_array
)) {
152 recurse(obj
, obj
->size
);
153 } else if (isKindOf(obj
, class_func
)) {
155 } else if (isKindOf(obj
, class_method
)) {
157 } else if (isKindOf(obj
, class_thread
)) {
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
];
194 SuperCollider real time audio synthesis system
195 Copyright (c) 2002 James McCartney. All rights reserved.
196 http://www.audiosynth.com
198 This program is free software; you can redistribute it and/or modify
199 it under the terms of the GNU General Public License as published by
200 the Free Software Foundation; either version 2 of the License, or
201 (at your option) any later version.
203 This program is distributed in the hope that it will be useful,
204 but WITHOUT ANY WARRANTY; without even the implied warranty of
205 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
206 GNU General Public License for more details.
208 You should have received a copy of the GNU General Public License
209 along with this program; if not, write to the Free Software
210 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
214 An object archiving system for SuperCollider.