private async Task ConstruireEtiquetteAsync( IEnumerable <Etat> etatsDebut, IEnumerable <Etat> etatsFin, ElementEtiquetteConstructionDto donnees, Dictionary <string, IConstructionElementArbre> dicoReferences = null) {//todo injecter les étiquette (en début ou fin) dans les états et interdire (après mise en place) les ajouts de transitions sortantes (si début) ou entrantes (si fin) try { if (null != donnees?.Element) { if (donnees.TypeBlock != EnumTypeBlock.Autre && !string.IsNullOrWhiteSpace(donnees.Id)) { // Enregistrement du block pour permettre les références dessus lock (blocksInfos) { var blockInfosEnregistre = blocksInfos .FirstOrDefault(b => b.Id == donnees.Id); if (null != blockInfosEnregistre) { if (null != blockInfosEnregistre.Donnees) { throw new ExceptionTechniqueArbreConstruction(); } else { // Le block a été enregistré par une référence en attente => on garnit la/les référence(s) en attente blockInfosEnregistre.Donnees = donnees.Element; blockInfosEnregistre.TypeBlock = donnees.TypeBlock; var elementsEnAttente = blockInfosEnregistre.ElementsEnAttente; if (elementsEnAttente.Any()) { var tasks = new List <Task>(); foreach (var elementEnAttente in elementsEnAttente) { var task = ConstruireAsync( new Etat[] { elementEnAttente.EtatEntree }, new Etat[] { elementEnAttente.EtatSortie }, donnees.Element, dicoReferences); tasks .Add(task); } Task .WaitAll( tasks.ToArray()); foreach (var elementEnAttente in elementsEnAttente) { arbre .Etiquetter( donnees.Id, donnees.TypeBlock, elementEnAttente.EtatEntree, elementEnAttente.EtatSortie); } } } } else { // Le block n'existe pas encore => ajout var infos = new BlockInfos( donnees.Id, donnees.TypeBlock, donnees.Element); blocksInfos .Add(infos); } } } } } catch (Exception ex) { throw EncapsulerEtGererException <ExceptionTechniqueArbreConstruction>( ex); } }
private async Task ConstruireReferenceAsync( IEnumerable <Etat> etatsDebut, IEnumerable <Etat> etatsFin, ElementReferenceConstructionDto donnees, Dictionary <string, IConstructionElementArbre> dicoReferences = null) { try { if (null != donnees?.Id && !string.IsNullOrWhiteSpace(donnees.Id)) { dicoReferences = dicoReferences ?? new Dictionary <string, IConstructionElementArbre>(); var elementParent = await CreerElementAsync( etatsDebut, etatsFin); IConstructionElementArbre elementRefCirculaire; if (dicoReferences.TryGetValue(donnees.Id, out elementRefCirculaire)) { // C'est une référence circulaire => ajout d'une transition vers le début de la construction de la référence arbre .AjouterTransition( elementParent.EtatEntree, elementRefCirculaire.EtatEntree); arbre .AjouterTransition( elementRefCirculaire.EtatSortie, elementParent.EtatSortie); arbre .Etiquetter( $"RefCirculaire: {donnees.Id}-{elementParent.EtatEntree}/{elementParent.EtatSortie}", EnumTypeBlock.Autre, elementParent.EtatEntree, elementParent.EtatSortie); } else { // Pas de référence circulaire => construction de la référence (reportée si l'étiquette n'est pas encore définie) BlockInfos blockInfosEnregistre = null; lock (blocksInfos) { blockInfosEnregistre = blocksInfos .FirstOrDefault(b => b.Id == donnees.Id); if (null == blockInfosEnregistre) { blockInfosEnregistre = new BlockInfos( donnees.Id); blocksInfos .Add( blockInfosEnregistre); } if (null == blockInfosEnregistre.Donnees) { // Le block n'existe pas encore => ajout pour référencer cette cible blockInfosEnregistre .AjouterElementEnAttente( elementParent); } } if (null != blockInfosEnregistre?.Donnees) { // Création de la référence var elementSource = blockInfosEnregistre.Donnees; var dicoReferencesPourEnfants = new Dictionary <string, IConstructionElementArbre>( dicoReferences); dicoReferencesPourEnfants .Add( donnees.Id, elementParent); await ConstruireAsync( new Etat[] { elementParent.EtatEntree }, new Etat[] { elementParent.EtatSortie }, elementSource, dicoReferencesPourEnfants); arbre .Etiquetter( donnees.Id, blockInfosEnregistre.TypeBlock, elementParent.EtatEntree, elementParent.EtatSortie); } } } } catch (Exception ex) { throw EncapsulerEtGererException <ExceptionTechniqueArbreConstruction>( ex); } }
public void LoadFromFile(bool inEditor) { var childrenToDestroy = Enumerable.Range(0, transform.childCount).Select(a => transform.GetChild(a)).ToList(); foreach (var block in childrenToDestroy) { if (inEditor) { DestroyImmediate(block.gameObject); } else { Destroy(block.gameObject); } } Blocks = new List <GameObject>(); var lines = File.ReadAllLines("Assets/Levels.txt").ToList(); for (int i = 0; i < Level; i++) { lines = lines.SkipUntil(a => a.Contains("//")).ToList(); } var linesForThisLevel = lines.TakeUntil(a => a.Contains("//")).ToList(); BlockInfos = BoardParser.ExtractBlockTypes(linesForThisLevel); foreach (var blockRow in BlockInfos.GroupBy(a => a.Y)) { foreach (var blockLocation in blockRow.OrderBy(a => a.X)) { GameObject newBlock; switch (blockLocation.Type) { case BlockType.Normal: newBlock = Instantiate(NormalBlockPrefab); break; case BlockType.RowInvert: newBlock = Instantiate(RowInvertBlockPrefab); break; case BlockType.ColumnInvert: newBlock = Instantiate(ColumnInvertBlockPrefab); break; case BlockType.RowAndColumnInvert: newBlock = Instantiate(RowColumnInvertBlockPrefab); break; case BlockType.PreviousInvert: newBlock = Instantiate(PreviousInvertBlockPrefab); break; case BlockType.SameInvert: newBlock = Instantiate(SameInvertBlockPrefab); break; case BlockType.Walkable: newBlock = Instantiate(WalkableBlockPrefab); var player = Instantiate(PlayerPrefab); var playerComp = player.GetComponent <Player>(); playerComp.Board = this; playerComp.Coord = new Vector2(blockLocation.X, blockLocation.Y); playerComp.MoveToAction = (player1, destination) => { var blockComps = Blocks.Select(a => a.GetComponent <IBlock>()); if (blockComps.Any(a => a.Coord == destination)) { player1.Coord = destination; player1.transform.position = new Vector3(destination.x, -destination.y, player1.transform.position.z) * BlockSpacing; var destBlock = blockComps.Single(a => a.Coord == destination); destBlock.ToggleActivationWithEffect(!destBlock.Activated); } }; player.transform.position = new Vector3(blockLocation.X, -blockLocation.Y, 0) * BlockSpacing; player.transform.parent = transform; break; default: throw new ArgumentOutOfRangeException(); } var blockComponent = newBlock.GetComponent <Block>(); blockComponent.Board = this; blockComponent.X = blockLocation.X; blockComponent.Y = blockLocation.Y; blockComponent.Clickable = blockLocation.Clickable; newBlock.transform.position = new Vector3(blockLocation.X, -blockLocation.Y, 0) * BlockSpacing; newBlock.transform.parent = transform; Blocks.Add(newBlock); } } Camera.main.transform.position = new Vector3((float)BlockInfos.Average(a => a.X) * BlockSpacing, (float)BlockInfos.Average(a => a.Y) * -BlockSpacing, CameraZ); }