Fix #595 - IDisposable crash.

This commit is contained in:
Paul Chote
2011-03-17 22:22:09 +13:00
parent d05b979e53
commit c568759e49
5 changed files with 31 additions and 8 deletions

View File

@@ -39,8 +39,9 @@ namespace OpenRA.Mods.RA.Air
NextActivity);
var res = dest.TraitOrDefault<Reservable>();
var heli = self.Trait<Helicopter>();
if (res != null)
self.Trait<Helicopter>().reservation = res.Reserve(dest, self);
heli.reservation = res.Reserve(dest, self, heli);
var exit = dest.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
var offset = exit != null ? exit.SpawnOffset : int2.Zero;

View File

@@ -92,7 +92,7 @@ namespace OpenRA.Mods.RA.Air
if (Reservable.IsReserved(order.TargetActor)) return;
var res = order.TargetActor.TraitOrDefault<Reservable>();
if (res != null)
reservation = res.Reserve(order.TargetActor, self);
reservation = res.Reserve(order.TargetActor, self, this);
var exit = order.TargetActor.Info.Traits.WithInterface<ExitInfo>().FirstOrDefault();
var offset = exit != null ? exit.SpawnOffset : int2.Zero;

View File

@@ -46,7 +46,7 @@ namespace OpenRA.Mods.RA.Air
{
var res = afld.Trait<Reservable>();
if (res != null)
reservation = res.Reserve(afld, self);
reservation = res.Reserve(afld, self, this);
}
}
}

View File

@@ -46,7 +46,7 @@ namespace OpenRA.Mods.RA.Air
if (res != null)
{
plane.UnReserve();
plane.reservation = res.Reserve(dest, self);
plane.reservation = res.Reserve(dest, self, plane);
}
var landPos = dest.CenterLocation;

View File

@@ -10,14 +10,16 @@
using System;
using OpenRA.Traits;
using OpenRA.Mods.RA.Air;
namespace OpenRA.Mods.RA
{
class ReservableInfo : TraitInfo<Reservable> {}
public class Reservable : ITick
public class Reservable : ITick, INotifyDamage, INotifyCapture, INotifySold
{
Actor reservedFor;
Aircraft herp;
public void Tick(Actor self)
{
@@ -28,15 +30,16 @@ namespace OpenRA.Mods.RA
reservedFor = null; /* not likely to arrive now. */
}
public IDisposable Reserve(Actor self, Actor forActor)
public IDisposable Reserve(Actor self, Actor forActor, Aircraft derp)
{
reservedFor = forActor;
herp = derp;
// NOTE: we really dont care about the GC eating DisposableActions that apply to a world *other* than
// the one we're playing in.
return new DisposableAction(
() => reservedFor = null,
() => {reservedFor = null; herp = null;},
() => Game.RunAfterTick(
() => { if (Game.IsCurrentWorld( self.World )) throw new InvalidOperationException(
"Attempted to finalize an undisposed DisposableAction. {0} ({1}) reserved {2} ({3})"
@@ -48,5 +51,24 @@ namespace OpenRA.Mods.RA
var res = a.TraitOrDefault<Reservable>();
return res != null && res.reservedFor != null;
}
public void Damaged(Actor self, AttackInfo e)
{
if (herp != null && e.DamageStateChanged && e.DamageState == DamageState.Dead)
herp.UnReserve();
}
public void OnCapture (Actor self, Actor captor, Player oldOwner, Player newOwner)
{
if (herp != null)
herp.UnReserve();
}
public void Selling (Actor self) { Sold(self); }
public void Sold (Actor self)
{
if (herp != null)
herp.UnReserve();
}
}
}