private static bool OpenWithFailover(ILoader loader, IGeoModel model, bool finished, bool showTryOthers) { // TODO: Maybe we can use the finished parameter to determine whether // we need to present the 'Try Others' option. Maybe the finished // arg should be renamed to hideTryOthers... bool tryAgain = false; do { try { loader.Open(model); finished = true; break; } catch (OpenException openException) { // TODO: Notify the user of the open failure // "Failed to open URI because ... Console.WriteLine(openException.Message); // Do you want to Try again? Abort? Try other loaders? List <Pair <object, string> > choices = new List <Pair <object, string> >(3); choices.Add(new Pair <object, string>(OpenChoice.TryAgain, "Try Again")); choices.Add(new Pair <object, string>(OpenChoice.TryOthers, "Try Other Formats")); choices.Add(new Pair <object, string>(OpenChoice.Abort, "Cancel")); IChoiceList choiceList = Factory <IChoiceList> .Instance.CreateDefault(choices); OpenChoice decision = (OpenChoice)choiceList.Show(); switch (decision) { case OpenChoice.TryAgain: tryAgain = true; finished = false; break; case OpenChoice.TryOthers: tryAgain = false; finished = false; break; case OpenChoice.Abort: tryAgain = false; finished = true; break; } } }while (tryAgain); return(finished); }
// public for testing purpose // this chooses what is parsed next, IE a branch, a dialog or descision public BrigitGraph ParseBrigitGraph(TomeStream stream) { BrigitGraph ll = new BrigitGraph(); while (!(stream.Complete() || stream.PeekChar() == '}')) { // getting rid of some beginning whitespace EatWhitespace(stream); // the real parsing starts here // can't use switch need to use if elses char c = stream.PeekChar(); if (Char.IsLetterOrDigit(c)) { // start parsing as a dialog // this one is simple. parse the dialog. then add // it to the list Node n = ParseDialog(stream); // for the new AddInBetween function // this will only work for whatever comes next. This isn't very good // if there's multiple branches to place // TODO make this functionality work better with dummy tail in the subgraphs foreach (KeyValuePair <string, OpenChoice> kvp in BranchesToPlace) { if (kvp.Value.TailNode == null) { kvp.Value.TailNode = n; break; } } ll.AddNode(n); } else if (c == '@') { // naybe use a struct here? Dictionary <string, OpenChoice> branchesToNode = new Dictionary <string, OpenChoice>(); // TODO change signature of ParseDescision to (obj stream, Dict brachesToNode) BrigitGraph subGraph = ParseDescision(stream, branchesToNode); foreach (KeyValuePair <string, OpenChoice> kvp in branchesToNode) { BranchesToPlace.Add(kvp.Key, kvp.Value); } // adding the dictionary entries to this ll.AddGraph(subGraph); } else if (c == '{') { // this is a branch selector // we can just pass in the big dictionary BrigitGraph subGraph = ParseBranchSelector(BranchesToPlace); ll.AddGraph(subGraph); } else if (c == '>') { // this is a branch name // TODO change signature of ParseBranch to ParseBranch(stream, ref string branchName) // TODO i'll probably need a wrapper for the Node and Ch entires string branchName = String.Empty; BrigitGraph subGraph = ParseBranch(stream, ref branchName); if (BranchesToPlace.ContainsKey(branchName)) { OpenChoice openCh = BranchesToPlace[branchName]; Node n = openCh.EnclosingNode; Choice ch = openCh.BranchingChoice; ll.AddInBetween(n, new List <Node>() { openCh.TailNode }, subGraph); ch.NextNode = n.Next.Count - 1; } else { String msg = String.Format("{0} not found in dictionary, could the name be mispelled?", branchName); throw new Exception(msg); } } else { // panic here String msg = String.Format("Expected beginning of character name, branch or chioce but found {0} at {1}", stream.PeekChar(), stream.Position); throw new Exception(msg); } EatWhitespace(stream); } if (!stream.Complete()) { AssertChar(stream, '}'); } return(ll); }
public BrigitGraph ParseDescision(TomeStream stream, Dictionary <string, OpenChoice> branchEndings) { Decision descision = new Decision(); BrigitGraph ll = new BrigitGraph(); Node root = new Node() { Data = descision }; ll.AddNode(root); // first parse away the @player: AssertChar(stream, '@'); AssertAlphaDigitString(stream, "player"); AssertChar(stream, '{'); EatWhitespace(stream); ParsingState state = ParsingState.ExpectingMore; while (state == ParsingState.ExpectingMore) { // parse the choice (same as parse text with esacape) // parse attributes if there are any Choice ch = ParseChoice(stream, ref state); // -1 is the place holder for now. will be set to an actual number // or to the size of list ch.NextNode = -1; descision.Choices.Add(ch); // at this point either the parsing is complete // or there is an arrow pointing to a sub branch or a branch name // Parseing.Expecting more implies that the arrow maybe still be here // Some branches have multiple "nexts" where the next either points to the same node // or to two different ones within the same branching pattern. // It's the addition of the nodes that's wrong if (ParseArrow(stream)) { // whitespace EatWhitespace(stream); // either it's a branch if (stream.PeekChar() == '{') { AssertChar(stream, '{'); // parse the subbranch if there is one // parse the branch name is there is one, and we didn't parse a sub branch // add the subbranch to the next list if there is none set their "next" to -1 BrigitGraph subGraph = ParseBrigitGraph(stream); ll.AddBranch(root, subGraph); ch.NextNode = root.Next.Count - 1; } // or a branch name else { string BranchName = ParseOnlyTextNoEscape(stream); OpenChoice openCh = new OpenChoice(root, ch); branchEndings.Add(BranchName, openCh); } // this means it has reach the end if (stream.PeekChar() == '}') { state = ParsingState.Complete; stream.NextChar(); } } } // any next nodes in descision that are -1 should be set // to the count of the list foreach (Choice c in descision.Choices) { if (c.NextNode == -1) { c.NextNode = root.Next.Count; } } return(ll); }
// this will select a branch from a set given to it // this looks really similar to chioce with some smaller but important changes public BrigitGraph ParseBranchSelector(Dictionary <string, OpenChoice> branchEndings) { AssertChar(Stream, '{'); // the loop consists of parsing expression, parsing branch // then check for a new expression or the end // TODO replace this fix with a more elegant solution // hot fix used for resetting the open choices List <string> branches = new List <string>(); Decision selector = new Decision(); selector.Interactive = false; BrigitGraph graph = new BrigitGraph(); Node root = new Node() { Data = selector }; graph.AddNode(root); while (Stream.PeekChar() != '}') { // gets chars up to the * string expression = FetchNonStarSubString(); IExpression exp; if (expression == "_") { //exp = new Tautalogy(); exp = new Variable("TRUE"); } else { exp = BrigitExpressionParser.Parse(expression); } // eat the star that ends the expresssion AssertChar(Stream, '*'); Choice ch = new Choice(); ch.Attributes.Expression = exp; ch.Text = string.Empty; ch.NextNode = -1; EatWhitespace(Stream); // if there is no arrow then it should be considered a // "pass" // there can be multiple passes, but there can only be one default which is "_" if (Stream.PeekChar() == '-') { // parse either a sub graph or parse a branchname ParseArrow(Stream); EatWhitespace(Stream); if (Stream.PeekChar() == '{') { AssertChar(Stream, '{'); BrigitGraph subGraph = ParseBrigitGraph(Stream); graph.AddBranch(root, subGraph); ch.NextNode = root.Next.Count - 1; } else if (Char.IsLetterOrDigit(Stream.PeekChar())) { string BranchName = ParseOnlyTextNoEscape(Stream); branches.Add(BranchName); OpenChoice open = new OpenChoice(root, ch); branchEndings.Add(BranchName, open); } else { // throw not recognized string msg = String.Format("Expected beginning of branch name or sub graph but found {0} at {1}", Stream.PeekChar(), Stream.Position); throw new Exception(msg); } } // a pass else { } selector.Choices.Add(ch); EatWhitespace(Stream); } // to end this off AssertChar(Stream, '}'); foreach (Choice ch in selector.Choices) { if (ch.NextNode == -1) { ch.NextNode = root.Next.Count; } } foreach (string s in branches) { branchEndings[s].TailNode = null; } return(graph); }