Store Hollywoo objects in improved FuzzyMap

This commit is contained in:
2021-12-15 15:05:28 -07:00
parent 010caf26e3
commit 8930deb9ac
3 changed files with 48 additions and 19 deletions

View File

@@ -4,9 +4,10 @@ import haxe.ds.StringMap;
using hx.strings.Strings;
// TODO forward and implement the full Map API
abstract FuzzyMap<T>(StringMap<T>) from StringMap<T> to StringMap<T> {
public inline function new(m:StringMap<T>) {
this = m;
public inline function new(?m:StringMap<T>) {
this = if (m != null) m else new StringMap<T>();
}
@:from
@@ -19,24 +20,50 @@ abstract FuzzyMap<T>(StringMap<T>) from StringMap<T> to StringMap<T> {
return this;
}
@:arrayAccess
public inline function get(searchKey:String):Null<T> {
var bestMatch:Null<T> = null;
var bestScore = 0;
static var threshold = 0.8;
function bestMatch(fuzzySearchKey:String, ?throwIfNone=true):String {
if (this.exists(fuzzySearchKey)) return fuzzySearchKey;
for (key => value in this) {
var score = searchKey.getFuzzyDistance(key);
var bestScore = 0.0;
var bestKey = null;
for (key in this.keys()) {
var score = 1 - (key.getLevenshteinDistance(fuzzySearchKey) / Math.max(key.length, fuzzySearchKey.length));
if (score > bestScore) {
bestScore = score;
bestMatch = value;
bestKey = key;
}
}
return bestMatch;
if (bestScore < threshold) {
if (throwIfNone)
throw 'No good match for $fuzzySearchKey in $this -- best was $bestKey with $bestScore';
else
return null;
}
#if (test || debug)
trace('Fuzzy match $bestKey for $fuzzySearchKey score: $bestScore');
#end
return bestKey;
}
@:arrayAccess
public inline function set(key:String, v:T):T {
public inline function get(fuzzySearchKey:String):Null<T> {
return this.get(bestMatch(fuzzySearchKey));
}
public inline function remove(fuzzySearchKey:String):Bool {
var key = bestMatch(fuzzySearchKey, false);
if (key == null) return false;
return this.remove(key);
}
@:arrayAccess
public inline function set(fuzzySearchKey:String, v:T):T {
var key = bestMatch(fuzzySearchKey, false);
if (key == null) key = fuzzySearchKey;
this.set(key, v);
return v;
}

View File

@@ -4,6 +4,7 @@ import haxe.Constraints.Function;
import haxe.Timer;
import kiss.AsyncEmbeddedScript;
import kiss.Prelude;
import kiss.FuzzyMap;
import hollywoo.Scene;
import hollywoo.Director;
@@ -20,5 +21,5 @@ enum DelayHandling {
class Movie<Set, StagePosition, StageFacing, ScreenPosition, Actor, Sound, Song, Prop> extends AsyncEmbeddedScript {
// TODO for some reason this wasn't working when declared in Movie.kiss:
// Mutable representation of frames in time:
var scenes:Map<String, Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor, Prop>> = [];
var scenes:FuzzyMap<Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor, Prop>> = new FuzzyMap<Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor, Prop>>();
}

View File

@@ -2,19 +2,20 @@
(#unless subclass
// Mostly immutable, reusable resources:
(prop :Map<String,Set> sets (new Map))
(prop :Map<String,Actor> actors (new Map))
(prop :Map<String,Sound> sounds (new Map))
(prop :Map<String,Song> songs (new Map))
(prop :Map<String,Prop> props (new Map))
(prop :FuzzyMap<Set> sets (new FuzzyMap<Set>))
(prop :FuzzyMap<Actor> actors (new FuzzyMap<Actor>))
(prop :FuzzyMap<Sound> sounds (new FuzzyMap<Sound>))
(prop :FuzzyMap<Song> songs (new FuzzyMap<Song>))
(prop :FuzzyMap<Prop> props (new FuzzyMap<Prop>))
(prop &mut :DelayHandling delayHandling AutoWithSkip)
// TODO for some reason this won't work when declared in Kiss syntax:
// Mutable representation of frames in time:
// var scenes:Map<String, Scene<Set, StagePosition, StageFacing, ScreenPosition, Actor>> = [];
(prop :Map<String,Bool> shownScenes (new Map))
(prop :Map<String,Bool> shownCharacters (new Map))
(prop :FuzzyMap<Bool> shownScenes (new FuzzyMap<Bool>))
(prop :FuzzyMap<Bool> shownCharacters (new FuzzyMap<Bool>))
// This is set and unset by doPreload defined in HollywooDSL.kiss
(prop &mut isLoading false)