| """Task registry, in the shape ManiSkill uses: one class per task, registered by name. |
| |
| @register_task("grape_box") |
| class GrapeBoxTask(YamTask): |
| ... |
| |
| `make("grape_box")` then builds it. Importing `bimanual.yam_tasks.tasks` pulls in every task |
| module, which is what fills this registry -- the same trick as ManiSkill's `envs/tasks/__init__`. |
| """ |
| from __future__ import annotations |
|
|
| REGISTRY: dict[str, type] = {} |
|
|
|
|
| def register_task(name: str, **meta): |
| """Class decorator: put a task class in the registry under `name`.""" |
| def deco(cls): |
| if name in REGISTRY: |
| raise ValueError(f"task {name!r} is already registered by {REGISTRY[name].__name__}") |
| cls.task_name = name |
| cls.meta = meta |
| REGISTRY[name] = cls |
| return cls |
| return deco |
|
|
|
|
| def make(name: str, **kwargs): |
| if name not in REGISTRY: |
| raise SystemExit(f"unknown task {name!r}. Registered: {sorted(REGISTRY)}") |
| return REGISTRY[name](**kwargs) |
|
|
|
|
| def list_tasks(): |
| rows = [] |
| for n, cls in sorted(REGISTRY.items()): |
| rows.append({"name": n, "class": cls.__name__, |
| "title": getattr(cls, "title", ""), |
| "tags": ",".join(getattr(cls, "tags", [])), |
| "skill": getattr(cls, "skill", "")}) |
| return rows |
|
|