/// <summary>
 /// Callback to be executed after displaying the message box.
 /// Unfreezes the canvas and closes the message box.
 /// </summary>
 /// <param name="triggerData">Data to pass from the trigger source to the trigger target.</param>
 public void Trigger(MessageBoxTriggerData triggerData)
 {
     Canvas.Frozen = false;
     Destroy(triggerData.Sender.gameObject);
     return;
 }
예제 #2
0
        /// <summary>
        /// Callback to be executed after PlayChallengeMessageBox.
        /// Unfreezes the canvas and closes the message box.
        /// Positive trigger clears the current circuit and loads a challenge from JSON.
        /// </summary>
        /// <param name="triggerData">Data to pass from the trigger source to the trigger target.</param>
        public void Trigger(MessageBoxTriggerData triggerData)
        {
            if (triggerData.ButtonPressed == UIMessageBox.MessageBoxButtonType.Positive)
            {
                // Check for unsaved changes
                if (triggerData.Sender.GetType() == typeof(PlayChallengeMessageBox) &&
                    Canvas.IsUnsaved)
                {
                    // Ask for confirmation of unsaved changes, save filename
                    SelectedFilenameStash.Push(triggerData.TextInput);
                    MessageBoxFactory.MakeFromConfig(UnsavedChangesMessageBoxConfig, this);
                    Destroy(triggerData.Sender.gameObject);
                    return;
                }
                else if (triggerData.Sender.GetType() == typeof(ConfirmMessageBox))
                {
                    // Confirmation received, pop filename
                    triggerData.TextInput = SelectedFilenameStash.Pop();
                    SelectedFilenameStash.Clear();
                }

                string fullpath = Directories.CHALLENGE_FOLDER_FULL_PATH + "/" + triggerData.TextInput + ".json";

                // Read from file
                Debug.Log("Opening circuit from " + fullpath);
                string data;
                try
                {
                    data = File.ReadAllText(fullpath);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    MessageBoxFactory.MakeFromConfig(OpenErrorMessageBoxConfig);
                    Canvas.Frozen = false;
                    Destroy(triggerData.Sender.gameObject);
                    return;
                }

                // Parse JSON into configs
                var circuitConfig          = JsonUtility.FromJson <CircuitConfig>(data);
                var componentConfigs       = circuitConfig.logic_components;
                var edgeConfigs            = circuitConfig.edges;
                var togglerConfigs         = circuitConfig.toggles;
                var numberedTogglerConfigs = circuitConfig.numbered_toggles;
                var testCaseConfigs        = circuitConfig.test_cases;
                var clockConfigs           = circuitConfig.clocks;
                var titleText        = circuitConfig.title_text;
                var bodyText         = circuitConfig.body_text;
                var testCaseStepsRun = circuitConfig.test_case_steps_run;

                Assert.AreNotEqual(circuitConfig.game_mode, GameMode.Sandbox);

                // Clear the canvas
                for (int i = Canvas.Components.Count - 1; i >= 0; --i)
                {
                    Canvas.Components[i].Delete();
                }

                var logicComponentFactory = new SPLogicComponentFactory(Canvas.Foreground);

                // Build components whilst populating GUID map
                Dictionary <Guid, SPLogicComponent> guidMap = componentConfigs.ToDictionary(
                    config => config.Guid,
                    config => logicComponentFactory.MakeFromConfig(config));
                Canvas.Components.AddRange(guidMap.Values);

                // Restore state for input togglers
                foreach (var config in togglerConfigs)
                {
                    Guid           guid         = Guid.Parse(config.guid_string);
                    SPInputToggler inputToggler = (SPInputToggler)guidMap[guid];
                    if (((InputComponent)inputToggler.LogicComponent).value != config.value)
                    {
                        inputToggler.ToggleValue();
                    }
                }

                foreach (var config in numberedTogglerConfigs)
                {
                    Guid guid = Guid.Parse(config.guid_string);
                    SPNumberedInputToggler inputToggler = (SPNumberedInputToggler)guidMap[guid];
                    if (((InputComponent)inputToggler.LogicComponent).value != config.value)
                    {
                        inputToggler.ToggleValue();
                    }
                }

                // Restore state for clock components
                foreach (var config in clockConfigs)
                {
                    Guid    guid  = Guid.Parse(config.guid_string);
                    SPClock clock = (SPClock)guidMap[guid];
                    ((Clock)clock.LogicComponent).Period = config.period;
                }

                // Build edges using GUID map
                foreach (var config in edgeConfigs)
                {
                    Canvas.StartEdge(guidMap[config.ComponentGuids[0]].InConnectors[config.connector_ids[0]]);
                    Canvas.FinishEdge(guidMap[config.ComponentGuids[1]].OutConnectors[config.connector_ids[1]]);
                }

                // Set all initial components to immutable
                foreach (var component in Canvas.Components)
                {
                    component.Immutable = true;
                }

                foreach (var edge in Canvas.Edges)
                {
                    edge.Immutable = true;
                }

                // TODO: USE THE TEST CASES GENERATED.
                foreach (TestCaseConfig testCase in testCaseConfigs)
                {
                    foreach (KeyValuePair <uint, bool> kvp in testCase.GetAllInputs())
                    {
                        Debug.Log("Input: " + kvp.Key.ToString() + ": " + kvp.Value.ToString());
                    }
                    foreach (KeyValuePair <uint, bool> kvp in testCase.GetAllOutputs())
                    {
                        Debug.Log("Output: " + kvp.Key.ToString() + ": " + kvp.Value.ToString());
                    }
                }

                // Load the test cases into SPCanvas
                Canvas.TestCases = testCaseConfigs;

                // Load how many test case steps to run:
                Canvas.TestCaseStepsRun = testCaseStepsRun;

                // Put the canvas into challenge mode
                Canvas.CurrentMode        = circuitConfig.game_mode;
                Canvas.ChallengeCompleted = false;
                Canvas.SetAsSaved();
                FindObjectOfType <UIOverlayControlVerifyChallengeButton>().GetComponent <RectTransform>().sizeDelta = new Vector2
                {
                    x = 40,
                    y = 40
                };

                // Set the Info Panel information.
                Canvas.InfoPanelTitle = titleText;
                Canvas.InfoPanelText  = bodyText;
                InfoPanel.SetInfoTarget(Canvas);
                InfoPanel.Show();
            }

            Canvas.Frozen = false;
            Destroy(triggerData.Sender.gameObject);
        }
        /// <summary>
        /// Callback to be executed after SaveCircuitMessageBox.
        /// Unfreezes the canvas and closes the message box.
        /// Positive trigger saves the circuit as JSON.
        /// </summary>
        /// <param name="triggerData">Data to pass from the trigger source to the trigger target.</param>
        public void Trigger(MessageBoxTriggerData triggerData)
        {
            if (triggerData.ButtonPressed == UIMessageBox.MessageBoxButtonType.Positive)
            {
                // Bind a GUID for each component
                Dictionary <SPLogicComponent, Guid> guidMap = Canvas.Components
                                                              .ToDictionary(c => c, c => Guid.NewGuid());

                // Generate configs for components
                List <LogicComponentConfig> componentConfigs = guidMap
                                                               .Select(kvp => kvp.Key.GenerateConfig(kvp.Value))
                                                               .ToList();

                // Generate configs for edges, mapping connected components using GUIDs
                List <EdgeConfig> edgeConfigs = Canvas.Edges
                                                .Select(e => e.GenerateConfig(guidMap))
                                                .ToList();

                // Generate additional configs to save state of input togglers
                List <InputToggleConfig> toggleConfigs = guidMap
                                                         .Where(kvp => kvp.Key.GetType() == typeof(SPInputToggler))
                                                         .Select(kvp => new InputToggleConfig
                {
                    guid_string = kvp.Value.ToString(),
                    value       = ((InputComponent)kvp.Key.LogicComponent).value
                })
                                                         .ToList();

                List <InputToggleConfig> numberedToggleConfigs = guidMap
                                                                 .Where(kvp => kvp.Key.GetType() == typeof(SPNumberedInputToggler))
                                                                 .Select(kvp => new InputToggleConfig
                {
                    guid_string = kvp.Value.ToString(),
                    value       = ((InputComponent)kvp.Key.LogicComponent).value
                })
                                                                 .ToList();

                // Generate additional configs to save state of clock components
                List <ClockComponentConfig> clockConfigs = guidMap
                                                           .Where(kvp => kvp.Key.GetType() == typeof(SPClock))
                                                           .Select(kvp => new ClockComponentConfig
                {
                    guid_string = kvp.Value.ToString(),
                    period      = ((Clock)kvp.Key.LogicComponent).Period
                })
                                                           .ToList();

                // Generate an empty test cases config:
                List <TestCaseConfig> testCaseConfigs = new List <TestCaseConfig>();

                // Build savefile
                CircuitConfig spConfig = new CircuitConfig(
                    componentConfigs,
                    edgeConfigs,
                    toggleConfigs,
                    numberedToggleConfigs,
                    clockConfigs,
                    testCaseConfigs,
                    mode: GameMode.Sandbox);

#if DEVELOPMENT_BUILD
                string saveData = JsonUtility.ToJson(spConfig, prettyPrint: true);
#else
                string saveData = JsonUtility.ToJson(spConfig, prettyPrint: false);
#endif

                // Build full file path
                string filename = triggerData.TextInput + ".json";
                string fullpath = Directories.SAVEFILE_FOLDER_FULL_PATH + "/" + filename;

                // Write to file
                Debug.Log("Saving to " + fullpath);
                try
                {
                    Directory.CreateDirectory(Directories.SAVEFILE_FOLDER_FULL_PATH);
                    File.WriteAllText(fullpath, saveData);
                    Canvas.SetAsSaved();
                }
                catch (Exception e)
                {
                    // uh oh
                    Debug.LogException(e);
                    MessageBoxFactory.MakeFromConfig(SaveErrorMessageBoxConfig);
                }
            }
            else if (triggerData.ButtonPressed == UIMessageBox.MessageBoxButtonType.Neutral)
            {
                // Bind a GUID for each component
                Dictionary <SPLogicComponent, Guid> guidMap = Canvas.Components
                                                              .ToDictionary(c => c, c => Guid.NewGuid());

                // Generate configs for components
                List <LogicComponentConfig> componentConfigs = guidMap
                                                               .Select(kvp => kvp.Key.GenerateConfig(kvp.Value))
                                                               .ToList();

                // Generate configs for edges, mapping connected components using GUIDs
                List <EdgeConfig> edgeConfigs = Canvas.Edges
                                                .Select(e => e.GenerateConfig(guidMap))
                                                .ToList();

                // Generate additional configs to save state of input togglers
                List <InputToggleConfig> toggleConfigs = guidMap
                                                         .Where(kvp => kvp.Key.GetType() == typeof(SPInputToggler))
                                                         .Select(kvp => new InputToggleConfig
                {
                    guid_string = kvp.Value.ToString(),
                    value       = ((InputComponent)kvp.Key.LogicComponent).value
                })
                                                         .ToList();

                List <InputToggleConfig> numberedToggleConfigs = guidMap
                                                                 .Where(kvp => kvp.Key.GetType() == typeof(SPNumberedInputToggler))
                                                                 .Select(kvp => new InputToggleConfig
                {
                    guid_string = kvp.Value.ToString(),
                    value       = ((InputComponent)kvp.Key.LogicComponent).value
                })
                                                                 .ToList();

                // Generate test cases config:
                List <TestCaseConfig> testCaseConfigs = new List <TestCaseConfig>();
                // Generate one based on Circuit:
                // Just a dummy one so you have a template on how to modify it.
                TestCaseConfig testCase = new TestCaseConfig();
                foreach (var kvp in Canvas.NumberedInputs)
                {
                    InputComponent inputComponent = kvp.Value.LogicComponent as InputComponent;
                    testCase.SetInput(kvp.Key, inputComponent.value);
                }
                foreach (var kvp in Canvas.NumberedOutputs)
                {
                    Output output = kvp.Value.LogicComponent as Output;
                    testCase.SetOutput(kvp.Key, output.Value);
                }
                testCaseConfigs.Add(testCase);

                // Generate additional configs to save state of clock components
                List <ClockComponentConfig> clockConfigs = guidMap
                                                           .Where(kvp => kvp.Key.GetType() == typeof(SPClock))
                                                           .Select(kvp => new ClockComponentConfig
                {
                    guid_string = kvp.Value.ToString(),
                    period      = ((Clock)kvp.Key.LogicComponent).Period
                })
                                                           .ToList();

                // Generate default title strings.
                String titleText = "Objective";
                String bodyText  = "Your aim is to turn all the lights on.\nYou can not delete pre-placed components.\nAll components placed must use all endpoints and contribute to at least one output light.";

                // Build savefile
                CircuitConfig spConfig = new CircuitConfig(
                    componentConfigs,
                    edgeConfigs,
                    toggleConfigs,
                    numberedToggleConfigs,
                    clockConfigs,
                    testCaseConfigs,
                    GameMode.ActivateAllOutputsChallenge,
                    titleText: titleText,
                    bodyText: bodyText);

#if DEVELOPMENT_BUILD
                string saveData = JsonUtility.ToJson(spConfig, prettyPrint: true);
#else
                string saveData = JsonUtility.ToJson(spConfig, prettyPrint: false);
#endif

                // Build full file path
                string filename = triggerData.TextInput + ".json";
                string fullpath = Directories.CHALLENGE_FOLDER_FULL_PATH + "/" + filename;

                // Write to file
                Debug.Log("Saving to " + fullpath);
                try
                {
                    Directory.CreateDirectory(Directories.CHALLENGE_FOLDER_FULL_PATH);
                    File.WriteAllText(fullpath, saveData);
                    Canvas.SetAsSaved();
                }
                catch (Exception e)
                {
                    // uh oh
                    Debug.LogException(e);
                    MessageBoxFactory.MakeFromConfig(SaveErrorMessageBoxConfig);
                }
            }

            Canvas.Frozen = false;
            Destroy(triggerData.Sender.gameObject);
        }
예제 #4
0
        /// <summary>
        /// Callback to be executed after OpenCircuitMessageBox.
        /// Unfreezes the canvas and closes the message box.
        /// Positive trigger loads a saved circuit from JSON.
        /// </summary>
        /// <param name="triggerData">Data to pass from the trigger source to the trigger target.</param>
        public void Trigger(MessageBoxTriggerData triggerData)
        {
            if (triggerData.ButtonPressed == UIMessageBox.MessageBoxButtonType.Positive)
            {
                string fullpath = Directories.SAVEFILE_FOLDER_FULL_PATH + "/" + triggerData.TextInput + ".json";

                // Read from file
                Debug.Log("Importing circuit from " + fullpath);
                string data;
                try
                {
                    data = File.ReadAllText(fullpath);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    MessageBoxFactory.MakeFromConfig(ImportErrorMessageBoxConfig);
                    Canvas.Frozen = false;
                    Destroy(triggerData.Sender.gameObject);
                    return;
                }

                // Parse JSON into configs
                var circuitConfig          = JsonUtility.FromJson <CircuitConfig>(data);
                var componentConfigs       = circuitConfig.logic_components;
                var edgeConfigs            = circuitConfig.edges;
                var togglerConfigs         = circuitConfig.toggles;
                var numberedTogglerConfigs = circuitConfig.numbered_toggles;
                var clockConfigs           = circuitConfig.clocks;

                Assert.AreEqual(circuitConfig.game_mode, GameMode.Sandbox);

                var logicComponentFactory = new SPLogicComponentFactory(Canvas.Foreground);

                // Build components whilst populating GUID map
                Dictionary <Guid, SPLogicComponent> guidMap = componentConfigs.ToDictionary(
                    config => config.Guid,
                    config => logicComponentFactory.MakeFromConfig(config));
                Canvas.Components.AddRange(guidMap.Values);

                // Restore state for input togglers
                foreach (var config in togglerConfigs)
                {
                    Guid           guid         = Guid.Parse(config.guid_string);
                    SPInputToggler inputToggler = (SPInputToggler)guidMap[guid];
                    if (((InputComponent)inputToggler.LogicComponent).value != config.value)
                    {
                        inputToggler.ToggleValue();
                    }
                }

                foreach (var config in numberedTogglerConfigs)
                {
                    Guid guid = Guid.Parse(config.guid_string);
                    SPNumberedInputToggler inputToggler = (SPNumberedInputToggler)guidMap[guid];
                    if (((InputComponent)inputToggler.LogicComponent).value != config.value)
                    {
                        inputToggler.ToggleValue();
                    }
                }

                // Restore state for clock components
                foreach (var config in clockConfigs)
                {
                    Guid    guid  = Guid.Parse(config.guid_string);
                    SPClock clock = (SPClock)guidMap[guid];
                    ((Clock)clock.LogicComponent).Period = config.period;
                }

                // Build edges using GUID map
                foreach (var config in edgeConfigs)
                {
                    Canvas.StartEdge(guidMap[config.ComponentGuids[0]].InConnectors[config.connector_ids[0]]);
                    Canvas.FinishEdge(guidMap[config.ComponentGuids[1]].OutConnectors[config.connector_ids[1]]);
                }
            }

            Canvas.Frozen = false;
            Destroy(triggerData.Sender.gameObject);
        }
예제 #5
0
        /// <summary>
        /// Callback to be executed after OpenCircuitMessageBox.
        /// Unfreezes the canvas and closes the message box.
        /// Positive trigger clears the current circuit and loads a saved one from JSON.
        /// </summary>
        /// <param name="triggerData">Data to pass from the trigger source to the trigger target.</param>
        public void Trigger(MessageBoxTriggerData triggerData)
        {
            if (triggerData.ButtonPressed == UIMessageBox.MessageBoxButtonType.Positive)
            {
                // Check for unsaved changes
                if (triggerData.Sender.GetType() == typeof(OpenCircuitMessageBox) &&
                    Canvas.IsUnsaved)
                {
                    // Ask for confirmation of unsaved changes, save filename
                    SelectedFilenameStash.Push(triggerData.TextInput);
                    MessageBoxFactory.MakeFromConfig(UnsavedChangesMessageBoxConfig, this);
                    Destroy(triggerData.Sender.gameObject);
                    return;
                }
                else if (triggerData.Sender.GetType() == typeof(ConfirmMessageBox))
                {
                    // Confirmation received, pop filename
                    triggerData.TextInput = SelectedFilenameStash.Pop();
                    SelectedFilenameStash.Clear();
                }

                string fullpath = Directories.SAVEFILE_FOLDER_FULL_PATH + "/" + triggerData.TextInput + ".json";

                // Read from file
                Debug.Log("Opening circuit from " + fullpath);
                string data;
                try
                {
                    data = File.ReadAllText(fullpath);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    MessageBoxFactory.MakeFromConfig(OpenErrorMessageBoxConfig);
                    Canvas.Frozen = false;
                    Destroy(triggerData.Sender.gameObject);
                    return;
                }

                // Parse JSON into configs
                var circuitConfig          = JsonUtility.FromJson <CircuitConfig>(data);
                var componentConfigs       = circuitConfig.logic_components;
                var edgeConfigs            = circuitConfig.edges;
                var togglerConfigs         = circuitConfig.toggles;
                var numberedTogglerConfigs = circuitConfig.numbered_toggles;
                var clockConfigs           = circuitConfig.clocks;

                Assert.AreEqual(circuitConfig.game_mode, GameMode.Sandbox);

                // Clear the canvas
                for (int i = Canvas.Components.Count - 1; i >= 0; --i)
                {
                    Canvas.Components[i].Delete();
                }

                var logicComponentFactory = new SPLogicComponentFactory(Canvas.Foreground);

                // Build components whilst populating GUID map
                Dictionary <Guid, SPLogicComponent> guidMap = componentConfigs.ToDictionary(
                    config => config.Guid,
                    config => logicComponentFactory.MakeFromConfig(config));
                Canvas.Components.AddRange(guidMap.Values);

                // Restore state for input togglers
                foreach (var config in togglerConfigs)
                {
                    Guid           guid         = Guid.Parse(config.guid_string);
                    SPInputToggler inputToggler = (SPInputToggler)guidMap[guid];
                    if (((InputComponent)inputToggler.LogicComponent).value != config.value)
                    {
                        inputToggler.ToggleValue();
                    }
                }

                foreach (var config in numberedTogglerConfigs)
                {
                    Guid guid = Guid.Parse(config.guid_string);
                    SPNumberedInputToggler inputToggler = (SPNumberedInputToggler)guidMap[guid];
                    if (((InputComponent)inputToggler.LogicComponent).value != config.value)
                    {
                        inputToggler.ToggleValue();
                    }
                }

                // Restore state for clock components
                foreach (var config in clockConfigs)
                {
                    Guid    guid  = Guid.Parse(config.guid_string);
                    SPClock clock = (SPClock)guidMap[guid];
                    ((Clock)clock.LogicComponent).Period = config.period;
                }

                // Build edges using GUID map
                foreach (var config in edgeConfigs)
                {
                    Canvas.StartEdge(guidMap[config.ComponentGuids[0]].InConnectors[config.connector_ids[0]]);
                    Canvas.FinishEdge(guidMap[config.ComponentGuids[1]].OutConnectors[config.connector_ids[1]]);
                }

                // Loading a circuit means the circuit that was just loaded is "saved"
                Canvas.CurrentMode = GameMode.Sandbox;
                Canvas.SetAsSaved();
                FindObjectOfType <UIOverlayControlVerifyChallengeButton>().GetComponent <RectTransform>().sizeDelta = new Vector2
                {
                    x = 0,
                    y = 0
                };
            }

            Canvas.Frozen = false;
            Destroy(triggerData.Sender.gameObject);
        }