From 02c809625a710a6fc92eab78efe156fa055b4c4c Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 12 Jan 2016 00:38:36 +0100 Subject: [PATCH] implemented many create/clone/destroy functions --- src/clump.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++++++-- src/rwobjects.h | 24 ++++++++++- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/src/clump.cpp b/src/clump.cpp index 7ec69ca..05e26d9 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -40,9 +40,47 @@ Frame::create(void) return f; } +Frame* +Frame::cloneHierarchy(void) +{ + Frame *frame = this->cloneAndLink(NULL); + frame->purgeClone(); + return frame; +} + void Frame::destroy(void) { + this->destructPlugins(); + Frame *parent = this->getParent(); + Frame *child; + if(parent){ + // remove from child list + child = parent->child; + if(child == this) + parent->child = this->next; + else{ + for(child = child->next; child != this; child = child->next) + ; + child->next = this->next; + } + this->object.parent = NULL; + // Doesn't seem to make much sense, blame criterion. + this->setHierarchyRoot(this); + } + for(Frame *f = this->child; f; f = f->next) + f->object.parent = NULL; + free(this); +} + +void +Frame::destroyHierarchy(void) +{ + Frame *next; + for(Frame *child = this->child; child; child = next){ + next = child->next; + child->destroyHierarchy(); + } this->destructPlugins(); free(this); } @@ -138,6 +176,43 @@ Frame::setDirty(void) this->forAllChildren(dirtyCB, NULL); } +void +Frame::setHierarchyRoot(Frame *root) +{ + this->root = root; + for(Frame *child = this->child; child; child = child->next) + child->setHierarchyRoot(root); +} + +// Clone a frame hierarchy. Link cloned frames into Frame::root of the originals. +Frame* +Frame::cloneAndLink(Frame *clonedroot) +{ + Frame *frame = Frame::create(); + if(clonedroot == NULL) + clonedroot = frame; + frame->object.copy(&this->object); + memcpy(frame->matrix, this->matrix, sizeof(this->matrix)); + frame->root = clonedroot; + this->root = frame; // Remember cloned frame + for(Frame *child = this->child; child; child = child->next){ + Frame *clonedchild = child->cloneAndLink(clonedroot); + clonedchild->next = frame->child; + frame->child = clonedchild; + clonedchild->object.parent = frame; + } + frame->copyPlugins(this); + return frame; +} + +// Remove links to cloned frames from hierarchy. +void +Frame::purgeClone(void) +{ + Frame *parent = this->getParent(); + this->setHierarchyRoot(parent ? parent->root : this); +} + static Frame* sizeCB(Frame *f, void *size) { @@ -176,7 +251,15 @@ Clump* Clump::clone(void) { Clump *clump = Clump::create(); - // TODO actually clone + Frame *root = this->getFrame()->cloneHierarchy(); + clump->setFrame(root); + FORLIST(lnk, this->atomics){ + Atomic *a = Atomic::fromClump(lnk); + Atomic *atomic = a->clone(); + atomic->setFrame(a->getFrame()->root); + clump->addAtomic(atomic); + } + root->purgeClone(); clump->copyPlugins(this); return clump; } @@ -184,7 +267,14 @@ Clump::clone(void) void Clump::destroy(void) { + Frame *f; this->destructPlugins(); + FORLIST(lnk, this->atomics) + Atomic::fromClump(lnk)->destroy(); + FORLIST(lnk, this->lights) + Light::fromClump(lnk)->destroy(); + if(f = this->getFrame()) + f->destroyHierarchy(); free(this); } @@ -445,13 +535,19 @@ Atomic::create(void) atomic->pipeline = NULL; atomic->constructPlugins(); return atomic; -} +} Atomic* Atomic::clone() { Atomic *atomic = Atomic::create(); - //TODO + atomic->object.copy(&this->object); + atomic->object.privateFlags |= 1; + if(this->geometry){ + atomic->geometry = this->geometry; + atomic->geometry->refCount++; + } + atomic->pipeline = this->pipeline; atomic->copyPlugins(this); return atomic; } @@ -459,8 +555,10 @@ Atomic::clone() void Atomic::destroy(void) { - //TODO this->destructPlugins(); + if(this->geometry) + this->geometry->destroy(); + this->setFrame(NULL); free(this); } diff --git a/src/rwobjects.h b/src/rwobjects.h index b6a7d69..29125f7 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -64,6 +64,13 @@ struct Object this->privateFlags = 0; this->parent = NULL; } + void copy(Object *o){ + this->type = o->type; + this->subType = o->subType; + this->flags = o->flags; + this->privateFlags = o->privateFlags; + this->parent = NULL; + } }; struct Frame : PluginBase @@ -85,14 +92,22 @@ struct Frame : PluginBase // MEM create, clonehiearchy, destroy, destroy hierarchy static Frame *create(void); + Frame *cloneHierarchy(void); void destroy(void); - + void destroyHierarchy(void); Frame *addChild(Frame *f); Frame *removeChild(void); Frame *forAllChildren(Callback cb, void *data); + Frame *getParent(void){ + return (Frame*)this->object.parent; + } int32 count(void); void updateLTM(void); void setDirty(void); + + void setHierarchyRoot(Frame *root); + Frame *cloneAndLink(Frame *clonedroot); + void purgeClone(void); }; Frame **makeFrameList(Frame *frame, Frame **flist); @@ -515,6 +530,7 @@ struct Atomic : PluginBase Atomic *clone(void); void destroy(void); void setFrame(Frame *f) { this->object.setFrame(f); } + Frame *getFrame(void) { return (Frame*)this->object.parent; } static Atomic *fromClump(LLLink *lnk){ return LLLinkGetData(lnk, Atomic, inClump); } @@ -553,6 +569,12 @@ struct Clump : PluginBase l->clump = this; this->lights.append(&l->inClump); } + void setFrame(Frame *f){ + this->object.parent = f; + } + Frame *getFrame(void){ + return (Frame*)this->object.parent; + } static Clump *streamRead(Stream *stream); bool streamWrite(Stream *stream); uint32 streamGetSize(void);