PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/JTacticalSim.Service/UnitService.cs

https://github.com/Queztionmark/JTacticalSim
C# | 535 lines | 425 code | 104 blank | 6 comment | 38 complexity | 8c1b499855c17e515c41f62278ec05c1 MD5 | raw file
  1. using System;
  2. using System.Configuration;
  3. using System.Threading.Tasks;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Transactions;
  7. using System.ServiceModel;
  8. using JTacticalSim.API;
  9. using JTacticalSim.API.Component;
  10. using JTacticalSim.API.Data;
  11. using JTacticalSim.API.InfoObjects;
  12. using JTacticalSim.API.Service;
  13. using JTacticalSim.Component.Battle;
  14. using JTacticalSim.Service;
  15. using JTacticalSim.Utility;
  16. using JTacticalSim.DataContext;
  17. using JTacticalSim.DataContext.Repository;
  18. using ctxUtil = JTacticalSim.DataContext.Utility;
  19. using JTacticalSim.Component.GameBoard;
  20. using JTacticalSim.World;
  21. namespace JTacticalSim.Service
  22. {
  23. [ServiceBehavior]
  24. public sealed class UnitService : BaseGameService, IUnitService
  25. {
  26. static readonly object padlock = new object();
  27. private static volatile IUnitService _instance = null;
  28. public static IUnitService Instance
  29. {
  30. get
  31. {
  32. if (_instance == null)
  33. {
  34. lock (padlock)
  35. if (_instance == null) _instance = new UnitService();
  36. }
  37. return _instance;
  38. }
  39. }
  40. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  41. private UnitService()
  42. {}
  43. #region Service Methods
  44. [OperationBehavior]
  45. public IServiceResult<IUnit> CreateUnit(string name,
  46. ICoordinate coordinate,
  47. ICountry country,
  48. UnitInfo unitInfo,
  49. ISubNodeLocation subNodeLocation)
  50. {
  51. var result = new ServiceResult<IUnit>();
  52. result.Status = ResultStatus.SUCCESS;
  53. try
  54. {
  55. var unit = new Unit(name, coordinate, unitInfo) { Country = country, SubNodeLocation = subNodeLocation };
  56. result.SuccessfulObjects.Add(unit);
  57. result.Result = unit;
  58. result.Messages.Add("Unit Created");
  59. }
  60. catch (Exception ex)
  61. {
  62. result.ex = ex;
  63. result.Status = ResultStatus.EXCEPTION;
  64. result.Messages.Add("Unit not created");
  65. }
  66. return result;
  67. }
  68. [OperationBehavior]
  69. public IServiceResult<IUnit> SaveUnits(List<IUnit> units)
  70. {
  71. return ComponentRepository.SaveUnits(units);
  72. }
  73. [OperationBehavior]
  74. public IServiceResult<IUnit> RemoveUnits(List<IUnit> units)
  75. {
  76. return ComponentRepository.RemoveUnits(units);
  77. }
  78. [OperationBehavior]
  79. public IServiceResult<IUnit> UpdateUnits(List<IUnit> units)
  80. {
  81. return ComponentRepository.UpdateUnits(units);
  82. }
  83. [OperationBehavior]
  84. public void UpdateUnitLocation(IUnit unit, INode node, INode lastNode)
  85. {
  86. if (!unit.ExistsInContext()) return;
  87. // Set node coordinate location
  88. unit.Location = node.Location;
  89. // Set SubNodeLocation
  90. // TODO: we might need to force a setting based on hybrid demographics and multiple stacks. Not sure yet.
  91. var direction = (lastNode != null)
  92. ? (Direction)JTSServices.NodeService.GetNodeDirectionFromNeighborSourceNode(lastNode, node)
  93. : Direction.NONE;
  94. unit.SubNodeLocation = (direction == Direction.NONE)
  95. ? new SubNodeLocation(5)
  96. : new SubNodeLocation(Orienting.ConvertDirectionToSubNodeLocation(direction));
  97. UpdateUnits(new List<IUnit> { unit });
  98. }
  99. [OperationBehavior]
  100. public IEnumerable<IUnit> GetAllUnits(IEnumerable<IFaction> factions)
  101. {
  102. var q = ComponentRepository.GetUnits();
  103. var comps = q.Select(u => u.ToComponent());
  104. return comps
  105. .Where(u => factions.Contains(u.Country.Faction))
  106. .Select(u => u);
  107. }
  108. [OperationBehavior]
  109. public IEnumerable<IUnit> GetAllUnits(ICountry country)
  110. {
  111. var q = ComponentRepository.GetUnits();
  112. var comps = q.Select(u => u.ToComponent());
  113. return comps
  114. .Where(u => u.Country.Equals(country));
  115. }
  116. [OperationBehavior]
  117. public List<IUnit> GetUnitsAt(ICoordinate coordinate, IEnumerable<IFaction> factions)
  118. {
  119. var comps = ComponentRepository.GetUnits().Where(u => u.Location != null).Select(u => u.ToComponent());
  120. return comps
  121. .Where(u => u.LocationEquals(coordinate))
  122. .Where(u => factions.Any(f => f.Equals(u.Faction)))
  123. .Select(u => u).ToList();
  124. }
  125. [OperationBehavior]
  126. public List<IUnit> GetUnitsAt(ICoordinate coordinate, IEnumerable<ICountry> countries)
  127. {
  128. var comps = ComponentRepository.GetUnits().Where(u => u.Location != null).Select(u => u.ToComponent());
  129. return comps
  130. .Where(u => u.Location.Equals(coordinate))
  131. .Where(u => countries.Any(c => c.Equals(u.Country)))
  132. .Select(u => u).ToList();
  133. }
  134. [OperationBehavior]
  135. public List<IUnit> GetAllUnitsAt(ICoordinate coordinate)
  136. {
  137. var factions = JTSServices.GameService.GetAllFactions();
  138. return GetUnitsAt(coordinate, factions);
  139. }
  140. [OperationBehavior]
  141. public List<IUnit> GetUnitsByUnitAssignment(int unitID)
  142. {
  143. var ids = DataRepository.GetUnitAssignments().Where(ua => ua.AssignedToUnit == unitID).Select(ua => ua.Unit);
  144. var retVal = ComponentRepository.GetUnits().Where(u => ids.Contains(u.ID)).Select(u => u.ToComponent());
  145. return retVal.ToList();
  146. }
  147. [OperationBehavior]
  148. public List<IUnit> GetUnitsByUnitAssignmentRecursive(int unitID)
  149. {
  150. var retVal = new List<IUnit>();
  151. var nextLevel = GetUnitsByUnitAssignment(unitID);
  152. retVal.AddRange(nextLevel);
  153. while (nextLevel.Any())
  154. {
  155. var thisLevel = new List<IUnit>();
  156. // Get all units by assignment for current level
  157. nextLevel.ForEach(u => thisLevel.AddRange(GetUnitsByUnitAssignment(u.ID)));
  158. // Add this level to the total assigned units
  159. retVal.AddRange(thisLevel);
  160. nextLevel = thisLevel;
  161. }
  162. return retVal;
  163. }
  164. [OperationBehavior]
  165. public List<IUnit> GetUnitsByTransport(int transportID)
  166. {
  167. var ids = DataRepository.GetUnitTransports().Where(ut => ut.TransportUnit == transportID).Select(ua => ua.Unit);
  168. var retVal = ComponentRepository.GetUnits().Where(u => ids.Contains(u.ID)).Select(u => u.ToComponent());
  169. return retVal.ToList();
  170. }
  171. [OperationBehavior]
  172. public IUnit GetUnitAssignedToUnit(int unitID)
  173. {
  174. var id = DataRepository.GetUnitAssignments()
  175. .Where(ua => ua.Unit == unitID)
  176. .Select(ua => ua.AssignedToUnit)
  177. .SingleOrDefault();
  178. var unit = ComponentRepository.GetUnits().SingleOrDefault(u => u.ID == id);
  179. return unit.ToComponent();
  180. }
  181. [OperationBehavior]
  182. public IUnit GetUnitByID(int id)
  183. {
  184. var dto = ComponentRepository.GetUnits().SingleOrDefault(u => u.ID == id);
  185. if (dto == null)
  186. throw new ComponentNotFoundException("No unit found with id {0}".F(id));
  187. return dto.ToComponent();
  188. }
  189. [OperationBehavior]
  190. public IServiceResult<IEnumerable<IUnitClass>> GetAllowableUnitClassesForUnit(IUnit unit)
  191. {
  192. var r = new ServiceResult<IEnumerable<IUnitClass>>();
  193. var ids = JTSServices.DataService.LookupAllowableUnitClassesByUnitBaseType(unit.UnitInfo.UnitType.BaseType.ID);
  194. r.Result = JTSServices.UnitService.GetUnitClassesByIDs(ids).Result;
  195. return r;
  196. }
  197. [OperationBehavior]
  198. public IUnitClass GetUnitClassByID(int id)
  199. {
  200. var dto = ComponentRepository.GetUnitClasses().SingleOrDefault(uc => uc.ID == id);
  201. if (dto == null)
  202. throw new ComponentNotFoundException("No unit class found with id {0}".F(id));
  203. return dto.ToComponent();
  204. }
  205. [OperationBehavior]
  206. public IUnitClass GetUnitClassByName(string name)
  207. {
  208. var dto = ComponentRepository.GetUnitClasses().SingleOrDefault(uc => uc.Name.ToLowerInvariant() == name.ToLowerInvariant());
  209. if (dto == null)
  210. throw new ComponentNotFoundException("No unit class found with name {0}".F(name));
  211. return dto.ToComponent();
  212. }
  213. [OperationBehavior]
  214. public IServiceResult<IEnumerable<IUnitClass>> GetUnitClassesByIDs(IEnumerable<int> ids)
  215. {
  216. var r = new ServiceResult<IEnumerable<IUnitClass>>();
  217. r.Result = ComponentRepository.GetUnitClasses().Where(uc => ids.Contains(uc.ID)).Select(uc => uc.ToComponent());
  218. return r;
  219. }
  220. [OperationBehavior]
  221. public IEnumerable<IUnitClass> GetUnitClasses()
  222. {
  223. return ComponentRepository.GetUnitClasses().Select(uc => uc.ToComponent());
  224. }
  225. [OperationBehavior]
  226. public IServiceResult<IUnitClass> SaveUnitClasses(List<IUnitClass> unitClasses)
  227. {
  228. return ComponentRepository.SaveUnitClasses(unitClasses);
  229. }
  230. [OperationBehavior]
  231. public IServiceResult<IUnitClass> RemoveUnitClasses(List<IUnitClass> unitClasses)
  232. {
  233. return ComponentRepository.RemoveUnitClasses(unitClasses);
  234. }
  235. [OperationBehavior]
  236. public IServiceResult<IUnitClass> UpdateUnitClasses(List<IUnitClass> unitClasses)
  237. {
  238. return ComponentRepository.UpdateUnitClasses(unitClasses);
  239. }
  240. [OperationBehavior]
  241. public IEnumerable<IUnitBaseType> GetUnitBaseTypes()
  242. {
  243. return ComponentRepository.GetUnitBaseTypes().Select(ubt => ubt.ToComponent());
  244. }
  245. [OperationBehavior]
  246. public IServiceResult<IUnitBaseType> SaveUnitBaseTypes(List<IUnitBaseType> unitBaseTypes)
  247. {
  248. return ComponentRepository.SaveUnitBaseTypes(unitBaseTypes);
  249. }
  250. [OperationBehavior]
  251. public IServiceResult<IUnitBaseType> RemoveUnitBaseTypes(List<IUnitBaseType> unitBaseTypes)
  252. {
  253. return ComponentRepository.RemoveUnitBaseTypes(unitBaseTypes);
  254. }
  255. [OperationBehavior]
  256. public IServiceResult<IUnitBaseType> UpdateUnitBaseTypes(List<IUnitBaseType> unitBaseTypes)
  257. {
  258. return ComponentRepository.UpdateUnitBaseTypes(unitBaseTypes);
  259. }
  260. [OperationBehavior]
  261. public IUnitGroupType GetUnitGroupTypeByID(int id)
  262. {
  263. var dto = ComponentRepository.GetUnitGroupTypes().SingleOrDefault(ugt => ugt.ID == id);
  264. if (dto == null)
  265. throw new ComponentNotFoundException("No unit group type found with id {0}".F(id));
  266. return dto.ToComponent();
  267. }
  268. [OperationBehavior]
  269. public IUnitGroupType GetUnitGroupTypeByName(string name)
  270. {
  271. var dto = ComponentRepository.GetUnitGroupTypes().SingleOrDefault(o => o.Name.ToLowerInvariant() == name.ToLowerInvariant());
  272. if (dto == null)
  273. throw new ComponentNotFoundException("No unit group type found with name {0}".F(name));
  274. return dto.ToComponent();
  275. }
  276. [OperationBehavior]
  277. public IServiceResult<IEnumerable<IUnitGroupType>> GetUnitGroupTypesByIDs(IEnumerable<int> ids)
  278. {
  279. var r = new ServiceResult<IEnumerable<IUnitGroupType>>();
  280. r.Result = ComponentRepository.GetUnitGroupTypes().Where(ugt => ids.Contains(ugt.ID)).Select(ugt => ugt.ToComponent());
  281. return r;
  282. }
  283. [OperationBehavior]
  284. public IEnumerable<IUnitGroupType> GetUnitGroupTypes()
  285. {
  286. return ComponentRepository.GetUnitGroupTypes().Select(ugt => ugt.ToComponent());
  287. }
  288. [OperationBehavior]
  289. public IServiceResult<IUnitGroupType> SaveUnitGroupTypes(List<IUnitGroupType> unitGroupTypes)
  290. {
  291. return ComponentRepository.SaveUnitGroupTypes(unitGroupTypes);
  292. }
  293. [OperationBehavior]
  294. public IServiceResult<IUnitGroupType> RemoveUnitGroupTypes(List<IUnitGroupType> unitGroupTypes)
  295. {
  296. return ComponentRepository.RemoveUnitGroupTypes(unitGroupTypes);
  297. }
  298. [OperationBehavior]
  299. public IServiceResult<IUnitGroupType> UpdateUnitGroupTypes(List<IUnitGroupType> unitGroupTypes)
  300. {
  301. return ComponentRepository.UpdateUnitGroupTypes(unitGroupTypes);
  302. }
  303. [OperationBehavior]
  304. public IUnitGroupType GetNextHighestUnitGroupType(IUnitGroupType ugt)
  305. {
  306. var allUnitLevels = ComponentRepository.GetUnitGroupTypes().Select(gt => gt.ToComponent()).ToList();
  307. allUnitLevels.Sort();
  308. return allUnitLevels.FirstOrDefault(ul => ul.Level > ugt.Level);
  309. }
  310. [OperationBehavior]
  311. public IEnumerable<IUnitGeogType> GetUnitGeogTypes()
  312. {
  313. return ComponentRepository.GetUnitGeogTypes().Select(ugt => ugt.ToComponent());
  314. }
  315. [OperationBehavior]
  316. public IServiceResult<IUnitGeogType> SaveUnitGeogTypes(List<IUnitGeogType> unitGeogTypes)
  317. {
  318. return ComponentRepository.SaveUnitGeogTypes(unitGeogTypes);
  319. }
  320. [OperationBehavior]
  321. public IServiceResult<IUnitGeogType> RemoveUnitGeogTypes(List<IUnitGeogType> unitGeogTypes)
  322. {
  323. return ComponentRepository.RemoveUnitGeogTypes(unitGeogTypes);
  324. }
  325. [OperationBehavior]
  326. public IServiceResult<IUnitGeogType> UpdateUnitGeogTypes(List<IUnitGeogType> unitGeogTypes)
  327. {
  328. return ComponentRepository.UpdateUnitGeogTypes(unitGeogTypes);
  329. }
  330. [OperationBehavior]
  331. public IEnumerable<IUnitTask> GetUnitTasks()
  332. {
  333. return ComponentRepository.GetUnitTasks().Select(ut => ut.ToComponent());
  334. }
  335. [OperationBehavior]
  336. public IServiceResult<IUnitTask> SaveUnitTasks(List<IUnitTask> unitTasks)
  337. {
  338. return ComponentRepository.SaveUnitTasks(unitTasks);
  339. }
  340. [OperationBehavior]
  341. public IServiceResult<IUnitTask> RemoveUnitTasks(List<IUnitTask> unitTasks)
  342. {
  343. return ComponentRepository.RemoveUnitTasks(unitTasks);
  344. }
  345. [OperationBehavior]
  346. public IServiceResult<IUnitTask> UpdateUnitTasks(List<IUnitTask> unitTasks)
  347. {
  348. return ComponentRepository.UpdateUnitTasks(unitTasks);
  349. }
  350. [OperationBehavior]
  351. public IServiceResult<List<IUnitTask>> GetUnitTasksForMissionObjective(IMissionObjective objective)
  352. {
  353. var r = new ServiceResult<List<IUnitTask>> { Status = ResultStatus.SUCCESS };
  354. try
  355. {
  356. var unitTaskIDs = DataRepository.GetMissionObjectiveUnitTasks()
  357. .Where(mout => mout.MissionObjective == objective.ID).ToList()
  358. .Select(mout => Convert.ToInt32(mout.UnitTask));
  359. r.Result = ComponentRepository.GetUnitTasks().Where(ut => unitTaskIDs.Contains(ut.ID)).Select(ut => ut.ToComponent()).ToList();
  360. return r;
  361. }
  362. catch (Exception ex)
  363. {
  364. r.Status = ResultStatus.EXCEPTION;
  365. r.ex = ex;
  366. return r;
  367. }
  368. }
  369. [OperationBehavior]
  370. public IUnitType GetUnitTypeByID(int id)
  371. {
  372. var dto = ComponentRepository.GetUnitTypes().SingleOrDefault(ut => ut.ID == id);
  373. if (dto == null)
  374. throw new ComponentNotFoundException("No unit type found with id {0}".F(id));
  375. return dto.ToComponent();
  376. }
  377. [OperationBehavior]
  378. public IUnitType GetUnitTypeByName(string name)
  379. {
  380. var dto = ComponentRepository.GetUnitTypes().SingleOrDefault(o => o.Name.ToLowerInvariant() == name.ToLowerInvariant());
  381. if (dto == null)
  382. throw new ComponentNotFoundException("No unit type found with name {0}".F(name));
  383. return dto.ToComponent();
  384. }
  385. [OperationBehavior]
  386. public IServiceResult<IEnumerable<IUnitType>> GetUnitTypesByIDs(IEnumerable<int> ids)
  387. {
  388. var r = new ServiceResult<IEnumerable<IUnitType>>();
  389. r.Result = ComponentRepository.GetUnitTypes().Where(ut => ids.Contains(ut.ID)).Select(ut => ut.ToComponent());
  390. return r;
  391. }
  392. [OperationBehavior]
  393. public IServiceResult<IUnitType> SaveUnitTypes(List<IUnitType> unitTypes)
  394. {
  395. return ComponentRepository.SaveUnitTypes(unitTypes);
  396. }
  397. [OperationBehavior]
  398. public IServiceResult<IUnitType> RemoveUnitTypes(List<IUnitType> unitTypes)
  399. {
  400. return ComponentRepository.RemoveUnitTypes(unitTypes);
  401. }
  402. [OperationBehavior]
  403. public IServiceResult<IUnitType> UpdateUnitTypes(List<IUnitType> unitTypes)
  404. {
  405. return ComponentRepository.UpdateUnitTypes(unitTypes.ToList());
  406. }
  407. [OperationBehavior]
  408. public IEnumerable<IUnitType> GetUnitTypesAllowableForTile(ITile tile)
  409. {
  410. var retVal = new List<IUnitType>();
  411. var unitTypes = ComponentRepository.GetUnitTypes().Select(ut => ut.ToComponent());
  412. Action<IUnitType> componentAction = ut =>
  413. {
  414. if (JTSServices.RulesService.TileIsAllowableForUnitType(ut, tile).Result) retVal.Add(ut);
  415. };
  416. if (Convert.ToBoolean(ConfigurationManager.AppSettings["run_multithreaded"]))
  417. {
  418. Parallel.ForEach(unitTypes, componentAction);
  419. }
  420. else
  421. {
  422. foreach (var ut in unitTypes)
  423. {
  424. componentAction(ut);
  425. };
  426. }
  427. return retVal;
  428. }
  429. #endregion
  430. }
  431. }