mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-27 10:32:31 +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:
parent
6da3e73e63
commit
971301d5b8
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user