85 lines
3.3 KiB
Python
85 lines
3.3 KiB
Python
import ctypes
|
|
from enum import Enum
|
|
|
|
def inspect_structure(obj):
|
|
"""
|
|
Analizza ricorsivamente una struttura o unione ctypes e ritorna un dizionario
|
|
che descrive la gerarchia dei dati, i valori attuali e i metadati per la GUI.
|
|
"""
|
|
|
|
# 1. Gestione Smart Types (es. Velocity, Semicircle)
|
|
# Se la classe ha una property 'value' o 'degrees', la trattiamo come un valore singolo
|
|
cls = obj.__class__
|
|
if hasattr(cls, 'value') and isinstance(getattr(cls, 'value'), property):
|
|
return {
|
|
"type": "smart_value",
|
|
"value": obj.value,
|
|
"obj_ref": obj, # Riferimento all'oggetto per il setter
|
|
"attr_name": "value" # Nome dell'attributo da settare
|
|
}
|
|
if hasattr(cls, 'degrees') and isinstance(getattr(cls, 'degrees'), property):
|
|
return {
|
|
"type": "smart_angle",
|
|
"value": obj.degrees,
|
|
"obj_ref": obj,
|
|
"attr_name": "degrees"
|
|
}
|
|
|
|
# 2. Gestione Strutture Complesse (Structure o Union)
|
|
if hasattr(obj, "_fields_"):
|
|
children = {}
|
|
|
|
# Recuperiamo eventuali metadati per gli Enum definiti nella classe
|
|
# Esempio: _enums_ = {"target_history": TargetHistory}
|
|
enums_map = getattr(obj, "_enums_", {})
|
|
|
|
for field_desc in obj._fields_:
|
|
field_name = field_desc[0]
|
|
field_type = field_desc[1]
|
|
|
|
# Saltiamo i campi 'raw' se esiste una vista 'bits' o 'fields' (tipico delle Union)
|
|
if field_name == "raw" and (hasattr(obj, "bits") or hasattr(obj, "fields")):
|
|
continue
|
|
|
|
field_val = getattr(obj, field_name)
|
|
|
|
# Caso A: Campo mappato su Enum
|
|
if field_name in enums_map:
|
|
enum_cls = enums_map[field_name]
|
|
try:
|
|
current_enum = enum_cls(field_val)
|
|
except ValueError:
|
|
# Se il valore raw non è nell'enum, gestiamo l'errore o usiamo un fallback
|
|
current_enum = field_val
|
|
|
|
children[field_name] = {
|
|
"type": "enum",
|
|
"value": current_enum,
|
|
"enum_cls": enum_cls,
|
|
"obj_ref": obj,
|
|
"attr_name": field_name
|
|
}
|
|
|
|
# Caso B: Altra Struttura/Union (Ricorsione)
|
|
elif hasattr(field_val, "_fields_"):
|
|
children[field_name] = inspect_structure(field_val)
|
|
|
|
# Caso C: Primitiva (int, float, array fissi)
|
|
else:
|
|
# Gestione array ctypes semplici
|
|
if hasattr(field_type, "_length_"):
|
|
# Per ora semplifichiamo gli array come stringa o lista non editabile
|
|
val_repr = str(list(field_val))
|
|
children[field_name] = {"type": "readonly", "value": val_repr}
|
|
else:
|
|
children[field_name] = {
|
|
"type": "primitive",
|
|
"value": field_val,
|
|
"obj_ref": obj,
|
|
"attr_name": field_name
|
|
}
|
|
|
|
return {"type": "compound", "children": children}
|
|
|
|
# Fallback
|
|
return {"type": "unknown", "value": str(obj)} |