Просмотр исходного кода

行为树配置改成每行一颗行为树

tanghai 10 лет назад
Родитель
Сommit
2734b79cc2

+ 23 - 23
CSharp/App/Editor/app.config

@@ -1,48 +1,48 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
-        <assemblyIdentity name="Microsoft.Practices.Prism" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"/>
+        <assemblyIdentity name="Microsoft.Practices.Prism" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
       </dependentAssembly>
       <dependentAssembly>
-        <assemblyIdentity name="MySql.Data" publicKeyToken="c5687fc88969c44d" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-6.6.4.0" newVersion="6.6.4.0"/>
+        <assemblyIdentity name="MySql.Data" publicKeyToken="c5687fc88969c44d" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-6.6.4.0" newVersion="6.6.4.0" />
       </dependentAssembly>
       <dependentAssembly>
-        <assemblyIdentity name="Microsoft.Practices.ServiceLocation" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0"/>
+        <assemblyIdentity name="Microsoft.Practices.ServiceLocation" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
       </dependentAssembly>
       <dependentAssembly>
-        <assemblyIdentity name="System.Windows.Interactivity" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
+        <assemblyIdentity name="System.Windows.Interactivity" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
       </dependentAssembly>
       <dependentAssembly>
-        <assemblyIdentity name="Microsoft.Practices.Prism.SharedInterfaces" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.1.0"/>
+        <assemblyIdentity name="Microsoft.Practices.Prism.SharedInterfaces" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.1.0" />
       </dependentAssembly>
       <dependentAssembly>
-        <assemblyIdentity name="Microsoft.Practices.Prism.PubSubEvents" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0"/>
+        <assemblyIdentity name="Microsoft.Practices.Prism.PubSubEvents" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
       </dependentAssembly>
     </assemblyBinding>
   </runtime>
   <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
+    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
   </startup>
   <appSettings>
-    <add key="IP" value="192.168.11.95"/>
-    <add key="Port" value="8888"/>
-    <add key="Account" value="egametang@163.com"/>
-    <add key="Password" value="163bio1"/>
-    <add key="NodePath" value="D:\Source\SLOL\Program\Unity\Assets\Resources\Config\NodeProto.txt"/>
-    <add key="ClientSettingsProvider.ServiceUri" value=""/>
+    <add key="IP" value="192.168.11.95" />
+    <add key="Port" value="8888" />
+    <add key="Account" value="egametang@163.com" />
+    <add key="Password" value="163bio1" />
+    <add key="NodePath" value="D:\Source\Egametang\CSharp\NodeProto.txt" />
+    <add key="ClientSettingsProvider.ServiceUri" value="" />
   </appSettings>
   <system.serviceModel>
     <bindings>
       <netTcpBinding>
-        <binding name="NetTcpBinding_Calculator"/>
+        <binding name="NetTcpBinding_Calculator" />
       </netTcpBinding>
     </bindings>
     <client>
@@ -53,12 +53,12 @@
   <system.web>
     <membership defaultProvider="ClientAuthenticationMembershipProvider">
       <providers>
-        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri=""/>
+        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
       </providers>
     </membership>
     <roleManager defaultProvider="ClientRoleProvider" enabled="true">
       <providers>
-        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400"/>
+        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
       </providers>
     </roleManager>
   </system.web>

+ 0 - 20
CSharp/App/Modules/BehaviorTreeModule/AllTreeData.cs

@@ -1,20 +0,0 @@
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-
-namespace Modules.BehaviorTreeModule
-{
-	[DataContract]
-	public class AllTreeData
-	{
-		private readonly List<TreeNodeData> treeNodeDatas = new List<TreeNodeData>();
-
-		[DataMember(Order = 1)]
-		public List<TreeNodeData> TreeNodeDatas
-		{
-			get
-			{
-				return this.treeNodeDatas;
-			}
-		}
-	}
-}

+ 36 - 36
CSharp/App/Modules/BehaviorTreeModule/AllTreeView.xaml

@@ -9,44 +9,44 @@
 		d:DesignWidth="1280" 
 		d:DataContext="{d:DesignInstance Tree:AllTreeViewModel}">
 	<DockPanel>
-	<Grid>
-		<Grid.RowDefinitions>
-			<RowDefinition/>
-			<RowDefinition/>
-		</Grid.RowDefinitions>
-		<Grid.ColumnDefinitions>
-			<ColumnDefinition Width="230"/>
-			<ColumnDefinition Width="Auto"/>
-			<ColumnDefinition />
-		</Grid.ColumnDefinitions>
-		<GroupBox Grid.Row="0" Grid.Column="0" Header="行为树列表:" Margin="0,0,0,289" Grid.RowSpan="2">
-			<ListBox Name="lbTreeRoots" ItemsSource="{Binding RootList}" >
-				<ListBox.ContextMenu>
-					<ContextMenu>
-						<MenuItem Header="打开" Click="MenuItem_Open" />
-						<MenuItem Header="保存" Click="MenuItem_Save" />
-						<MenuItem Header="新建" Click="MenuItem_New" />
-						<MenuItem Header="删除" Click="MenuItem_Remove" />
-						<MenuItem Header="克隆" Click="MenuItem_Clone" />
-					</ContextMenu>
-				</ListBox.ContextMenu>
-				<ListBox.ItemTemplate>
-					<DataTemplate DataType="Tree:TreeNodeViewModel">
-						<StackPanel MouseLeftButtonDown="ListBoxItem_OnMouseLeftButtonDown" MouseLeftButtonUp="ListBoxItem_OnMouseLeftButtonUp" 
+		<Grid>
+			<Grid.RowDefinitions>
+				<RowDefinition/>
+				<RowDefinition/>
+			</Grid.RowDefinitions>
+			<Grid.ColumnDefinitions>
+				<ColumnDefinition Width="230"/>
+				<ColumnDefinition Width="Auto"/>
+				<ColumnDefinition />
+			</Grid.ColumnDefinitions>
+			<GroupBox Grid.Row="0" Grid.Column="0" Header="行为树列表:" Margin="0,0,0,289" Grid.RowSpan="2">
+				<ListBox Name="lbTrees" ItemsSource="{Binding TreeViewModels}" >
+					<ListBox.ContextMenu>
+						<ContextMenu>
+							<MenuItem Header="打开" Click="MenuItem_Open" />
+							<MenuItem Header="保存" Click="MenuItem_Save" />
+							<MenuItem Header="新建" Click="MenuItem_New" />
+							<MenuItem Header="删除" Click="MenuItem_Remove" />
+							<MenuItem Header="克隆" Click="MenuItem_Clone" />
+						</ContextMenu>
+					</ListBox.ContextMenu>
+					<ListBox.ItemTemplate>
+						<DataTemplate DataType="Tree:TreeViewModel">
+							<StackPanel MouseLeftButtonDown="ListBoxItem_OnMouseLeftButtonDown" 
 									Orientation="Horizontal" Margin="1,0">
-							<Label Content="{Binding TreeId}" VerticalAlignment="Stretch" Width="30"/>
-							<Label Content="{Binding Comment}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
-						</StackPanel>
-					</DataTemplate>
-				</ListBox.ItemTemplate>
-			</ListBox>
-		</GroupBox>
-		<GroupBox Grid.Row="1" Grid.Column="0" Header="节点编辑:" Height="250" VerticalAlignment="Bottom">
-			<Tree:NodeDataEditor x:Name="nodeDataEditor" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" />
-		</GroupBox>
-		<GridSplitter Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Width="3" ShowsPreview="False" VerticalAlignment="Stretch"
+								<Label Content="{Binding TreeId}" VerticalAlignment="Stretch" Width="30"/>
+								<Label Content="{Binding Comment}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
+							</StackPanel>
+						</DataTemplate>
+					</ListBox.ItemTemplate>
+				</ListBox>
+			</GroupBox>
+			<GroupBox Grid.Row="1" Grid.Column="0" Header="节点编辑:" Height="250" VerticalAlignment="Bottom">
+				<Tree:NodeDataEditor x:Name="nodeDataEditor" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" />
+			</GroupBox>
+			<GridSplitter Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Width="3" ShowsPreview="False" VerticalAlignment="Stretch"
 				HorizontalAlignment="Stretch" />
-		<Tree:TreeView x:Name="treeView" Grid.Row="0" Grid.Column="2" Grid.RowSpan="2" />
+			<Tree:TreeView x:Name="treeView" Grid.Row="0" Grid.Column="2" Grid.RowSpan="2" />
 		</Grid>
 	</DockPanel>
 </UserControl>

+ 15 - 21
CSharp/App/Modules/BehaviorTreeModule/AllTreeView.xaml.cs

@@ -18,9 +18,9 @@ namespace Modules.BehaviorTreeModule
 
 			this.nodeDataEditor.AllTreeView = this;
 			this.treeView.AllTreeView = this;
+		    this.ViewModel = AllTreeViewModel.Instance;
 		}
 
-		[Import]
 		private AllTreeViewModel ViewModel
 		{
 			get
@@ -37,7 +37,7 @@ namespace Modules.BehaviorTreeModule
 		{
 			string nodePath = ConfigurationManager.AppSettings["NodePath"];
 			this.ViewModel.Open(nodePath);
-			this.lbTreeRoots.SelectedIndex = -1;
+			this.lbTrees.SelectedIndex = -1;
 			this.treeView.ViewModel = null;
 		}
 
@@ -50,52 +50,46 @@ namespace Modules.BehaviorTreeModule
 		private void MenuItem_New(object sender, RoutedEventArgs e)
 		{
 			TreeViewModel treeViewModel = this.ViewModel.New();
+			this.lbTrees.SelectedItem = treeViewModel;
 			this.treeView.ViewModel = treeViewModel;
 		}
 
 		private void MenuItem_Clone(object sender, RoutedEventArgs e)
 		{
-			if (this.lbTreeRoots.SelectedItem == null)
+			if (this.lbTrees.SelectedItem == null)
 			{
 				return;
 			}
-			TreeNodeViewModel treeNodeViewModel = this.lbTreeRoots.SelectedItem as TreeNodeViewModel;
-			TreeViewModel treeViewModel = this.ViewModel.Clone(treeNodeViewModel);
-			this.treeView.ViewModel = treeViewModel;
+			TreeViewModel treeViewModel = this.lbTrees.SelectedItem as TreeViewModel;
+			TreeViewModel newTreeViewModel = this.ViewModel.Clone(treeViewModel);
+			this.treeView.ViewModel = newTreeViewModel;
 		}
 
 		private void MenuItem_Remove(object sender, RoutedEventArgs e)
 		{
-			if (this.lbTreeRoots.SelectedItem == null)
+			if (this.lbTrees.SelectedItem == null)
 			{
 				return;
 			}
-			TreeNodeViewModel treeNodeViewModel = this.lbTreeRoots.SelectedItem as TreeNodeViewModel;
-			this.ViewModel.Remove(treeNodeViewModel.TreeId);
-			this.lbTreeRoots.SelectedItem = null;
+			TreeViewModel treeViewModel = this.lbTrees.SelectedItem as TreeViewModel;
+			this.ViewModel.Remove(treeViewModel);
+			this.lbTrees.SelectedItem = null;
 			e.Handled = true;
 		}
 
 		private void ListBoxItem_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 		{
 			FrameworkElement item = (FrameworkElement) sender;
-			TreeNodeViewModel treeNodeViewModel = item.DataContext as TreeNodeViewModel;
+			TreeViewModel treeViewModel = item.DataContext as TreeViewModel;
 			if (this.treeView.ViewModel != null)
 			{
-				if (this.treeView.ViewModel.TreeId == treeNodeViewModel.TreeId)
+				if (this.treeView.ViewModel.TreeId == treeViewModel.TreeId)
 				{
 					return;
 				}
 			}
-			this.treeView.ViewModel = this.ViewModel.Get(treeNodeViewModel.TreeId);
-		}
-
-		private void ListBoxItem_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
-		{
-			FrameworkElement item = (FrameworkElement) sender;
-			TreeNodeViewModel treeNodeViewModel = item.DataContext as TreeNodeViewModel;
-
-			this.lbTreeRoots.SelectedItem = treeNodeViewModel;
+			this.lbTrees.SelectedItem = treeViewModel;
+			this.treeView.ViewModel = treeViewModel;
 		}
 	}
 }

+ 30 - 72
CSharp/App/Modules/BehaviorTreeModule/AllTreeViewModel.cs

@@ -1,40 +1,36 @@
 using System;
-using System.Collections.Generic;
 using System.Collections.ObjectModel;
-using System.ComponentModel.Composition;
 using System.IO;
 using Common.Helper;
 
 namespace Modules.BehaviorTreeModule
 {
-	[Export(typeof(AllTreeViewModel)), PartCreationPolicy(CreationPolicy.NonShared)]
 	public class AllTreeViewModel
 	{
-		public int MaxNodeId { get; set; }
+        private static readonly AllTreeViewModel instance = new AllTreeViewModel();
+	    public static AllTreeViewModel Instance
+	    {
+	        get
+	        {
+	            return instance;
+	        }
+	    }
 		public int MaxTreeId { get; set; }
 
-		private readonly Dictionary<int, TreeViewModel> treeViewModelsDict =
-				new Dictionary<int, TreeViewModel>();
+		private readonly ObservableCollection<TreeViewModel> treeViewModels =
+				new ObservableCollection<TreeViewModel>();
 
-		public readonly ObservableCollection<TreeNodeViewModel> rootList =
-				new ObservableCollection<TreeNodeViewModel>();
-
-		public ObservableCollection<TreeNodeViewModel> RootList
+		public ObservableCollection<TreeViewModel> TreeViewModels
 		{
 			get
 			{
-				return this.rootList;
+				return this.treeViewModels;
 			}
 		}
 
 		public void Open(string file)
 		{
-			this.rootList.Clear();
-			this.treeViewModelsDict.Clear();
-
-			var treeDict = new Dictionary<int, List<TreeNodeData>>();
-
-			AllTreeData allTreeData = new AllTreeData();
+			this.treeViewModels.Clear();
 			string content = File.ReadAllText(file);
 			foreach (string line in content.Split(new[] { "\r\n" }, StringSplitOptions.None))
 			{
@@ -42,54 +38,24 @@ namespace Modules.BehaviorTreeModule
 				{
 					continue;
 				}
-				TreeNodeData treeNodeData = MongoHelper.FromJson<TreeNodeData>(line);
-				allTreeData.TreeNodeDatas.Add(treeNodeData);
-			}
-
-			this.MaxNodeId = 0;
-			this.MaxTreeId = 0;
-			foreach (TreeNodeData treeNodeData in allTreeData.TreeNodeDatas)
-			{
-				List<TreeNodeData> tree;
-				treeDict.TryGetValue(treeNodeData.TreeId, out tree);
-				if (tree == null)
-				{
-					tree = new List<TreeNodeData>();
-					treeDict[treeNodeData.TreeId] = tree;
-				}
-				tree.Add(treeNodeData);
-				if (treeNodeData.Id > this.MaxNodeId)
-				{
-					this.MaxNodeId = treeNodeData.Id;
-				}
-				if (treeNodeData.TreeId > this.MaxTreeId)
+				TreeViewModel treeViewModel = MongoHelper.FromJson<TreeViewModel>(line);
+				this.treeViewModels.Add(treeViewModel);
+				TreeLayout layout = new TreeLayout(treeViewModel);
+				layout.ExcuteLayout();
+				if (treeViewModel.TreeId > this.MaxTreeId)
 				{
-					this.MaxTreeId = treeNodeData.TreeId;
+					this.MaxTreeId = treeViewModel.TreeId;
 				}
 			}
-
-			foreach (KeyValuePair<int, List<TreeNodeData>> pair in treeDict)
-			{
-				TreeViewModel treeViewModel = new TreeViewModel(this, pair.Value);
-				this.treeViewModelsDict[pair.Key] = treeViewModel;
-				this.RootList.Add(treeViewModel.Root);
-			}
 		}
 
 		public void Save(string file)
 		{
-			AllTreeData allTreeData = new AllTreeData();
-			foreach (TreeViewModel value in this.treeViewModelsDict.Values)
-			{
-				List<TreeNodeData> list = value.GetDatas();
-				allTreeData.TreeNodeDatas.AddRange(list);
-			}
-
 			using (StreamWriter stream = new StreamWriter(new FileStream(file, FileMode.Create, FileAccess.Write)))
 			{
-				foreach (TreeNodeData treeNodeData in allTreeData.TreeNodeDatas)
+				foreach (TreeViewModel value in this.treeViewModels)
 				{
-					string content = MongoHelper.ToJson(treeNodeData);
+					string content = MongoHelper.ToJson(value);
 					stream.Write(content);
 					stream.Write("\r\n");
 				}
@@ -98,30 +64,22 @@ namespace Modules.BehaviorTreeModule
 
 		public TreeViewModel New()
 		{
-			TreeViewModel treeViewModel = new TreeViewModel(this);
-			this.treeViewModelsDict[treeViewModel.TreeId] = treeViewModel;
-			this.rootList.Add(treeViewModel.Root);
+			TreeViewModel treeViewModel = new TreeViewModel();
+			treeViewModel.TreeId = ++this.MaxTreeId;
+			this.treeViewModels.Add(treeViewModel);
 			return treeViewModel;
 		}
 
-		public void Remove(int treeId)
+		public void Remove(TreeViewModel treeViewModel)
 		{
-			TreeViewModel treeViewModel = this.treeViewModelsDict[treeId];
-			this.treeViewModelsDict.Remove(treeId);
-			this.rootList.Remove(treeViewModel.Root);
-		}
-
-		public TreeViewModel Clone(TreeNodeViewModel treeNodeViewModel)
-		{
-			TreeViewModel treeViewModel = (TreeViewModel)treeNodeViewModel.TreeViewModel.Clone();
-			this.treeViewModelsDict[treeViewModel.TreeId] = treeViewModel;
-			this.rootList.Add(treeViewModel.Root);
-			return treeViewModel;
+			this.treeViewModels.Remove(treeViewModel);
 		}
 
-		public TreeViewModel Get(int treeId)
+		public TreeViewModel Clone(TreeViewModel treeViewModel)
 		{
-			return this.treeViewModelsDict[treeId];
+			TreeViewModel newTreeViewModel = (TreeViewModel)treeViewModel.Clone();
+			this.treeViewModels.Add(treeViewModel);
+			return newTreeViewModel;
 		}
 	}
 }

+ 4 - 3
CSharp/App/Modules/BehaviorTreeModule/BehaviorTreeModule.csproj

@@ -71,6 +71,10 @@
       <HintPath>..\..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
       <Private>True</Private>
     </Reference>
+    <Reference Include="MongoDB.Bson, Version=2.0.0.828, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\..\packages\MongoDB.Bson.2.0.0\lib\net45\MongoDB.Bson.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
     <Reference Include="System" />
@@ -86,7 +90,6 @@
     <Reference Include="WindowsBase" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="TreeInfoViewModel.cs" />
     <Compile Include="AllTreeViewModel.cs" />
     <Compile Include="TreeLayout.cs" />
     <Compile Include="TreeView.xaml.cs">
@@ -105,8 +108,6 @@
       <DependentUpon>NodeDataEditor.xaml</DependentUpon>
     </Compile>
     <Compile Include="NodeType.cs" />
-    <Compile Include="TreeNodeData.cs" />
-    <Compile Include="AllTreeData.cs" />
     <Compile Include="TreeNodeViewModel.cs" />
   </ItemGroup>
   <ItemGroup>

+ 8 - 12
CSharp/App/Modules/BehaviorTreeModule/NodeDataEditor.xaml

@@ -15,24 +15,20 @@
 			<RowDefinition Height="*"/>
 			<RowDefinition Height="*"/>
 			<RowDefinition Height="*"/>
-			<RowDefinition Height="*"/>
 			<RowDefinition Height="4*"/>
-			<RowDefinition Height="*"/>
 		</Grid.RowDefinitions>
 		<Grid.ColumnDefinitions>
 			<ColumnDefinition Width="40"/>
 			<ColumnDefinition Width="*"/>
 		</Grid.ColumnDefinitions>
-		<Label Content="Tree:" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" VerticalContentAlignment="Stretch" Height="30" />
-		<Label Content="ID  :" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" VerticalContentAlignment="Stretch" Height="30"/>
-		<Label Content="类型:" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" Height="30"/>
-		<Label Content="参数:" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" Height="30"/>
-		<Label Content="备注:" Grid.Row="4" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" Height="30"/>
+		<Label Content="ID  :" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" VerticalContentAlignment="Stretch" Height="30"/>
+		<Label Content="类型:" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" Height="30"/>
+		<Label Content="参数:" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" Height="30"/>
+		<Label Content="备注:" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" Height="30"/>
 		
-		<Label Name="lblTreeId" Grid.Column="1" Grid.Row="0" Content="{Binding TreeId}" HorizontalAlignment="Stretch"/>
-		<Label Name="lblId" Grid.Column="1" Grid.Row="1" Content="{Binding Id}" HorizontalAlignment="Stretch"/>
-		<ComboBox Name="cbType" Grid.Column="1" Grid.Row="2" Margin="2" SelectionChanged="CbType_OnSelectionChanged" HorizontalAlignment="Stretch"/>
-		<TextBox Name="tbArgs" Grid.Column="1" Grid.Row="3" Margin="2" Text="{Binding Args, Converter={StaticResource ListToStringConverter}, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch"/>
-		<TextBox Name="tbComment" Grid.Column="1" Grid.Row="4" Margin="2" Text="{Binding Comment, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch"/>
+		<Label Name="lblId" Grid.Column="1" Grid.Row="0" Content="{Binding Id}" HorizontalAlignment="Stretch"/>
+		<ComboBox Name="cbType" Grid.Column="1" Grid.Row="1" Margin="2" SelectionChanged="CbType_OnSelectionChanged" HorizontalAlignment="Stretch"/>
+		<TextBox Name="tbArgs" Grid.Column="1" Grid.Row="2" Margin="2" Text="{Binding Args, Converter={StaticResource ListToStringConverter}, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch"/>
+		<TextBox Name="tbComment" Grid.Column="1" Grid.Row="3" Margin="2" Text="{Binding Comment, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch"/>
 	</Grid>
 </UserControl>

+ 1 - 0
CSharp/App/Modules/BehaviorTreeModule/Packages.config

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="CommonServiceLocator" version="1.3" targetFramework="net45" />
+  <package id="MongoDB.Bson" version="2.0.0" targetFramework="net451" />
   <package id="Prism" version="5.0.0" targetFramework="net45" />
   <package id="Prism.Composition" version="5.0.0" targetFramework="net45" />
   <package id="Prism.Interactivity" version="5.0.0" targetFramework="net45" />

+ 0 - 30
CSharp/App/Modules/BehaviorTreeModule/TreeInfoViewModel.cs

@@ -1,30 +0,0 @@
-namespace Modules.BehaviorTreeModule
-{
-	public class TreeInfoViewModel
-	{
-		private readonly int id;
-		private readonly string comment;
-
-		public TreeInfoViewModel(int id, string comment)
-		{
-			this.id = id;
-			this.comment = comment;
-		}
-
-		public int Id
-		{
-			get
-			{
-				return this.id;
-			}
-		}
-
-		public string Comment
-		{
-			get
-			{
-				return this.comment;
-			}
-		}
-	}
-}

+ 20 - 22
CSharp/App/Modules/BehaviorTreeModule/TreeLayout.cs

@@ -1,4 +1,6 @@
-namespace Modules.BehaviorTreeModule
+using Common.Logger;
+
+namespace Modules.BehaviorTreeModule
 {
 	public class TreeLayout
 	{
@@ -24,7 +26,7 @@
 			}
 			for (int i = 0; i < treeNodeViewModel.Children.Count; ++i)
 			{
-				TreeNodeViewModel child = this.treeViewModel.Get(treeNodeViewModel.Children[i]);
+				TreeNodeViewModel child = treeNodeViewModel.Children[i];
 				child.AncestorModify = treeNodeViewModel.Modify + treeNodeViewModel.AncestorModify;
 				TreeNodeViewModel offspring = this.LeftMostOffspring(child, currentLevel + 1, searchLevel);
 				if (offspring == null)
@@ -45,7 +47,7 @@
 			}
 			for (int i = treeNodeViewModel.Children.Count - 1; i >= 0; --i)
 			{
-				TreeNodeViewModel child = this.treeViewModel.Get(treeNodeViewModel.Children[i]);
+				TreeNodeViewModel child = treeNodeViewModel.Children[i];
 				child.AncestorModify = treeNodeViewModel.Modify + treeNodeViewModel.AncestorModify;
 				TreeNodeViewModel offspring = this.RightMostOffspring(child, currentLevel + 1, searchLevel);
 				if (offspring == null)
@@ -84,8 +86,8 @@
 			{
 				for (int j = i + 1; j < treeNodeViewModel.Children.Count; ++j)
 				{
-					TreeNodeViewModel left = this.treeViewModel.Get(treeNodeViewModel.Children[i]);
-					TreeNodeViewModel right = this.treeViewModel.Get(treeNodeViewModel.Children[j]);
+					TreeNodeViewModel left = treeNodeViewModel.Children[i];
+					TreeNodeViewModel right = treeNodeViewModel.Children[j];
 					this.AjustSubTreeGap(left, right);
 				}
 			}
@@ -93,9 +95,8 @@
 
 		private void CalculatePrelimAndModify(TreeNodeViewModel treeNodeViewModel)
 		{
-			foreach (int childId in treeNodeViewModel.Children)
+			foreach (TreeNodeViewModel child in treeNodeViewModel.Children)
 			{
-				TreeNodeViewModel child = this.treeViewModel.Get(childId);
 				this.CalculatePrelimAndModify(child);
 			}
 
@@ -134,36 +135,33 @@
 			treeNodeViewModel.Prelim = prelim;
 			treeNodeViewModel.Modify = modify;
 
-			// Log.Debug("Id: " + treeNodeViewModel.Id + " Prelim: " + treeNodeViewModel.Prelim + " Modify: " +
-			// 	treeNodeViewModel.Modify);
+			Log.Debug("Id: " + treeNodeViewModel.Id + " Prelim: " + treeNodeViewModel.Prelim + " Modify: " + treeNodeViewModel.Modify);
 		}
 
 		private void CalculateRelativeXAndY(
 				TreeNodeViewModel treeNodeViewModel, int level, double totalModify)
 		{
-			foreach (int childId in treeNodeViewModel.Children)
+			foreach (TreeNodeViewModel child in treeNodeViewModel.Children)
 			{
-				TreeNodeViewModel child = this.treeViewModel.Get(childId);
 				this.CalculateRelativeXAndY(child, level + 1, treeNodeViewModel.Modify + totalModify);
 			}
 			if (treeNodeViewModel.IsLeaf)
 			{
-				treeNodeViewModel.X = treeNodeViewModel.Prelim + totalModify;
+				treeNodeViewModel.XX = treeNodeViewModel.Prelim + totalModify;
 			}
 			else
 			{
-				treeNodeViewModel.X = (treeNodeViewModel.FirstChild.X + treeNodeViewModel.LastChild.X) / 2;
+				treeNodeViewModel.XX = (treeNodeViewModel.FirstChild.XX + treeNodeViewModel.LastChild.XX) / 2;
 			}
-			treeNodeViewModel.Y = level * (TreeNodeViewModel.Height + YGap);
+			treeNodeViewModel.YY = level * (TreeNodeViewModel.Height + YGap);
 		}
 
 		private void FixXAndY(TreeNodeViewModel treeNode)
 		{
-			treeNode.X += this.rootOffsetX;
-			treeNode.Y += this.rootOffsetY;
-			foreach (var childId in treeNode.Children)
+			treeNode.XX += this.rootOffsetX;
+			treeNode.YY += this.rootOffsetY;
+			foreach (TreeNodeViewModel child in treeNode.Children)
 			{
-				TreeNodeViewModel child = this.treeViewModel.Get(childId);
 				this.FixXAndY(child);
 			}
 		}
@@ -175,13 +173,13 @@
 			{
 				return;
 			}
-			this.rootOrigX = root.X;
-			this.rootOrigY = root.Y;
+			this.rootOrigX = root.XX;
+			this.rootOrigY = root.YY;
 			this.CalculatePrelimAndModify(root);
 			this.CalculateRelativeXAndY(root, 0, 0);
 
-			this.rootOffsetX = this.rootOrigX - root.X;
-			this.rootOffsetY = this.rootOrigY - root.Y;
+			this.rootOffsetX = this.rootOrigX - root.XX;
+			this.rootOffsetY = this.rootOrigY - root.YY;
 			this.FixXAndY(root);
 		}
 	}

+ 0 - 70
CSharp/App/Modules/BehaviorTreeModule/TreeNodeData.cs

@@ -1,70 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using Common.Helper;
-
-namespace Modules.BehaviorTreeModule
-{
-	[DataContract]
-	public class TreeNodeData : ICloneable
-	{
-		private List<int> children = new List<int>();
-
-		/// <summary>
-		/// 节点唯一Id
-		/// </summary>
-		[DataMember(Order = 1)]
-		public int Id { get; set; }
-
-		/// <summary>
-		/// 节点类型
-		/// </summary>
-		[DataMember(Order = 2)]
-		public int Type { get; set; }
-
-		/// <summary>
-		/// 节点配置参数
-		/// </summary>
-		[DataMember(Order = 3)]
-		public List<string> Args { get; set; }
-
-		/// <summary>
-		/// 父节点
-		/// </summary>
-		[DataMember(Order = 4)]
-		public int Parent { get; set; }
-
-		/// <summary>
-		/// 子节点
-		/// </summary>
-		[DataMember(Order = 5)]
-		public List<int> Children
-		{
-			get
-			{
-				return this.children;
-			}
-			set
-			{
-				this.children = value;
-			}
-		}
-
-		/// <summary>
-		/// 该节点属于哪颗树
-		/// </summary>
-		[DataMember(Order = 6)]
-		public int TreeId { get; set; }
-
-		/// <summary>
-		/// 节点说明
-		/// </summary>
-		[DataMember(Order = 7)]
-		public string Comment { get; set; }
-
-		public object Clone()
-		{
-			return ProtobufHelper.FromBytes<TreeNodeData>(ProtobufHelper.ToBytes(this));
-		}
-	}
-}

+ 92 - 88
CSharp/App/Modules/BehaviorTreeModule/TreeNodeViewModel.cs

@@ -1,15 +1,30 @@
 using System;
 using System.Collections.Generic;
+using Common.Helper;
 using Microsoft.Practices.Prism.Mvvm;
+using MongoDB.Bson.Serialization.Attributes;
 
 namespace Modules.BehaviorTreeModule
 {
-	public class TreeNodeViewModel: BindableBase
+	[BsonDiscriminator("NodeProto", RootClass = true)]
+	public class TreeNodeViewModel: BindableBase, ICloneable
 	{
+		[BsonElement]
+		private int id;
+		[BsonElement]
+		private int type;
+		[BsonElement, BsonIgnoreIfNull]
+		private List<string> args;
+		[BsonElement, BsonIgnoreIfNull]
+		private string comment;
+		[BsonElement, BsonIgnoreIfNull]
+		private List<TreeNodeViewModel> children = new List<TreeNodeViewModel>();
+
+		private TreeNodeViewModel parent;
+
 		private static double width = 80;
 		private static double height = 50;
-		public TreeViewModel TreeViewModel { get; private set; }
-		private readonly TreeNodeData data;
+
 		private double x;
 		private double y;
 		private double connectorX2;
@@ -19,15 +34,15 @@ namespace Modules.BehaviorTreeModule
 		private double ancestorModify;
 		private bool isFold;
 
+		[BsonIgnore]
+		public TreeViewModel TreeViewModel { get; set; }
+
 		public TreeNodeViewModel(TreeViewModel treeViewModel, double x, double y)
 		{
 			this.TreeViewModel = treeViewModel;
 			this.x = x;
 			this.y = y;
-			this.data = new TreeNodeData();
-			this.data.Id = ++treeViewModel.AllTreeViewModel.MaxNodeId;
-			this.data.TreeId = treeViewModel.TreeId;
-			this.data.Parent = 0;
+			this.id = ++treeViewModel.MaxNodeId;
 			this.connectorX2 = 0;
 			this.connectorY2 = Height / 2;
 		}
@@ -35,75 +50,54 @@ namespace Modules.BehaviorTreeModule
 		public TreeNodeViewModel(TreeViewModel treeViewModel, TreeNodeViewModel parent)
 		{
 			this.TreeViewModel = treeViewModel;
-			this.data = new TreeNodeData();
-			this.data.Id = ++treeViewModel.AllTreeViewModel.MaxNodeId;
-			this.data.TreeId = treeViewModel.TreeId;
+			this.Id = ++treeViewModel.MaxNodeId;
 			this.Parent = parent;
 
-			this.connectorX2 = Width + this.Parent.X - this.X;
-			this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
-		}
-
-		public TreeNodeViewModel(TreeViewModel treeViewModel, TreeNodeData data)
-		{
-			this.TreeViewModel = treeViewModel;
-			this.data = data;
-			if (this.IsRoot)
-			{
-				this.x = 300;
-				this.y = 100;
-				this.connectorX2 = 0;
-				this.connectorY2 = Height / 2;
-			}
-			else
-			{
-				this.connectorX2 = Width + this.Parent.X - this.X;
-				this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
-			}
-		}
-
-		public TreeNodeData Data
-		{
-			get
-			{
-				return this.data;
-			}
+			this.connectorX2 = Width + this.Parent.XX - this.XX;
+			this.connectorY2 = Height / 2 + this.Parent.YY - this.YY;
 		}
 
+		[BsonIgnore]
 		public int Id
 		{
 			get
 			{
-				return this.data.Id;
+				return this.id;
 			}
 			set
 			{
-				if (this.data.Id == value)
+				if (this.id == value)
 				{
 					return;
 				}
-				this.data.Id = value;
+				this.id = value;
 				this.OnPropertyChanged("Id");
 			}
 		}
 
+		[BsonIgnore]
 		public string Comment
 		{
 			get
 			{
-				return this.data.Comment;
+				return this.comment;
 			}
 			set
 			{
-				if (this.data.Comment == value)
+				if (this.comment == value)
 				{
 					return;
 				}
-				this.data.Comment = value;
+				this.comment = value;
+				if (this.IsRoot)
+				{
+					this.TreeViewModel.Comment = this.comment;
+				}
 				this.OnPropertyChanged("Comment");
 			}
 		}
 
+		[BsonIgnore]
 		public static double Width
 		{
 			get
@@ -116,6 +110,7 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public static double Height
 		{
 			get
@@ -128,6 +123,7 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public bool IsRoot
 		{
 			get
@@ -136,6 +132,7 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public double Prelim
 		{
 			get
@@ -148,6 +145,7 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public double Modify
 		{
 			get
@@ -160,7 +158,8 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
-		public double X
+		[BsonIgnore]
+		public double XX
 		{
 			get
 			{
@@ -173,22 +172,22 @@ namespace Modules.BehaviorTreeModule
 					return;
 				}
 				this.x = value;
-				this.OnPropertyChanged("X");
+				this.OnPropertyChanged("XX");
 
 				if (this.Parent != null)
 				{
-					this.ConnectorX2 = Width / 2 + this.Parent.X - this.X;
+					this.ConnectorX2 = Width / 2 + this.Parent.XX - this.XX;
 				}
 
-				foreach (var childId in this.Children)
+				foreach (TreeNodeViewModel child in this.Children)
 				{
-					TreeNodeViewModel child = this.TreeViewModel.Get(childId);
-					child.ConnectorX2 = Width / 2 + this.X - child.X;
+					child.ConnectorX2 = Width / 2 + this.XX - child.XX;
 				}
 			}
 		}
 
-		public double Y
+		[BsonIgnore]
+		public double YY
 		{
 			get
 			{
@@ -196,27 +195,27 @@ namespace Modules.BehaviorTreeModule
 			}
 			set
 			{
-				if (Math.Abs(this.Y - value) < 0.1)
+				if (Math.Abs(this.YY - value) < 0.1)
 				{
 					return;
 				}
 
 				this.y = value;
-				this.OnPropertyChanged("Y");
+				this.OnPropertyChanged("YY");
 
 				if (this.Parent != null)
 				{
-					this.ConnectorY2 = Height + this.Parent.Y - this.Y;
+					this.ConnectorY2 = Height + this.Parent.YY - this.YY;
 				}
 
-				foreach (var childId in this.Children)
+				foreach (TreeNodeViewModel child in this.Children)
 				{
-					TreeNodeViewModel child = this.TreeViewModel.Get(childId);
-					child.ConnectorY2 = Height + this.Y - child.Y;
+					child.ConnectorY2 = Height + this.YY - child.YY;
 				}
 			}
 		}
 
+		[BsonIgnore]
 		public double ConnectorX1
 		{
 			get
@@ -225,6 +224,7 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public double ConnectorY1
 		{
 			get
@@ -233,6 +233,7 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public double ConnectorX2
 		{
 			get
@@ -245,6 +246,7 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public double ConnectorY2
 		{
 			get
@@ -257,72 +259,59 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public int Type
 		{
 			get
 			{
-				return this.data.Type;
+				return this.type;
 			}
 			set
 			{
-				if (this.data.Type == value)
+				if (this.type == value)
 				{
 					return;
 				}
-				this.data.Type = value;
+				this.type = value;
 				this.OnPropertyChanged("Type");
 			}
 		}
 
+		[BsonIgnore]
 		public List<string> Args
 		{
 			get
 			{
-				return this.data.Args;
+				return this.args;
 			}
 			set
 			{
-				if (this.data.Args == value)
+				if (this.args == value)
 				{
 					return;
 				}
-				this.data.Args = value;
+				this.args = value;
 				this.OnPropertyChanged("Args");
 			}
 		}
 
-		public int TreeId
-		{
-			get
-			{
-				return this.data.TreeId;
-			}
-		}
-
+		[BsonIgnore]
 		public TreeNodeViewModel Parent
 		{
 			get
 			{
-				if (this.data.Parent == 0)
-				{
-					return null;
-				}
-				TreeNodeViewModel parent = this.TreeViewModel.Get(this.data.Parent);
 				return parent;
 			}
 			set
 			{
-				if (value == null)
-				{
-					this.data.Parent = 0;
-				}
-				this.data.Parent = value.Id;
+				this.parent = value;
 			}
 		}
 
 		/// <summary>
 		/// 节点是否折叠
 		/// </summary>
+		[BsonIgnore]
 		public bool IsFold
 		{
 			get
@@ -340,18 +329,24 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
-		public List<int> Children
+		[BsonIgnore]
+		public List<TreeNodeViewModel> Children
 		{
 			get
 			{
 				if (this.isFold)
 				{
-					return new List<int>();
+					return new List<TreeNodeViewModel>();
 				}
-				return this.data.Children;
+				return this.children;
+			}
+			set
+			{
+				this.children = value;
 			}
 		}
 
+		[BsonIgnore]
 		public TreeNodeViewModel LeftSibling
 		{
 			get
@@ -361,11 +356,12 @@ namespace Modules.BehaviorTreeModule
 					return null;
 				}
 
-				int index = this.Parent.Children.IndexOf(this.Id);
-				return index == 0? null : this.TreeViewModel.Get(this.Parent.Children[index - 1]);
+				int index = this.Parent.Children.IndexOf(this);
+				return index == 0? null : this.Parent.Children[index - 1];
 			}
 		}
 
+		[BsonIgnore]
 		public TreeNodeViewModel LastChild
 		{
 			get
@@ -376,18 +372,20 @@ namespace Modules.BehaviorTreeModule
 				}
 
 				int maxIndex = this.Children.Count - 1;
-				return this.TreeViewModel.Get(this.Children[maxIndex]);
+				return this.Children[maxIndex];
 			}
 		}
 
+		[BsonIgnore]
 		public TreeNodeViewModel FirstChild
 		{
 			get
 			{
-				return this.Children.Count == 0? null : this.TreeViewModel.Get(this.Children[0]);
+				return this.Children.Count == 0? null : this.Children[0];
 			}
 		}
 
+		[BsonIgnore]
 		public bool IsLeaf
 		{
 			get
@@ -396,6 +394,7 @@ namespace Modules.BehaviorTreeModule
 			}
 		}
 
+		[BsonIgnore]
 		public double AncestorModify
 		{
 			get
@@ -407,5 +406,10 @@ namespace Modules.BehaviorTreeModule
 				this.ancestorModify = value;
 			}
 		}
+
+		public object Clone()
+		{
+			return MongoHelper.FromJson<TreeNodeViewModel>(MongoHelper.ToJson(this));
+		}
 	}
 }

+ 7 - 7
CSharp/App/Modules/BehaviorTreeModule/TreeView.xaml

@@ -10,7 +10,7 @@
 
 	<UserControl.Resources>
 		<tree:ListToStringConverter x:Key="ListToStringConverter"/>
-		
+
 		<LinearGradientBrush x:Key="treeNodeSelectorFillBrush" StartPoint="0,0" EndPoint="0,1">
 			<GradientStop Color="White" Offset="0" />
 			<GradientStop Color="#FFF37FFF" Offset="0.6" />
@@ -32,14 +32,14 @@
 			<GradientStop Color="#FF06CBF7" Offset="0.6" />
 		</LinearGradientBrush>
 		<SolidColorBrush x:Key="treeNodeBorderBrush" Color="Black" />
-		
+
 		<tree:NodeTypeColorConverter x:Key="NodeTypeColorConverter"/>
 		<tree:NodeTypeToStringConverter x:Key="NodeTypeToStringConverter"/>
 		<tree:FolderVisiableConverter x:Key="FolderVisiableConverter"/>
 	</UserControl.Resources>
-	
+
 	<Grid>
-		<ListBox Name="listBox" SelectionMode="Single" ItemsSource="{Binding TreeNodes}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
+		<ListBox Name="listBox" SelectionMode="Single" ItemsSource="{Binding AllNodes}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
 			<ListBox.ContextMenu>
 				<ContextMenu>
 					<MenuItem Header="新建" Click="MenuItem_New" />
@@ -53,8 +53,8 @@
 			</ListBox.ContextMenu>
 			<ListBox.Resources>
 				<Style TargetType="{x:Type ListBoxItem}">
-					<Setter Property="Canvas.Left" Value="{Binding X}" />
-					<Setter Property="Canvas.Top" Value="{Binding Y}" />
+					<Setter Property="Canvas.Left" Value="{Binding XX}" />
+					<Setter Property="Canvas.Top" Value="{Binding YY}" />
 				</Style>
 			</ListBox.Resources>
 			<ListBox.ItemsPanel>
@@ -66,7 +66,7 @@
 				<DataTemplate DataType="tree:TreeNodeViewModel">
 					<Canvas MouseDown="ListBoxItem_MouseDown" MouseUp="ListBoxItem_MouseUp" MouseMove="ListBoxItem_MouseMove"
 							PreviewMouseLeftButtonDown="ListBoxItem_PreviewMouseLeftButtonDown"
-							PreviewMouseLeftButtonUp="ListBoxItem_PreviewMouseLeftButtonUp">
+							PreviewMouseLeftButtonUp="ListBoxItem_PreviewMouseLeftButtonUp" Background="#FFD62121" >
 						<Rectangle Name="rectNode" Width="{Binding Width}" Height="{Binding Height}" Cursor="Hand" StrokeThickness="0"
 								RadiusX="10" RadiusY="10" Stroke="{StaticResource treeNodeBorderBrush}" Fill="{StaticResource treeNodeSelectorFillBrush}"/>
 						<Label Content="+" Visibility="{Binding IsFold, Converter={StaticResource FolderVisiableConverter}}" Canvas.Left="60" Canvas.Top="10"/>

+ 1 - 1
CSharp/App/Modules/BehaviorTreeModule/TreeView.xaml.cs

@@ -159,7 +159,7 @@ namespace Modules.BehaviorTreeModule
 			Point point = Mouse.GetPosition(this.listBox);
 
 			// one root node
-			if (this.ViewModel.TreeNodes.Count == 0)
+			if (this.ViewModel.AllNodes.Count == 0)
 			{
 				TreeNodeViewModel addTreeNode = new TreeNodeViewModel(this.ViewModel, point.X, point.Y)
 				{

+ 130 - 121
CSharp/App/Modules/BehaviorTreeModule/TreeViewModel.cs

@@ -1,139 +1,152 @@
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using System.ComponentModel;
 using System.ComponentModel.Composition;
+using Common.Helper;
 using Microsoft.Practices.Prism.Mvvm;
+using MongoDB.Bson.Serialization.Attributes;
 
 namespace Modules.BehaviorTreeModule
 {
+	[BsonDiscriminator("TreeProto", RootClass = true)]
 	[Export(typeof (TreeViewModel)), PartCreationPolicy(CreationPolicy.NonShared)]
-	public class TreeViewModel: BindableBase, ICloneable
+	public class TreeViewModel: BindableBase, ICloneable, ISupportInitialize
 	{
-		private readonly ObservableCollection<TreeNodeViewModel> treeNodes =
-				new ObservableCollection<TreeNodeViewModel>();
-
-		private readonly Dictionary<int, TreeNodeViewModel> treeNodeDict =
-				new Dictionary<int, TreeNodeViewModel>();
-
-		public ObservableCollection<TreeNodeViewModel> TreeNodes
+		[BsonElement]
+		private TreeNodeViewModel root;
+		[BsonElement]
+		private int treeId;
+		[BsonElement]
+		private int maxNodeId;
+        [BsonIgnore]
+		public ObservableCollection<TreeNodeViewModel> allNodes = new ObservableCollection<TreeNodeViewModel>();
+
+		[BsonIgnore]
+		public ObservableCollection<TreeNodeViewModel> AllNodes
 		{
 			get
 			{
-				return this.treeNodes;
+				return this.allNodes;
 			}
 		}
 
-		public int TreeId { get; private set; }
-
-		public int copyId;
-
-		public TreeViewModel(AllTreeViewModel allTreeViewModel)
+		[BsonIgnore]
+		public int TreeId
 		{
-			this.AllTreeViewModel = allTreeViewModel;
-			this.TreeId = ++this.AllTreeViewModel.MaxTreeId;
-			TreeNodeViewModel treeNodeViewModel = new TreeNodeViewModel(this, 300, 100);
-			this.treeNodes.Add(treeNodeViewModel);
-			this.treeNodeDict[treeNodeViewModel.Id] = treeNodeViewModel;
-
-			TreeLayout treeLayout = new TreeLayout(this);
-			treeLayout.ExcuteLayout();
+			get
+			{
+				return this.treeId;
+			}
+			set
+			{
+				if (this.treeId == value)
+				{
+					return;
+				}
+				this.treeId = value;
+				this.OnPropertyChanged("TreeId");
+			}
 		}
 
-		public TreeViewModel(AllTreeViewModel allTreeViewModel, List<TreeNodeData> treeNodeDatas)
+		[BsonIgnore]
+		public string Comment
 		{
-			this.AllTreeViewModel = allTreeViewModel;
-			this.TreeId = treeNodeDatas[0].TreeId;
-			foreach (TreeNodeData treeNodeData in treeNodeDatas)
+			get
 			{
-				TreeNodeViewModel treeNodeViewModel = new TreeNodeViewModel(this, treeNodeData);
-				this.treeNodes.Add(treeNodeViewModel);
-				this.treeNodeDict[treeNodeViewModel.Id] = treeNodeViewModel;
+				if (this.root == null)
+				{
+					return "";
+				}
+				return this.root.Comment;
+			}
+			set
+			{
+				this.OnPropertyChanged("Comment");
 			}
-			TreeLayout treeLayout = new TreeLayout(this);
-			treeLayout.ExcuteLayout();
 		}
 
-		public List<TreeNodeData> GetDatas()
+		public int MaxNodeId 
 		{
-			var treeNodeDatas = new List<TreeNodeData>();
-			foreach (TreeNodeViewModel treeNodeViewModel in this.treeNodes)
+			get
 			{
-				TreeNodeData treeNodeData = (TreeNodeData) treeNodeViewModel.Data.Clone();
-				treeNodeDatas.Add(treeNodeData);
+				return this.maxNodeId;
 			}
-			return treeNodeDatas;
+			set
+			{
+				this.maxNodeId = value;
+			} 
 		}
 
-		public AllTreeViewModel AllTreeViewModel { get; private set; }
-
+		[BsonIgnore]
+		public TreeNodeViewModel copy;
+        
+		[BsonIgnore]
 		public TreeNodeViewModel Root
 		{
 			get
 			{
-				return this.treeNodes.Count == 0? null : this.treeNodes[0];
+				return this.root;
+			}
+			set
+			{
+				this.root = value;
 			}
-		}
-
-		public TreeNodeViewModel Get(int id)
-		{
-			TreeNodeViewModel node;
-			this.treeNodeDict.TryGetValue(id, out node);
-			return node;
 		}
 
 		public void Add(TreeNodeViewModel treeNode, TreeNodeViewModel parent)
 		{
 			// 如果父节点是折叠的,需要先展开父节点
-			if (parent != null && parent.IsFold)
-			{
-				this.UnFold(parent);
-			}
-
-			this.treeNodes.Add(treeNode);
-			this.treeNodeDict[treeNode.Id] = treeNode;
-
 			if (parent != null)
 			{
+				if (parent.IsFold)
+				{
+					this.UnFold(parent);
+				}
 				treeNode.Parent = parent;
-				parent.Children.Add(treeNode.Id);
+				parent.Children.Add(treeNode);
 			}
+			else
+			{
+				this.root = treeNode;
+			}
+
+			treeNode.TreeViewModel = this;
+			allNodes.Add(treeNode);
 
 			TreeLayout treeLayout = new TreeLayout(this);
 			treeLayout.ExcuteLayout();
 		}
 
-		private void GetChildrenIdAndSelf(TreeNodeViewModel treeNodeViewModel, List<int> children)
+		private void GetChildrenIdAndSelf(TreeNodeViewModel treeNodeViewModel, List<TreeNodeViewModel> children)
 		{
-			children.Add(treeNodeViewModel.Id);
+			children.Add(treeNodeViewModel);
 			this.GetAllChildrenId(treeNodeViewModel, children);
 		}
 
-		private void GetAllChildrenId(TreeNodeViewModel treeNodeViewModel, List<int> children)
+		private void GetAllChildrenId(TreeNodeViewModel treeNodeViewModel, List<TreeNodeViewModel> children)
 		{
-			foreach (int childId in treeNodeViewModel.Children)
+			foreach (TreeNodeViewModel child in treeNodeViewModel.Children)
 			{
-				TreeNodeViewModel child = this.Get(childId);
-				children.Add(child.Id);
+				children.Add(child);
 				this.GetAllChildrenId(child, children);
 			}
 		}
 
 		public void Remove(TreeNodeViewModel treeNodeViewModel)
 		{
-			var allId = new List<int>();
-			this.GetChildrenIdAndSelf(treeNodeViewModel, allId);
+			var all = new List<TreeNodeViewModel>();
+			this.GetChildrenIdAndSelf(treeNodeViewModel, all);
 
-			foreach (int childId in allId)
+			foreach (TreeNodeViewModel child in all)
 			{
-				TreeNodeViewModel child = this.Get(childId);
-				this.treeNodes.Remove(child);
-				this.treeNodes.Remove(treeNodeViewModel);
+				this.allNodes.Remove(child);
 			}
 
 			TreeNodeViewModel parent = treeNodeViewModel.Parent;
 			if (parent != null)
 			{
-				parent.Children.Remove(treeNodeViewModel.Id);
+				parent.Children.Remove(treeNodeViewModel);
 			}
 
 			TreeLayout treeLayout = new TreeLayout(this);
@@ -142,11 +155,10 @@ namespace Modules.BehaviorTreeModule
 
 		private void RecursionMove(TreeNodeViewModel treeNodeViewModel, double offsetX, double offsetY)
 		{
-			treeNodeViewModel.X += offsetX;
-			treeNodeViewModel.Y += offsetY;
-			foreach (int childId in treeNodeViewModel.Children)
+			treeNodeViewModel.XX += offsetX;
+			treeNodeViewModel.YY += offsetY;
+			foreach (TreeNodeViewModel child in treeNodeViewModel.Children)
 			{
-				TreeNodeViewModel child = this.Get(childId);
 				this.RecursionMove(child, offsetX, offsetY);
 			}
 		}
@@ -182,8 +194,8 @@ namespace Modules.BehaviorTreeModule
 			{
 				this.UnFold(to);
 			}
-			from.Parent.Children.Remove(from.Id);
-			to.Children.Add(from.Id);
+			from.Parent.Children.Remove(from);
+			to.Children.Add(from);
 			from.Parent = to;
 			TreeLayout treeLayout = new TreeLayout(this);
 			treeLayout.ExcuteLayout();
@@ -195,13 +207,12 @@ namespace Modules.BehaviorTreeModule
 		/// <param name="treeNodeViewModel"></param>
 		public void Fold(TreeNodeViewModel treeNodeViewModel)
 		{
-			var allChildId = new List<int>();
-			this.GetAllChildrenId(treeNodeViewModel, allChildId);
+			var allChild = new List<TreeNodeViewModel>();
+			this.GetAllChildrenId(treeNodeViewModel, allChild);
 
-			foreach (int childId in allChildId)
+			foreach (TreeNodeViewModel child in allChild)
 			{
-				TreeNodeViewModel child = this.Get(childId);
-				this.treeNodes.Remove(child);
+				this.allNodes.Remove(child);
 			}
 
 			treeNodeViewModel.IsFold = true;
@@ -218,13 +229,12 @@ namespace Modules.BehaviorTreeModule
 		{
 			treeNodeViewModel.IsFold = false;
 
-			var allChildId = new List<int>();
-			this.GetAllChildrenId(treeNodeViewModel, allChildId);
+			var allChild = new List<TreeNodeViewModel>();
+			this.GetAllChildrenId(treeNodeViewModel, allChild);
 
-			foreach (int childId in allChildId)
+			foreach (TreeNodeViewModel child in allChild)
 			{
-				TreeNodeViewModel child = this.Get(childId);
-				this.treeNodes.Add(child);
+				this.allNodes.Add(child);
 			}
 
 			TreeLayout treeLayout = new TreeLayout(this);
@@ -238,13 +248,13 @@ namespace Modules.BehaviorTreeModule
 				return;
 			}
 			TreeNodeViewModel parent = treeNodeViewModel.Parent;
-			int index = parent.Children.IndexOf(treeNodeViewModel.Id);
+			int index = parent.Children.IndexOf(treeNodeViewModel);
 			if (index == 0)
 			{
 				return;
 			}
-			parent.Children.Remove(treeNodeViewModel.Id);
-			parent.Children.Insert(index - 1, treeNodeViewModel.Id);
+			parent.Children.Remove(treeNodeViewModel);
+			parent.Children.Insert(index - 1, treeNodeViewModel);
 
 			TreeLayout treeLayout = new TreeLayout(this);
 			treeLayout.ExcuteLayout();
@@ -257,13 +267,13 @@ namespace Modules.BehaviorTreeModule
 				return;
 			}
 			TreeNodeViewModel parent = treeNodeViewModel.Parent;
-			int index = parent.Children.IndexOf(treeNodeViewModel.Id);
+			int index = parent.Children.IndexOf(treeNodeViewModel);
 			if (index == parent.Children.Count - 1)
 			{
 				return;
 			}
-			parent.Children.Remove(treeNodeViewModel.Id);
-			parent.Children.Insert(index + 1, treeNodeViewModel.Id);
+			parent.Children.Remove(treeNodeViewModel);
+			parent.Children.Insert(index + 1, treeNodeViewModel);
 
 			TreeLayout treeLayout = new TreeLayout(this);
 			treeLayout.ExcuteLayout();
@@ -271,17 +281,17 @@ namespace Modules.BehaviorTreeModule
 
 		public void Copy(TreeNodeViewModel copyTreeNodeViewModel)
 		{
-			this.copyId = copyTreeNodeViewModel.Id;
+			this.copy = copyTreeNodeViewModel;
 		}
 
 		public void Paste(TreeNodeViewModel pasteTreeNodeViewModel)
 		{
-			if (this.copyId == 0)
+			if (this.copy == null)
 			{
 				return;
 			}
 
-			TreeNodeViewModel copyTreeNodeViewModel = this.treeNodeDict[this.copyId];
+			TreeNodeViewModel copyTreeNodeViewModel = this.copy;
 			// copy节点不能是paste节点的父级节点
 			TreeNodeViewModel tmpNode = pasteTreeNodeViewModel;
 			while (tmpNode != null)
@@ -296,53 +306,52 @@ namespace Modules.BehaviorTreeModule
 				}
 				tmpNode = tmpNode.Parent;
 			}
-			this.copyId = 0;
+			this.copy = null;
 			this.CopyTree(copyTreeNodeViewModel, pasteTreeNodeViewModel);
 		}
 
 		private void CopyTree(TreeNodeViewModel copyTreeNodeViewModel, TreeNodeViewModel parent)
 		{
-			TreeNodeData newTreeNodeData = (TreeNodeData) copyTreeNodeViewModel.Data.Clone();
-			newTreeNodeData.Id = ++this.AllTreeViewModel.MaxNodeId;
-			newTreeNodeData.TreeId = this.TreeId;
-			newTreeNodeData.Children.Clear();
-			TreeNodeViewModel newTreeNodeViewModel = new TreeNodeViewModel(this, newTreeNodeData);
+			TreeNodeViewModel newTreeNodeViewModel = (TreeNodeViewModel)copyTreeNodeViewModel.Clone();
+			newTreeNodeViewModel.Id = ++this.MaxNodeId;
 
 			this.Add(newTreeNodeViewModel, parent);
 
-			foreach (int childId in copyTreeNodeViewModel.Children)
+			foreach (TreeNodeViewModel child in copyTreeNodeViewModel.Children)
 			{
-				TreeNodeViewModel child = this.Get(childId);
 				this.CopyTree(child, newTreeNodeViewModel);
 			}
 		}
 
 		public object Clone()
 		{
-			int treeId = ++this.AllTreeViewModel.MaxTreeId;
-			List<TreeNodeData> treeNodeDatas = this.GetDatas();
-			// 旧id和新id的映射关系
-			var idMapping = new Dictionary<int, int>();
-			idMapping[0] = 0;
-			foreach (TreeNodeData treeNodeData in treeNodeDatas)
+			return MongoHelper.FromJson<TreeViewModel>(MongoHelper.ToJson(this));
+		}
+
+		private void SetChildParent(TreeNodeViewModel node)
+		{
+			if (node == null)
 			{
-				int newId = ++this.AllTreeViewModel.MaxNodeId;
-				idMapping[treeNodeData.Id] = newId;
-				treeNodeData.Id = newId;
-				treeNodeData.TreeId = treeId;
+				return;
 			}
-
-			foreach (TreeNodeData treeNodeData in treeNodeDatas)
+			node.TreeViewModel = this;
+            allNodes.Add(node);
+			foreach (TreeNodeViewModel child in node.Children)
 			{
-				treeNodeData.Parent = idMapping[treeNodeData.Parent];
-				for (int i = 0; i < treeNodeData.Children.Count; ++i)
-				{
-					treeNodeData.Children[i] = idMapping[treeNodeData.Children[i]];
-				}
+				child.Parent = node;
+				SetChildParent(child);
 			}
+		}
+
+		public void BeginInit()
+		{
+		}
 
-			TreeViewModel clone = new TreeViewModel(this.AllTreeViewModel, treeNodeDatas);
-			return clone;
+		public void EndInit()
+		{
+			SetChildParent(Root);
+			this.Root.XX = 250;
+			this.Root.YY = 10;
 		}
 	}
 }

+ 8 - 8
CSharp/App/Modules/BehaviorTreeModule/app.config

@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
-        <assemblyIdentity name="Microsoft.Practices.ServiceLocation" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0"/>
+        <assemblyIdentity name="Microsoft.Practices.ServiceLocation" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
       </dependentAssembly>
       <dependentAssembly>
-        <assemblyIdentity name="Microsoft.Practices.Prism.SharedInterfaces" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.1.0"/>
+        <assemblyIdentity name="Microsoft.Practices.Prism.SharedInterfaces" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.1.0" />
       </dependentAssembly>
       <dependentAssembly>
-        <assemblyIdentity name="Microsoft.Practices.Prism.PubSubEvents" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0"/>
+        <assemblyIdentity name="Microsoft.Practices.Prism.PubSubEvents" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
       </dependentAssembly>
     </assemblyBinding>
   </runtime>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/></startup></configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" /></startup></configuration>

+ 1 - 0
CSharp/CSharp.sln.DotSettings

@@ -19,6 +19,7 @@
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SpecifyACultureInStringConversionExplicitly/@EntryIndexedValue">DO_NOT_SHOW</s:String>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestUseVarKeywordEverywhere/@EntryIndexedValue">DO_NOT_SHOW</s:String>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestUseVarKeywordEvident/@EntryIndexedValue">DO_NOT_SHOW</s:String>
+	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FElsewhere/@EntryIndexedValue">DO_NOT_SHOW</s:String>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">DO_NOT_SHOW</s:String>