public void ExchangerLimbo() {
     InvalidCallbackMaker.AssertCollectedAfter(a => {
         var r = new LifetimeExchanger();
         var life = r.StartNextAndEndPreviousLifetime();
         life.WhenDead(a);
         return life;
     });
 }
 public void ExchangerConcurrency() {
     var repeats = 5;
     foreach (var _ in Enumerable.Range(0, repeats)) {
         var n = 0;
         var exchanger = new LifetimeExchanger();
         TestUtil.ConcurrencyTest(
             threadCount: 4,
             callbackCount: 3000,
             repeatedWork: (t, i) => {
                 exchanger.ActiveLifetime.WhenDead(() => Interlocked.Increment(ref n));
                 exchanger.StartNextAndEndPreviousLifetime();
             });
         n.AssertEquals(3000 * 4);
     }
 }
    public void Exchanger() {
        var r = new LifetimeExchanger();
        var life1 = r.ActiveLifetime;
        life1.IsMortal.AssertIsTrue();

        var life2 = r.StartNextAndEndPreviousLifetime();
        r.ActiveLifetime.AssertEquals(life2);
        life1.IsDead.AssertIsTrue();
        life2.IsMortal.AssertIsTrue();

        var life3 = r.StartNextAndImmortalizePreviousLifetime();
        r.ActiveLifetime.AssertEquals(life3);
        life2.IsImmortal.AssertIsTrue();
        life3.IsMortal.AssertIsTrue();
    }
        public MainWindow() {
            InitializeComponent();

            var gameLifeExchanger = new LifetimeExchanger();

            // show initial practice game
            this.Loaded += (sender, arg) =>
                SetupAndRunGame(
                    new Game(gameLifeExchanger.ActiveLifetime),
                    initial: true);

            // setup start button
            ButtonStart.Click += (sender, arg) => {
                MenuPanel.Visibility = Visibility.Collapsed;
                SetupAndRunGame(
                    new Game(gameLifeExchanger.StartNextAndEndPreviousLifetime()),
                    initial: false);
            };
        }