订阅集合元素中的计算值

时间:2018-02-09 23:09:57

标签: c# unity3d reactive-programming unirx

我有玩家建筑的ReactiveCollection。是否可以仅在ProductionPerHour或ProducedResourceId值更改时订阅此集合?

我的意思是这样的?

public void Sub()
{
      var collection = new ReactiveCollection<PlayerBuilding>();
      collection
         .where(x => x.ProducedResourceId == 1)
         .sum(y => y)
         .subscribe(_ => something);
}

public class PlayerBuilding
{
     public ReactiveProperty<SimpleRessourceEnum?> ProducedResourceId;
     public ReactiveProperty<int?> ProductionPerHour;
     public ReactiveProperty<int?> ProductionLimit;
}

更新

这样做的目的是将生产金额映射到textValue。因此,只有当ProductionPerHour改变时,我才需要订阅信号,其中任何建筑物的ProducedResourceId = myResource或ProducedResourceId将被设置为myResource.Pseudo代码示例

public class ResourceItemScript : MonoBehaviour {
     private Text _valueText;
     private void Awake()
     {
          _valueText = transform.FindDeepChild("Text").GetComponent<Text>();
     }
     private void Start()
     {
     _productionService.GetProductionSumObservable(myResource)
          .SubscribeToText(_valueText);
     }
}

1 个答案:

答案 0 :(得分:0)

我是新的反应式编程,经过一些调查后我找到了解决这个问题的方法。我创建了Subject,它是我的Buildings集合和我的UI textBox之间的桥梁。我不认为这是最好的解决方案,但它看起来它以某种方式工作。所有的提示和建议都非常受欢迎。

public class ProductionSummaryObservable
{
    static Subject<Dictionary<SimpleRessourceEnum, int>> _subject;
    IBuildingsService _buildingService;
    IProductionService _productionService;

    private static readonly object lockObject = new object();

    protected Subject<Dictionary<SimpleRessourceEnum, int>> Subject
    {
        get
        {
            lock (lockObject)
            {
                if (_subject == null)
                {
                    _subject = new Subject<Dictionary<SimpleRessourceEnum, int>>();

                    var observables = _buildingService.GetProductionBuildings()
                        .Select(x => new { Level = x.Level, ProducedResource = x.ProducedResourceId })
                        .ToList();

                    Observable.Merge(observables
                        .Select(x => x.Level.AsObservable()))
                        .Subscribe(_ => _subject.OnNext(_productionService.GetProductionSummary()));
                    Observable.Merge(observables
                        .Select(x => x.ProducedResource.AsObservable()))
                        .Subscribe(_ => _subject.OnNext(_productionService.GetProductionSummary()));
                }
            }

            return _subject;
        }
    }

    public ProductionSummaryObservable(IBuildingsService buildingService, IProductionService productionService)
    {
        _buildingService = buildingService;
        _productionService = productionService;
    }

    public IObservable<int> ProductionSummaryByResourceObservable(SimpleRessourceEnum resource)
    {
        return Subject.Select(x => x.First(y => y.Key == resource).Value);
    }
}