RapidGameFramework
Reusable Godot managers for data-driven small games
Loading...
Searching...
No Matches
condition_evaluator.gd
Go to the documentation of this file.
1extends RefCounted
2
3
7
8
9
10func matches(conditions:Dictionary, context:Dictionary = {}) -> bool:
11 if conditions.is_empty():
12 return true
13 for key in conditions.keys():
14 var expected = conditions[key]
15 if str(key) == "all" and expected is Array:
16 for child in expected:
17 if child is Dictionary and not matches(child, context):
18 return false
19 continue
20 if str(key) == "any" and expected is Array:
21 var matched := false
22 for child in expected:
23 if child is Dictionary and matches(child, context):
24 matched = true
25 break
26 if not matched:
27 return false
28 continue
29 if str(key) == "not" and expected is Dictionary:
30 if matches(expected, context):
31 return false
32 continue
33 if not _value_matches(value_at(context, str(key)), expected):
34 return false
35 return true
36
37
38
39func value_at(context:Dictionary, dotted_key:String, default_value = null):
40 var current = context
41 for part in dotted_key.split("."):
42 if current is Dictionary and current.has(part):
43 current = current[part]
44 else:
45 return default_value
46 return current
47
48
49func _value_matches(actual, expected) -> bool:
50 if expected is Dictionary:
51 if expected.has("exists"):
52 return (actual != null) == bool(expected.get("exists", true))
53 if expected.has("equals") and actual != expected.get("equals"):
54 return false
55 if expected.has("not_equals") and actual == expected.get("not_equals"):
56 return false
57 if expected.has("at_least") and _to_float(actual) < _to_float(expected.get("at_least", 0.0)):
58 return false
59 if expected.has("at_most") and _to_float(actual) > _to_float(expected.get("at_most", 0.0)):
60 return false
61 if expected.has("greater_than") and _to_float(actual) <= _to_float(expected.get("greater_than", 0.0)):
62 return false
63 if expected.has("less_than") and _to_float(actual) >= _to_float(expected.get("less_than", 0.0)):
64 return false
65 if expected.has("contains"):
66 if actual is Array:
67 if not actual.has(expected.get("contains")):
68 return false
69 elif not str(actual).contains(str(expected.get("contains"))):
70 return false
71 if expected.has("in"):
72 var allowed = expected.get("in")
73 if not allowed is Array or not allowed.has(actual):
74 return false
75 return true
76 return actual == expected
77
78
79func _to_float(value) -> float:
80 if value is int or value is float:
81 return float(value)
82 if value is bool:
83 return 1.0 if value else 0.0
84 if value == null:
85 return 0.0
86 return str(value).to_float()