Code Search for Developers
 
 
  

FcloneNode.C from Magnus at Krugle


Show FcloneNode.C syntax highlighted

#include "crossTrainer.h"

#include "FcloneNode.h"
#include "GLfunctions.h"
#include "FGLstepper.h"
#include "nodeMsg.h"

	
FcloneNode::FcloneNode(FObject *aSupervisor,FGLvar *cloneFrom,
		FGLvar *cloneTo,long scratchOffset)
	:FGLwalkNode(aSupervisor,cloneFrom){

//  CAUTION: don't alter the graphs of cloneFrom or cloneTo
//  while the clone node is running.  Don't try to clone part of a GLvar
//  onto itself.  Instead, clone a GLvar to another GLvar of the same
//  class and then glue the two graphs together.
 
//	the part of v to be cloned is indicated by v->bv, which must be a
//  real vertex of v 

//	the cloned data is attached vClone at vClone->bv, which must be a
//  real vertex of vClone

//  scratchOffset is an offset into the GLrv backYard of v.
//  This is an area that FcloneNode will overwrite and it
//  must be at least sizeof(GLref) bytes

  	FGLstepper *stepper;

	vClone=cloneTo;	
	if(v==vClone){
		nodeErr(23);
	}
	if(v->backYardSize[GLrv]-scratchOffset<(long)sizeof(GLref)){	
		nodeErr(22);
	}
	totalOffset=v->backYardOffset[GLrv]+scratchOffset;	
}

Boolean FcloneNode::walk(void){
	switch(entryPoint){
		case firstVertex:
			if(v==ZERO)nodeErr(4);
			if(v->Qideal())nodeErr(11);
			startUp();	
			virginCloneVertex(v->bv,vClone->bv);
			entryPoint=nextVertex;
		//control flows directly to GLrun
		case nextVertex:
			return(processVertex());
		case firstEdge:{
			// Process the first edge, if there is one.
			// if there is no defined edge, control flows to GLnextVertex
			
			Ptr DEREF=v&v->bv;
			GLref startRef;
			v->xGetPacketRef(startRef,GLr,DEREF);
			v-v->bv;
			if(isNull(startRef)){
				entryPoint=nextVertex;  // no real link
				return(TRUE);  
			}
			
			// start search for first edge at the very beginning
			GLref entryPacketRef;
			v->xsetToFirstPacket(entryPacketRef,startRef);  

			if(itsStepper->firstEdge(entryPacketRef)){
				// first edge detected
				GLref ref;
				v->xEdgeEntryToOwner(ref,itsStepper->refDatum);
				v->cv=ref;
				entryPoint=nextEdge; 
				return(processEdge()); 
			}
			else{	
				// real link has no edges
				
				entryPoint=nextVertex; 
				return(TRUE);  
			}
		}
		case nextEdge:{
			if(itsStepper->nextEdge()){
				// next edge detected
				GLref ref;
				v->xEdgeEntryToOwner(ref,itsStepper->refDatum);
				v->cv=ref;
				entryPoint=nextEdge; 
				return(processEdge()); 
			}
			else{	
				// real link has no more edges
				
				entryPoint=nextVertex; 
				return(TRUE);  
			}

		}
		default: nodeErr(6);
	}
	nodeErr(8);
}

void FcloneNode::virginCloneVertex(const GLref& original,const GLref& clone){	
	childVertices->Push(original);
	Ptr DEREF=v&original;
	v->xPutID(DEREF,IDslot,IDchild);
	BlockMove((Ptr)&clone,&DEREF[totalOffset],sizeof(GLref));
	v-original;
}

Boolean FcloneNode::processVertex(){
	
	Ptr DEREF;
	GLref bvClone,ref;
	childVertices->Pop(ref);
	v->bv=ref;
	Boolean locked;
	if(isNull(v->bv)){
		return finish();
	}
	getClone(v->bv,bvClone);
	vClone->bv=bvClone;
	DEREF=v&v->bv;			
	v->xPutID(DEREF,IDslot,IDadult);
	entryPoint=firstEdge;
	v-v->bv;
	return(TRUE);
}	
Boolean FcloneNode::processEdge(void){	

	Ptr DEREF;
	long IDvertex;	
	DEREF=v&v->cv;
	IDvertex=v->xGetID(DEREF,IDslot);
	v-v->cv;
	if(IDvertex<IDchild){
		//virgin, edge is maximal
		vClone->e=v->e;
		vClone->V();
		virginCloneVertex(v->cv,vClone->cv);
	}
	else if(IDvertex==IDchild){
		//child, edge is a basis edge
		GLref clone;
		vClone->e=v->e;
		getClone(v->cv,clone);
		vClone->cv=clone;
		vClone->Lnk();
	}
	else if(IDvertex==IDadult){
		if(SameAddr(v->bv,v->cv)){
			if(v->e>0){
				//loop, edge is a basis edge
				vClone->e=v->e;
				vClone->cv=vClone->bv;
				vClone->Lnk();
			}
		}
	}
	else nodeErr(12);
	return(TRUE);
}

void FcloneNode::auRevoir(void){
	FGLwalkNode::auRevoir();
	send(cloneAuRevoirMsg);
}

void FcloneNode::goodbyeKiss(void){
	send(cloneGoodbyeKissMsg);
}
	
// backyard

void FcloneNode:: getClone(const GLref& original,GLref& clone){
	Ptr DEREF=v&original;
	BlockMove(&DEREF[totalOffset],(Ptr)&clone,sizeof(GLref));
	v-original;
}






See more files for this project here

Magnus

Magnus is a special purpose mathematical package for Infinite Group Theory computations

Project homepage: http://sourceforge.net/projects/magnus
Programming language(s): C,C++
License: other

  FBlockManager.C
  FBlockManager.h
  FGLink.C
  FGLink.h
  FGLnode.C
  FGLnode.h
  FGLrecycleStack.C
  FGLrecycleStack.h
  FGLstack.C
  FGLstack.h
  FGLstepper.C
  FGLstepper.h
  FGLwalkNode.C
  FGLwalkNode.h
  FcleanUpNode.C
  FcleanUpNode.h
  FcloneNode.C
  FcloneNode.h
  FdebugNode.C
  FdebugNode.h
  FfoldNode.C
  FfoldNode.h
  FfoldStepper.C
  FfoldStepper.h
  FgrowNode.C
  FgrowNode.h
  FrandomRef.C
  FrandomRef.h
  FreducedFoldNode.C
  FreducedFoldNode.h
  FreducedVertexFolder.C
  FreducedVertexFolder.h
  FvertexFolder.C
  FvertexFolder.h
  GLfunctions.C
  GLfunctions.h
  GLref.h
  _FnameNode.cp_
  _FnameNode.h_
  _FrankNode.cp_
  _FrankNode.h_
  _FstrToGLvarNode.cp_
  _FstrToGLvarNode.h_
  debugGLink.C
  debugGLink.h