refactor: 拆分 claude-dev-stack 为 windows-dev-stack 和 wsl-dev-stack
将原 claude-dev-stack 目录拆分为独立的 Windows 和 WSL 部署栈,便于分别维护和使用。 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
@tool
|
||||
extends RefCounted
|
||||
|
||||
## Parse a string value into the appropriate Godot type
|
||||
static func parse_value(value: Variant, target_type: int = TYPE_NIL) -> Variant:
|
||||
if value == null:
|
||||
return null
|
||||
|
||||
# If already the correct type, return as-is
|
||||
if target_type == TYPE_NIL:
|
||||
return _auto_parse(value)
|
||||
|
||||
match target_type:
|
||||
TYPE_BOOL:
|
||||
if value is bool: return value
|
||||
if value is String: return value.to_lower() in ["true", "1", "yes"]
|
||||
return bool(value)
|
||||
TYPE_INT:
|
||||
return int(value)
|
||||
TYPE_FLOAT:
|
||||
return float(value)
|
||||
TYPE_STRING:
|
||||
return str(value)
|
||||
TYPE_VECTOR2:
|
||||
return _parse_vector2(value)
|
||||
TYPE_VECTOR2I:
|
||||
return _parse_vector2i(value)
|
||||
TYPE_VECTOR3:
|
||||
return _parse_vector3(value)
|
||||
TYPE_VECTOR3I:
|
||||
return _parse_vector3i(value)
|
||||
TYPE_RECT2:
|
||||
return _parse_rect2(value)
|
||||
TYPE_COLOR:
|
||||
return _parse_color(value)
|
||||
TYPE_NODE_PATH:
|
||||
return NodePath(str(value))
|
||||
TYPE_ARRAY:
|
||||
if value is Array: return value
|
||||
return [value]
|
||||
TYPE_DICTIONARY:
|
||||
if value is Dictionary: return value
|
||||
return {}
|
||||
_:
|
||||
return value
|
||||
|
||||
|
||||
static func _auto_parse(value: Variant) -> Variant:
|
||||
if not value is String:
|
||||
return value
|
||||
|
||||
var s: String = value
|
||||
|
||||
# Boolean
|
||||
if s == "true": return true
|
||||
if s == "false": return false
|
||||
|
||||
# Integer
|
||||
if s.is_valid_int(): return s.to_int()
|
||||
|
||||
# Float
|
||||
if s.is_valid_float(): return s.to_float()
|
||||
|
||||
# Vector2: "Vector2(x, y)" or "(x, y)" or "x, y"
|
||||
if s.begins_with("Vector2(") or s.begins_with("Vector2i("):
|
||||
return _parse_vector2(s)
|
||||
|
||||
# Vector3
|
||||
if s.begins_with("Vector3(") or s.begins_with("Vector3i("):
|
||||
return _parse_vector3(s)
|
||||
|
||||
# Color
|
||||
if s.begins_with("Color(") or s.begins_with("#"):
|
||||
return _parse_color(s)
|
||||
|
||||
# Rect2
|
||||
if s.begins_with("Rect2("):
|
||||
return _parse_rect2(s)
|
||||
|
||||
return s
|
||||
|
||||
|
||||
static func _extract_numbers(s: String) -> PackedFloat64Array:
|
||||
# Remove type prefix and parentheses
|
||||
var cleaned := s
|
||||
for prefix in ["Vector3i(", "Vector3(", "Vector2i(", "Vector2(", "Rect2(", "Color(", "("]:
|
||||
if cleaned.begins_with(prefix):
|
||||
cleaned = cleaned.substr(prefix.length())
|
||||
break
|
||||
cleaned = cleaned.trim_suffix(")")
|
||||
cleaned = cleaned.strip_edges()
|
||||
|
||||
var parts := cleaned.split(",")
|
||||
var numbers: PackedFloat64Array = []
|
||||
for part in parts:
|
||||
numbers.append(part.strip_edges().to_float())
|
||||
return numbers
|
||||
|
||||
|
||||
static func _parse_vector2(value: Variant) -> Vector2:
|
||||
if value is Vector2: return value
|
||||
if value is Dictionary:
|
||||
return Vector2(float(value.get("x", 0)), float(value.get("y", 0)))
|
||||
var nums := _extract_numbers(str(value))
|
||||
if nums.size() >= 2:
|
||||
return Vector2(nums[0], nums[1])
|
||||
return Vector2.ZERO
|
||||
|
||||
|
||||
static func _parse_vector2i(value: Variant) -> Vector2i:
|
||||
var v := _parse_vector2(value)
|
||||
return Vector2i(int(v.x), int(v.y))
|
||||
|
||||
|
||||
static func _parse_vector3(value: Variant) -> Vector3:
|
||||
if value is Vector3: return value
|
||||
if value is Dictionary:
|
||||
return Vector3(float(value.get("x", 0)), float(value.get("y", 0)), float(value.get("z", 0)))
|
||||
var nums := _extract_numbers(str(value))
|
||||
if nums.size() >= 3:
|
||||
return Vector3(nums[0], nums[1], nums[2])
|
||||
return Vector3.ZERO
|
||||
|
||||
|
||||
static func _parse_vector3i(value: Variant) -> Vector3i:
|
||||
var v := _parse_vector3(value)
|
||||
return Vector3i(int(v.x), int(v.y), int(v.z))
|
||||
|
||||
|
||||
static func _parse_rect2(value: Variant) -> Rect2:
|
||||
if value is Rect2: return value
|
||||
if value is Dictionary:
|
||||
return Rect2(
|
||||
float(value.get("x", 0)), float(value.get("y", 0)),
|
||||
float(value.get("w", value.get("width", 0))),
|
||||
float(value.get("h", value.get("height", 0)))
|
||||
)
|
||||
var nums := _extract_numbers(str(value))
|
||||
if nums.size() >= 4:
|
||||
return Rect2(nums[0], nums[1], nums[2], nums[3])
|
||||
return Rect2()
|
||||
|
||||
|
||||
static func _parse_color(value: Variant) -> Color:
|
||||
if value is Color: return value
|
||||
var s := str(value)
|
||||
if s.begins_with("#"):
|
||||
return Color.html(s)
|
||||
if s.begins_with("Color("):
|
||||
var nums := _extract_numbers(s)
|
||||
match nums.size():
|
||||
3: return Color(nums[0], nums[1], nums[2])
|
||||
4: return Color(nums[0], nums[1], nums[2], nums[3])
|
||||
# Try named color
|
||||
if Color.html_is_valid(s):
|
||||
return Color.html(s)
|
||||
return Color.WHITE
|
||||
|
||||
|
||||
## Serialize a Variant to JSON-safe representation
|
||||
static func serialize_value(value: Variant) -> Variant:
|
||||
if value == null:
|
||||
return null
|
||||
match typeof(value):
|
||||
TYPE_VECTOR2:
|
||||
var v: Vector2 = value
|
||||
return {"x": v.x, "y": v.y}
|
||||
TYPE_VECTOR2I:
|
||||
var v: Vector2i = value
|
||||
return {"x": v.x, "y": v.y}
|
||||
TYPE_VECTOR3:
|
||||
var v: Vector3 = value
|
||||
return {"x": v.x, "y": v.y, "z": v.z}
|
||||
TYPE_VECTOR3I:
|
||||
var v: Vector3i = value
|
||||
return {"x": v.x, "y": v.y, "z": v.z}
|
||||
TYPE_RECT2:
|
||||
var r: Rect2 = value
|
||||
return {"x": r.position.x, "y": r.position.y, "width": r.size.x, "height": r.size.y}
|
||||
TYPE_COLOR:
|
||||
var c: Color = value
|
||||
return {"r": c.r, "g": c.g, "b": c.b, "a": c.a, "html": "#" + c.to_html()}
|
||||
TYPE_NODE_PATH:
|
||||
return str(value)
|
||||
TYPE_OBJECT:
|
||||
if value is Resource:
|
||||
var res: Resource = value
|
||||
return {"type": res.get_class(), "path": res.resource_path}
|
||||
return str(value)
|
||||
TYPE_ARRAY:
|
||||
var arr: Array = value
|
||||
var result: Array = []
|
||||
for item in arr:
|
||||
result.append(serialize_value(item))
|
||||
return result
|
||||
TYPE_DICTIONARY:
|
||||
var dict: Dictionary = value
|
||||
var result: Dictionary = {}
|
||||
for key in dict:
|
||||
result[str(key)] = serialize_value(dict[key])
|
||||
return result
|
||||
_:
|
||||
return value
|
||||
Reference in New Issue
Block a user