Fixed the error that causes problems with the tile allocation.
The error was in selStretchEraseFunc2() which was calling DBErase(). But DBErase() can call DBSrPaintArea() and thereby start another search of the same plane while the plane is already in a search. This is absolutely invalid. However, it is simple just to use selStretchEraseFunc2() to collect a mask of the types that need to be erased and pass that back to the caller, and apply DBErase() to each type in the mask, outside of the DBSrPaintArea() search. With this fix, the tile allocation is no longer causing problems, and the code to add tiles deallocated by TiJoinX and TiJoinY to the free tile list has been uncommented again.
This commit is contained in:
parent
c87e5baff4
commit
227f264838
|
|
@ -60,6 +60,7 @@ typedef struct planeAndArea
|
|||
int pa_plane; /* Plane of interest */
|
||||
Rect *pa_area; /* Area affected */
|
||||
TileTypeBitMask *pa_mask; /* Mask used in plane search */
|
||||
TileTypeBitMask pa_rmask; /* Mask to generate during search */
|
||||
} planeAndArea;
|
||||
|
||||
/* The following structure type is used to build up a list of areas
|
||||
|
|
@ -1739,9 +1740,18 @@ selStretchEraseFunc(tile, plane)
|
|||
pa.pa_area = &editArea;
|
||||
pa.pa_plane = planeNum;
|
||||
pa.pa_mask = &tmpmask;
|
||||
TTMaskZero(&pa.pa_rmask);
|
||||
|
||||
/* Find all the types that need to be erased inside editArea and
|
||||
* generate a mask from them. Then erase each type.
|
||||
*/
|
||||
DBSrPaintArea((Tile *)NULL, EditCellUse->cu_def->cd_planes[planeNum],
|
||||
&editArea, &tmpmask, selStretchEraseFunc2, (ClientData)&pa);
|
||||
|
||||
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
|
||||
if (TTMaskHasType(&pa.pa_rmask, t))
|
||||
DBErase(EditCellUse->cu_def, &editArea, t);
|
||||
|
||||
ui.pu_pNum = planeNum;
|
||||
ui.pu_def = EditCellUse->cu_def;
|
||||
DBPaintPlane(EditCellUse->cu_def->cd_planes[planeNum], &editArea,
|
||||
|
|
@ -1755,18 +1765,21 @@ selStretchEraseFunc2(tile, pa)
|
|||
Tile *tile;
|
||||
planeAndArea *pa;
|
||||
{
|
||||
TileType type = TT_SPACE;
|
||||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
if (TTMaskHasType(pa->pa_mask, TiGetLeftType(tile)))
|
||||
DBErase(EditCellUse->cu_def, pa->pa_area,
|
||||
DBPlaneToResidue(TiGetLeftType(tile), pa->pa_plane));
|
||||
type = DBPlaneToResidue(TiGetLeftType(tile), pa->pa_plane);
|
||||
if (TTMaskHasType(pa->pa_mask, TiGetRightType(tile)))
|
||||
DBErase(EditCellUse->cu_def, pa->pa_area,
|
||||
DBPlaneToResidue(TiGetRightType(tile), pa->pa_plane));
|
||||
type = DBPlaneToResidue(TiGetRightType(tile), pa->pa_plane);
|
||||
}
|
||||
else
|
||||
DBErase(EditCellUse->cu_def, pa->pa_area,
|
||||
DBPlaneToResidue(TiGetType(tile), pa->pa_plane));
|
||||
type = DBPlaneToResidue(TiGetType(tile), pa->pa_plane);
|
||||
|
||||
if (type != TT_SPACE)
|
||||
TTMaskSetType(&pa->pa_rmask, type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -820,7 +820,7 @@ TiJoinX1(Tile **delay1, Tile *tile1, Tile *tile2, Plane *plane)
|
|||
{
|
||||
TiFreeIf(*delay1);
|
||||
TiJoinX(tile1, tile2, plane);
|
||||
// *delay1 = tile2;
|
||||
*delay1 = tile2;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -828,7 +828,7 @@ TiJoinY1(Tile **delay1, Tile *tile1, Tile *tile2, Plane *plane)
|
|||
{
|
||||
TiFreeIf(*delay1);
|
||||
TiJoinY(tile1, tile2, plane);
|
||||
// *delay1 = tile2;
|
||||
*delay1 = tile2;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ TiJoinX1(Tile **delay1, Tile *tile1, Tile *tile2, Plane *plane)
|
|||
{
|
||||
TiFreeIf(*delay1);
|
||||
TiJoinX(tile1, tile2, plane);
|
||||
// *delay1 = tile2;
|
||||
*delay1 = tile2;
|
||||
}
|
||||
|
||||
inline void
|
||||
|
|
@ -315,7 +315,7 @@ TiJoinY1(Tile **delay1, Tile *tile1, Tile *tile2, Plane *plane)
|
|||
{
|
||||
TiFreeIf(*delay1);
|
||||
TiJoinY(tile1, tile2, plane);
|
||||
// *delay1 = tile2;
|
||||
*delay1 = tile2;
|
||||
}
|
||||
#else
|
||||
/* To support older compilers (that don't auto emit based on -O level) */
|
||||
|
|
|
|||
Loading…
Reference in New Issue