0

I have ReactiveCollection of PlayerBuildings. Is it possible to subscribe to this collection only when ProductionPerHour or ProducedResourceId value will change ?

I mean something like this ?

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;
}

Update

The purpose of this is to map production sum to textValue. So I need a subscription signal only if ProductionPerHour will change where ProducedResourceId = myResource or ProducedResourceId of any building will be set to myResource.Pseudo code example

public class ResourceItemScript : MonoBehaviour {
     private Text _valueText;
     private void Awake()
     {
          _valueText = transform.FindDeepChild("Text").GetComponent<Text>();
     }
     private void Start()
     {
     _productionService.GetProductionSumObservable(myResource)
          .SubscribeToText(_valueText);
     }
}
Malv20
  • 159
  • 4
  • 11
  • Well, using a method to modify the value and then if the result is something then do something...? No? You could also look into IObservable interface. – Everts Feb 10 '18 at 17:39

1 Answers1

0

Im new in reactive programming and after some investigation I found some solution to this problem. I created Subject which is a bridge between my Buildings collection and my UI textBox. I dont think this is the best solution but it looks that it works somehow. All hints and suggestions are very welcome.

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);
    }
}
Malv20
  • 159
  • 4
  • 11