mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-07 16:13:23 +08:00
Tidying
This commit is contained in:
parent
48f72ec123
commit
f26954f330
@ -27,9 +27,9 @@ from typing import TYPE_CHECKING
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Dict, Type, Tuple
|
from typing import Any, Dict, Type, Tuple
|
||||||
|
|
||||||
# For fields with these type strings, we require a passed value's type
|
# For fields with these string types, we require a passed value's type
|
||||||
# to exactly match one of the tuple values to consider the assignment valid.
|
# to exactly match one of the tuple values to consider the assignment valid.
|
||||||
_ASSIGN_TYPES: Dict[str, Tuple[Type, ...]] = {
|
_SIMPLE_ASSIGN_TYPES: Dict[str, Tuple[Type, ...]] = {
|
||||||
'bool': (bool, ),
|
'bool': (bool, ),
|
||||||
'str': (str, ),
|
'str': (str, ),
|
||||||
'int': (int, ),
|
'int': (int, ),
|
||||||
@ -55,9 +55,9 @@ def dataclass_assign(instance: Any, values: Dict[str, Any]) -> None:
|
|||||||
An AttributeError will be raised if attributes are passed which are
|
An AttributeError will be raised if attributes are passed which are
|
||||||
not present on the dataclass as fields.
|
not present on the dataclass as fields.
|
||||||
|
|
||||||
This function may be significantly slower than simply passing dict
|
This function may add significant overhead compared to passing dict
|
||||||
values to a dataclass' constructor or other more direct methods, but
|
values to a dataclass' constructor or other more direct methods, but
|
||||||
the increased safety checks may be worth the extra overhead in some
|
the increased safety checks may be worth the speed tradeoff in some
|
||||||
cases.
|
cases.
|
||||||
"""
|
"""
|
||||||
if not dataclasses.is_dataclass(instance):
|
if not dataclasses.is_dataclass(instance):
|
||||||
@ -72,8 +72,8 @@ def dataclass_assign(instance: Any, values: Dict[str, Any]) -> None:
|
|||||||
f" no '{key}' field.")
|
f" no '{key}' field.")
|
||||||
field = fieldsdict[key]
|
field = fieldsdict[key]
|
||||||
|
|
||||||
# We expect to be operating with 'from __future__ import annotations'
|
# We expect to be operating under 'from __future__ import annotations'
|
||||||
# so this should always be a string for us; not an actual type.
|
# so field types should always be strings for us; not an actual types.
|
||||||
# Complain if we come across an actual type.
|
# Complain if we come across an actual type.
|
||||||
fieldtype: str = field.type # type: ignore
|
fieldtype: str = field.type # type: ignore
|
||||||
if not isinstance(fieldtype, str):
|
if not isinstance(fieldtype, str):
|
||||||
@ -82,11 +82,10 @@ def dataclass_assign(instance: Any, values: Dict[str, Any]) -> None:
|
|||||||
f' been created without "from __future__ import annotations";'
|
f' been created without "from __future__ import annotations";'
|
||||||
f' those dataclasses are unsupported here.')
|
f' those dataclasses are unsupported here.')
|
||||||
|
|
||||||
reqtypes = _ASSIGN_TYPES.get(fieldtype)
|
reqtypes = _SIMPLE_ASSIGN_TYPES.get(fieldtype)
|
||||||
if reqtypes is not None:
|
if reqtypes is not None:
|
||||||
# pylint: disable=unidiomatic-typecheck
|
# pylint: disable=unidiomatic-typecheck
|
||||||
if not any(type(value) is t for t in reqtypes):
|
if not any(type(value) is t for t in reqtypes):
|
||||||
# if not isinstance(value, reqtype):
|
|
||||||
if len(reqtypes) == 1:
|
if len(reqtypes) == 1:
|
||||||
expected = reqtypes[0].__name__
|
expected = reqtypes[0].__name__
|
||||||
else:
|
else:
|
||||||
@ -105,8 +104,8 @@ def dataclass_assign(instance: Any, values: Dict[str, Any]) -> None:
|
|||||||
def dataclass_validate(instance: Any) -> None:
|
def dataclass_validate(instance: Any) -> None:
|
||||||
"""Ensure values in a dataclass are correct types.
|
"""Ensure values in a dataclass are correct types.
|
||||||
|
|
||||||
Note that this will always fail if a dataclass has value types
|
Note that this will always fail if a dataclass contains field types
|
||||||
unsupported by this module.
|
not supported by this module.
|
||||||
"""
|
"""
|
||||||
# We currently simply operate by grabbing dataclass values as a dict
|
# We currently simply operate by grabbing dataclass values as a dict
|
||||||
# and passing them through dataclass_assign().
|
# and passing them through dataclass_assign().
|
||||||
|
|||||||
@ -38,9 +38,9 @@ sys.path += [
|
|||||||
str(Path(os.getcwd(), 'dist', 'ba_data', 'python-site-packages'))
|
str(Path(os.getcwd(), 'dist', 'ba_data', 'python-site-packages'))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
from efro.dataclassutils import dataclass_assign, dataclass_validate
|
||||||
from bacommon.servermanager import (ServerConfig, ServerCommand,
|
from bacommon.servermanager import (ServerConfig, ServerCommand,
|
||||||
make_server_command)
|
make_server_command)
|
||||||
from efro.dataclassutils import dataclass_assign
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Optional, List, Dict
|
from typing import Optional, List, Dict
|
||||||
@ -50,8 +50,8 @@ if TYPE_CHECKING:
|
|||||||
class ServerManagerApp:
|
class ServerManagerApp:
|
||||||
"""An app which manages BallisticaCore server execution.
|
"""An app which manages BallisticaCore server execution.
|
||||||
|
|
||||||
Handles configuring, launching, re-launching, and controlling
|
Handles configuring, launching, re-launching, and otherwise
|
||||||
BallisticaCore binaries operating in server mode.
|
managing a BallisticaCore binary operating as a server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
@ -82,11 +82,16 @@ class ServerManagerApp:
|
|||||||
"""The current config settings for the app."""
|
"""The current config settings for the app."""
|
||||||
return self._config
|
return self._config
|
||||||
|
|
||||||
|
@config.setter
|
||||||
|
def config(self, value: ServerConfig) -> None:
|
||||||
|
dataclass_validate(value)
|
||||||
|
self._config = value
|
||||||
|
|
||||||
def _load_config(self) -> ServerConfig:
|
def _load_config(self) -> ServerConfig:
|
||||||
user_config_path = 'config.yaml'
|
user_config_path = 'config.yaml'
|
||||||
|
|
||||||
# Start with a default config, and if there is a config.yaml,
|
# Start with a default config, and if there is a config.yaml,
|
||||||
# override parts of it.
|
# assign whatever is contained within.
|
||||||
config = ServerConfig()
|
config = ServerConfig()
|
||||||
if os.path.exists(user_config_path):
|
if os.path.exists(user_config_path):
|
||||||
import yaml
|
import yaml
|
||||||
@ -99,7 +104,6 @@ class ServerManagerApp:
|
|||||||
if not isinstance(user_config, dict):
|
if not isinstance(user_config, dict):
|
||||||
raise RuntimeError(f'Invalid config format; expected dict,'
|
raise RuntimeError(f'Invalid config format; expected dict,'
|
||||||
f' got {type(user_config)}.')
|
f' got {type(user_config)}.')
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def _get_binary_path(self) -> str:
|
def _get_binary_path(self) -> str:
|
||||||
@ -256,6 +260,8 @@ class ServerManagerApp:
|
|||||||
assert self._process is not None
|
assert self._process is not None
|
||||||
|
|
||||||
# Send the initial server config which should kick things off.
|
# Send the initial server config which should kick things off.
|
||||||
|
# (but make sure its values are still valid first)
|
||||||
|
dataclass_validate(self._config)
|
||||||
cmd = make_server_command(ServerCommand.CONFIG, self._config)
|
cmd = make_server_command(ServerCommand.CONFIG, self._config)
|
||||||
assert self._process.stdin is not None
|
assert self._process.stdin is not None
|
||||||
self._process.stdin.write(cmd)
|
self._process.stdin.write(cmd)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user