Explicitly include a boost "windows" folder even on linux
[supercollider.git] / include / lang / PyrDeepCopier.h
blob6f5f025f1cf3f17fafc163a24b6db91fb4172ec0
1 /*
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"
36 #include "GC.h"
38 const int32 kDeepCopierObjectArrayInitialCapacity = 32;
40 class PyrDeepCopier
42 public:
43 PyrDeepCopier(VMGlobals *inG)
44 : g(inG), objectArray(initialObjectArray), numObjects(0),
45 objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity )
48 ~PyrDeepCopier()
50 if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
51 g->allocPool->Free(objectArray);
55 long doDeepCopy(PyrSlot *objectSlot)
57 long err = errNone;
59 try {
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) {
72 error(ex.what());
73 err = errFailed;
75 return err;
78 private:
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)
106 obj->SetMark();
107 obj->scratch1 = numObjects;
109 // expand array if needed
110 if (numObjects >= objectArrayCapacity) growObjectArray();
112 //post("putSelf %d %08X\n", numObjects, obj);
113 // add to array
114 objectArray[numObjects++] = obj;
117 void putCopy(PyrObject *obj)
119 obj->SetMark();
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);
127 copy->ClearMark();
129 //post("putCopy %d %08X\n", numObjects, copy);
131 // add to array
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)) {
141 putSelf(obj);
142 } else if (isKindOf(obj, class_process)) {
143 putSelf(obj);
144 } else if (isKindOf(obj, s_interpreter->u.classobj)) {
145 putSelf(obj);
146 } else if (isKindOf(obj, class_rawarray)) {
147 putCopy(obj);
148 } else if (isKindOf(obj, class_array)) {
149 putCopy(obj);
150 recurse(obj, obj->size);
151 } else if (isKindOf(obj, class_func)) {
152 putSelf(obj);
153 } else if (isKindOf(obj, class_method)) {
154 putSelf(obj);
155 } else if (isKindOf(obj, class_thread)) {
156 putSelf(obj);
157 } else if (isKindOf(obj, class_server_shm_interface)) {
158 putSelf(obj);
159 } else {
160 putCopy(obj);
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);
184 VMGlobals *g;
186 PyrObject **objectArray;
187 int32 numObjects;
188 int32 objectArrayCapacity;
190 PyrObject *initialObjectArray[kDeepCopierObjectArrayInitialCapacity];
193 #endif