Действуйте на turnOff () только один раз, когда все объекты, вызвавшие turnOn (), вызывают turnOff () - PullRequest
0 голосов
/ 17 июля 2009

Я хочу иметь 2 статические функции, которые называются turnOn () и turnOff ().

Скажем, objectA вызывает turnOn (), затем objectB вызывает turnOn (). Затем objectA вызывает turnOff (), он не должен выключаться, потому что objectB также включал его.

Также, скажем, objectA вызывает turnOn (), затем objectB вызывает turnOn (). Затем objectB вызывает turnOff (), он не должен выключаться, потому что objectA еще не выключил его.

Наконец, если objectA и objectB включают его, он выключается, когда они оба выключают его.

Я думал о том, чтобы отследить, сколько вызовов TurnOn и TurnOff, и убедиться, что они совпадают, но это не совсем точно, потому что objectA может дважды вызывать turnOff ().

Так, как лучше всего справиться с этим?

Спасибо!

Ответы [ 5 ]

1 голос
/ 17 июля 2009

Самый простой способ, как вы описываете: вести счет. Если вы действительно заинтересованы в том, чтобы объект отключил его, когда он еще не включил, вы можете сохранить список всех объектов, которые его включили, и удалить их из списка, когда они его выключат. Если список пуст, вы можете его отключить.

1 голос
/ 17 июля 2009

Это похоже на подсчет ссылок

0 голосов
/ 17 июля 2009

Решение состоит из двух частей: - счетчик статических объектов, как предложено в другом месте, - и флаг isTurnedOn для каждого объекта, который предотвращает включение или выключение объекта дважды, что-то вроде этого псевдокода:

...
private static in count = 0;
private boolean isTurnedOn = false;
...
public void TurnON() {
    if (!isTurnedOn) {
        isTurnedOn = true;
        ++count;
    }
}

public void TurnOff() {
    if (isTurnedOn) {
        isTunedOn = false;
        --count;
        if (count == 0) {
            // the conter reached 0, do soemthing
            // but do not forget to protect against concurretn access
    }
 }

Обратите внимание, что эта конструкция позволяет многократно включать и выключать объект. Если вы хотите предотвратить это, возможно, вам следует использовать два отдельных логических значения для isTurnedOn и isTurnedOff.

0 голосов
/ 17 июля 2009

Я не уверен на 100%, что это то, что вы ищете, но я думаю, вы захотите иметь статический массив, чтобы определить, что включено или нет. Также ... честное предупреждение, я не тестировал этот код. Это очень грубая оценка того, что, как я думал, вы хотели бы сделать.

class Switchable {
    static var _onObjects:Array=new Array  ;
    static public  function turnOn(obj:Object):Void {
        if (_onObjects.indexOf(obj) == -1) {
            _onObjects.push(obj);
        }
    }
    static public  function turnOff(obj:Object):Void {
        var index=_onObjects.indexOf(obj);
        if (isOn() && index >= 0) {
            _onObjects=_onObjects.splice(index,1);
        }
    }
    static public  function isOn():Boolean {
        return _onObjects.length > 0;
    }
}
class ObjectA {
    public function Foo():Void {
        Switchable.turnOn(this);
    }
    public function Bar():Void {
        Switchable.turnOff(this);
    }
}
class ObjectB {
    public function Foo():Void {
        Switchable.turnOn(this);
    }
    public function Bar():Void {
        Switchable.turnOff(this);
    }
}
class Test {
    static public  function Main():Void {
        trace(Switchable.isOn());
        var a:ObjectA=new ObjectA  ;
        var b:ObjectB=new ObjectB  ;
        a.Foo();
        trace(Switchable.isOn());
        b.Foo();
        trace(Switchable.isOn());
        a.Bar();
        trace(Switchable.isOn());
        b.Bar();
        trace(Switchable.isOn());
    }
}
0 голосов
/ 17 июля 2009

Редактировать: пример кода на c # - я не знал, что это не был вопрос c #. Если у вас есть хеш-таблицы, словари или даже двумерные массивы (таблицы) на вашем языке, этот же базовый шаблон все еще должен работать.

Звучит так, будто вам нужен модифицированный счетчик ссылок - счетчик по объекту. Как насчет такого:


public class Switch
{
  private bool On;
  private Dictionary<object, int> ReferenceCounts = new ...
  public void TurnOn(object source)
  {
     int count = 0;
     if(ReferenceCounts.ContainsKey(source))
        count = ReferenceCounts[source];
     count++;
     ReferenceCounts[source] = count;
     On = true;
  }

  public void TurnOff(object source)
  {
    if(!ReferenceCounts.ContainsKey(source))
       return;

    int count = ReferenceCounts[source];
    count--;
    if(count == 0)
      ReferenceCounts.Remove(source)
    else
      ReferenceCounts[source] = count;

    if(ReferenceCounts.Count == 0)
      this.On = false;
  }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...