diff options
author | Tim Blechmann <timblech@users.sourceforge.net> | 2004-07-14 16:21:44 +0000 |
---|---|---|
committer | IOhannes m zmölnig <zmoelnig@iem.at> | 2015-10-14 15:11:54 +0200 |
commit | d0ae3caca5828675335d3b19ab5dd987e7369b23 (patch) | |
tree | ffb89eb98dc91b1c1b471d2c221f18dafbfb48a6 /sc4pd/headers/lang/PyrDeepFreezer.h | |
parent | e0775c6066f90ece58bf84326ab7180cb6c3d539 (diff) |
This commit was generated by cvs2svn to compensate for changes in r1857,
which included commits to RCS files with non-trunk default branches.
svn path=/trunk/externals/tb/; revision=1858
Diffstat (limited to 'sc4pd/headers/lang/PyrDeepFreezer.h')
-rwxr-xr-x | sc4pd/headers/lang/PyrDeepFreezer.h | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/sc4pd/headers/lang/PyrDeepFreezer.h b/sc4pd/headers/lang/PyrDeepFreezer.h new file mode 100755 index 0000000..28d9a12 --- /dev/null +++ b/sc4pd/headers/lang/PyrDeepFreezer.h @@ -0,0 +1,178 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +An object archiving system for SuperCollider. + +*/ + +#ifndef _PyrDeepFreezer_ +#define _PyrDeepFreezer_ + +#include "PyrObject.h" +#include "SC_AllocPool.h" +#include "PyrKernel.h" +#include "PyrPrimitive.h" +#include "VMGlobals.h" +#include "GC.h" + +const int32 kDeepFreezerObjectArrayInitialCapacity = 32; + +class PyrDeepFreezer +{ +public: + PyrDeepFreezer(VMGlobals *inG) + : g(inG), objectArray(initialObjectArray), numObjects(0), + objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity ) + { + } + + ~PyrDeepFreezer() + { + if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) { + g->allocPool->Free(objectArray); + } + } + + long doDeepFreeze(PyrSlot *objectSlot) + { + long err = errNone; + + try { + if (IsObj(objectSlot)) { + constructObjectArray(objectSlot->uo); + for (int i=0; i<numObjects; ++i) { + g->gc->BecomePermanent( objectArray[i] ); + } + } + } catch (std::exception &ex) { + error(ex.what()); + err = errFailed; + } + return err; + } + +private: + + void recurse(PyrObject *obj, int n) + { + PyrSlot *slot = obj->slots; + for (int i=0; i<n; ++i, ++slot) { + if (IsObj(slot)) constructObjectArray(slot->uo); + } + } + + void growObjectArray() + { + int32 newObjectArrayCapacity = objectArrayCapacity << 1; + + int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*); + PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize); + memcpy(newArray, objectArray, numObjects * sizeof(PyrObject*)); + if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) { + g->allocPool->Free(objectArray); + } + objectArrayCapacity = newObjectArrayCapacity; + objectArray = newArray; + } + + void putObject(PyrObject *obj) + { + obj->SetMark(); + obj->scratch1 = numObjects; + + // expand array if needed + if (numObjects >= objectArrayCapacity) growObjectArray(); + + // add to array + objectArray[numObjects++] = obj; + } + + void constructObjectArray(PyrObject *obj) + { + if (obj->IsPermanent()) return; + + if (!obj->IsMarked()) { + if (isKindOf(obj, class_process)) { + throw std::runtime_error("cannot freeze Process.\n"); + } else if (isKindOf(obj, s_interpreter->u.classobj)) { + throw std::runtime_error("cannot freeze Interpreter.\n"); + } else if (isKindOf(obj, class_rawarray)) { + putObject(obj); + } else if (isKindOf(obj, class_array)) { + putObject(obj); + recurse(obj, obj->size); + } else if (isKindOf(obj, class_func)) { + if (NotNil(&((PyrClosure*)obj)->block.uoblk->context)) { + throw std::runtime_error("open Function can not be frozen.\n"); + } + putObject(obj); + recurse(obj, obj->size); + } else if (isKindOf(obj, class_method)) { + throw std::runtime_error("cannot freeze Methods.\n"); + } else if (isKindOf(obj, class_thread)) { + throw std::runtime_error("cannot freeze Threads.\n"); + } else if (isKindOf(obj, class_frame)) { + throw std::runtime_error("cannot freeze Frames.\n"); + } else { + putObject(obj); + recurse(obj, obj->size); + } + } + } + + VMGlobals *g; + + PyrObject **objectArray; + int32 numObjects; + int32 objectArrayCapacity; + + PyrObject *initialObjectArray[kDeepCopierObjectArrayInitialCapacity]; +}; + +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +An object archiving system for SuperCollider. + +*/ + + + +#endif + |