0

I have two classes. One of them have BoolReactiveProperty. I want the second class to be able to subscribe only without being able to change the value. This is my current code

public class SourceToggle : MonoBehaviour
{
    public BoolReactiveProperty boolRP { get; private set; } 
        = new BoolReactiveProperty();

    private void Start()
    {
        boolRP.Subscribe(b => GetComponent<Toggle>().isOn = b);

        GetComponent<Toggle>()
            .OnValueChangedAsObservable()
            .Subscribe(b => boolRP.SetValueAndForceNotify(b));
    }
}

public class SubscribedToggle : MonoBehaviour
{
    [SerializeField]
    private SourceToggle sourceToggle;

    private void Start()
    {
        sourceToggle.boolRP
            .Subscribe(b => GetComponent<Toggle>().isOn = b);

        GetComponent<Toggle>()
            .OnValueChangedAsObservable()
            .Subscribe(b => sourceToggle.boolRP.SetValueAndForceNotify(b));
    }
}
TANDEROID
  • 31
  • 4

2 Answers2

0

I don't totally get what you want to prevent. I guess you want to prevent your SubscribedToggle to call SetValueAndForceNotify on your ReactiveProperty?

Then declare a public IReadOnlyReactiveProperty and manage a private BoolReactiveProperty in your SourceToggle class.

public class SourceToggle : MonoBehaviour
{
    private BoolReactiveProperty isOn;
    private Toggle toggle;

    public IReadOnlyReactiveProperty<bool> IsOn => isOn;

    private void Awake()
    {
        toggle = GetComponent<Toggle>();

        isOn = new BoolReactiveProperty(toggle.isOn);

        toggle
            .OnValueChangedAsObservable()
            .Subscribe(b => isOn.SetValueAndForceNotify(b));

        isOn.Subscribe(b => toggle.isOn = b);
    }
}

public class SubscribedToggle : MonoBehaviour
{
    [SerializeField]
    private SourceToggle sourceToggle;

    private void Start()
    {
        sourceToggle.IsOn
            .Subscribe(b => GetComponent<Toggle>().isOn = b);

        // GetComponent<Toggle>()
        //     .OnValueChangedAsObservable()
        //     .Subscribe(b => sourceToggle.IsOn.SetValueAndForceNotify(b)); // Impossible to call SetValueAndForceNotify
    }
}
Hellium
  • 7,206
  • 2
  • 19
  • 49
  • Yes, I want to prevent your SubscribedToggle to call SetValueAndForceNotify on your ReactiveProperty. But, with your code I have an error: ```NullReferenceException: Object reference not set to an instance of an object UniRx.ObservableExtensions.Subscribe[T] (System.IObservable`1[T] source, System.Action`1[T] onNext) (at Assets/Plugins/UniRx/Scripts/Observer.cs:414) TEDinc.JustTiles.SubscribedToggle.Start () (at Assets/Scripts/SubscribedToggle.cs:15)``` but, i fixed it by changing Start() to Awake() method in SourceToggle – TANDEROID Mar 27 '20 at 13:14
  • Yes, changing to Awake solves the issue indeed, my bad. – Hellium Mar 27 '20 at 13:17
0

Thanks to @Hellium I found a solution

public class SourceToggle : MonoBehaviour
{
    public ReadOnlyReactiveProperty<bool> IsOn { get; private set; }

    private void Awake()
    {
        Toggle toggle = GetComponent<Toggle>();

        IsOn = new ReadOnlyReactiveProperty<bool>(toggle.OnValueChangedAsObservable());
    }
}

public class SubscribedToggle : MonoBehaviour
{
    [SerializeField]
    private SourceToggle sourceToggle;

    private void Start()
    {
        Toggle toggle = GetComponent<Toggle>();

        sourceToggle.IsOn
            .Subscribe(b => toggle.isOn = b);
    }
}
TANDEROID
  • 31
  • 4
  • The behaviour will be different than the one from your question. In your question, you had the possibility to change the value of your toggle by changing the value of the reactive property. With your new code, you don't have this possibility anymore. – Hellium Mar 27 '20 at 13:51
  • I wrote, that I should not be able to change value, as I did in my code – TANDEROID Mar 29 '20 at 11:42
  • I meant in the `SourceToggle` class. If you only have a `ReadOnlyReactiveProperty`, you can't change it's value, even if inside `SourceToggle`.With the code I've provided, you still have this possibility thanks to the private ReactiveProperty. – Hellium Mar 29 '20 at 15:59
  • I understand what you mean. But in may case, I just needed subscribe to toggle.OnValueChangedAsObservable() – TANDEROID Mar 30 '20 at 09:04