// This code is part of the Fungus library (http://fungusgames.com) maintained by Chris Gregan (http://twitter.com/gofungus).
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
using UnityEngine;
using UnityEngine.Serialization;
using System;
using System.Collections.Generic;
namespace Fungus
{
///
/// Attribute class for Fungus commands.
///
///
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class CommandInfoAttribute : Attribute
{
///
/// Metadata atribute for the Command class.
///
/// The category to place this command in.
/// The display name of the command.
/// Help information to display in the inspector.
/// If two command classes have the same name, the one with highest priority is listed. Negative priority removess the command from the list.///
public CommandInfoAttribute(string category, string commandName, string helpText, int priority = 0)
{
this.Category = category;
this.CommandName = commandName;
this.HelpText = helpText;
this.Priority = priority;
}
public string Category { get; set; }
public string CommandName { get; set; }
public string HelpText { get; set; }
public int Priority { get; set; }
}
///
/// Base class for Commands. Commands can be added to Blocks to create an execution sequence.
///
public abstract class Command : MonoBehaviour
{
[FormerlySerializedAs("commandId")]
[HideInInspector]
[SerializeField] protected int itemId = -1; // Invalid flowchart item id
[HideInInspector]
[SerializeField] protected int indentLevel;
protected string errorMessage = "";
#region Public members
///
/// Unique identifier for this command.
/// Unique for this Flowchart.
///
public virtual int ItemId { get { return itemId; } set { itemId = value; } }
///
/// Error message to display in the command inspector.
///
public virtual string ErrorMessage { get { return errorMessage; } }
///
/// Indent depth of the current commands.
/// Commands are indented inside If, While, etc. sections.
///
public virtual int IndentLevel { get { return indentLevel; } set { indentLevel = value; } }
///
/// Index of the command in the parent block's command list.
///
public virtual int CommandIndex { get; set; }
///
/// Set to true by the parent block while the command is executing.
///
public virtual bool IsExecuting { get; set; }
///
/// Timer used to control appearance of executing icon in inspector.
///
public virtual float ExecutingIconTimer { get; set; }
///
/// Reference to the Block object that this command belongs to.
/// This reference is only populated at runtime and in the editor when the
/// block is selected.
///
public virtual Block ParentBlock { get; set; }
///
/// Returns the Flowchart that this command belongs to.
///
public virtual Flowchart GetFlowchart()
{
var flowchart = GetComponent();
if (flowchart == null &&
transform.parent != null)
{
flowchart = transform.parent.GetComponent();
}
return flowchart;
}
///
/// Execute the command.
///
public virtual void Execute()
{
OnEnter();
}
///
/// End execution of this command and continue execution at the next command.
///
public virtual void Continue()
{
// This is a noop if the Block has already been stopped
if (IsExecuting)
{
Continue(CommandIndex + 1);
}
}
///
/// End execution of this command and continue execution at a specific command index.
///
/// Next command index.
public virtual void Continue(int nextCommandIndex)
{
OnExit();
if (ParentBlock != null)
{
ParentBlock.JumpToCommandIndex = nextCommandIndex;
}
}
///
/// Stops the parent Block executing.
///
public virtual void StopParentBlock()
{
OnExit();
if (ParentBlock != null)
{
ParentBlock.Stop();
}
}
///
/// Called when the parent block has been requested to stop executing, and
/// this command is the currently executing command.
/// Use this callback to terminate any asynchronous operations and
/// cleanup state so that the command is ready to execute again later on.
///
public virtual void OnStopExecuting()
{}
///
/// Called when the new command is added to a block in the editor.
///
public virtual void OnCommandAdded(Block parentBlock)
{}
///
/// Called when the command is deleted from a block in the editor.
///
public virtual void OnCommandRemoved(Block parentBlock)
{}
///
/// Called when this command starts execution.
///
public virtual void OnEnter()
{}
///
/// Called when this command ends execution.
///
public virtual void OnExit()
{}
///
/// Called when this command is reset. This happens when the Reset command is used.
///
public virtual void OnReset()
{}
///
/// Populates a list with the Blocks that this command references.
///
public virtual void GetConnectedBlocks(ref List connectedBlocks)
{}
///
/// Returns true if this command references the variable.
/// Used to highlight variables in the variable list when a command is selected.
///
public virtual bool HasReference(Variable variable)
{
return false;
}
///
/// Returns the summary text to display in the command inspector.
///
public virtual string GetSummary()
{
return "";
}
///
/// Returns the help text to display for this command.
///
public virtual string GetHelpText()
{
return "";
}
///
/// Return true if this command opens a block of commands. Used for indenting commands.
///
public virtual bool OpenBlock()
{
return false;
}
///
/// Return true if this command closes a block of commands. Used for indenting commands.
///
public virtual bool CloseBlock()
{
return false;
}
///
/// Return the color for the command background in inspector.
///
/// The button color.
public virtual Color GetButtonColor()
{
return Color.white;
}
///
/// Returns true if the specified property should be displayed in the inspector.
/// This is useful for hiding certain properties based on the value of another property.
///
public virtual bool IsPropertyVisible(string propertyName)
{
return true;
}
///
/// Returns true if the specified property should be displayed as a reorderable list in the inspector.
/// This only applies for array properties and has no effect for non-array properties.
///
public virtual bool IsReorderableArray(string propertyName)
{
return false;
}
///
/// Returns the localization id for the Flowchart that contains this command.
///
public virtual string GetFlowchartLocalizationId()
{
// If no localization id has been set then use the Flowchart name
var flowchart = GetFlowchart();
if (flowchart == null)
{
return "";
}
string localizationId = GetFlowchart().LocalizationId;
if (localizationId.Length == 0)
{
localizationId = flowchart.GetName();
}
return localizationId;
}
#endregion
}
}