Skip to content

Instantly share code, notes, and snippets.

@jbroadway
Last active February 6, 2018 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbroadway/cf2ec36db3f17e2c16d5392f349b9cc0 to your computer and use it in GitHub Desktop.
Save jbroadway/cf2ec36db3f17e2c16d5392f349b9cc0 to your computer and use it in GitHub Desktop.
How unidirectional data flow in pure Unity might work (inspired by Redux, Vuex, etc.), minus UniRx. Assumes Zenject for dependency injection. Latest: https://github.com/lux/reactive-tests
// Business logic
public class TutorialActions {
private State _state;
[Inject]
private void Init (TutorialState state) {
_state = state;
// Fetch latest from database then call _state.SetSteps()
// and _state.SetCurrentStep()
}
public void NextStep () {
// Business logic, sync to web, etc. then update local state
_state.IncrementStep ();
}
}
// State mutations
public class TutorialState {
public delegate void StepChanged (int step);
public StepChanged OnStepChanged;
public delegate void Complete ();
public Complete OnTutorialComplete;
public delegate void StepsReady (Step[] steps);
public StepsReady OnStepsReady;
public delegate void ErrorOccurred (string err);
public ErrorOccurred OnError;
public class Step {
public string title;
public string instructions;
}
private Step[] steps;
private int step = 0;
// Called by action during initializations
public void SetSteps (Step[] steps) {
this.steps = steps;
if (OnStepsReady != null) OnStepsReady (steps);
}
// Called by action during initializations
public void SetCurrentStep (int cur) {
// Validations
if (cur < 0) {
if (OnError != null) OnError ("Can't set step below zero");
return;
}
if (cur >= steps.Length) {
if (OnError != null) OnError ("Can't set step above number of steps in tutorial");
return;
}
step = cur;
if (OnStepChanged != null) OnStepChanged (step);
}
public void IncrementStep () {
if (step + 1 == steps.Length) {
if (OnTutorialComplete != null) OnTutorialComplete ();
return;
}
step++;
if (OnStepChanged != null) OnStepChanged (step);
}
}
public class TutorialStepView : MonoBehaviour {
private TutorialActions _actions;
private TutorialState _state;
private int currentStep;
[Inject]
private void Init (TutorialActions actions, TutorialState state) {
_actions = actions;
_state = state;
}
private void OnEnable {
_state.OnStepChanged += HandleStepChanged;
_state.OnTutorialComplete += HandleCompleted;
_state.OnError += HandleError;
}
private void OnDisable () {
_state.OnStepChanged -= HandleStepChanged;
_state.OnTutorialComplete -= HandleCompleted;
_state.OnError -= HandleError;
}
// Handle next step button clicks
public void NextStep () {
_actions.nextStep ();
}
public void HandleStepChanged (int step) {
// Update UI with next step
currentStep = step;
}
public void HandleCompleted () {
// Update UI to show tutorial completed
}
public void HandleError (string err) {
// Handle errors
Debug.LogError (err);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment