1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-11 17:29:29 +00:00

Fix object timeout

Remember how object references from plugins are proxy objects that
time out if you don't access them for a while?  I didn't either.

This reshuffles the code to keep WireframeObject references rather
than IVisualizationWireframe.
This commit is contained in:
Andy McFadden 2020-03-10 11:23:18 -07:00
parent 6da3e73e63
commit 971301d5b8
5 changed files with 53 additions and 49 deletions

View File

@ -140,7 +140,8 @@ namespace PluginCommon {
foreach (IntPair ip in mEdges) {
if (ip.Val0 < 0 || ip.Val0 >= vertexCount ||
ip.Val1 < 0 || ip.Val1 >= vertexCount) {
msg = "invalid edge";
msg = "invalid edge (vertices " + ip.Val0 + ", " + ip.Val1 +
"; count=" + vertexCount + ")";
return false;
}
}
@ -149,7 +150,7 @@ namespace PluginCommon {
foreach (IntPair ip in mVertexFaces) {
if (ip.Val0 < 0 || ip.Val0 >= vertexCount ||
ip.Val1 < 0 || ip.Val1 >= faceCount) {
msg = "invalid vertex-face";
msg = "invalid vertex-face (v=" + ip.Val0 + ", f=" + ip.Val1 + ")";
return false;
}
}
@ -158,7 +159,7 @@ namespace PluginCommon {
foreach (IntPair ip in mVertexFaces) {
if (ip.Val0 < 0 || ip.Val0 >= edgeCount ||
ip.Val1 < 0 || ip.Val1 >= faceCount) {
msg = "invalid edge-face";
msg = "invalid edge-face (e=" + ip.Val0 + ", f=" + ip.Val1 + ")";
return false;
}
}

View File

@ -51,7 +51,7 @@ namespace SourceGen {
public const string P_DELTA_ROT_Y = "_deltaRotY";
public const string P_DELTA_ROT_Z = "_deltaRotZ";
private IVisualizationWireframe mVisWire;
private WireframeObject mWireObj;
/// <summary>
@ -59,10 +59,10 @@ namespace SourceGen {
/// </summary>
public VisWireframeAnimation(string tag, string visGenIdent,
ReadOnlyDictionary<string, object> visGenParams, Visualization oldObj,
IVisualizationWireframe visWire)
WireframeObject wireObj)
: base(tag, visGenIdent, visGenParams, oldObj) {
// visWire may be null when loading from project file
mVisWire = visWire;
// wireObj may be null when loading from project file
mWireObj = wireObj;
OverlayImage = ANIM_OVERLAY_IMAGE;
}
@ -71,7 +71,7 @@ namespace SourceGen {
/// </summary>
/// <remarks>
/// We override it because this is our first opportunity to capture the
/// IVisualizationWireframe reference when the object was created during project
/// wireframe object reference if the object was created during project
/// file loading.
/// </remarks>
/// <param name="visWire">Reference to wireframe data generated by plugin.</param>
@ -79,7 +79,7 @@ namespace SourceGen {
public override void SetThumbnail(IVisualizationWireframe visWire,
ReadOnlyDictionary<string, object> parms) {
base.SetThumbnail(visWire, parms);
mVisWire = visWire;
mWireObj = WireframeObject.Create(visWire);
}
/// <summary>
@ -100,7 +100,7 @@ namespace SourceGen {
bool doBfc = Util.GetFromObjDict(VisGenParams, VisWireframe.P_IS_BFC_ENABLED, false);
for (int frame = 0; frame < frameCount; frame++) {
BitmapSource bs = GenerateWireframeImage(mVisWire, dim,
BitmapSource bs = GenerateWireframeImage(mWireObj, dim,
curX, curY, curZ, doPersp, doBfc);
encoder.AddFrame(BitmapFrame.Create(bs), frameDelayMsec);

View File

@ -196,7 +196,8 @@ namespace SourceGen {
ReadOnlyDictionary<string, object> parms) {
Debug.Assert(visWire != null);
Debug.Assert(parms != null);
CachedImage = GenerateWireframeImage(visWire, THUMBNAIL_DIM, parms);
WireframeObject wireObj = WireframeObject.Create(visWire);
CachedImage = GenerateWireframeImage(wireObj, THUMBNAIL_DIM, parms);
}
/// <summary>
@ -257,30 +258,30 @@ namespace SourceGen {
/// <param name="dim">Output bitmap dimension (width and height).</param>
/// <param name="parms">Parameter set, for rotations and render options.</param>
/// <returns>Rendered bitmap.</returns>
public static BitmapSource GenerateWireframeImage(IVisualizationWireframe visWire,
public static BitmapSource GenerateWireframeImage(WireframeObject wireObj,
double dim, ReadOnlyDictionary<string, object> parms) {
int eulerX = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_X, 0);
int eulerY = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Y, 0);
int eulerZ = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Z, 0);
bool doPersp = Util.GetFromObjDict(parms, VisWireframe.P_IS_PERSPECTIVE, false);
bool doBfc = Util.GetFromObjDict(parms, VisWireframe.P_IS_BFC_ENABLED, false);
return GenerateWireframeImage(visWire, dim, eulerX, eulerY, eulerZ, doPersp, doBfc);
return GenerateWireframeImage(wireObj, dim, eulerX, eulerY, eulerZ, doPersp, doBfc);
}
/// <summary>
/// Generates a BitmapSource from IVisualizationWireframe data. Useful for thumbnails
/// and GIF exports.
/// </summary>
public static BitmapSource GenerateWireframeImage(IVisualizationWireframe visWire,
public static BitmapSource GenerateWireframeImage(WireframeObject wireObj,
double dim, int eulerX, int eulerY, int eulerZ, bool doPersp, bool doBfc) {
// Generate the path geometry.
GeometryGroup geo = GenerateWireframePath(visWire, dim, eulerX, eulerY, eulerZ,
GeometryGroup geo = GenerateWireframePath(wireObj, dim, eulerX, eulerY, eulerZ,
doPersp, doBfc);
// Render Path to bitmap -- https://stackoverflow.com/a/23582564/294248
Rect bounds = geo.GetRenderBounds(null);
Debug.WriteLine("RenderWF dim=" + dim + " bounds=" + bounds + ": " + visWire);
Debug.WriteLine("RenderWF dim=" + dim + " bounds=" + bounds + ": " + wireObj);
// Create bitmap.
RenderTargetBitmap bitmap = new RenderTargetBitmap(
@ -319,14 +320,14 @@ namespace SourceGen {
/// <param name="visWire">Visualization data.</param>
/// <param name="dim">Width/height to use for path area.</param>
/// <param name="parms">Visualization parameters.</param>
public static GeometryGroup GenerateWireframePath(IVisualizationWireframe visWire,
public static GeometryGroup GenerateWireframePath(WireframeObject wireObj,
double dim, ReadOnlyDictionary<string, object> parms) {
int eulerX = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_X, 0);
int eulerY = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Y, 0);
int eulerZ = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Z, 0);
bool doPersp = Util.GetFromObjDict(parms, VisWireframe.P_IS_PERSPECTIVE, false);
bool doBfc = Util.GetFromObjDict(parms, VisWireframe.P_IS_BFC_ENABLED, false);
return GenerateWireframePath(visWire, dim, eulerX, eulerY, eulerZ, doPersp, doBfc);
return GenerateWireframePath(wireObj, dim, eulerX, eulerY, eulerZ, doPersp, doBfc);
}
/// <summary>
@ -334,20 +335,21 @@ namespace SourceGen {
/// scaled if the output area is larger or smaller than the path bounds, so this scales
/// coordinates so they fit within the box.
/// </summary>
public static GeometryGroup GenerateWireframePath(IVisualizationWireframe visWire,
public static GeometryGroup GenerateWireframePath(WireframeObject wireObj,
double dim, int eulerX, int eulerY, int eulerZ, bool doPersp, bool doBfc) {
// WPF path drawing is based on a system where a pixel is drawn at the center
// of the coordinate, and integer coordinates start at the top left edge. If
// you draw a pixel at (0,0), most of the pixel will be outside the window
// (visible or not based on ClipToBounds).
// of its coordinates, and integer coordinates start at the top left edge of
// the drawing area. If you draw a pixel at (0,0), 3/4ths of the pixel will be
// outside the window (visible or not based on ClipToBounds).
//
// If you draw a line from (1,1 to 4,1), the line's length will appear to
// be (4 - 1) = 3. It touches four pixels -- the end point is not exclusive --
// but because the thickness doesn't extend past the endpoints, the filled
// area is only three. If you have a window of size 10x10, and you draw from
// 0,0 to 9,9, the line will extend for half a line-thickness off the top,
// but will not go past the right/left edges. (This becomes very obvious when
// you're working with an up-scaled 8x8 path.)
// but the filled area is only three, because the thickness doesn't extend the
// line's length, and the line stops at the coordinate at the center of the pixel.
// You're not drawing N pixels, you're drawing from one coordinate point to another.
// If you have a window of size 8x8, and you draw from 0,0 to 7,0, the line will
// extend for half a line-thickness off the top, but will not go past the right/left
// edges. (This becomes very obvious when you're working with an up-scaled 8x8 path.)
//
// Similarly, drawing a horizontal line two units long results in a square, and
// drawing a line that starts and ends at the same point doesn't appear to
@ -357,12 +359,13 @@ namespace SourceGen {
// This turns out to be important for another reason: a line from (1,1) to (9,1)
// shows up as a double-wide half-bright line, while a line from (1.5,1.5) to
// (9.5,1.5) is drawn as a single-wide full-brightness line. This is because of
// the anti-aliasing.
// the anti-aliasing. Anti-aliasing can be disabled, but the lines look much
// nicer with it enabled.
//
// The path has an axis-aligned bounding box that covers the pixel centers. If we
// want a path-drawn shape to animate smoothly we want to ensure that the bounds
// want a path-drawn mesh to animate smoothly we want to ensure that the bounds
// are constant across all renderings of a shape (which could get thinner or wider
// as it rotates), so we draw an invisible pixel in our desired bottom-right corner.
// as it rotates), so we plot an invisible point in our desired bottom-right corner.
//
// If we want an 8x8 bitmap, we draw a line from (8,8) to (8,8) to establish the
// bounds, then draw lines with coordinates from 0.5 to 7.5.
@ -377,7 +380,6 @@ namespace SourceGen {
// Generate a list of clip-space line segments. Coordinate values are in the
// range [-1,1], with +X to the right and +Y upward.
WireframeObject wireObj = WireframeObject.Create(visWire);
List<WireframeObject.LineSeg> segs = wireObj.Generate(eulerX, eulerY, eulerZ,
doPersp, doBfc);

View File

@ -52,8 +52,8 @@ namespace SourceGen.WpfGui {
private SortedList<int, VisualizationSet> mEditedList;
private Visualization mOrigVis;
// IVisualization2d or IVisualizationWireframe
public object mVisObj;
private BitmapSource mThumbnail;
private WireframeObject mWireObj;
/// <summary>
/// Visualization generation identifier for the last visualizer we used, for the benefit
@ -384,19 +384,19 @@ namespace SourceGen.WpfGui {
Debug.Assert(isTagValid);
if (isWireframe && IsWireframeAnimated) {
NewVis = new VisWireframeAnimation(trimTag, item.VisDescriptor.Ident, valueDict,
mOrigVis, (IVisualizationWireframe) mVisObj);
mOrigVis, mWireObj);
} else {
NewVis = new Visualization(trimTag, item.VisDescriptor.Ident, valueDict, mOrigVis);
}
// Set the thumbnail image.
if (isWireframe) {
Debug.Assert(mVisObj is IVisualizationWireframe);
NewVis.CachedImage =
Visualization.GenerateWireframeImage((IVisualizationWireframe)mVisObj,
Visualization.THUMBNAIL_DIM, valueDict);
Debug.Assert(mWireObj != null);
NewVis.CachedImage = Visualization.GenerateWireframeImage(mWireObj,
Visualization.THUMBNAIL_DIM, valueDict);
} else {
Debug.Assert(mVisObj is IVisualization2d);
NewVis.CachedImage =
Visualization.ConvertToBitmapSource((IVisualization2d)mVisObj);
Debug.Assert(mThumbnail != null);
NewVis.CachedImage = mThumbnail;
}
sLastVisIdent = NewVis.VisGenIdent;
@ -600,16 +600,17 @@ namespace SourceGen.WpfGui {
BitmapDimensions = string.Format("{0}x{1}",
previewImage.Source.Width, previewImage.Source.Height);
mVisObj = vis2d;
mThumbnail = (BitmapSource)previewImage.Source;
} else {
previewGrid.Background = Brushes.Black;
previewImage.Source = Visualization.BLANK_IMAGE;
double dim = Math.Floor(
Math.Min(previewImage.ActualWidth, previewImage.ActualHeight));
wireframePath.Data = Visualization.GenerateWireframePath(visWire, dim, parms);
WireframeObject wireObj = WireframeObject.Create(visWire);
wireframePath.Data = Visualization.GenerateWireframePath(wireObj, dim, parms);
BitmapDimensions = "n/a";
mVisObj = visWire;
mWireObj = wireObj;
}
}
@ -690,7 +691,7 @@ namespace SourceGen.WpfGui {
}
private void TestAnim_Click(object sender, RoutedEventArgs e) {
ShowWireframeAnimation dlg = new ShowWireframeAnimation(this, (IVisualizationWireframe)mVisObj,
ShowWireframeAnimation dlg = new ShowWireframeAnimation(this, mWireObj,
CreateVisGenParams(true));
dlg.ShowDialog();
}

View File

@ -33,7 +33,7 @@ namespace SourceGen.WpfGui {
/// </summary>
private DispatcherTimer mTimer;
IVisualizationWireframe mVisWire;
WireframeObject mWireObj;
private int mFrameCount;
private int mInitialX, mInitialY, mInitialZ;
private int mDeltaX, mDeltaY, mDeltaZ;
@ -43,12 +43,12 @@ namespace SourceGen.WpfGui {
private int mCurFrame;
public ShowWireframeAnimation(Window owner, IVisualizationWireframe visWire,
public ShowWireframeAnimation(Window owner, WireframeObject wireObj,
ReadOnlyDictionary<string, object> parms) {
InitializeComponent();
Owner = owner;
mVisWire = visWire;
mWireObj = wireObj;
mCurX = mInitialX = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_X, 0);
mCurY = mInitialY = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Y, 0);
@ -98,7 +98,7 @@ namespace SourceGen.WpfGui {
// We use the dimensions of the Border surrounding the ViewBox, rather than the
// ViewBox itself, because on the first iteration the ViewBox has a size of zero.
double dim = Math.Floor(Math.Min(testBorder.ActualWidth, testBorder.ActualHeight));
wireframePath.Data = Visualization.GenerateWireframePath(mVisWire, dim,
wireframePath.Data = Visualization.GenerateWireframePath(mWireObj, dim,
mCurX, mCurY, mCurZ, mDoPersp, mDoBfc);
}
}