Corrected the last commit's problem with file locking, which is that
there was no distinction between a locked file and a new cell (initial state) before writing to disk. This prevents any new cell from being saved! Also: Revised the behavior of the "select short" search, but this still has issues with long run-times on complex layouts, so this is an ongoing effort.
This commit is contained in:
parent
1bb4cb92ea
commit
1fceef6acd
|
|
@ -1109,7 +1109,7 @@ CmdCellname(w, cmd)
|
||||||
{
|
{
|
||||||
/* Check if file is already read-write */
|
/* Check if file is already read-write */
|
||||||
#ifdef FILE_LOCKS
|
#ifdef FILE_LOCKS
|
||||||
if (!(cellDef->cd_flags & CDNOEDIT) && (cellDef->cd_fd != -1))
|
if (!(cellDef->cd_flags & CDNOEDIT) && (cellDef->cd_fd != -2))
|
||||||
#else
|
#else
|
||||||
if (!(cellDef->cd_flags & CDNOEDIT))
|
if (!(cellDef->cd_flags & CDNOEDIT))
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1117,10 +1117,10 @@ CmdCellname(w, cmd)
|
||||||
|
|
||||||
/* Make file read-write */
|
/* Make file read-write */
|
||||||
#ifdef FILE_LOCKS
|
#ifdef FILE_LOCKS
|
||||||
if (cellDef->cd_fd == -1)
|
if (cellDef->cd_fd < 0)
|
||||||
dbReadOpen(cellDef, NULL, TRUE, NULL);
|
dbReadOpen(cellDef, NULL, TRUE, NULL);
|
||||||
|
|
||||||
if (cellDef->cd_fd == -1)
|
if (cellDef->cd_fd == -2)
|
||||||
{
|
{
|
||||||
TxError("An advisory lock is held on cell %s. Cell can now"
|
TxError("An advisory lock is held on cell %s. Cell can now"
|
||||||
" be made editable but is not writeable.\n",
|
" be made editable but is not writeable.\n",
|
||||||
|
|
@ -1147,10 +1147,10 @@ CmdCellname(w, cmd)
|
||||||
#ifdef FILE_LOCKS
|
#ifdef FILE_LOCKS
|
||||||
/* Release any advisory lock held on this file */
|
/* Release any advisory lock held on this file */
|
||||||
|
|
||||||
if (cellDef->cd_fd != -1)
|
if (cellDef->cd_fd >= 0)
|
||||||
{
|
{
|
||||||
close(cellDef->cd_fd);
|
close(cellDef->cd_fd);
|
||||||
cellDef->cd_fd = -1;
|
cellDef->cd_fd = -1; /* Set to initial state */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1205,7 +1205,7 @@ DBCellRead(cellDef, name, ignoreTech, dereference, errptr)
|
||||||
|
|
||||||
#ifdef FILE_LOCKS
|
#ifdef FILE_LOCKS
|
||||||
/* Close files that were locked by another user */
|
/* Close files that were locked by another user */
|
||||||
if (cellDef->cd_fd == -1) fclose(f);
|
if (cellDef->cd_fd == -2) fclose(f);
|
||||||
#else
|
#else
|
||||||
/* When using fcntl() to enforce file locks, we can't */
|
/* When using fcntl() to enforce file locks, we can't */
|
||||||
/* close the file descriptor without losing the lock. */
|
/* close the file descriptor without losing the lock. */
|
||||||
|
|
@ -1261,10 +1261,10 @@ dbReadOpen(cellDef, name, setFileName, errptr)
|
||||||
bool is_locked;
|
bool is_locked;
|
||||||
|
|
||||||
#ifdef FILE_LOCKS
|
#ifdef FILE_LOCKS
|
||||||
if (cellDef->cd_fd != -1)
|
if (cellDef->cd_fd >= 0)
|
||||||
{
|
{
|
||||||
close(cellDef->cd_fd);
|
close(cellDef->cd_fd);
|
||||||
cellDef->cd_fd = -1;
|
cellDef->cd_fd = -1; /* Set to initial state */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1385,7 +1385,9 @@ dbReadOpen(cellDef, name, setFileName, errptr)
|
||||||
else
|
else
|
||||||
cellDef->cd_flags &= ~CDNOEDIT;
|
cellDef->cd_flags &= ~CDNOEDIT;
|
||||||
|
|
||||||
if (is_locked == FALSE)
|
if (is_locked == TRUE)
|
||||||
|
cellDef->cd_fd = -2; /* Indicates locked file */
|
||||||
|
else
|
||||||
cellDef->cd_fd = fileno(f);
|
cellDef->cd_fd = fileno(f);
|
||||||
cellDef->cd_flags &= ~CDNOTFOUND;
|
cellDef->cd_flags &= ~CDNOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
@ -3235,7 +3237,7 @@ DBCellWrite(cellDef, fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FILE_LOCKS
|
#ifdef FILE_LOCKS
|
||||||
if (cellDef->cd_fd == -1)
|
if (cellDef->cd_fd == -2)
|
||||||
{
|
{
|
||||||
TxPrintf("File %s is locked by another user and "
|
TxPrintf("File %s is locked by another user and "
|
||||||
"cannot be written\n", realname);
|
"cannot be written\n", realname);
|
||||||
|
|
@ -3307,10 +3309,10 @@ DBCellWrite(cellDef, fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FILE_LOCKS
|
#ifdef FILE_LOCKS
|
||||||
if (cellDef->cd_fd != -1)
|
if (cellDef->cd_fd >= 0)
|
||||||
{
|
{
|
||||||
close(cellDef->cd_fd);
|
close(cellDef->cd_fd);
|
||||||
cellDef->cd_fd = -1;
|
cellDef->cd_fd = -1; /* Set to initial state */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -3430,8 +3432,11 @@ DBCellWrite(cellDef, fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FILE_LOCKS
|
#ifdef FILE_LOCKS
|
||||||
|
cellDef->cd_fd = -1;
|
||||||
if (FileLocking && (is_locked == FALSE))
|
if (FileLocking && (is_locked == FALSE))
|
||||||
cellDef->cd_fd = fd;
|
cellDef->cd_fd = fd;
|
||||||
|
else if (FileLocking && (is_locked == TRUE))
|
||||||
|
cellDef->cd_fd = -2;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
fclose(realf);
|
fclose(realf);
|
||||||
|
|
|
||||||
287
select/selOps.c
287
select/selOps.c
|
|
@ -314,13 +314,13 @@ SelectFlat()
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* selShortFindPath --
|
* selShortFindReverse --
|
||||||
*
|
*
|
||||||
* Trace back through a path found by selShortFindNext from destination
|
* Trace back through a path found by selShortFindForward from destination
|
||||||
* to source, picking the lowest cost return path, and adding each tile
|
* to source, picking the lowest cost return path, and adding each tile
|
||||||
* found to the linked list.
|
* found to the linked list.
|
||||||
*
|
*
|
||||||
* Algorithm notes (for this and selShortFindNext): Note that by not
|
* Algorithm notes (for this and selShortFindForward): Note that by not
|
||||||
* using one of the standard database search routines, TT_SIDE is NOT
|
* using one of the standard database search routines, TT_SIDE is NOT
|
||||||
* set on any tile. To find out what side we're looking at, we keep
|
* set on any tile. To find out what side we're looking at, we keep
|
||||||
* a record of what direction we were traveling from the previous
|
* a record of what direction we were traveling from the previous
|
||||||
|
|
@ -335,7 +335,7 @@ SelectFlat()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
selShortFindPath(rlist, tile, pnum, fdir)
|
selShortFindReverse(rlist, tile, pnum, fdir)
|
||||||
ExtRectList **rlist;
|
ExtRectList **rlist;
|
||||||
Tile *tile;
|
Tile *tile;
|
||||||
int pnum;
|
int pnum;
|
||||||
|
|
@ -518,16 +518,15 @@ donesides:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Data structure used by selShortFindNext() to store a tile and */
|
/* Data structure used by selShortFindForward() to store a tile and */
|
||||||
/* the current search parameters, including cost, direction, plane, */
|
/* the current search parameters, including cost, direction, plane, */
|
||||||
/* and the mask of connecting types. */
|
/* and the mask of connecting types. */
|
||||||
|
|
||||||
typedef struct _shortdata {
|
typedef struct _shortdata {
|
||||||
int cost;
|
int cost;
|
||||||
Tile *tile;
|
Tile *tile;
|
||||||
|
TileType type;
|
||||||
int pnum;
|
int pnum;
|
||||||
int fdir;
|
|
||||||
TileTypeBitMask *mask;
|
|
||||||
} ShortData;
|
} ShortData;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -543,12 +542,11 @@ typedef struct _shortdata {
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ShortData *NewSD(cost, tile, pnum, fdir, mask)
|
ShortData *NewSD(cost, tile, type, pnum)
|
||||||
int cost;
|
int cost;
|
||||||
Tile *tile;
|
Tile *tile;
|
||||||
|
TileType type;
|
||||||
int pnum;
|
int pnum;
|
||||||
int fdir;
|
|
||||||
TileTypeBitMask *mask;
|
|
||||||
{
|
{
|
||||||
ShortData *sd;
|
ShortData *sd;
|
||||||
|
|
||||||
|
|
@ -556,9 +554,8 @@ ShortData *NewSD(cost, tile, pnum, fdir, mask)
|
||||||
|
|
||||||
sd->cost = cost;
|
sd->cost = cost;
|
||||||
sd->tile = tile;
|
sd->tile = tile;
|
||||||
|
sd->type = type;
|
||||||
sd->pnum = pnum;
|
sd->pnum = pnum;
|
||||||
sd->fdir = fdir;
|
|
||||||
sd->mask = mask;
|
|
||||||
|
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
@ -566,14 +563,81 @@ ShortData *NewSD(cost, tile, pnum, fdir, mask)
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* selShortFindNext --
|
* selShortProcessTile --
|
||||||
*
|
*
|
||||||
* Recursive function for finding shorts. This routine makes strong
|
* Process a tile, finding if it extends the connection from the
|
||||||
* assumptions; namely, that all non-space material in the cell being
|
* last position, and setting its cost to be one higher than the
|
||||||
* searched belongs to the same net. The cell searched is always
|
* previous position.
|
||||||
* SelectDef. (Although rather than actually recursing, which is
|
*
|
||||||
* likely to exceed the computer's stack depth, we create our own
|
* Return value:
|
||||||
* stack of unprocessed tiles and process them.)
|
* 0 if tile was updated with new cost.
|
||||||
|
* 1 if tile was unchanged.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* Writes cost to the tile's ClientData record.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
selShortProcessTile(tile, cost, fdir, mask)
|
||||||
|
Tile *tile;
|
||||||
|
int cost;
|
||||||
|
int fdir;
|
||||||
|
TileTypeBitMask *mask;
|
||||||
|
{
|
||||||
|
TileType ttype;
|
||||||
|
|
||||||
|
if (IsSplit(tile))
|
||||||
|
{
|
||||||
|
switch(fdir)
|
||||||
|
{
|
||||||
|
case GEO_NORTH:
|
||||||
|
ttype = SplitBottomType(tile);
|
||||||
|
break;
|
||||||
|
case GEO_SOUTH:
|
||||||
|
ttype = SplitTopType(tile);
|
||||||
|
break;
|
||||||
|
case GEO_EAST:
|
||||||
|
ttype = SplitLeftType(tile);
|
||||||
|
break;
|
||||||
|
case GEO_WEST:
|
||||||
|
ttype = SplitRightType(tile);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ttype = SplitLeftType(tile);
|
||||||
|
if (ttype == TT_SPACE) ttype = SplitRightType(tile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ttype = TiGetTypeExact(tile);
|
||||||
|
|
||||||
|
/* Ignore space tiles */
|
||||||
|
if (ttype == TT_SPACE) return 1;
|
||||||
|
|
||||||
|
/* Ignore non-connecting tiles */
|
||||||
|
if (!TTMaskHasType(mask, ttype)) return 1;
|
||||||
|
|
||||||
|
/* If this tile is unvisited, or has a lower cost, then return and */
|
||||||
|
/* keep going. Otherwise, return 1 to stop the search this direction */
|
||||||
|
|
||||||
|
if (tile->ti_client == (ClientData)CLIENTDEFAULT)
|
||||||
|
TiSetClient(tile, cost);
|
||||||
|
else if ((int)tile->ti_client > cost)
|
||||||
|
TiSetClient(tile, cost);
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* selShortFindForward --
|
||||||
|
*
|
||||||
|
* Function for finding shorts. The cell searched is always SelectDef.
|
||||||
*
|
*
|
||||||
* Results:
|
* Results:
|
||||||
* Return 0 to keep going; return 1 to stop when the tile contains
|
* Return 0 to keep going; return 1 to stop when the tile contains
|
||||||
|
|
@ -587,27 +651,30 @@ ShortData *NewSD(cost, tile, pnum, fdir, mask)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
selShortFindNext(tile, pnum, ldest, mask)
|
selShortFindForward(srctile, srctype, srcpnum, desttile)
|
||||||
Tile *tile;
|
Tile *srctile;
|
||||||
int pnum;
|
TileType srctype;
|
||||||
Label *ldest;
|
int srcpnum;
|
||||||
TileTypeBitMask *mask;
|
Tile *desttile;
|
||||||
{
|
{
|
||||||
TileType ttype;
|
TileType type;
|
||||||
TileTypeBitMask *lmask;
|
TileTypeBitMask *lmask;
|
||||||
Tile *tp;
|
Tile *tile, *tp;
|
||||||
|
int pnum;
|
||||||
ShortData *sd;
|
ShortData *sd;
|
||||||
static Stack *ShortStack = (Stack *)NULL;
|
static Stack *ShortStack = (Stack *)NULL;
|
||||||
|
|
||||||
int cost = 0;
|
int cost = 0;
|
||||||
int best = INT_MAX;
|
int best = INT_MAX;
|
||||||
int fdir = GEO_CENTER;
|
|
||||||
|
|
||||||
if (ShortStack == (Stack *)NULL)
|
if (ShortStack == (Stack *)NULL)
|
||||||
ShortStack = StackNew(64);
|
ShortStack = StackNew(64);
|
||||||
|
|
||||||
|
/* Set the cost of the source tile to zero */
|
||||||
|
TiSetClient(srctile, (ClientData)0);
|
||||||
|
|
||||||
/* Drop the first entry on the stack */
|
/* Drop the first entry on the stack */
|
||||||
sd = NewSD(cost, tile, pnum, fdir, mask);
|
sd = NewSD(cost, srctile, srctype, srcpnum);
|
||||||
STACKPUSH(sd, ShortStack);
|
STACKPUSH(sd, ShortStack);
|
||||||
|
|
||||||
while (!StackEmpty(ShortStack))
|
while (!StackEmpty(ShortStack))
|
||||||
|
|
@ -616,54 +683,12 @@ selShortFindNext(tile, pnum, ldest, mask)
|
||||||
tile = sd->tile;
|
tile = sd->tile;
|
||||||
cost = sd->cost;
|
cost = sd->cost;
|
||||||
pnum = sd->pnum;
|
pnum = sd->pnum;
|
||||||
fdir = sd->fdir;
|
type = sd->type;
|
||||||
mask = sd->mask;
|
|
||||||
freeMagic((char *)sd);
|
freeMagic((char *)sd);
|
||||||
|
|
||||||
if (IsSplit(tile))
|
/* If this tile is the destination tile, do not search further */
|
||||||
{
|
|
||||||
switch(fdir)
|
|
||||||
{
|
|
||||||
case GEO_NORTH:
|
|
||||||
ttype = SplitBottomType(tile);
|
|
||||||
break;
|
|
||||||
case GEO_SOUTH:
|
|
||||||
ttype = SplitTopType(tile);
|
|
||||||
break;
|
|
||||||
case GEO_EAST:
|
|
||||||
ttype = SplitLeftType(tile);
|
|
||||||
break;
|
|
||||||
case GEO_WEST:
|
|
||||||
ttype = SplitRightType(tile);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ttype = SplitLeftType(tile);
|
|
||||||
if (ttype == TT_SPACE) ttype = SplitRightType(tile);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ttype = TiGetTypeExact(tile);
|
|
||||||
|
|
||||||
/* Ignore space tiles */
|
if (tile == desttile)
|
||||||
if (ttype == TT_SPACE) continue;
|
|
||||||
|
|
||||||
/* Ignore non-connecting tiles */
|
|
||||||
if (!TTMaskHasType(mask, ttype)) continue;
|
|
||||||
|
|
||||||
/* If this tile is unvisited, or has a lower cost, then return and */
|
|
||||||
/* keep going. Otherwise, return 1 to stop the search this direction */
|
|
||||||
|
|
||||||
if (tile->ti_client == (ClientData)CLIENTDEFAULT)
|
|
||||||
TiSetClient(tile, cost);
|
|
||||||
else if ((int)tile->ti_client > cost)
|
|
||||||
TiSetClient(tile, cost);
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* If this tile contains the destination point, do not search further */
|
|
||||||
|
|
||||||
if ((ttype == ldest->lab_type) && EnclosePoint(tile, &ldest->lab_rect.r_ll))
|
|
||||||
{
|
{
|
||||||
if (best >= cost) best = (cost - 1);
|
if (best >= cost) best = (cost - 1);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -673,27 +698,18 @@ selShortFindNext(tile, pnum, ldest, mask)
|
||||||
/* do not search further. */
|
/* do not search further. */
|
||||||
|
|
||||||
if (cost >= best) continue;
|
if (cost >= best) continue;
|
||||||
lmask = &DBConnectTbl[ttype];
|
lmask = &DBConnectTbl[type];
|
||||||
|
|
||||||
/* Search top */
|
/* Search top */
|
||||||
if (IsSplit(tile))
|
if (IsSplit(tile))
|
||||||
{
|
if (TiGetTopType(tile) != type)
|
||||||
if (fdir == GEO_NORTH) goto srchleft;
|
goto srchleft;
|
||||||
else if (SplitDirection(tile) && fdir == GEO_EAST) goto srchleft;
|
|
||||||
else if (!SplitDirection(tile) && fdir == GEO_WEST) goto srchleft;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* As a small optimization, check for space tiles and avoid going
|
|
||||||
* through the hoops of allocating a structure and pushing it on the
|
|
||||||
* stack. This check is not rigorous, but it saves time for the
|
|
||||||
* most common case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
||||||
{
|
{
|
||||||
if (TiGetTypeExact(tp) != TT_SPACE)
|
if (selShortProcessTile(tp, cost + 1, GEO_NORTH, lmask) == 0)
|
||||||
{
|
{
|
||||||
sd = NewSD(cost + 1, tp, pnum, GEO_NORTH, lmask);
|
sd = NewSD(cost + 1, tp, TiGetBottomType(tp), pnum);
|
||||||
STACKPUSH(sd, ShortStack);
|
STACKPUSH(sd, ShortStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -701,17 +717,14 @@ selShortFindNext(tile, pnum, ldest, mask)
|
||||||
/* Search left */
|
/* Search left */
|
||||||
srchleft:
|
srchleft:
|
||||||
if (IsSplit(tile))
|
if (IsSplit(tile))
|
||||||
{
|
if (TiGetLeftType(tile) != type)
|
||||||
if (fdir == GEO_WEST) goto srchbot;
|
goto srchbot;
|
||||||
else if (SplitDirection(tile) && fdir == GEO_SOUTH) goto srchbot;
|
|
||||||
else if (!SplitDirection(tile) && fdir == GEO_NORTH) goto srchbot;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
||||||
{
|
{
|
||||||
if (TiGetTypeExact(tp) != TT_SPACE)
|
if (selShortProcessTile(tp, cost + 1, GEO_WEST, lmask) == 0)
|
||||||
{
|
{
|
||||||
sd = NewSD(cost + 1, tp, pnum, GEO_WEST, lmask);
|
sd = NewSD(cost + 1, tp, TiGetRightType(tp), pnum);
|
||||||
STACKPUSH(sd, ShortStack);
|
STACKPUSH(sd, ShortStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -719,17 +732,14 @@ srchleft:
|
||||||
/* Search bottom */
|
/* Search bottom */
|
||||||
srchbot:
|
srchbot:
|
||||||
if (IsSplit(tile))
|
if (IsSplit(tile))
|
||||||
{
|
if (TiGetBottomType(tile) != type)
|
||||||
if (fdir == GEO_SOUTH) goto srchright;
|
goto srchright;
|
||||||
else if (SplitDirection(tile) && fdir == GEO_WEST) goto srchright;
|
|
||||||
else if (!SplitDirection(tile) && fdir == GEO_EAST) goto srchright;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
|
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
|
||||||
{
|
{
|
||||||
if (TiGetTypeExact(tp) != TT_SPACE)
|
if (selShortProcessTile(tp, cost + 1, GEO_SOUTH, lmask) == 0)
|
||||||
{
|
{
|
||||||
sd = NewSD(cost + 1, tp, pnum, GEO_SOUTH, lmask);
|
sd = NewSD(cost + 1, tp, TiGetTopType(tp), pnum);
|
||||||
STACKPUSH(sd, ShortStack);
|
STACKPUSH(sd, ShortStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -737,29 +747,26 @@ srchbot:
|
||||||
/* Search right */
|
/* Search right */
|
||||||
srchright:
|
srchright:
|
||||||
if (IsSplit(tile))
|
if (IsSplit(tile))
|
||||||
{
|
if (TiGetRightType(tile) != type)
|
||||||
if (fdir == GEO_EAST) goto donesrch;
|
goto donesrch;
|
||||||
else if (SplitDirection(tile) && fdir == GEO_NORTH) goto donesrch;
|
|
||||||
else if (!SplitDirection(tile) && fdir == GEO_SOUTH) goto donesrch;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
|
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
|
||||||
{
|
{
|
||||||
if (TiGetTypeExact(tp) != TT_SPACE)
|
if (selShortProcessTile(tp, cost + 1, GEO_EAST, lmask) == 0)
|
||||||
{
|
{
|
||||||
sd = NewSD(cost + 1, tp, pnum, GEO_EAST, lmask);
|
sd = NewSD(cost + 1, tp, TiGetLeftType(tp), pnum);
|
||||||
STACKPUSH(sd, ShortStack);
|
STACKPUSH(sd, ShortStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search other connecting planes */
|
/* Search other connecting planes */
|
||||||
donesrch:
|
donesrch:
|
||||||
if (DBIsContact(ttype))
|
if ((!IsSplit(tile)) && DBIsContact(type))
|
||||||
{
|
{
|
||||||
PlaneMask pmask;
|
PlaneMask pmask;
|
||||||
int p;
|
int p;
|
||||||
|
|
||||||
pmask = DBConnPlanes[ttype];
|
pmask = DBConnPlanes[type];
|
||||||
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
|
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
|
||||||
{
|
{
|
||||||
if (PlaneMaskHasPlane(pmask, p) && (p != pnum))
|
if (PlaneMaskHasPlane(pmask, p) && (p != pnum))
|
||||||
|
|
@ -767,9 +774,9 @@ donesrch:
|
||||||
tp = SelectDef->cd_planes[p]->pl_hint;
|
tp = SelectDef->cd_planes[p]->pl_hint;
|
||||||
GOTOPOINT(tp, &tile->ti_ll);
|
GOTOPOINT(tp, &tile->ti_ll);
|
||||||
SelectDef->cd_planes[p]->pl_hint = tp;
|
SelectDef->cd_planes[p]->pl_hint = tp;
|
||||||
if (TiGetTypeExact(tp) != TT_SPACE)
|
if (selShortProcessTile(tp, cost + 1, GEO_CENTER, lmask) == 0)
|
||||||
{
|
{
|
||||||
sd = NewSD(cost + 1, tp, p, GEO_CENTER, lmask);
|
sd = NewSD(cost + 1, tp, TiGetLeftType(tp), p);
|
||||||
STACKPUSH(sd, ShortStack);
|
STACKPUSH(sd, ShortStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -809,9 +816,10 @@ ExtRectList *
|
||||||
SelectShort(char *lab1, char *lab2)
|
SelectShort(char *lab1, char *lab2)
|
||||||
{
|
{
|
||||||
Label *selLabel, *srclab = NULL, *destlab = NULL;
|
Label *selLabel, *srclab = NULL, *destlab = NULL;
|
||||||
Tile *tile;
|
Tile *srctile, *desttile;
|
||||||
|
TileType srctype, desttype;
|
||||||
|
int srcpnum, destpnum;
|
||||||
Plane *plane;
|
Plane *plane;
|
||||||
int pnum;
|
|
||||||
PlaneMask pmask;
|
PlaneMask pmask;
|
||||||
ExtRectList *rlist;
|
ExtRectList *rlist;
|
||||||
|
|
||||||
|
|
@ -872,38 +880,43 @@ SelectShort(char *lab1, char *lab2)
|
||||||
|
|
||||||
/* Must be able to find tiles associated with each label */
|
/* Must be able to find tiles associated with each label */
|
||||||
|
|
||||||
pmask = DBTypePlaneMaskTbl[srclab->lab_type];
|
pmask = DBTypePlaneMaskTbl[destlab->lab_type];
|
||||||
for (pnum = PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++)
|
for (destpnum = PL_TECHDEPBASE; destpnum < DBNumPlanes; destpnum++)
|
||||||
{
|
{
|
||||||
if (PlaneMaskHasPlane(pmask, pnum))
|
if (PlaneMaskHasPlane(pmask, destpnum))
|
||||||
{
|
{
|
||||||
plane = SelectDef->cd_planes[pnum];
|
plane = SelectDef->cd_planes[destpnum];
|
||||||
tile = plane->pl_hint;
|
desttile = plane->pl_hint;
|
||||||
GOTOPOINT(tile, &srclab->lab_rect.r_ll)
|
GOTOPOINT(desttile, &destlab->lab_rect.r_ll)
|
||||||
if (TiGetType(tile) == srclab->lab_type) break;
|
desttype = TiGetTopType(desttile);
|
||||||
|
if (TTMaskHasType(&DBConnectTbl[destlab->lab_type], desttype)) break;
|
||||||
|
desttype = TiGetBottomType(desttile);
|
||||||
|
if (TTMaskHasType(&DBConnectTbl[destlab->lab_type], desttype)) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selShortFindNext(tile, pnum, destlab, &DBConnectTbl[srclab->lab_type]);
|
pmask = DBTypePlaneMaskTbl[srclab->lab_type];
|
||||||
|
for (srcpnum = PL_TECHDEPBASE; srcpnum < DBNumPlanes; srcpnum++)
|
||||||
|
{
|
||||||
|
if (PlaneMaskHasPlane(pmask, srcpnum))
|
||||||
|
{
|
||||||
|
plane = SelectDef->cd_planes[srcpnum];
|
||||||
|
srctile = plane->pl_hint;
|
||||||
|
GOTOPOINT(srctile, &srclab->lab_rect.r_ll)
|
||||||
|
srctype = TiGetTopType(srctile);
|
||||||
|
if (TTMaskHasType(&DBConnectTbl[srclab->lab_type], srctype)) break;
|
||||||
|
srctype = TiGetBottomType(srctile);
|
||||||
|
if (TTMaskHasType(&DBConnectTbl[srclab->lab_type], srctype)) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selShortFindForward(srctile, srctype, srcpnum, desttile, desttype);
|
||||||
|
|
||||||
/* Now see if destination has been counted */
|
/* Now see if destination has been counted */
|
||||||
|
if (desttile->ti_client == (ClientData)CLIENTDEFAULT) return NULL;
|
||||||
pmask = DBTypePlaneMaskTbl[destlab->lab_type];
|
|
||||||
for (pnum = PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++)
|
|
||||||
{
|
|
||||||
if (PlaneMaskHasPlane(pmask, pnum))
|
|
||||||
{
|
|
||||||
plane = SelectDef->cd_planes[pnum];
|
|
||||||
tile = plane->pl_hint;
|
|
||||||
GOTOPOINT(tile, &destlab->lab_rect.r_ll)
|
|
||||||
if (TiGetType(tile) == destlab->lab_type) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile->ti_client == (ClientData)CLIENTDEFAULT) return NULL;
|
|
||||||
|
|
||||||
/* Now find the shortest path between source and destination */
|
/* Now find the shortest path between source and destination */
|
||||||
rlist = NULL;
|
rlist = NULL;
|
||||||
selShortFindPath(&rlist, tile, pnum, GEO_CENTER);
|
selShortFindReverse(&rlist, desttile, destpnum, GEO_CENTER);
|
||||||
|
|
||||||
return rlist;
|
return rlist;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue