view Main/jungle-main/transaction/DefaultJungleTreeEditor.cs @ 33:56de71ae6f7e

Implementation of fmap.
author Kazuma Takeda
date Sat, 28 Jan 2017 19:12:18 +0900
parents 1466993c104c
children a79781723862
line wrap: on
line source

using UnityEngine;
using System.Collections.Generic;

namespace JungleDB {
	public class DefaultJungleTreeEditor : JungleTreeEditor {

		private TransactionManager txManager;
		private TreeNode root;
		private TreeEditor editor;
		private TreeOperationLog log;
		private NodePath prevPath;

		public void SetPrevPath (NodePath path) {
			this.prevPath = path;
		}

		public DefaultJungleTreeEditor(TreeNode _root,TransactionManager _txManager,TreeEditor _editor)
			: this(_root, _txManager, _editor, new DefaultTreeOperationLog())
		{
		}



		public DefaultJungleTreeEditor(TreeNode newNode, TransactionManager txManager,TreeEditor editor,TreeOperationLog log)
		{
			this.root = newNode;
			this.txManager = txManager;
			this.editor = editor;
			this.log = log;
		}



		private Either<Error,JungleTreeEditor> _edit(NodePath _path, NodeEditor _e)
		{
			Either<Error, LoggingNode> either = editor.edit (root, _path, _e);
			if (either.isA ())
				return DefaultEither<Error, JungleTreeEditor>.newA (either.a ());

			LoggingNode newLogging = either.b ();
			OperationLog newLog = newLogging.getOperationLog ();
			TreeNode newNode = newLogging.getWrap ();

			IterableConverter<TreeOperation,NodeOperation>.Converter<TreeOperation, NodeOperation> converter = new InnerConverter (_path);


			IEnumerable<TreeOperation> iterable = new IterableConverter<TreeOperation, NodeOperation> (newLog, converter);
			DefaultTreeOperationLog treeOperationLog = new DefaultTreeOperationLog (iterable, newLog.length ());
			TreeOperationLog newTreeOpLog = log.append (treeOperationLog);

			JungleTreeEditor newEditor = new DefaultJungleTreeEditor (newNode, txManager, editor, newTreeOpLog);
			newEditor.SetPrevPath (this.prevPath);

			return DefaultEither<Error, JungleTreeEditor>.newB (newEditor);

		}


		public Either<Error, JungleTreeEditor> replaceNewRootNode() {
			replaceRootNodeAt appendChildAt = new replaceRootNodeAt ();
			return _edit (new DefaultNodePath(), appendChildAt);
		}

		public Either<Error, JungleTreeEditor> addNewChildAt(NodePath _path, int _pos) {
			prevPath = _path.add (_pos);
			AppendChildAt appendChildAt = new AppendChildAt (_pos);
			return _edit (_path, appendChildAt);
		}

		public Either<Error,JungleTreeEditor> deleteChildAt(NodePath _path, int _pos) {
			DeleteChildAt deleteChildAt = new DeleteChildAt(_pos);
			return _edit(_path,deleteChildAt);
		}


		public Either<Error, JungleTreeEditor> putAttribute(NodePath _path, string _key, object _value) {
			PutAttribute putAttribute = new PutAttribute (_key, _value);
			return _edit (_path, putAttribute);
		}

		public Either<Error, JungleTreeEditor> putAttribute(NodePath _path, object _value) {
			PutAttribute putAttribute = new PutAttribute (_value.ToString(), _value);
			return _edit (_path, putAttribute);
		}

		public Either<Error, JungleTreeEditor> putAttribute(string _key, object _value) {
			PutAttribute putAttribute = new PutAttribute (_key, _value);
			return _edit (prevPath, putAttribute);
		}

		public Either<Error, JungleTreeEditor> putAttribute(object _value) {
			PutAttribute putAttribute = new PutAttribute (_value);
			return _edit (prevPath, putAttribute);
		}

		public Either<Error, JungleTreeEditor> deleteAttribute(NodePath _path, string _key) {
			DeleteAttribute deleteAttribute = new DeleteAttribute (_key);
			return _edit (_path, deleteAttribute);
		}

		public Either<Error,JungleTreeEditor> edit(NodePath _path, NodeEditor _editor) {
			return _edit(_path,_editor);
		}
			
		public Either<Error,JungleTreeEditor> commit() {
			Either<Error,TransactionManager> either = this.txManager.commit(this.root, this.log);
			if(either.isA()){
				return DefaultEither<Error, JungleTreeEditor>.newA(either.a());
			}

			TransactionManager newTxManager = either.b();
			JungleTreeEditor newTreeEditor = new DefaultJungleTreeEditor(this.root, newTxManager, this.editor);

			return DefaultEither<Error, JungleTreeEditor>.newB(newTreeEditor);
		}
			
		public Either<Error, JungleTreeEditor> flushSuccess() {
			return commit();
		}

		public class InnerConverter : IterableConverter<TreeOperation,NodeOperation>.Converter<TreeOperation,NodeOperation>{

			NodePath path;

			public InnerConverter(NodePath _path) {
				path = _path;
			}


			public TreeOperation conv(NodeOperation _b){
				return new DefaultTreeOperation(path,_b);
			}
		}
	}
}