mirror of
https://github.com/hypervortex/VH-Bombsquad-Modded-Server-Files
synced 2026-08-29 13:05:07 +00:00
updated files
This commit is contained in:
parent
5ba4986d59
commit
7a5e7698c0
1269 changed files with 551814 additions and 0 deletions
131
dist/ba_data/python/efro/entity/util.py
vendored
Normal file
131
dist/ba_data/python/efro/entity/util.py
vendored
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""Misc utility functionality related to the entity system."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Union, Tuple, List
|
||||
from efro.entity._value import CompoundValue
|
||||
from efro.entity._support import BoundCompoundValue
|
||||
|
||||
|
||||
def diff_compound_values(
|
||||
obj1: Union[BoundCompoundValue, CompoundValue],
|
||||
obj2: Union[BoundCompoundValue, CompoundValue]) -> str:
|
||||
"""Generate a string showing differences between two compound values.
|
||||
|
||||
Both must be associated with data and have the same set of fields.
|
||||
"""
|
||||
|
||||
# Ensure fields match and both are attached to data...
|
||||
value1, data1 = get_compound_value_and_data(obj1)
|
||||
if data1 is None:
|
||||
raise ValueError(f'Invalid unbound compound value: {obj1}')
|
||||
value2, data2 = get_compound_value_and_data(obj2)
|
||||
if data2 is None:
|
||||
raise ValueError(f'Invalid unbound compound value: {obj2}')
|
||||
if not have_matching_fields(value1, value2):
|
||||
raise ValueError(
|
||||
f"Can't diff objs with non-matching fields: {value1} and {value2}")
|
||||
|
||||
# Ok; let 'er rip...
|
||||
diff = _diff(obj1, obj2, 2)
|
||||
return ' <no differences>' if diff == '' else diff
|
||||
|
||||
|
||||
class CompoundValueDiff:
|
||||
"""Wraps diff_compound_values() in an object for efficiency.
|
||||
|
||||
It is preferable to pass this to logging calls instead of the
|
||||
final diff string since the diff will never be generated if
|
||||
the associated logging level is not being emitted.
|
||||
"""
|
||||
|
||||
def __init__(self, obj1: Union[BoundCompoundValue, CompoundValue],
|
||||
obj2: Union[BoundCompoundValue, CompoundValue]):
|
||||
self._obj1 = obj1
|
||||
self._obj2 = obj2
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return diff_compound_values(self._obj1, self._obj2)
|
||||
|
||||
|
||||
def _diff(obj1: Union[BoundCompoundValue, CompoundValue],
|
||||
obj2: Union[BoundCompoundValue, CompoundValue], indent: int) -> str:
|
||||
from efro.entity._support import BoundCompoundValue
|
||||
bits: List[str] = []
|
||||
indentstr = ' ' * indent
|
||||
vobj1, _data1 = get_compound_value_and_data(obj1)
|
||||
fields = sorted(vobj1.get_fields().keys())
|
||||
for field in fields:
|
||||
val1 = getattr(obj1, field)
|
||||
val2 = getattr(obj2, field)
|
||||
# for nested compounds, dive in and do nice piecewise compares
|
||||
if isinstance(val1, BoundCompoundValue):
|
||||
assert isinstance(val2, BoundCompoundValue)
|
||||
diff = _diff(val1, val2, indent + 2)
|
||||
if diff != '':
|
||||
bits.append(f'{indentstr}{field}:')
|
||||
bits.append(diff)
|
||||
# for all else just do a single line
|
||||
# (perhaps we could improve on this for other complex types)
|
||||
else:
|
||||
if val1 != val2:
|
||||
bits.append(f'{indentstr}{field}: {val1} -> {val2}')
|
||||
return '\n'.join(bits)
|
||||
|
||||
|
||||
def have_matching_fields(val1: CompoundValue, val2: CompoundValue) -> bool:
|
||||
"""Return whether two compound-values have matching sets of fields.
|
||||
|
||||
Note this just refers to the field configuration; not data.
|
||||
"""
|
||||
# Quick-out: matching types will always have identical fields.
|
||||
if type(val1) is type(val2):
|
||||
return True
|
||||
|
||||
# Otherwise do a full comparison.
|
||||
return val1.get_fields() == val2.get_fields()
|
||||
|
||||
|
||||
def get_compound_value_and_data(
|
||||
obj: Union[BoundCompoundValue,
|
||||
CompoundValue]) -> Tuple[CompoundValue, Any]:
|
||||
"""Return value and data for bound or unbound compound values."""
|
||||
# pylint: disable=cyclic-import
|
||||
from efro.entity._support import BoundCompoundValue
|
||||
from efro.entity._value import CompoundValue
|
||||
if isinstance(obj, BoundCompoundValue):
|
||||
value = obj.d_value
|
||||
data = obj.d_data
|
||||
elif isinstance(obj, CompoundValue):
|
||||
value = obj
|
||||
data = getattr(obj, 'd_data', None) # may not exist
|
||||
else:
|
||||
raise TypeError(
|
||||
f'Expected a BoundCompoundValue or CompoundValue; got {type(obj)}')
|
||||
return value, data
|
||||
|
||||
|
||||
def compound_eq(obj1: Union[BoundCompoundValue, CompoundValue],
|
||||
obj2: Union[BoundCompoundValue, CompoundValue]) -> Any:
|
||||
"""Compare two compound value/bound-value objects for equality."""
|
||||
|
||||
# Criteria for comparison: both need to be a compound value
|
||||
# and both must have data (which implies they are either a entity
|
||||
# or bound to a subfield in an entity).
|
||||
value1, data1 = get_compound_value_and_data(obj1)
|
||||
if data1 is None:
|
||||
return NotImplemented
|
||||
value2, data2 = get_compound_value_and_data(obj2)
|
||||
if data2 is None:
|
||||
return NotImplemented
|
||||
|
||||
# Ok we can compare them. To consider them equal we look for
|
||||
# matching sets of fields and matching data. Note that there
|
||||
# could be unbound data causing inequality despite their field
|
||||
# values all matching; not sure if that's what we want.
|
||||
return have_matching_fields(value1, value2) and data1 == data2
|
||||
Loading…
Add table
Add a link
Reference in a new issue