mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-13 13:52:34 +00:00
Add files via upload
This commit is contained in:
1 parent
08537cf425
commit
5d4a5082ec
2 files changed
+51
-7
No files matched your search
@@ -427,6 +427,8 @@ fn version_rank(v: &str) -> (u64, u64) {
|
||||
pub(super) struct VarCanon {
|
||||
by_key: HashMap<String, String>,
|
||||
by_id: HashMap<String, String>,
|
||||
/// Every live variable node of the file, with a key or not.
|
||||
local: BTreeSet<String>,
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
@@ -446,10 +448,12 @@ impl VarCanon {
|
||||
fn install(m: &Mapper) -> VarCanonGuard {
|
||||
let mut newest: HashMap<String, ((u64, u64), String)> = HashMap::new();
|
||||
let mut copies: Vec<(String, String)> = Vec::new();
|
||||
let mut local = BTreeSet::new();
|
||||
for (id, n) in &m.nodes {
|
||||
if n.get("type").and_then(Kv::str) != Some("VARIABLE") || n.get("isSoftDeleted").and_then(Kv::bool) == Some(true) {
|
||||
continue;
|
||||
}
|
||||
local.insert(id.clone());
|
||||
let Some(key) = n.get("key").and_then(Kv::str).filter(|k| !k.is_empty()) else { continue };
|
||||
let rank = version_rank(n.get("version").and_then(Kv::str).unwrap_or(""));
|
||||
copies.push((id.clone(), key.to_string()));
|
||||
@@ -465,21 +469,25 @@ impl VarCanon {
|
||||
}
|
||||
}
|
||||
t.by_key = newest.into_iter().map(|(k, (_, id))| (k, id)).collect();
|
||||
t.local = local;
|
||||
VAR_CANON.with(|c| *c.borrow_mut() = Some(t));
|
||||
VarCanonGuard
|
||||
}
|
||||
|
||||
/// The variable a reference (`{guid}` or `{assetRef}`) names, as its newest copy.
|
||||
/// The variable a reference (`{guid}` or `{assetRef}`) names, as its newest copy. A guid
|
||||
/// counts when this file holds a variable by it; one from another file (a paste carries the
|
||||
/// library's own guids) names nothing here, so the asset it also names is tried before it is
|
||||
/// kept as it is.
|
||||
pub(super) fn resolve(r: &Kv) -> Option<String> {
|
||||
let by_guid = r.get("guid").and_then(guid).filter(|g| g != NO_STYLE);
|
||||
VAR_CANON.with(|c| {
|
||||
let c = c.borrow();
|
||||
let Some(t) = c.as_ref() else { return by_guid.clone() };
|
||||
if let Some(g) = &by_guid {
|
||||
if let Some(g) = by_guid.as_ref().filter(|g| t.local.contains(*g)) {
|
||||
return Some(t.by_id.get(g).cloned().unwrap_or_else(|| g.clone()));
|
||||
}
|
||||
let key = r.get("assetRef")?.get("key").and_then(Kv::str)?;
|
||||
t.by_key.get(key).cloned()
|
||||
let by_asset = r.get("assetRef").and_then(|a| a.get("key")).and_then(Kv::str).and_then(|k| t.by_key.get(k)).cloned();
|
||||
by_asset.or(by_guid)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1522,7 +1522,8 @@ fn library_copies_of_several_versions_become_the_newest() {
|
||||
Some((2, "!")),
|
||||
"VARIABLE_SET",
|
||||
"Products",
|
||||
vec![("variableSetModes", arr(vec![mode(90, "Blue", "!")])), ("key", s("products")), ("version", s("10:1"))],
|
||||
// "Legacy" was removed from the library since: only this older copy has it.
|
||||
vec![("variableSetModes", arr(vec![mode(90, "Blue", "!"), mode(93, "Legacy", "\"")])), ("key", s("products")), ("version", s("10:1"))],
|
||||
),
|
||||
node(
|
||||
6,
|
||||
@@ -1557,6 +1558,37 @@ fn library_copies_of_several_versions_become_the_newest() {
|
||||
("version", s("20:1")),
|
||||
],
|
||||
),
|
||||
// A pasted layer names the variable by the library's own guid (not a node of this file)
|
||||
// and by its asset: the asset wins.
|
||||
node(
|
||||
11,
|
||||
Some((1, "\"")),
|
||||
"FRAME",
|
||||
"Pasted button",
|
||||
vec![
|
||||
("size", xy(100.0, 40.0)),
|
||||
(
|
||||
"fillPaints",
|
||||
arr(vec![o(vec![
|
||||
("type", e("SOLID")),
|
||||
("color", rgb(0.0, 0.0, 1.0)),
|
||||
(
|
||||
"colorVar",
|
||||
o(vec![
|
||||
(
|
||||
"value",
|
||||
o(vec![(
|
||||
"alias",
|
||||
o(vec![("guid", g(777)), ("assetRef", o(vec![("key", s("button-bg")), ("version", s("20:1"))]))]),
|
||||
)]),
|
||||
),
|
||||
("dataType", e("ALIAS")),
|
||||
]),
|
||||
),
|
||||
])]),
|
||||
),
|
||||
],
|
||||
),
|
||||
// The button names the older copy of the variable.
|
||||
node(
|
||||
10,
|
||||
@@ -1575,14 +1607,18 @@ fn library_copies_of_several_versions_become_the_newest() {
|
||||
let (doc, warnings) = import(&canvas(&schema(), &o(vec![("nodeChanges", arr(nodes))])), "x").unwrap();
|
||||
assert_eq!(doc.variables.collections.len(), 1, "{:?}", doc.variables.collections);
|
||||
let products = &doc.variables.collections[0];
|
||||
assert_eq!(products.modes.iter().map(|m| m.name.as_str()).collect::<Vec<_>>(), ["Blue", "Purple"]);
|
||||
assert_eq!(products.modes.iter().map(|m| m.name.as_str()).collect::<Vec<_>>(), ["Blue", "Purple", "Legacy"]);
|
||||
assert_eq!(doc.variables.variables.len(), 1);
|
||||
let var = &doc.variables.variables[0];
|
||||
assert_eq!(var.collection, products.id);
|
||||
assert_eq!(var.values.len(), 2, "the newest copy's values: {:?}", var.values);
|
||||
// The newest copy's values: Purple included (a mode only it has), Legacy filled from the default.
|
||||
assert_eq!(var.values.len(), 3, "{:?}", var.values);
|
||||
assert!(matches!(var.values.get("1:92"), Some(figcraft_doc::VariableValue::Color(c)) if (c.r - 0.5).abs() < 1e-6), "{:?}", var.values);
|
||||
let page = doc.nodes().find(|n| n.name == "Page").unwrap();
|
||||
assert_eq!(page.var_modes.get(&products.id).map(String::as_str), Some("1:92"));
|
||||
let button = named(&doc, "Button");
|
||||
assert_eq!(button.bound.values().next(), Some(&var.id), "{:?}", button.bound);
|
||||
let pasted = named(&doc, "Pasted button");
|
||||
assert_eq!(pasted.bound.values().next(), Some(&var.id), "{:?}", pasted.bound);
|
||||
assert!(!warnings.iter().any(|w| w.contains("variable modes of collections")), "{warnings:?}");
|
||||
}
|
||||
Reference in new issue
Block a user