PageRenderTime 2455ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/FlowEditor/HAB/Expressions/SearchExpression.cs

https://gitlab.com/Tiger66639/neural_network_designer
C# | 248 lines | 165 code | 23 blank | 60 comment | 41 complexity | 0242455182c3bcb3481a630cd982f426 MD5 | raw file
  1. using JaStDev.HAB.Brain;
  2. using JaStDev.HAB.Brain.Thread_syncing;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace JaStDev.HAB.Expressions
  6. {
  7. /// <summary>
  8. /// An expression that performs a search on links.
  9. /// </summary>
  10. [NeuronID((ulong)PredefinedNeurons.SearchExpression, typeof(Neuron))]
  11. public class SearchExpression : SimpleResultExpression
  12. {
  13. /// <summary>
  14. /// Default constructor.
  15. /// </summary>
  16. public SearchExpression()
  17. {
  18. }
  19. /// <summary>
  20. /// Constructor that creates correct initial links.
  21. /// </summary>
  22. /// <param name="toSearch">The object to search, if expression, it will be executed before the search.</param>
  23. /// <param name="listId">The neuron that identifies the list that should be searched. If this is an expression, it is executed first.</param>
  24. /// <param name="searchFor">Defines all the meanings that should be allowed in the result set.</param>
  25. public SearchExpression(Neuron toSearch, Neuron listId, Neuron searchFor)
  26. {
  27. Link iNew = new Link(toSearch, this, (ulong)PredefinedNeurons.ToSearch);
  28. iNew = new Link(listId, this, (ulong)PredefinedNeurons.ListToSearch);
  29. iNew = new Link(searchFor, this, (ulong)PredefinedNeurons.SearchFor);
  30. }
  31. #region InfoToSearchFor
  32. /// <summary>
  33. /// Gets/sets the (list of) info values that will be searched for. May be null.
  34. /// Only valid for In and Out <see cref="SearchExpression.ListToSearch"/>.
  35. /// </summary>
  36. /// <remarks>
  37. /// If this is a <see cref="ResultExpression"/>, it will be solved before the search is done.
  38. /// If this is a regular neuron, this is used as the search criteria.
  39. /// To search for all the children of a cluster, use a sub search expression.
  40. /// </remarks>
  41. public Neuron InfoToSearchFor
  42. {
  43. get
  44. {
  45. return FindFirstOut((ulong)PredefinedNeurons.InfoToSearchFor);
  46. }
  47. set
  48. {
  49. SetFirstOutgoingLinkTo((ulong)PredefinedNeurons.InfoToSearchFor, value);
  50. }
  51. }
  52. #endregion InfoToSearchFor
  53. #region ListToSearch
  54. /// <summary>
  55. /// Gets/sets the list that needs searching. This usually references the word 'In' or 'Out'
  56. /// for their respective lists.
  57. /// </summary>
  58. /// <remarks>
  59. /// If this is a <see cref="ResultExpression"/>, it will be solved before the search is done.
  60. /// </remarks>
  61. public Neuron ListToSearch
  62. {
  63. get
  64. {
  65. return FindFirstOut((ulong)PredefinedNeurons.ListToSearch);
  66. }
  67. set
  68. {
  69. SetFirstOutgoingLinkTo((ulong)PredefinedNeurons.ListToSearch, value);
  70. }
  71. }
  72. #endregion ListToSearch
  73. #region SearchFor
  74. /// <summary>
  75. /// Gets/sets the (list of) meaning(s) that will be searched for. May be null
  76. /// </summary>
  77. /// <remarks>
  78. /// If this is a <see cref="ResultExpression"/>, it will be solved before the search is done.
  79. /// If this is a regular neuron, this is used as the search criteria.
  80. /// To search for all the children of a cluster, use a sub search expression.
  81. /// </remarks>
  82. public Neuron SearchFor
  83. {
  84. get
  85. {
  86. return FindFirstOut((ulong)PredefinedNeurons.SearchFor);
  87. }
  88. set
  89. {
  90. SetFirstOutgoingLinkTo((ulong)PredefinedNeurons.SearchFor, value);
  91. }
  92. }
  93. #endregion SearchFor
  94. /// <summary>
  95. /// Gets/sets the object who's list will be searched.
  96. /// </summary>
  97. /// <remarks>
  98. /// If this is a <see cref="ResultExpression"/>, it will be solved before the search is done. To search in the list of a
  99. /// result expression itself, use a <see cref="Variable"/>.
  100. /// </remarks>
  101. public Neuron ToSearch
  102. {
  103. get
  104. {
  105. return FindFirstOut((ulong)PredefinedNeurons.ToSearch);
  106. }
  107. set
  108. {
  109. SetFirstOutgoingLinkTo((ulong)PredefinedNeurons.ToSearch, value);
  110. }
  111. }
  112. #region TypeOfNeuron
  113. /// <summary>
  114. /// Gets the type of this neuron expressed as a Neuron.
  115. /// </summary>
  116. /// <value><see cref="PredefinedNeurons.SearchExpression"/>.</value>
  117. public override Neuron TypeOfNeuron
  118. {
  119. get
  120. {
  121. return Brain.Brain.Current[(ulong)PredefinedNeurons.SearchExpression];
  122. }
  123. }
  124. #endregion TypeOfNeuron
  125. public override IEnumerable<Neuron> GetValue(Processor.Processor processor)
  126. {
  127. List<Neuron> iSearchList = Neuron.SolveResultExp(ToSearch, processor).ToList();
  128. if (iSearchList != null) //if there is no object to search, don't write an error, simply return an empty result.
  129. {
  130. List<Neuron> iListsToSearch = Neuron.SolveResultExp(ListToSearch, processor).ToList();
  131. if (iListsToSearch != null)
  132. {
  133. SearchData iSearchData = new SearchData();
  134. iSearchData.Result = new List<Neuron>();
  135. iSearchData.SearchFor = (from i in Neuron.SolveResultExp(SearchFor, processor) select i.ID).ToList();
  136. iSearchData.InfoToSearchFor = (from i in Neuron.SolveResultExp(InfoToSearchFor, processor) select i.ID).ToList();
  137. foreach (Neuron iToSearch in iSearchList)
  138. {
  139. foreach (Neuron iList in iListsToSearch)
  140. {
  141. switch (iList.ID)
  142. {
  143. case (ulong)PredefinedNeurons.In:
  144. using (LinksAccessor iLinksIn = iToSearch.LinksIn)
  145. {
  146. iSearchData.ToSearch = iLinksIn.Items;
  147. SearchForItemsIn(iSearchData, true);
  148. }
  149. break;
  150. case (ulong)PredefinedNeurons.Out:
  151. using (LinksAccessor iLinksOut = iToSearch.LinksOut)
  152. iSearchData.ToSearch = iLinksOut.Items;
  153. SearchForItemsIn(iSearchData, false);
  154. break;
  155. default:
  156. break;
  157. }
  158. }
  159. }
  160. return iSearchData.Result;
  161. }
  162. }
  163. return null;
  164. }
  165. ///// <summary>
  166. ///// Searches a list of neurons using the specified criteria.
  167. ///// </summary>
  168. ///// <param name="search">The search data, containing the result set.</param>
  169. ///// <param name="list">The actual list that needs to be searched.</param>
  170. //private void SearchForItemsIn(SearchData search, IList<Neuron> list)
  171. //{
  172. //}
  173. /// <summary>
  174. /// Searches a list of links and returns
  175. /// </summary>
  176. /// <param name="searchData">Searchdata: result list, meanings to search, info to search, list to search.</param>
  177. /// <param name="getFrom">true: return the from field, otherwise the to field</param>
  178. private void SearchForItemsIn(SearchData searchData, bool getFrom)
  179. {
  180. if (searchData.ToSearch != null && searchData.ToSearch.Count > 0)
  181. {
  182. bool iHasSearchFor = searchData.SearchFor != null && searchData.SearchFor.Count > 0;
  183. bool iHasSearchInfo = searchData.InfoToSearchFor != null && searchData.InfoToSearchFor.Count > 0;
  184. if (iHasSearchFor == true && iHasSearchInfo == true)
  185. {
  186. if (getFrom == true)
  187. searchData.Result.Concat(from i in searchData.ToSearch
  188. where searchData.SearchFor.Contains(i.MeaningID) == true && i.Info.Contains(searchData.InfoToSearchFor) == true
  189. select i.From);
  190. else
  191. searchData.Result.Concat(from i in searchData.ToSearch
  192. where searchData.SearchFor.Contains(i.MeaningID) == true && i.Info.Contains(searchData.InfoToSearchFor) == true
  193. select i.To);
  194. }
  195. else if (iHasSearchFor == true)
  196. {
  197. if (getFrom == true)
  198. searchData.Result.Concat(from i in searchData.ToSearch where searchData.SearchFor.Contains(i.MeaningID) == true select i.From);
  199. else
  200. searchData.Result.Concat(from i in searchData.ToSearch where searchData.SearchFor.Contains(i.MeaningID) == true select i.To);
  201. }
  202. else if (iHasSearchInfo == true)
  203. {
  204. if (getFrom == true)
  205. searchData.Result.Concat(from i in searchData.ToSearch where i.Info.Contains(searchData.InfoToSearchFor) == true select i.From); //direct access to Info is thread safe: object is IDisposable.
  206. else
  207. searchData.Result.Concat(from i in searchData.ToSearch where i.Info.Contains(searchData.InfoToSearchFor) == true select i.To);
  208. }
  209. else if (getFrom == true)
  210. searchData.Result.Concat(from i in searchData.ToSearch select i.From); //nothing to filter on, so copy over the intire search list
  211. else
  212. searchData.Result.Concat(from i in searchData.ToSearch select i.To); //nothing to filter on, so copy over the intire search list
  213. }
  214. }
  215. #region internal types
  216. private class SearchData
  217. {
  218. public List<ulong> SearchFor { get; set; } //we use ulong to compare against, a little slower in compare, but don't tax the brain by getting the object reference from the brain.
  219. public List<ulong> InfoToSearchFor { get; set; }
  220. public List<Neuron> Result { get; set; }
  221. public IList<Link> ToSearch { get; set; }
  222. }
  223. #endregion internal types
  224. }
  225. }