fixed some enumeration and state resolution problems (I think)
This commit is contained in:
parent
692d7a670a
commit
611cde2e29
|
@ -22,7 +22,7 @@
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
}
|
}
|
||||||
var rend = new HtmlRenderer();
|
var rend = new HtmlRenderer();
|
||||||
rend.Render(story, path);
|
rend.Render(story, path, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
namespace Ficdown.Parser.Model.Parser
|
namespace Ficdown.Parser.Model.Parser
|
||||||
{
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public class ResolvedPage
|
public class ResolvedPage
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Content { get; set; }
|
public string Content { get; set; }
|
||||||
|
public IEnumerable<string> ActiveToggles { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
public IDictionary<string, int> StateMatrix { get; set; }
|
public IDictionary<string, int> StateMatrix { get; set; }
|
||||||
|
|
||||||
public string Resolved { get; set; }
|
|
||||||
public IDictionary<string, string> Links { get; set; }
|
public IDictionary<string, string> Links { get; set; }
|
||||||
|
|
||||||
private string _uniqueHash;
|
private string _uniqueHash;
|
||||||
|
|
|
@ -7,5 +7,6 @@
|
||||||
public BitArray PlayerState { get; set; }
|
public BitArray PlayerState { get; set; }
|
||||||
public BitArray ScenesSeen { get; set; }
|
public BitArray ScenesSeen { get; set; }
|
||||||
public BitArray ActionsToShow { get; set; }
|
public BitArray ActionsToShow { get; set; }
|
||||||
|
public BitArray ActionFirstToggles { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
new ResolvedPage
|
new ResolvedPage
|
||||||
{
|
{
|
||||||
Name = GetPageNameForHash(page.CompressedHash),
|
Name = GetPageNameForHash(page.CompressedHash),
|
||||||
Content = ResolveDescription(page)
|
Content = ResolveDescription(page),
|
||||||
|
ActiveToggles = GetStateDictionary(page).Where(t => t.Value).Select(t => t.Key)
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,30 +55,44 @@
|
||||||
var resolved = new StringBuilder();
|
var resolved = new StringBuilder();
|
||||||
resolved.AppendFormat("## {0}\n\n", page.Scene.Name);
|
resolved.AppendFormat("## {0}\n\n", page.Scene.Name);
|
||||||
|
|
||||||
|
var firstToggleCounter = 0;
|
||||||
for (var i = 0; i < page.State.ActionsToShow.Count; i++)
|
for (var i = 0; i < page.State.ActionsToShow.Count; i++)
|
||||||
{
|
{
|
||||||
if (page.State.ActionsToShow[i])
|
if (page.State.ActionsToShow[i])
|
||||||
{
|
{
|
||||||
resolved.AppendFormat("{0}\n\n", _story.Actions.Single(a => a.Value.Id == i + 1).Value.Description);
|
var actionTuple = _story.Actions.Single(a => a.Value.Id == i + 1);
|
||||||
|
var actionAnchors = Utilities.ParseAnchors(actionTuple.Value.Description);
|
||||||
|
var anchorDict = GetStateDictionary(page);
|
||||||
|
if (actionAnchors.Any(a => a.Href.Conditions.ContainsKey(actionTuple.Key)))
|
||||||
|
{
|
||||||
|
if (page.State.ActionFirstToggles[firstToggleCounter++])
|
||||||
|
{
|
||||||
|
anchorDict[actionTuple.Key] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
resolved.AppendFormat("{0}\n\n", actionAnchors.Aggregate(actionTuple.Value.Description,
|
||||||
var text = resolved.Append(page.Scene.Description).ToString();
|
|
||||||
|
|
||||||
var anchors = Utilities.ParseAnchors(text);
|
|
||||||
|
|
||||||
text = RegexLib.EmptyListItem.Replace(anchors.Aggregate(text,
|
|
||||||
(current, anchor) =>
|
(current, anchor) =>
|
||||||
current.Replace(anchor.Original,
|
current.Replace(anchor.Original,
|
||||||
ResolveAnchor(anchor, GetStateDictionary(page),
|
ResolveAnchor(anchor, anchorDict,
|
||||||
|
page.Links.ContainsKey(anchor.Original) ? page.Links[anchor.Original] : null))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var anchors = Utilities.ParseAnchors(page.Scene.Description);
|
||||||
|
var stateDict = GetStateDictionary(page);
|
||||||
|
var text =
|
||||||
|
RegexLib.EmptyListItem.Replace(
|
||||||
|
anchors.Aggregate(page.Scene.Description,
|
||||||
|
(current, anchor) =>
|
||||||
|
current.Replace(anchor.Original,
|
||||||
|
ResolveAnchor(anchor, stateDict,
|
||||||
page.Links.ContainsKey(anchor.Original) ? page.Links[anchor.Original] : null))),
|
page.Links.ContainsKey(anchor.Original) ? page.Links[anchor.Original] : null))),
|
||||||
string.Empty);
|
string.Empty);
|
||||||
|
|
||||||
var seen = page.State.ScenesSeen[page.Scene.Id - 1];
|
var seen = page.State.ScenesSeen[page.Scene.Id - 1];
|
||||||
text = !seen
|
resolved.Append(!seen
|
||||||
? RegexLib.BlockQuoteToken.Replace(text, string.Empty)
|
? RegexLib.BlockQuoteToken.Replace(text, string.Empty)
|
||||||
: RegexLib.BlockQuotes.Replace(text, string.Empty);
|
: RegexLib.BlockQuotes.Replace(text, string.Empty));
|
||||||
return text;
|
return resolved.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IDictionary<string, bool> GetStateDictionary(PageState page)
|
private IDictionary<string, bool> GetStateDictionary(PageState page)
|
||||||
|
|
|
@ -49,6 +49,24 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure every page gets affected data on every page that it links to
|
||||||
|
foreach (var pageTuple in _processed)
|
||||||
|
{
|
||||||
|
foreach (var linkTuple in pageTuple.Value.Links)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < _processed[linkTuple.Value].AffectedState.PlayerState.Count; i++)
|
||||||
|
{
|
||||||
|
pageTuple.Value.AffectedState.PlayerState[i] |=
|
||||||
|
_processed[linkTuple.Value].AffectedState.PlayerState[i];
|
||||||
|
}
|
||||||
|
for (var i = 0; i < _processed[linkTuple.Value].AffectedState.ScenesSeen.Count; i++)
|
||||||
|
{
|
||||||
|
pageTuple.Value.AffectedState.ScenesSeen[i] |=
|
||||||
|
_processed[linkTuple.Value].AffectedState.ScenesSeen[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// compress redundancies
|
// compress redundancies
|
||||||
foreach (var row in _processed)
|
foreach (var row in _processed)
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,13 +51,15 @@
|
||||||
{
|
{
|
||||||
PlayerState = new BitArray(_stateMatrix.Keys.Count),
|
PlayerState = new BitArray(_stateMatrix.Keys.Count),
|
||||||
ScenesSeen = new BitArray(_sceneCount),
|
ScenesSeen = new BitArray(_sceneCount),
|
||||||
ActionsToShow = new BitArray(_actionCount)
|
ActionsToShow = new BitArray(_actionCount),
|
||||||
|
ActionFirstToggles = null
|
||||||
},
|
},
|
||||||
AffectedState = new State
|
AffectedState = new State
|
||||||
{
|
{
|
||||||
PlayerState = new BitArray(_stateMatrix.Keys.Count),
|
PlayerState = new BitArray(_stateMatrix.Keys.Count),
|
||||||
ScenesSeen = new BitArray(_sceneCount),
|
ScenesSeen = new BitArray(_sceneCount),
|
||||||
ActionsToShow = new BitArray(_actionCount)
|
ActionsToShow = new BitArray(_actionCount),
|
||||||
|
ActionFirstToggles = null
|
||||||
},
|
},
|
||||||
Scene = _story.Scenes[_story.FirstScene].Single(s => s.Conditions == null),
|
Scene = _story.Scenes[_story.FirstScene].Single(s => s.Conditions == null),
|
||||||
StateMatrix = _stateMatrix
|
StateMatrix = _stateMatrix
|
||||||
|
@ -71,17 +73,26 @@
|
||||||
|
|
||||||
var newState = ClonePage(current);
|
var newState = ClonePage(current);
|
||||||
newState.State.ScenesSeen[current.Scene.Id - 1] = true;
|
newState.State.ScenesSeen[current.Scene.Id - 1] = true;
|
||||||
|
List<bool> actionFirstToggles = null;
|
||||||
if (anchor.Href.Toggles != null)
|
if (anchor.Href.Toggles != null)
|
||||||
{
|
{
|
||||||
foreach (var toggle in anchor.Href.Toggles)
|
foreach (var toggle in anchor.Href.Toggles)
|
||||||
{
|
{
|
||||||
if (_story.Actions.ContainsKey(toggle))
|
if (_story.Actions.ContainsKey(toggle))
|
||||||
{
|
{
|
||||||
|
if(actionFirstToggles == null) actionFirstToggles = new List<bool>();
|
||||||
newState.State.ActionsToShow[_story.Actions[toggle].Id - 1] = true;
|
newState.State.ActionsToShow[_story.Actions[toggle].Id - 1] = true;
|
||||||
|
if (
|
||||||
|
Utilities.ParseAnchors(_story.Actions[toggle].Description)
|
||||||
|
.Any(a => a.Href.Conditions.ContainsKey(toggle)))
|
||||||
|
actionFirstToggles.Add(!current.State.PlayerState[_stateMatrix[toggle]]);
|
||||||
}
|
}
|
||||||
newState.State.PlayerState[_stateMatrix[toggle]] = true;
|
newState.State.PlayerState[_stateMatrix[toggle]] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
newState.State.ActionFirstToggles = actionFirstToggles != null
|
||||||
|
? new BitArray(actionFirstToggles.ToArray())
|
||||||
|
: null;
|
||||||
newState.Scene = GetScene(target, newState.State.PlayerState);
|
newState.Scene = GetScene(target, newState.State.PlayerState);
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
@ -98,10 +109,16 @@
|
||||||
|
|
||||||
public static string GetUniqueHash(State state, string sceneKey)
|
public static string GetUniqueHash(State state, string sceneKey)
|
||||||
{
|
{
|
||||||
var combined = new bool[state.PlayerState.Count + state.ScenesSeen.Count + state.ActionsToShow.Count];
|
var combined =
|
||||||
|
new bool[
|
||||||
|
state.PlayerState.Count + state.ScenesSeen.Count + state.ActionsToShow.Count +
|
||||||
|
(state.ActionFirstToggles != null ? state.ActionFirstToggles.Count : 0)];
|
||||||
state.PlayerState.CopyTo(combined, 0);
|
state.PlayerState.CopyTo(combined, 0);
|
||||||
state.ScenesSeen.CopyTo(combined, state.PlayerState.Count);
|
state.ScenesSeen.CopyTo(combined, state.PlayerState.Count);
|
||||||
state.ActionsToShow.CopyTo(combined, state.PlayerState.Count + state.ScenesSeen.Count);
|
state.ActionsToShow.CopyTo(combined, state.PlayerState.Count + state.ScenesSeen.Count);
|
||||||
|
if (state.ActionFirstToggles != null)
|
||||||
|
state.ActionFirstToggles.CopyTo(combined,
|
||||||
|
state.PlayerState.Count + state.ScenesSeen.Count + state.ActionsToShow.Count);
|
||||||
var ba = new BitArray(combined);
|
var ba = new BitArray(combined);
|
||||||
var byteSize = (int)Math.Ceiling(combined.Length / 8.0);
|
var byteSize = (int)Math.Ceiling(combined.Length / 8.0);
|
||||||
var encoded = new byte[byteSize];
|
var encoded = new byte[byteSize];
|
||||||
|
@ -115,7 +132,8 @@
|
||||||
{
|
{
|
||||||
PlayerState = page.State.PlayerState.And(page.AffectedState.PlayerState),
|
PlayerState = page.State.PlayerState.And(page.AffectedState.PlayerState),
|
||||||
ScenesSeen = page.State.ScenesSeen.And(page.AffectedState.ScenesSeen),
|
ScenesSeen = page.State.ScenesSeen.And(page.AffectedState.ScenesSeen),
|
||||||
ActionsToShow = page.State.ActionsToShow
|
ActionsToShow = page.State.ActionsToShow,
|
||||||
|
ActionFirstToggles = page.State.ActionFirstToggles
|
||||||
};
|
};
|
||||||
return GetUniqueHash(compressed, page.Scene.Key);
|
return GetUniqueHash(compressed, page.Scene.Key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using MarkdownSharp;
|
using MarkdownSharp;
|
||||||
using Model.Parser;
|
using Model.Parser;
|
||||||
using Model.Story;
|
|
||||||
using Parser;
|
using Parser;
|
||||||
|
|
||||||
internal class HtmlRenderer : IRenderer
|
internal class HtmlRenderer : IRenderer
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
_md = new Markdown();
|
_md = new Markdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Render(IEnumerable<ResolvedPage> pages, string outPath)
|
public void Render(IEnumerable<ResolvedPage> pages, string outPath, bool debug = false)
|
||||||
{
|
{
|
||||||
foreach (var page in pages)
|
foreach (var page in pages)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,11 @@
|
||||||
var newAnchor = string.Format("[{0}]({1}.html)", anchor.Text, anchor.Href.Target);
|
var newAnchor = string.Format("[{0}]({1}.html)", anchor.Text, anchor.Href.Target);
|
||||||
content = content.Replace(anchor.Original, newAnchor);
|
content = content.Replace(anchor.Original, newAnchor);
|
||||||
}
|
}
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
content += string.Format("\n\n### State Debug\n\n{0}",
|
||||||
|
string.Join("\n", page.ActiveToggles.Select(t => string.Format("- {0}", t)).ToArray()));
|
||||||
|
}
|
||||||
File.WriteAllText(Path.Combine(outPath, string.Format("{0}.html", page.Name)), _md.Transform(content));
|
File.WriteAllText(Path.Combine(outPath, string.Format("{0}.html", page.Name)), _md.Transform(content));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Model.Parser;
|
using Model.Parser;
|
||||||
using Model.Story;
|
|
||||||
|
|
||||||
internal interface IRenderer
|
internal interface IRenderer
|
||||||
{
|
{
|
||||||
void Render(IEnumerable<ResolvedPage> pages, string outPath);
|
void Render(IEnumerable<ResolvedPage> pages, string outPath, bool debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue