private void OnDestroy()
 {
     // If we call StringAssetUtil.WriteJsonObject... in editor, it calls AssetDatabase.ImportAsset
     // Importing a Resource like a json can cause other Shader resources with float4x4 properties to discard their previously set properties.
     // So only write json when object is being destroyed
     if (sparseUpdates != null)
     {
         string stateUpdateFilename = string.Format("DisplayConfigUpdate{0}.json", isSlantedState ? "Slanted" : "Square");
         StringAssetUtil.WriteJsonObjectToDeviceAwareFilename(stateUpdateFilename, sparseUpdates, true);
     }
 }
        /// <summary>
        /// Starting from a _displayConfig with base data already populated by firmware / json profile, applies sparse update parameters.
        ///
        /// Selects between DisplayConfigUpdateSquare.json and DisplayConfigUpdateSlanted.json based on flags already on config.
        /// </summary>
        /// <param name="sparseUpdates">A collection of string-data pairs which provide sparse update information</param>
        /// <param name="accessLevel">Permission level which the update is applied with</param>
        protected virtual void ApplyDisplayConfigUpdate(DisplayConfigModifyPermission.Level accessLevel)
        {
            string stateUpdateFilename = string.Format("DisplayConfigUpdate{0}.json", _displayConfig.isSlanted ? "Slanted" : "Square");
            JsonParamCollection sparseUpdates;

            if (StringAssetUtil.TryGetJsonObjectFromDeviceAwareFilename(stateUpdateFilename, out sparseUpdates))
            {
                foreach (KeyValuePair <string, Array> pair in sparseUpdates)
                {
                    _displayConfig.SetPropertyByReflection(pair.Key, pair.Value, accessLevel);
                }
            }
        }
        void ConstructUI()
        {
            config         = LeiaDisplay.Instance.GetDisplayConfig();
            isSlantedState = config.isSlanted;
            // slant polarity
            slantLabel.text = config.Slant ? "Right" : "Left";

            AttachPrimitiveSliderCallbacks();
            AttachActSliderCallbacks();
            AttachFormattedTextCallbacks();

            // on opening config UI, retrieve values from DisplayConfig and assign them to sliders
            // callbacks in OnValueChanged are not triggered when callback attachment occurs in same code execution as callback trigger
            gammaSlider.value     = config.Gamma;
            disparitySlider.value = config.SystemDisparityPixels;
            betaSlider.value      = config.Beta;
            offsetSlider.value    = config.AlignmentOffset.x;
            resScaleSlider.value  = config.ResolutionScale;

            if (isSlantedState)
            {
                actcTitle.text   = "ACT Y[2]";
                actdTitle.text   = "ACT Y[3]";
                actaSlider.value = config.ActCoefficients.y[0];
                actbSlider.value = config.ActCoefficients.y[1];
                actcSlider.value = config.ActCoefficients.y[2];
                actdSlider.value = config.ActCoefficients.y[3];
            }
            else
            {
                actcTitle.text   = "ACT X[0]";
                actdTitle.text   = "ACT X[1]";
                actaSlider.value = config.ActCoefficients.y[0];
                actbSlider.value = config.ActCoefficients.y[1];
                actcSlider.value = config.ActCoefficients.x[0];
                actdSlider.value = config.ActCoefficients.x[1];
            }
            slantPage.SetActive(isSlantedState);
            betaSlider.gameObject.SetActive(isSlantedState);
            gammaSlider.GetComponent <RectTransform>().anchoredPosition = new Vector2(isSlantedState ? -200 : 0, gammaSlider.GetComponent <RectTransform>().anchoredPosition.y);
            string stateUpdateFilename   = string.Format("DisplayConfigUpdate{0}.json", isSlantedState ? "Slanted" : "Square");
            bool   loadedStateUpdateFile = StringAssetUtil.TryGetJsonObjectFromDeviceAwareFilename <JsonParamCollection>(stateUpdateFilename, out sparseUpdates);

            if (!loadedStateUpdateFile)
            {
                sparseUpdates = new JsonParamCollection();
            }
        }
        /// <summary>
        /// Starting from a new _displayConfig from constructor but with no settings from json yet,
        ///
        /// reads in data from the given filename as a JsonParamCollection and applies sparsely defined properties in
        /// the JsonParamCollection to the _displayConfig.
        /// </summary>
        /// <param name="deviceSimulationFilePath">A file name in Application.dataPath/Assets/LeiaLoft/Resources/</param>
        protected virtual void ApplyDisplayConfigUpdate(string deviceSimulationFilePath)
        {
            JsonParamCollection sparseUpdates;

            if (StringAssetUtil.TryGetJsonObjectFromDeviceAwareFilename(deviceSimulationFilePath, out sparseUpdates))
            {
                foreach (KeyValuePair <string, Array> pair in sparseUpdates)
                {
                    _displayConfig.SetPropertyByReflection(pair.Key, pair.Value, DisplayConfigModifyPermission.Level.DeviceSimulation);
                }
            }
            else
            {
                LogUtil.Log(LogLevel.Error, "Could not load simulated device profile {0}. Please re-set the emulated device profile on LeiaDisplay!", deviceSimulationFilePath);
            }
        }
        public void ResetValues()
        {
            sparseUpdates.Clear();

            // trigger a write of a blank SparseUpdates file
            string stateUpdateFilename = string.Format("DisplayConfigUpdate{0}.json", isSlantedState ? "Slanted" : "Square");

            StringAssetUtil.WriteJsonObjectToDeviceAwareFilename(stateUpdateFilename, sparseUpdates, true);

            this.DeconstructUI();

            // reload DisplayConfig from firmware up
            LeiaDisplay.Instance.LeiaDevice.GetDisplayConfig(true);
            LeiaDisplay.Instance.UpdateDevice();

            // reload UI, rebind callbacks
            this.ConstructUI();
        }