Beispiel #1
0
static void Dao_ParseTarget( DString *target, DList *parts, DaoValue *sval )
{
	DString *tmp = sval->xString.value;
	DaoInteger ival = {DAO_INTEGER,0,0,0,0,0};
	daoint i, n = DString_Size( target );
	int ch, ch2;
	DString_Clear( tmp );
	for(i=0; i<n; i++){
		ch = target->chars[i];
		ch2 = target->chars[i+1];
		if( ch == '%' && isdigit( ch2 ) ){
			DList_PushBack( parts, sval );
			DString_Clear( tmp );
			ival.value = ch2 - '0';
			DList_PushBack( parts, (DaoValue*) & ival );
			i ++;
		}else if( ch == '%' ){
			if( i+1 < n ){
				DString_AppendChar( tmp, (char)ch2 );
			}
			i ++;
		}else{
			DString_AppendChar( tmp, (char)ch );
		}
	}
	DList_PushBack( parts, sval );
}
Beispiel #2
0
static void NODE_Search( DaoProcess *proc, DaoValue *p[], int N )
{
	DList *nodes;
	DaoList *list = DaoProcess_PutList( proc );
	DaoxNode *self = (DaoxNode*) p[0];
	DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 1 );
	daoint method = p[1]->xEnum.value;
	daoint which = p[2]->xEnum.value;
	daoint i, j, entry;

	if( sect == NULL ) return;
	for(i=0; i<self->graph->nodes->size; i++){
		DaoxNode *node = (DaoxNode*) self->graph->nodes->items.pVoid[i];
		node->state = 0;
	}
	nodes = DList_New(0);
	DList_PushBack( nodes, self );

	entry = proc->topFrame->entry;
	while( nodes->size ){
		DaoxNode *node = NULL;
		if( method ){
			node = (DaoxNode*) DList_Front( nodes );
			DList_PopFront( nodes );
		}else{
			node = (DaoxNode*) DList_Back( nodes );
			DList_PopBack( nodes );
		}
		if( node->state ) continue;
		node->state = 1;

		if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, (DaoValue*) node );
		proc->topFrame->entry = entry;
		DaoProcess_Execute( proc );
		if( proc->status == DAO_PROCESS_ABORTED ) break;
		if( proc->stackValues[0]->xInteger.value ){
			DaoList_PushBack( list, (DaoValue*) node );
			if( which == 0 ) break;
		}

		for(j=0; j<node->outs->size; j++){
			DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j];
			DaoxNode *node2 = node == edge->first ? edge->second : edge->first;
			DList_PushBack( nodes, node2 );
		}
	}
	DaoProcess_PopFrame( proc );
	DList_Delete( nodes );
}
Beispiel #3
0
DaoxEdge* DaoxGraph_AddEdge( DaoxGraph *self, DaoxNode *first, DaoxNode *second )
{
	DaoxEdge *edge = DaoxEdge_New( self );
	DList_PushFront( first->outs, edge );
	if( self->directed ){
		if( second->ins == NULL ) second->ins = DList_New(DAO_DATA_VALUE);
		DList_PushBack( second->ins, edge );
	}else{
		DList_PushBack( second->outs, edge );
	}

	DList_Append( self->edges, edge );
	edge->first = first;
	edge->second = second;
	return edge;
}
Beispiel #4
0
void DList_Insert( DList *self, void *val, daoint id )
{
	void **buf = self->items.pVoid - self->offset;
	daoint i;
	if( id == 0 ){
		DList_PushFront( self, val );
		return;
	}else if( id >= self->size ){
		DList_PushBack( self, val );
		return;
	}
	if( self->type == DAO_DATA_VALUE ) DaoGC_LockData();
	if( (daoint)(self->offset + self->size + 1) >= self->bufsize ){
		if( self->offset > 0 ) memmove( buf, self->items.pVoid, self->size*sizeof(void*) );
		self->bufsize += self->bufsize/5 + 5;
		self->items.pVoid = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) );
		self->offset = 0;
	}
	if( self->type && val != NULL ){
		for( i=self->size; i>id; i-- ) self->items.pVoid[i] = self->items.pVoid[i-1];
		self->items.pVoid[ id ] = NULL;
	}else{
		for( i=self->size; i>id; i-- ) self->items.pVoid[i] = self->items.pVoid[i-1];
		self->items.pVoid[id] = val;
	}
	if( self->type == DAO_DATA_VALUE ) DaoGC_UnlockData();
	if( self->type && val != NULL ){
		self->items.pVoid[ id ] = DList_CopyItem( self, val );
	}
	self->size++;
}
Beispiel #5
0
void DaoxNode_BreadthFirstSearch( DaoxNode *self, DList *nodes )
{
	daoint i, j;
	DList_Clear( nodes );
	DList_PushBack( nodes, self );
	self->state = 1;
	for(i=0; i<nodes->size; i++){
		DaoxNode *node = (DaoxNode*) nodes->items.pVoid[i];
		for(j=0; j<node->outs->size; j++){
			DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j];
			DaoxNode *node2 = node == edge->first ? edge->second : edge->first;
			if( node2->state ) continue;
			node2->state = 1;
			DList_PushBack( nodes, node2 );
		}
	}
}
Beispiel #6
0
void DaoxNode_DepthFirstSearch( DaoxNode *self, DList *nodes )
{
	DList *stack = DList_New(0);
	daoint j;
	DList_Clear( nodes );
	DList_PushBack( stack, self );
	while( stack->size ){
		DaoxNode *node = (DaoxNode*) DList_Back( stack );
		DList_PopBack( stack );
		if( node->state ) continue;
		node->state = 1;
		DList_PushBack( nodes, node );
		for(j=0; j<node->outs->size; j++){
			DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j];
			DaoxNode *node2 = node == edge->first ? edge->second : edge->first;
			DList_PushBack( stack, node2 );
		}
	}
	DList_Delete( stack );
}
Beispiel #7
0
static double DaoxGraph_MaxFlow_PRTF_Float( DaoxGraph *self, DaoxNode *source, DaoxNode *sink )
{
	daoint i, n;
	double inf = 1.0;
	DList *list = DList_New(0);

	for(i=0,n=source->outs->size; i<n; i++){
		DaoxEdge *edge = source->outs->items.pgEdge[i];
		if( source == edge->first ) inf += edge->X.MF->capacity;
	}
	for(i=0,n=self->nodes->size; i<n; i++){
		DaoxNode *node = self->nodes->items.pgNode[i];
		node->X.MF->nextpush = 0;
		node->X.MF->height = 0;
		node->X.MF->excess = 0.0;
		if( node != source && node != sink ) DList_PushBack( list, node );
	}
	source->X.MF->nextpush = 0;
	source->X.MF->height = n;
	source->X.MF->excess = inf;
	for(i=0,n=self->edges->size; i<n; i++){
		DaoxEdge *edge = self->edges->items.pgEdge[i];
		edge->X.MF->flow_fw = 0.0;
		edge->X.MF->flow_bw = 0.0;
	}
	for(i=0,n=source->outs->size; i<n; i++){
		DaoxEdge *edge = source->outs->items.pgEdge[i];
		if( source == edge->first ) MaxFlow_PushFloat( source, edge );
	}
	i = 0;
	while( i < list->size ){
		DaoxNode *U = list->items.pgNode[i];
		daoint old_height = U->X.MF->height;
		MaxFlow_DischargeFloat( U );
		if( U->X.MF->height > old_height ){
			DList_Erase( list, i, 1 );
			DList_PushFront( list, U );
			i = 0;
		}else{
			i += 1;
		}
	}
	DList_Delete( list );
	inf = 0.0;
	for(i=0,n=source->outs->size; i<n; i++){
		DaoxEdge *edge = source->outs->items.pgEdge[i];
		if( source == edge->first ) inf += edge->X.MF->flow_fw;
	}
	return inf;
}
Beispiel #8
0
void DCondVar_Wait( DCondVar *self, DMutex *mtx )
{
	DThreadData *p = (DThreadData*)TlsGetValue( thdSpecKey );

	DMutex_Lock( & self->thdMutex );
	DList_PushBack( self->thdWaiting, (void*) p->thdObject );
	DMutex_Unlock( & self->thdMutex );

	if( mtx ) DMutex_Unlock( mtx );
	WaitForSingleObject( p->thdObject->condv.myCondVar, INFINITE );
	ResetEvent( p->thdObject->condv.myCondVar );
	if( mtx ) DMutex_Lock( mtx );

	if( p->state & DTHREAD_CANCELED ) DThread_Exit( p->thdObject );
}
Beispiel #9
0
int DCondVar_TimedWait( DCondVar *self, DMutex *mtx, double seconds )
{
	DWORD retc;
	DThreadData *p = (DThreadData*)TlsGetValue( thdSpecKey );

	DMutex_Lock( & self->thdMutex );
	DList_PushBack( self->thdWaiting, (void*) p->thdObject );
	DMutex_Unlock( & self->thdMutex );

	if( mtx ) DMutex_Unlock( mtx );
	retc = WaitForSingleObject( p->thdObject->condv.myCondVar, (DWORD)( seconds * 1000 ) );
	ResetEvent( p->thdObject->condv.myCondVar );
	if( mtx ) DMutex_Lock( mtx );

	if( p->state & DTHREAD_CANCELED ) DThread_Exit( p->thdObject );
	return ( retc == WAIT_TIMEOUT );
}
void DaoxTriangulator_PushPoint( DaoxTriangulator *self, float x, float y )
{
	DaoxVertexData *prev = NULL, *vertex = DaoxTriangulator_GetVertex( self, self->points->size );
	if( self->vertices->size ){
		prev = (DaoxVertexData*)  self->vertices->items.pVoid[self->vertices->size-1];
		if( prev->next ){
			vertex->contour = prev->contour + 1;
		}else{
			vertex->contour = prev->contour;
			prev->next = vertex;
			vertex->prev = prev;
		}
	}
	DArray_PushVectorXY( self->points, x, y );
	DList_PushBack( self->vertices, vertex );
	if( self->start == NULL ) self->start = vertex;
}
Beispiel #11
0
/* Lock daoCallServer::mutex before calling this function: */
static void DaoCallServer_CacheEvent( DaoTaskEvent *event )
{
	DaoCallServer *server = daoCallServer;
	DaoTaskEvent_Reset( event );
	DList_PushBack( server->caches, event );
}
Beispiel #12
0
/* Lock self::mutex before calling this function: */
static void DaoTaskletServer_CacheEvent( DaoTaskletServer *self, DaoTaskletEvent *event )
{
	DaoTaskletEvent_Reset( event );
	DList_PushBack( self->caches, event );
}
Beispiel #13
0
void DaoxGraph_ConnectedComponents( DaoxGraph *self, DList *cclist )
{
	DList *nodes;
	DaoxGraph *subgraph;
	daoint i, j, k, n;
	if( self->nodes->size == 0 ){
		DList_PushBack( cclist, self );
		return;
	}
	for(i=0; i<self->nodes->size; i++){
		DaoxNode *node = (DaoxNode*) self->nodes->items.pVoid[i];
		node->state = 0;
	}
	nodes = DList_New(0);
	while( self->nodes->size ){
		DaoxNode_BreadthFirstSearch( (DaoxNode*) self->nodes->items.pVoid[0], nodes );
#if 0
		printf( "self->nodes->size = %i, %i\n", self->nodes->size, nodes->size );
#endif
		if( nodes->size == self->nodes->size ){
			DList_PushBack( cclist, self );
			break;
		}
		subgraph = DaoxGraph_New( self->ctype, self->directed );
		DList_PushBack( cclist, subgraph );
		for(i=0,n=nodes->size; i<n; i++){
			DaoxNode *node = (DaoxNode*) nodes->items.pVoid[i];
			GC_Assign( & node->graph, subgraph );
			DList_PushBack( subgraph->nodes, node );
			for(j=0; j<node->outs->size; j++){
				DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j];
				if( edge->graph == subgraph ) continue;
				GC_Assign( & edge->graph, subgraph );
				DList_PushBack( subgraph->edges, edge );
			}
		}
		for(i=0,k=0,n=self->nodes->size; i<n; i++){
			DaoxNode *node = (DaoxNode*) self->nodes->items.pVoid[i];
			/* Ensure no duplication of the reference (for the Concurrent GC): */
			self->nodes->items.pVoid[i] = NULL;
			if( node->graph != self ){
				GC_DecRC( node );
				continue;
			}
			self->nodes->items.pVoid[k++] = node;
		}
		self->nodes->size = k;
		for(i=0,k=0,n=self->edges->size; i<n; i++){
			DaoxNode *edge = (DaoxNode*) self->edges->items.pVoid[i];
			/* Ensure no duplication of the reference (for the Concurrent GC): */
			self->edges->items.pVoid[i] = NULL;
			if( edge->graph != self ){
				GC_DecRC( edge );
				continue;
			}
			self->edges->items.pVoid[k++] = edge;
		}
		self->edges->size = k;
	}
	DList_Delete( nodes );
}
void DaoxTriangulator_Triangulate( DaoxTriangulator *self )
{
	DaoxVertexData *V, *A, *B, *C, *inside;
	DaoxVector2D PA, PB, PC, P, *points = self->points->data.vectors2d;
	int i, imin, imax, contours, K = 0, N = self->vertices->size;
	double dist, area, ymin, ymax, dmax, dmin;
	double AB, BC, CA, min_area = 1E-16;

	if( self->vertices->size == 0 ) return;

	DaoxTriangulator_InitContourOrientation( self );

	V = (DaoxVertexData*) self->vertices->items.pVoid[N-1];
	contours = V->contour;

	DList_Assign( self->worklist, self->vertices );
	while( self->worklist->size && (++K) < 10*N ){
		A = (DaoxVertexData*) self->worklist->items.pVoid[self->worklist->size-1];
		if( A->done ){
			DList_PopBack( self->worklist );
			continue;
		}
		B = A->next;
		C = A->prev;
		PA = points[A->index];
		PB = points[B->index];
		PC = points[C->index];
		area = DaoxTriangle_Area( PA, PB, PC );
		if( B->next == C ){ /* already a triangle: */
			if( fabs( area ) > min_area ) DaoxTriangulator_MakeTriangle( self, A );
			A->next->prev = A->prev;
			A->prev->next = A->next;
			A->done = B->done = C->done = 1;
			DList_PopBack( self->worklist );
			continue;
		}

		ymin = ymax = PA.y;
		if( PB.y < ymin ) ymin = PB.y; else if( PB.y > ymax ) ymax = PB.y;
		if( PC.y < ymin ) ymin = PC.y; else if( PC.y > ymax ) ymax = PC.y;
		imin = B->sorting < C->sorting ? B->sorting : C->sorting;
		imax = A->sorting;
		inside = NULL;
		dmax = - 1.0;
		dmin = 1E9;
		/*
		// find the closest point to the triangle:
		//
		// Note: no need to distinguish duplicated vertices, because:
		// 1. if they are outside of the trianlge, they cause no problem;
		// 2. they cannot be the "closest" vertex to "A" or another vertex again,
		//    so no problem for joining inner contour or splitting outer contour.
		//
		// The reason that they cannot be the "closest" vertex is that,
		// only a concave vertex from the outer contour or a convex
		// vertex from an inner contour for a hole can be chosen as the
		// the "closest" vertex.
		//
		// And when its original vertex was choose as the "closest" vertex,
		// the associated "A" will always be processed until it is removed
		// from the polygon(s), which will leave the duplicated vertices
		// as convex vertices on the outer contour!
		*/
		for(i=imin+1; i<imax; ++i){
			V = (DaoxVertexData*) self->vertices->items.pVoid[i];
			P = points[V->index];
			if( V->done ) continue;
			//printf( "%3i: %12f %12f %9p, %3i %3i %3i %3i\n", i, P.x, P.y, V, V->contour, A->contour, V->direction, A->direction );
			/* Ingore vertex from other contour with the same direction: */
			if( V->contour != A->contour && V->direction == A->direction ) continue;
			if( V->sorting == A->sorting || V->sorting == B->sorting || V->sorting == C->sorting )
				continue;
			if( P.y > ymax ) continue;
			if( P.y < ymin ) continue;
			//printf( "%3i: %12f %12f %9p, %3i %3i %3i %3i\n", i, P.x, P.y, V, V->contour, A->contour, V->direction, A->direction );
			BC = DaoxTriangle_Area( P, PB, PC );
			AB = DaoxTriangle_Area( P, PA, PB );
			CA = DaoxTriangle_Area( P, PC, PA );
			if( area < 0.0 ){
				AB = -AB;
				BC = -BC;
				CA = -CA;
			}
			//printf( "%3i: %12f %12f  %12f\n", i, AB, BC, CA );
			if( BC >= 0.0 && AB >= 0.0 && CA >= 0.0 ){
				float d = DaoxVector2D_Dist( P, PA );
				if( d < dmin ){
					dmin = d;
					inside = V;
				}
			}
		}
#if 0
		printf( "A:  %15f  %15f   %9p\n", PA.x, PA.y, A );
		printf( "B:  %15f  %15f   %9p\n", PB.x, PB.y, B );
		printf( "C:  %15f  %15f   %9p\n", PC.x, PC.y, C );
		if( inside ) printf( "I:  %15f  %15f\n", points[inside->index].x, points[inside->index].y );
		printf( "%p\n", inside );
		printf( "area: %15f\n", area );
#endif
		if( inside == NULL ){
			A->done = 1;
			//printf( "area: %15f\n", DaoxTriangle_Area( PA, PB, PC ) );
			if( fabs( area ) > min_area ) DaoxTriangulator_MakeTriangle( self, A );
			A->next->prev = A->prev;
			A->prev->next = A->next;
			DList_PopBack( self->worklist );
			//if( self->triangles->size >= 3*111 ) break;
		}else{ /* point inside the triangle: */
			DaoxVertexData *A2, *N2;
			int breaking = inside->contour == A->contour;
			if( inside->contour != A->contour ){ /* joining contour: */
				/* the "inside" vertex is from a hole: */
				DaoxVertexData *V2 = inside;
				//printf( "joining\n" );
				/* update contour: */
				do {
					V2->contour = A->contour;
					V2->direction = A->direction;
					V2 = V2->next;
				} while( V2 != inside );
			}
			/*
			// connect "inside" to "A" with duplicated vertices, this will either:
			// 1. connect the inner contour with the outer contour;
			// 2. or break the outer contour.
			 */
			N2 = DaoxTriangulator_GetVertex( self, inside->index );
			A2 = DaoxTriangulator_GetVertex( self, A->index );
			N2->sorting = inside->sorting;
			A2->sorting = A->sorting;
			A2->contour = N2->contour = A->contour;
			A2->direction = N2->direction = A->direction;

			A2->prev = A->prev;  A->prev->next = A2;
			A2->next = N2;  N2->prev = A2;
			N2->next = inside->next;  inside->next->prev = N2;
			inside->next = A;  A->prev = inside;

			//printf( "dup:  %9p  %9p\n", A2, N2 );

			if( breaking ){
				contours += 1;
				//printf( "contours = %3i\n", contours );
				DaoxVertexData *V2 = inside;
				/* update contour: */
				do {
					V2->contour = contours;
					V2 = V2->next;
				} while( V2 != inside );
			}

			DList_PushBack( self->vertices, N2 );
			DList_PushBack( self->vertices, A2 );
			DList_PopBack( self->worklist );
			DList_PushBack( self->worklist, N2 );
			DList_PushBack( self->worklist, A2 );
			DList_PushBack( self->worklist, A );
		}
	}
}