view Main/jungle-main/traverser/DefaultTraverser.cs @ 20:1f99e150f336

fix folder and add Object Mapper.
author Kazuma Takeda
date Thu, 15 Dec 2016 22:52:48 +0900
parents
children 9588ad364fdd
line wrap: on
line source

using System.Collections.Generic;
using System.Collections;
using UnityEngine;
using System;

namespace JungleDB {
	public class DefaultTraverser : Traverser  {


		public Either<Error, Traversal> traverse(TreeNode _root, Evaluator _evaluator) {
			Children warper = new InnerChildren(_root, _evaluator);

			Children chs = warper;
			Either<Error, List<Direction<TreeNode>>> ret = _traverse(chs, _evaluator, -1);

			if (ret.isA ()) {
				return DefaultEither<Error, Traversal>.newA (ret.a ());
			}

			List<Direction<TreeNode>> list = ret.b ();
			IEnumerator<Direction<TreeNode>> iterable = list.iterator ();
			TreeNode destination = ret.b ().headList ().getTarget ();

			Traversal traversal = new InnerTraversal (iterable, destination);

			return DefaultEither<Error, Traversal>.newB (traversal);

		}


		private Either<Error, List<Direction<TreeNode>>> _traverse(Children _chs, Evaluator _evaluator, int _pos) {
			int pos = _pos;
			TreeNode ch;
			for (int i = 0; i < _chs.size(); i++) {
				Either<Error,TreeNode> either = _chs.at(i);
				if (either.isA ()) {
					break;
				}

				ch = either.b();
				Evaluation e = _evaluator.evaluate (ch, pos);
				Result r = e.results();

				if (r == Result.ACCEPT) {
					return _accept (ch, pos, e.evaluators ());
				}

				if (r == Result.GOAL) {
					return DefaultEither<Error,List<Direction<TreeNode>>>.newB(_goal(ch, pos));
				}

				if (r == Result.BREAK) {
					break;
				}

				if (r == Result.CONTINUE) {
					pos++;
					continue;
				}

				return DefaultEither<Error, List<Direction<TreeNode>>>.newA (TraverserError.UNDEFINED_OPERATOR);
			}
			return DefaultEither<Error, List<Direction<TreeNode>>>.newA (TraverserError.PATH_NOT_FOUND);
		}


		private List<Direction<TreeNode>> _goal( TreeNode _current, int _pos) {
			Direction<TreeNode> d  = new InnerDirection<TreeNode> (_pos, _current);

			List<Direction<TreeNode>> list = new List<Direction<TreeNode>> ();
			List<Direction<TreeNode>> newList = list.addLast (d);

			return newList;
		}


		private Either<Error, List<Direction<TreeNode>>> _accept(TreeNode _current, int _pos,Evaluator _evaluator)
		{
			Children chs = _current.getChildren ();
			Either<Error, List<Direction<TreeNode>>> either = _traverse (chs, _evaluator, 0);
			if (either.isA ()) {
				return either;
			}
			List<Direction<TreeNode>> list = either.b ();
			Direction<TreeNode> d = new InnerDirection<TreeNode> (_pos, _current);

			List<Direction<TreeNode>> newList = list.addLast (d);
			return DefaultEither<Error,List<Direction<TreeNode>>>.newB (newList);
		}

		public class InnerTraversal : Traversal{
			IEnumerator<Direction<TreeNode>> iterable;
			TreeNode destination;

			IEnumerator IEnumerable.GetEnumerator()
			{
				return this.GetEnumerator();
			}

			public IEnumerator<Direction<TreeNode>> GetEnumerator()
			{
				return iterable;
			}


			public InnerTraversal(IEnumerator<Direction<TreeNode>> _iterable, TreeNode _distination){
				this.iterable = _iterable;
				this.destination = _distination;
			}

		
			public TreeNode destinations() {
				return destination;
			}

		}

		public class InnerChildren : Children{
			TreeNode root;
			Evaluator evaluator;

			public InnerChildren(TreeNode _root, Evaluator _evaluator){
				this.root = _root;
				this.evaluator = _evaluator;
			}

			public IEnumerator<TreeNode> iterator() {
				List<TreeNode> list = new List<TreeNode> ();
				return list.addLast (root).iterator ();
			}

			public int size() {
				return 1;
			}

			public Either<Error, TreeNode> at(int _pos) {
				if (_pos != 0) {
					return DefaultEither<Error, TreeNode>.newA (NodeEditorError.INDEX_OUT_OF_BOUNDS);
				}
				return DefaultEither<Error, TreeNode>.newB (root);
			}
		}

		public class InnerDirection<TreeNode> : Direction<TreeNode>{
			int pos;
			TreeNode current;

			public InnerDirection(int _pos, TreeNode _current) {
				this.pos = _pos;
				this.current = _current;
			}

			public int getPosition() {
				return pos;
			}

			public TreeNode getTarget(){
				return current;
			}
		}
	}
}