The best way to ensure that method logic is executed once without a boolean flag

This is a way to execute Dosomething logic after using the flag. (C # and Update code is always called once for each frame.)
And it’s not so difficult, simple, very simple and well used.

class Monster {
    bool isCalled = false;
    float energy = 0.0f;

    void Update()
    {
        energy += Random.Range(0f, 1f);
        if((isCalled == false) && (energy>100.0f))
        {
            isCalled = true;
            DoSomething();
        }
    }

    void DoSomething(){}
}

But I believe that managing a Boolean flag is a kind of tedious task.
Therefore, I am trying to find the best alternatives.

Is there a better or elegant way to do this (doing Dosomething once) without a boolean flag?
For example, another design template template, etc.

+4
source share
5 answers

.

, . bool, :

if(instance == null)
{
    .. // do something
}

, . , : string.IsNullOrEmpty, double.IsNaN, ..

, . , - .

state-machine, , Monster , , :

class Monster
{
    enum States { NotInitialized, Dead, Normal, EnergyMax, ... }
    States _state;
    float _energy;

    void Update()
    {
        _energy += Random.Range(0f, 1f);
        switch(_state)
        {
            case States.Normal:
                if(_energy > EnergyMax)
                {
                    DoSomething(); // called once when energy become max
                    _state = States.EnergyMax;
                }
                break;
            ...
        }
    }
    ...
}
+1

enum, :

class Monster {
  [Flags]
  private enum Status {
    Updated,
    Called,
    Killed,  
    ... 
  }

  private Status status;

  void Update() {
    if ((status & Status.Updated) == Status.Updated)
      return;

    try {
      ....
    }
    finally {
      status |= Status.Updated;
    } 
  }
}
+2

, DoSomething NOP :

class Monster {
    float energy = 0.0f;
    Action onUpdate;

    public Monster()
    {
        onUpdate = DoSomething;
    }

    void Update()
    {
        onUpdate();
    }

    void DoSomething()
    {
        energy += Random.Range(0f, 1f);
        if(energy > 100.0f)
        {
            // whatever you need to do
        }
        onUpdate = () => {};
    }
}

, boolean , , .

+1

- :

class Monster
{
    private Action _doSomething;

    public Monster()
    {
        _doSomething = DoSomething;
    }

    float energy = 0.0f;

    void Update()
    {
        energy += Random.Range(0f, 1f);
        if (energy > 100.0f)
            if (_doSomething != null)
                _doSomething();
    }

    void DoSomething() 
    {
        // logic...
        _doSomething = null;
    }
}

, - . - . /..

0

You can use the status template as follows:

class Monster
    {
        float energy = 0.0f;
        DoSomethingState state;

        public Monster()
        {
            this.state = new DoSomethingStateNotCalled(this);
        }

        public void Update()
        {
            energy += Random.Range(0f, 1f);
            this.state.Update();
        }

        public void DoSomething() {
            System.Diagnostics.Debug.Write("done something");
        }

        public float GetEnergy() {
            return this.energy;
        }

        public void SetState(DoSomethingState state) {
            this.state = state;
        }
    }

abstract class DoSomethingState {

        protected Monster Monster;

        public DoSomethingState(Monster monster) {
            this.Monster = monster;
        }

        public abstract void Update();
    }

class DoSomethingStateCalled : DoSomethingState
    {
        public DoSomethingStateCalled(Monster monster)
            : base(monster)
        {
        }

        public override void Update()
        {
        }
    }

 class DoSomethingStateNotCalled : DoSomethingState
    {
        public DoSomethingStateNotCalled(Monster monster)
            : base(monster)
        {
        }

        public override void Update()
        {
            if (this.Monster.GetEnergy() > 100.0f)
            {
                this.Monster.DoSomething();
                this.Monster.SetState(new DoSomethingStateCalled(this.Monster));
            }
        }
    }
0
source

Source: https://habr.com/ru/post/1617709/


All Articles