- using System.Text;
- namespace Ink.Runtime
- {
- public class Divert : Runtime.Object
- {
- public Path targetPath {
- get {
- // Resolve any relative paths to global ones as we come across them
- if (_targetPath != null && _targetPath.isRelative) {
- var targetObj = targetPointer.Resolve();
- if (targetObj) {
- _targetPath = targetObj.path;
- }
- }
- return _targetPath;
- }
- set {
- _targetPath = value;
- _targetPointer = Pointer.Null;
- }
- }
- Path _targetPath;
- public Pointer targetPointer {
- get {
- if (_targetPointer.isNull) {
- var targetObj = ResolvePath (_targetPath).obj;
- if (_targetPath.lastComponent.isIndex) {
- _targetPointer.container = targetObj.parent as Container;
- _targetPointer.index = _targetPath.lastComponent.index;
- } else {
- _targetPointer = Pointer.StartOf (targetObj as Container);
- }
- }
- return _targetPointer;
- }
- }
- Pointer _targetPointer;
-
- public string targetPathString {
- get {
- if (targetPath == null)
- return null;
- return CompactPathString (targetPath);
- }
- set {
- if (value == null) {
- targetPath = null;
- } else {
- targetPath = new Path (value);
- }
- }
- }
-
- public string variableDivertName { get; set; }
- public bool hasVariableTarget { get { return variableDivertName != null; } }
- public bool pushesToStack { get; set; }
- public PushPopType stackPushType;
- public bool isExternal { get; set; }
- public int externalArgs { get; set; }
- public bool isConditional { get; set; }
- public Divert ()
- {
- pushesToStack = false;
- }
- public Divert(PushPopType stackPushType)
- {
- pushesToStack = true;
- this.stackPushType = stackPushType;
- }
- public override bool Equals (object obj)
- {
- var otherDivert = obj as Divert;
- if (otherDivert) {
- if (this.hasVariableTarget == otherDivert.hasVariableTarget) {
- if (this.hasVariableTarget) {
- return this.variableDivertName == otherDivert.variableDivertName;
- } else {
- return this.targetPath.Equals(otherDivert.targetPath);
- }
- }
- }
- return false;
- }
- public override int GetHashCode ()
- {
- if (hasVariableTarget) {
- const int variableTargetSalt = 12345;
- return variableDivertName.GetHashCode() + variableTargetSalt;
- } else {
- const int pathTargetSalt = 54321;
- return targetPath.GetHashCode() + pathTargetSalt;
- }
- }
- public override string ToString ()
- {
- if (hasVariableTarget) {
- return "Divert(variable: " + variableDivertName + ")";
- }
- else if (targetPath == null) {
- return "Divert(null)";
- } else {
- var sb = new StringBuilder ();
- string targetStr = targetPath.ToString ();
- int? targetLineNum = DebugLineNumberOfPath (targetPath);
- if (targetLineNum != null) {
- targetStr = "line " + targetLineNum;
- }
- sb.Append ("Divert");
- if (isConditional)
- sb.Append ("?");
- if (pushesToStack) {
- if (stackPushType == PushPopType.Function) {
- sb.Append (" function");
- } else {
- sb.Append (" tunnel");
- }
- }
- sb.Append (" -> ");
- sb.Append (targetPathString);
- sb.Append (" (");
- sb.Append (targetStr);
- sb.Append (")");
- return sb.ToString ();
- }
- }
- }
- }