···136136 /// </summary>
137137 /// <param name="frameBuffer">The <see cref="FrameBuffer"/> to bind.</param>
138138 /// <returns>A token that must be disposed upon finishing use of <paramref name="frameBuffer"/>.</returns>
139139- protected ValueInvokeOnDisposal BindFrameBuffer(FrameBuffer frameBuffer)
139139+ protected IDisposable BindFrameBuffer(FrameBuffer frameBuffer)
140140 {
141141 // This setter will also take care of allocating a texture of appropriate size within the frame buffer.
142142 frameBuffer.Size = frameBufferSize;
143143144144 frameBuffer.Bind();
145145146146- return new ValueInvokeOnDisposal(frameBuffer.Unbind);
146146+ return new ValueInvokeOnDisposal<FrameBuffer>(frameBuffer, b => b.Unbind());
147147 }
148148149149- private ValueInvokeOnDisposal establishFrameBufferViewport()
149149+ private IDisposable establishFrameBufferViewport()
150150 {
151151 // Disable masking for generating the frame buffer since masking will be re-applied
152152 // when actually drawing later on anyways. This allows more information to be captured
···167167 GLWrapper.PushScissor(new RectangleI(0, 0, (int)frameBufferSize.X, (int)frameBufferSize.Y));
168168 GLWrapper.PushScissorOffset(screenSpaceMaskingRect.Location);
169169170170- return new ValueInvokeOnDisposal(returnViewport);
170170+ return new ValueInvokeOnDisposal<BufferedDrawNode>(this, d => d.returnViewport());
171171 }
172172173173 private void returnViewport()
···358358 /// <param name="delay">The offset in milliseconds from current time. Note that this stacks with other nested sequences.</param>
359359 /// <param name="recursive">Whether this should be applied to all children.</param>
360360 /// <returns>A <see cref="InvokeOnDisposal"/> to be used in a using() statement.</returns>
361361- public InvokeOnDisposal BeginDelayedSequence(double delay, bool recursive = false)
361361+ public IDisposable BeginDelayedSequence(double delay, bool recursive = false)
362362 {
363363 if (delay == 0)
364364 return null;
···366366 AddDelay(delay, recursive);
367367 double newTransformDelay = TransformDelay;
368368369369- return new InvokeOnDisposal(() =>
369369+ return new InvokeOnDisposal<(Transformable transformable, double delay, bool recursive, double newTransformDelay)>((this, delay, recursive, newTransformDelay), sender =>
370370 {
371371- if (!Precision.AlmostEquals(newTransformDelay, TransformDelay))
371371+ if (!Precision.AlmostEquals(sender.newTransformDelay, sender.transformable.TransformDelay))
372372 {
373373 throw new InvalidOperationException(
374374- $"{nameof(TransformStartTime)} at the end of delayed sequence is not the same as at the beginning, but should be. " +
375375- $"(begin={newTransformDelay} end={TransformDelay})");
374374+ $"{nameof(sender.transformable.TransformStartTime)} at the end of delayed sequence is not the same as at the beginning, but should be. " +
375375+ $"(begin={sender.newTransformDelay} end={sender.transformable.TransformDelay})");
376376 }
377377378378- AddDelay(-delay, recursive);
378378+ AddDelay(-sender.delay, sender.recursive);
379379 });
380380 }
381381···386386 /// <param name="recursive">Whether this should be applied to all children.</param>
387387 /// <returns>A <see cref="InvokeOnDisposal"/> to be used in a using() statement.</returns>
388388 /// <exception cref="InvalidOperationException">Absolute sequences should never be nested inside another existing sequence.</exception>
389389- public virtual InvokeOnDisposal BeginAbsoluteSequence(double newTransformStartTime, bool recursive = false)
389389+ public virtual IDisposable BeginAbsoluteSequence(double newTransformStartTime, bool recursive = false)
390390 {
391391 double oldTransformDelay = TransformDelay;
392392 double newTransformDelay = TransformDelay = newTransformStartTime - (Clock?.CurrentTime ?? 0);
393393394394- return new InvokeOnDisposal(() =>
394394+ return new InvokeOnDisposal<(Transformable transformable, double oldTransformDelay, double newTransformDelay)>((this, oldTransformDelay, newTransformDelay), sender =>
395395 {
396396- if (!Precision.AlmostEquals(newTransformDelay, TransformDelay))
396396+ if (!Precision.AlmostEquals(sender.newTransformDelay, sender.transformable.TransformDelay))
397397 {
398398 throw new InvalidOperationException(
399399- $"{nameof(TransformStartTime)} at the end of absolute sequence is not the same as at the beginning, but should be. " +
400400- $"(begin={newTransformDelay} end={TransformDelay})");
399399+ $"{nameof(sender.transformable.TransformStartTime)} at the end of absolute sequence is not the same as at the beginning, but should be. " +
400400+ $"(begin={sender.newTransformDelay} end={sender.transformable.TransformDelay})");
401401 }
402402403403- TransformDelay = oldTransformDelay;
403403+ sender.transformable.TransformDelay = sender.oldTransformDelay;
404404 });
405405 }
406406
+4-4
osu.Framework/Platform/NativeMemoryTracker.cs
···2424 getStatistic(source).Value += amount;
2525 GC.AddMemoryPressure(amount);
26262727- return new NativeMemoryLease(() => removeMemory(source, amount));
2727+ return new NativeMemoryLease((source, amount), sender => removeMemory(sender.source, sender.amount));
2828 }
29293030 /// <summary>
···4343 /// <summary>
4444 /// A leased on a native memory allocation. Should be disposed when the associated memory is freed.
4545 /// </summary>
4646- public class NativeMemoryLease : InvokeOnDisposal
4646+ public class NativeMemoryLease : InvokeOnDisposal<(object source, long amount)>
4747 {
4848- internal NativeMemoryLease(Action action)
4949- : base(action)
4848+ internal NativeMemoryLease((object source, long amount) sender, Action<(object source, long amount)> action)
4949+ : base(sender, action)
5050 {
5151 }
5252