Fix Recipe impl and create TypeTaggedUnion
This commit is contained in:
parent
a6cfb0e244
commit
8414154460
3 changed files with 32 additions and 68 deletions
|
@ -1,19 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from itertools import chain
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
Any,
|
||||
ClassVar,
|
||||
Collection,
|
||||
Generic,
|
||||
Iterable,
|
||||
Mapping,
|
||||
Self,
|
||||
Type,
|
||||
TypeVar,
|
||||
)
|
||||
from typing import Any, ClassVar, Generic, Self, Type, TypeVar
|
||||
|
||||
from common.deserialize import (
|
||||
TypedConfig,
|
||||
|
@ -161,17 +150,15 @@ class StatefulInternallyTaggedUnion(
|
|||
}
|
||||
|
||||
|
||||
StatefulUnions = Mapping[
|
||||
Type[StatefulInternallyTaggedUnion[AnyState]],
|
||||
Collection[Type[StatefulInternallyTaggedUnion[AnyState]]],
|
||||
]
|
||||
@dataclass(kw_only=True)
|
||||
class TypeTaggedUnion(StatefulInternallyTaggedUnion[AnyState], tag="type", value=None):
|
||||
type: ResourceLocation = field(init=False)
|
||||
|
||||
def __init_subclass__(cls, type: str | None) -> None:
|
||||
super().__init_subclass__("type", type)
|
||||
if type is not None:
|
||||
cls.type = ResourceLocation.from_str(type)
|
||||
|
||||
def make_stateful_union_hooks(
|
||||
base: Type[StatefulInternallyTaggedUnion[AnyState]],
|
||||
subtypes: Iterable[Type[StatefulInternallyTaggedUnion[AnyState]]],
|
||||
state: AnyState,
|
||||
) -> TypeHooks[StatefulInternallyTaggedUnion[AnyState]]:
|
||||
return {
|
||||
subtype: subtype.make_type_hook(state) for subtype in chain([base], subtypes)
|
||||
}
|
||||
@property
|
||||
def _tag_value(self) -> str:
|
||||
return str(self.type)
|
||||
|
|
|
@ -1,49 +1,36 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Self, TypeVar
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Self
|
||||
|
||||
from common.deserialize import TypeHook, load_json_data
|
||||
from common.state import BookState, StatefulInternallyTaggedUnion
|
||||
from common.state import AnyState, TypeTaggedUnion
|
||||
from minecraft.resource import ResourceLocation
|
||||
|
||||
_T_State = TypeVar("_T_State", bound=BookState)
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Recipe(StatefulInternallyTaggedUnion[_T_State], tag="type", value=None):
|
||||
class Recipe(TypeTaggedUnion[AnyState], type=None):
|
||||
id: ResourceLocation
|
||||
|
||||
type: ResourceLocation = field(init=False)
|
||||
group: str | None = None
|
||||
|
||||
def __init_subclass__(cls, type: str) -> None:
|
||||
super().__init_subclass__(__class__._tag_key, type)
|
||||
cls.type = ResourceLocation.from_str(type)
|
||||
|
||||
@classmethod
|
||||
def make_type_hook(cls, state: BookState) -> TypeHook[Self]:
|
||||
def make_type_hook(cls, state: AnyState) -> TypeHook[Self]:
|
||||
"""Creates a type hook which, given a stringified ResourceLocation, loads and
|
||||
returns the recipe json at that location."""
|
||||
super_hook = super().make_type_hook(state)
|
||||
|
||||
def type_hook(raw_id: str | Any) -> Self | dict[str, Any]:
|
||||
# FIXME: this should use isinstance_or_raise but I'm probably redoing it
|
||||
if isinstance(raw_id, cls):
|
||||
return raw_id
|
||||
def type_hook(data: str | Any) -> Self | dict[str, Any]:
|
||||
if isinstance(data, str):
|
||||
# FIXME: hack
|
||||
# the point of this is to ensure the recipe exists on all platforms
|
||||
# because we've had issues with that in the past, eg. in Hexal
|
||||
id = ResourceLocation.from_str(data)
|
||||
data = {}
|
||||
for recipe_dir in state.props.recipe_dirs:
|
||||
# TODO: should this use id.namespace somewhere?
|
||||
path = recipe_dir / f"{id.path}.json"
|
||||
data = load_json_data(cls, path, {"id": id})
|
||||
|
||||
# FIXME: hack
|
||||
# the point of this is to ensure the recipe exists on all platforms
|
||||
# because we've had issues with that in the past, eg. in Hexal
|
||||
id = ResourceLocation.from_str(raw_id)
|
||||
data: dict[str, Any] = {}
|
||||
for recipe_dir in state.props.recipe_dirs:
|
||||
# TODO: should this use id.namespace somewhere?
|
||||
data = load_json_data(cls, recipe_dir / f"{id.path}.json")
|
||||
|
||||
return data | {"id": id, "state": state}
|
||||
return super_hook(data)
|
||||
|
||||
return type_hook
|
||||
|
||||
@property
|
||||
def _tag_value(self) -> str:
|
||||
return str(self.type)
|
||||
|
|
|
@ -4,29 +4,23 @@ from typing import Any, Self
|
|||
|
||||
from common.deserialize import TypeHook, rename
|
||||
from common.formatting import FormatTree
|
||||
from common.state import AnyState, StatefulInternallyTaggedUnion
|
||||
from common.state import AnyState, TypeTaggedUnion
|
||||
from common.types import LocalizedStr
|
||||
from minecraft.recipe.concrete import CraftingRecipe
|
||||
from minecraft.resource import ResourceLocation
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Page(StatefulInternallyTaggedUnion[AnyState], tag="type", value=None):
|
||||
class Page(TypeTaggedUnion[AnyState], type=None):
|
||||
"""Base class for Patchouli page types.
|
||||
|
||||
See: https://vazkiimods.github.io/Patchouli/docs/patchouli-basics/page-types
|
||||
"""
|
||||
|
||||
type: ResourceLocation = field(init=False)
|
||||
advancement: ResourceLocation | None = None
|
||||
flag: str | None = None
|
||||
anchor: str | None = None
|
||||
|
||||
def __init_subclass__(cls, type: str | None) -> None:
|
||||
super().__init_subclass__("type", type)
|
||||
if type is not None:
|
||||
cls.type = ResourceLocation.from_str(type)
|
||||
|
||||
@classmethod
|
||||
def make_type_hook(cls, state: AnyState) -> TypeHook[Self]:
|
||||
super_hook = super().make_type_hook(state)
|
||||
|
@ -39,10 +33,6 @@ class Page(StatefulInternallyTaggedUnion[AnyState], tag="type", value=None):
|
|||
|
||||
return type_hook
|
||||
|
||||
@property
|
||||
def _tag_value(self) -> str:
|
||||
return str(self.type)
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class PageWithText(Page[AnyState], type=None):
|
||||
|
|
Loading…
Reference in a new issue