diff Orchestland/Assets/LeapMotion/Widgets/Scripts/Interfaces/DataBinder.cs @ 1:f7675884f2a1

Add Orchestland project
author Daiki OYAKAWA <e135764@ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2015 23:09:20 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Orchestland/Assets/LeapMotion/Widgets/Scripts/Interfaces/DataBinder.cs	Fri Jul 17 23:09:20 2015 +0900
@@ -0,0 +1,87 @@
+using UnityEngine;
+using System;
+using System.Collections.Generic;
+
+namespace LMWidgets {
+
+  // Interface to define an object that can be a data provider to a widget.
+  public abstract class DataBinder<WidgetType, PayloadType> : MonoBehaviour where WidgetType : IDataBoundWidget<WidgetType, PayloadType> {
+    [SerializeField]
+    private List<WidgetType> m_widgets;
+
+    private PayloadType m_lastDataValue;
+
+    // Fires when the data is updated with the most recent data as the payload
+    public event EventHandler<EventArg<PayloadType>> DataChangedHandler;
+
+    /// <summary>
+    /// Returns the current system value of the data.
+    /// </summary>
+    /// <remarks>
+    /// In the default implementation of the data-binder this is called every frame (in Update) so it's best to keep
+    /// this implementation light weight.
+    /// </remarks>
+    abstract public PayloadType GetCurrentData();
+
+    /// <summary>
+    /// Set the current system value of the data.
+    /// </summary>
+    abstract protected void setDataModel(PayloadType value);
+
+    // Directly set the current value of the data-model and send out the relevant updates.
+    public void SetCurrentData(PayloadType value) {
+      setDataModel (value);
+      updateLinkedWidgets ();
+      fireDataChangedEvent (GetCurrentData ());
+      m_lastDataValue = GetCurrentData ();
+    }
+
+    // Itterate through the linked widgets and update their values.
+    private void updateLinkedWidgets() {
+      foreach(WidgetType widget in m_widgets) {
+        widget.SetWidgetValue(GetCurrentData());
+      }
+    }
+
+    // Register all assigned widgets with the data-binder.
+    virtual protected void Awake() {
+      foreach (WidgetType widget in m_widgets) {
+        widget.RegisterDataBinder(this);
+      }
+    }
+
+    // Grab the inital value for GetCurrentData
+    virtual protected void Start() {
+      m_lastDataValue = GetCurrentData();
+    }
+
+    // Checks for change in data.
+    // We need this in addition to SetCurrentData as the data we're linked to 
+    // could be modified by an external source.
+    void Update() {
+      PayloadType currentData = GetCurrentData();
+      if (!compare (m_lastDataValue, currentData)) {
+        updateLinkedWidgets ();
+        fireDataChangedEvent (currentData);
+      }
+      m_lastDataValue = currentData;
+    }
+
+    // Fire the data changed event. 
+    // Wrapping this in a function allows child classes to call it and fire the event.
+    protected void fireDataChangedEvent(PayloadType currentData) {
+      EventHandler<EventArg<PayloadType>> handler = DataChangedHandler;
+      if ( handler != null ) { handler(this, new EventArg<PayloadType>(currentData)); }
+    }
+
+    // Handles proper comparison of generic types.
+    private bool compare(PayloadType x, PayloadType y)
+    {
+      return EqualityComparer<PayloadType>.Default.Equals(x, y);
+    }
+  }
+
+  public abstract class DataBinderSlider : DataBinder<SliderBase, float> {};
+  public abstract class DataBinderToggle : DataBinder<ButtonToggleBase, bool> {};
+  public abstract class DataBinderDial : DataBinder<DialGraphics, string> {};
+}
\ No newline at end of file