mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-29 10:43:21 +08:00
Syncing latest changes between public/private.
This commit is contained in:
parent
29b588f5f5
commit
068806facc
1
.idea/dictionaries/ericf.xml
generated
1
.idea/dictionaries/ericf.xml
generated
@ -1021,6 +1021,7 @@
|
||||
<w>nntplib</w>
|
||||
<w>nodepos</w>
|
||||
<w>nodpi</w>
|
||||
<w>nofiles</w>
|
||||
<w>noinspect</w>
|
||||
<w>noninfringement</w>
|
||||
<w>nonmultipart</w>
|
||||
|
||||
62
Makefile
62
Makefile
@ -41,9 +41,9 @@ help:
|
||||
|
||||
# Prerequisites that should be in place before running most any other build;
|
||||
# things like tool config files, etc.
|
||||
PREREQS = .dir-locals.el .mypy.ini .pycheckers \
|
||||
.pylintrc .style.yapf .clang-format \
|
||||
.projectile .editorconfig .cache/checkenv
|
||||
PREREQS = .cache/checkenv .dir-locals.el \
|
||||
.mypy.ini .pycheckers .pylintrc .style.yapf .clang-format \
|
||||
.projectile .editorconfig
|
||||
|
||||
prereqs: ${PREREQS}
|
||||
|
||||
@ -264,43 +264,43 @@ formatmakefile: prereqs
|
||||
# These are useful, but can take significantly longer and/or be a bit flaky.
|
||||
|
||||
check: updatecheck
|
||||
@$(MAKE) -j3 cpplintcode pylintscripts mypyscripts
|
||||
@$(MAKE) -j3 cpplint pylint mypy
|
||||
@echo ALL CHECKS PASSED!
|
||||
check2: updatecheck
|
||||
@$(MAKE) -j4 cpplintcode pylintscripts mypyscripts pycharmscripts
|
||||
@$(MAKE) -j4 cpplint pylint mypy pycharmscripts
|
||||
@echo ALL CHECKS PASSED!
|
||||
|
||||
checkfast: updatecheck
|
||||
@$(MAKE) -j3 cpplintcode pylintscriptsfast mypyscripts
|
||||
@$(MAKE) -j3 cpplint pylintfast mypy
|
||||
@echo ALL CHECKS PASSED!
|
||||
checkfast2: updatecheck
|
||||
@$(MAKE) -j4 cpplintcode pylintscriptsfast mypyscripts pycharmscripts
|
||||
@$(MAKE) -j4 cpplint pylintfast mypy pycharmscripts
|
||||
@echo ALL CHECKS PASSED!
|
||||
|
||||
checkfull: updatecheck
|
||||
@$(MAKE) -j3 cpplintcodefull pylintscriptsfull mypyscriptsfull
|
||||
@$(MAKE) -j3 cpplintfull pylintfull mypyfull
|
||||
@echo ALL CHECKS PASSED!
|
||||
checkfull2: updatecheck
|
||||
@$(MAKE) -j4 cpplintcodefull pylintscriptsfull mypyscriptsfull pycharmscriptsfull
|
||||
@$(MAKE) -j4 cpplintfull pylintfull mypyfull pycharmscriptsfull
|
||||
@echo ALL CHECKS PASSED!
|
||||
|
||||
cpplintcode: prereqs
|
||||
@tools/snippets cpplintcode
|
||||
cpplint: prereqs
|
||||
@tools/snippets cpplint
|
||||
|
||||
cpplintcodefull: prereqs
|
||||
@tools/snippets cpplintcode -full
|
||||
cpplintfull: prereqs
|
||||
@tools/snippets cpplint -full
|
||||
|
||||
pylintscripts: prereqs
|
||||
@tools/snippets pylintscripts
|
||||
pylint: prereqs
|
||||
@tools/snippets pylint
|
||||
|
||||
pylintscriptsfull: prereqs
|
||||
@tools/snippets pylintscripts -full
|
||||
pylintfull: prereqs
|
||||
@tools/snippets pylint -full
|
||||
|
||||
mypyscripts: prereqs
|
||||
@tools/snippets mypyscripts
|
||||
mypy: prereqs
|
||||
@tools/snippets mypy
|
||||
|
||||
mypyscriptsfull: prereqs
|
||||
@tools/snippets mypyscripts -full
|
||||
mypyfull: prereqs
|
||||
@tools/snippets mypy -full
|
||||
|
||||
pycharmscripts: prereqs
|
||||
@tools/snippets pycharmscripts
|
||||
@ -311,14 +311,14 @@ pycharmscriptsfull: prereqs
|
||||
# 'Fast' script checking using dependency recursion limits.
|
||||
# This can require much less re-checking but may miss problems in rare cases.
|
||||
# Its not a bad idea to run a non-fast check every so often or before pushing.
|
||||
pylintscriptsfast: prereqs
|
||||
@tools/snippets pylintscripts -fast
|
||||
pylintfast: prereqs
|
||||
@tools/snippets pylint -fast
|
||||
|
||||
# Tell make which of these targets don't represent files.
|
||||
.PHONY: format formatfull formatcode formatcodefull formatscripts \
|
||||
formatscriptsfull check check2 checkfast checkfast2 checkfull checkfull2 \
|
||||
cpplintcode cpplintcodefull pylintscripts pylintscriptsfull mypyscripts \
|
||||
mypyscriptsfull pycharmscripts pycharmscriptsfull
|
||||
cpplint cpplintfull pylint pylintfull mypy \
|
||||
mypyfull pycharmscripts pycharmscriptsfull
|
||||
|
||||
|
||||
################################################################################
|
||||
@ -338,24 +338,24 @@ updatecheck: prereqs
|
||||
# Run an update and check together; handy while iterating.
|
||||
# (slightly more efficient than running update/check separately).
|
||||
updatethencheck: update
|
||||
@$(MAKE) -j3 cpplintcode pylintscripts mypyscripts
|
||||
@$(MAKE) -j3 cpplint pylint mypy
|
||||
@echo ALL CHECKS PASSED!
|
||||
updatethencheck2: update
|
||||
@$(MAKE) -j4 cpplintcode pylintscripts mypyscripts pycharmscripts
|
||||
@$(MAKE) -j4 cpplint pylint mypy pycharmscripts
|
||||
@echo ALL CHECKS PASSED!
|
||||
|
||||
updatethencheckfast: update
|
||||
@$(MAKE) -j3 cpplintcode pylintscriptsfast mypyscripts
|
||||
@$(MAKE) -j3 cpplint pylintfast mypy
|
||||
@echo ALL CHECKS PASSED!
|
||||
updatethencheckfast2: update
|
||||
@$(MAKE) -j4 cpplintcode pylintscriptsfast mypyscripts pycharmscripts
|
||||
@$(MAKE) -j4 cpplint pylintfast mypy pycharmscripts
|
||||
@echo ALL CHECKS PASSED!
|
||||
|
||||
updatethencheckfull: update
|
||||
@$(MAKE) -j3 cpplintcodefull pylintscriptsfull mypyscriptsfull
|
||||
@$(MAKE) -j3 cpplintfull pylintfull mypyfull
|
||||
@echo ALL CHECKS PASSED!
|
||||
updatethencheckfull2: update
|
||||
@$(MAKE) -j4 cpplintcodefull pylintscriptsfull mypyscriptsfull pycharmscriptsfull
|
||||
@$(MAKE) -j4 cpplintfull pylintfull mypyfull pycharmscriptsfull
|
||||
@echo ALL CHECKS PASSED!
|
||||
|
||||
# Run a format, an update, and then a check.
|
||||
|
||||
@ -23,11 +23,11 @@ The Ballistica project is the foundation for the next generation of [BombSquad](
|
||||
* Migrate modding documentation to this repo's wiki, allowing other modders to add their own bits of wisdom
|
||||
|
||||
### Frequently Asked Questions
|
||||
* **Q: What's with the new name? Is BombSquad getting renamed?**
|
||||
* **Q: What's with this new name? Is BombSquad getting renamed?**
|
||||
* A: No, BombSquad is still BombSquad. 'Ballistica' is simply the new name for the engine/app-framework. This way it can be used for other game/app projects without causing confusion (though that is mostly theoretical at this point). As a modder, the biggest change you will notice is a lot of 'ba' prefixes in the APIs as opposed to 'bs'. You may also see the word 'BallisticaCore' show up various places, which in actual releases gets replaced by 'BombSquad'.
|
||||
|
||||
* **Q: Does this mean BombSquad is open source?**
|
||||
* A: Yes and no. All code contained in this repo is MIT licensed and free for use anywhere. This includes game scripts, pipeline tools, etc. In the future I hope to expand this to include at least some binary sources. Anything not included here, however, even if automatically downloaded by build scripts, is still copyrighted and cannot be redistributed without explicit consent. This includes assets and game binaries. So in a nutshell: create and share mods to your heart's content, but please don't distribute your own complete copy of the game. Please email support@froemling.net if you have any questions.
|
||||
* A: Yes and no. All code contained in this repo is MIT licensed and free for use anywhere. This includes game scripts, pipeline tools, etc. In the future I hope to expand this to include at least some binary sources. Anything not included here, however, even if automatically downloaded by build scripts, is still proprietary and cannot be redistributed without explicit consent. This includes assets and game binaries. So in a nutshell: create and share mods to your heart's content, but please don't distribute your own complete copy of the game. Please email support@froemling.net if you have any questions.
|
||||
|
||||
* **Q: Will my existing BombSquad 1.4.x mods still work?**
|
||||
* A: No. All mods will need to be explicitly updated to work with the new ballistica apis in 1.5+. This may or may not be a significant amount of work depending on the mod. I would highly suggest tinkering around with some of the new features in 1.5 such as type-safe Python and dynamic assets before attempting to port any old mods, as some things are done significantly differently now. You may also want to consider simply sticking with 1.4 builds for a while longer, especially for server duties, since they will remain fully compatible with clients running 1.5. The new ballistica apis may still be in significant flux for at least a while until the dust settles, but they will be worth switching to eventually, I promise!
|
||||
|
||||
@ -34,7 +34,7 @@ NOTE: This file was autogenerated by gendummymodule; do not edit by hand.
|
||||
"""
|
||||
|
||||
# (hash we can use to see if this file is out of date)
|
||||
# SOURCES_HASH=171913046369526584263358640346000279030
|
||||
# SOURCES_HASH=120456495529909322688635129785556212748
|
||||
|
||||
# I'm sorry Pylint. I know this file saddens you. Be strong.
|
||||
# pylint: disable=useless-suppression
|
||||
@ -3483,10 +3483,20 @@ def set_ui_input_device(input_device: Optional[ba.InputDevice]) -> None:
|
||||
|
||||
|
||||
def show_ad(purpose: str,
|
||||
on_completion_call: Callable[[], None] = None,
|
||||
pass_actually_showed: bool = False) -> None:
|
||||
"""show_ad(purpose: str, on_completion_call: Callable[[], None] = None,
|
||||
pass_actually_showed: bool = False) -> None
|
||||
on_completion_call: Callable[[], None] = None) -> None:
|
||||
"""show_ad(purpose: str, on_completion_call: Callable[[], None] = None)
|
||||
-> None
|
||||
|
||||
(internal)
|
||||
"""
|
||||
return None
|
||||
|
||||
|
||||
def show_ad_2(purpose: str,
|
||||
on_completion_call: Callable[[bool], None] = None) -> None:
|
||||
"""show_ad_2(purpose: str,
|
||||
on_completion_call: Callable[[bool], None] = None)
|
||||
-> None
|
||||
|
||||
(internal)
|
||||
"""
|
||||
|
||||
@ -667,7 +667,7 @@ class Achievement:
|
||||
from ba import _gameutils
|
||||
from bastd.actor.text import Text
|
||||
from bastd.actor.image import Image
|
||||
from ba._general import Call, WeakCall
|
||||
from ba._general import WeakCall
|
||||
from ba._lang import Lstr
|
||||
from ba._messages import DieMessage
|
||||
from ba._enums import TimeType, SpecialChar
|
||||
@ -692,7 +692,8 @@ class Achievement:
|
||||
_ba.playsound(_ba.getsound('achievement'), host_only=True)
|
||||
else:
|
||||
_ba.timer(
|
||||
0.5, Call(_ba.playsound, _ba.getsound('ding'), host_only=True))
|
||||
0.5,
|
||||
lambda: _ba.playsound(_ba.getsound('ding'), host_only=True))
|
||||
|
||||
in_time = 0.300
|
||||
out_time = 3.5
|
||||
|
||||
@ -247,27 +247,9 @@ class App:
|
||||
import urllib.request
|
||||
try:
|
||||
val = urllib.request.urlopen('https://example.com').read()
|
||||
print("HTTPS SUCCESS", len(val))
|
||||
print("HTTPS TEST SUCCESS", len(val))
|
||||
except Exception as exc:
|
||||
print("GOT EXC", exc)
|
||||
|
||||
try:
|
||||
import sqlite3
|
||||
print("GOT SQLITE", sqlite3)
|
||||
except Exception as exc:
|
||||
print("EXC IMPORTING SQLITE", exc)
|
||||
|
||||
try:
|
||||
import csv
|
||||
print("GOT CSV", csv)
|
||||
except Exception as exc:
|
||||
print("EXC IMPORTING CSV", exc)
|
||||
|
||||
try:
|
||||
import lzma
|
||||
print("GOT LZMA", lzma)
|
||||
except Exception as exc:
|
||||
print("EXC IMPORTING LZMA", exc)
|
||||
print("HTTPS TEST FAIL:", exc)
|
||||
|
||||
# Config.
|
||||
self.config_file_healthy = False
|
||||
@ -436,7 +418,7 @@ class App:
|
||||
# pylint: disable=too-many-locals
|
||||
# pylint: disable=cyclic-import
|
||||
from ba import _apputils
|
||||
from ba._general import Call
|
||||
# from ba._general import Call
|
||||
from ba import _appconfig
|
||||
from ba import ui as bsui
|
||||
from ba import _achievement
|
||||
@ -493,31 +475,23 @@ class App:
|
||||
self.small_ui = True
|
||||
self.med_ui = False
|
||||
with _ba.Context('ui'):
|
||||
_ba.pushcall(
|
||||
Call(_ba.screenmessage,
|
||||
'FORCING SMALL UI FOR TESTING',
|
||||
color=(1, 0, 1),
|
||||
log=True))
|
||||
_ba.pushcall(lambda: _ba.screenmessage(
|
||||
'FORCING SMALL UI FOR TESTING', color=(1, 0, 1), log=True))
|
||||
# noinspection PyUnreachableCode
|
||||
if 0: # force-test medium UI
|
||||
self.small_ui = False
|
||||
self.med_ui = True
|
||||
with _ba.Context('ui'):
|
||||
_ba.pushcall(
|
||||
Call(_ba.screenmessage,
|
||||
'FORCING MEDIUM UI FOR TESTING',
|
||||
color=(1, 0, 1),
|
||||
log=True))
|
||||
_ba.pushcall(lambda: _ba.screenmessage(
|
||||
'FORCING MEDIUM UI FOR TESTING', color=(1, 0, 1
|
||||
), log=True))
|
||||
# noinspection PyUnreachableCode
|
||||
if 0: # force-test large UI
|
||||
self.small_ui = False
|
||||
self.med_ui = False
|
||||
with _ba.Context('ui'):
|
||||
_ba.pushcall(
|
||||
Call(_ba.screenmessage,
|
||||
'FORCING LARGE UI FOR TESTING',
|
||||
color=(1, 0, 1),
|
||||
log=True))
|
||||
_ba.pushcall(lambda: _ba.screenmessage(
|
||||
'FORCING LARGE UI FOR TESTING', color=(1, 0, 1), log=True))
|
||||
# pylint: enable=using-constant-test
|
||||
|
||||
# If there's a leftover log file, attempt to upload
|
||||
@ -572,16 +546,17 @@ class App:
|
||||
server_addr = _ba.get_master_server_address()
|
||||
if 'localhost' in server_addr:
|
||||
_ba.timer(2.0,
|
||||
Call(_ba.screenmessage,
|
||||
"Note: using local server", (1, 1, 0),
|
||||
log=True),
|
||||
lambda: _ba.screenmessage("Note: using local server",
|
||||
(1, 1, 0),
|
||||
log=True),
|
||||
timetype=TimeType.REAL)
|
||||
elif 'test' in server_addr:
|
||||
_ba.timer(2.0,
|
||||
Call(_ba.screenmessage,
|
||||
"Note: using test server-module", (1, 1, 0),
|
||||
log=True),
|
||||
timetype=TimeType.REAL)
|
||||
_ba.timer(
|
||||
2.0,
|
||||
lambda: _ba.screenmessage("Note: using test server-module",
|
||||
(1, 1, 0),
|
||||
log=True),
|
||||
timetype=TimeType.REAL)
|
||||
|
||||
cfg['launchCount'] = launch_count
|
||||
cfg.commit()
|
||||
@ -786,7 +761,6 @@ class App:
|
||||
def do_remove_in_game_ads_message(self) -> None:
|
||||
"""(internal)"""
|
||||
from ba._lang import Lstr
|
||||
from ba._general import Call
|
||||
from ba._enums import TimeType
|
||||
|
||||
# Print this message once every 10 minutes at most.
|
||||
@ -797,15 +771,12 @@ class App:
|
||||
with _ba.Context('ui'):
|
||||
_ba.timer(
|
||||
1.0,
|
||||
Call(_ba.screenmessage,
|
||||
Lstr(
|
||||
resource='removeInGameAdsText',
|
||||
subs=[
|
||||
('${PRO}',
|
||||
Lstr(resource='store.bombSquadProNameText')),
|
||||
('${APP_NAME}', Lstr(resource='titleText'))
|
||||
]),
|
||||
color=(1, 1, 0)),
|
||||
lambda: _ba.screenmessage(Lstr(
|
||||
resource='removeInGameAdsText',
|
||||
subs=[('${PRO}',
|
||||
Lstr(resource='store.bombSquadProNameText')),
|
||||
('${APP_NAME}', Lstr(resource='titleText'))]),
|
||||
color=(1, 1, 0)),
|
||||
timetype=TimeType.REAL)
|
||||
|
||||
def shutdown(self) -> None:
|
||||
|
||||
@ -279,23 +279,29 @@ def print_corrupt_file_error() -> None:
|
||||
from ba._lang import get_resource
|
||||
from ba._general import Call
|
||||
from ba._enums import TimeType
|
||||
_ba.timer(2.0,
|
||||
Call(_ba.screenmessage,
|
||||
get_resource('internal.corruptFileText').replace(
|
||||
'${EMAIL}', 'support@froemling.net'),
|
||||
color=(1, 0, 0)),
|
||||
timetype=TimeType.REAL)
|
||||
_ba.timer(
|
||||
2.0,
|
||||
lambda: _ba.screenmessage(get_resource('internal.corruptFileText').
|
||||
replace('${EMAIL}', 'support@froemling.net'),
|
||||
color=(1, 0, 0)),
|
||||
timetype=TimeType.REAL)
|
||||
_ba.timer(2.0,
|
||||
Call(_ba.playsound, _ba.getsound('error')),
|
||||
timetype=TimeType.REAL)
|
||||
|
||||
|
||||
def show_ad(purpose: str,
|
||||
on_completion_call: Callable[[], Any] = None,
|
||||
pass_actually_showed: bool = False) -> None:
|
||||
on_completion_call: Callable[[], Any] = None) -> None:
|
||||
"""(internal)"""
|
||||
_ba.app.last_ad_purpose = purpose
|
||||
_ba.show_ad(purpose, on_completion_call, pass_actually_showed)
|
||||
_ba.show_ad(purpose, on_completion_call)
|
||||
|
||||
|
||||
def show_ad_2(purpose: str,
|
||||
on_completion_call: Callable[[bool], Any] = None) -> None:
|
||||
"""(internal)"""
|
||||
_ba.app.last_ad_purpose = purpose
|
||||
_ba.show_ad_2(purpose, on_completion_call)
|
||||
|
||||
|
||||
def call_after_ad(call: Callable[[], Any]) -> None:
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
# SOFTWARE.
|
||||
# -----------------------------------------------------------------------------
|
||||
"""Functionality related to object/asset dependencies."""
|
||||
# pylint: disable=redefined-builtin
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@ -74,8 +73,7 @@ class Dependency(Generic[T]):
|
||||
# return different things based on self's type and avoid the need for
|
||||
# the fake dep classes below.
|
||||
# See https://github.com/python/mypy/issues/5320
|
||||
# noinspection PyShadowingBuiltins
|
||||
def __get__(self, obj: Any, type: Any = None) -> Any:
|
||||
def __get__(self, obj: Any, cls: Any = None) -> Any:
|
||||
if obj is None:
|
||||
raise TypeError("Dependency must be accessed through an instance.")
|
||||
|
||||
@ -114,15 +112,13 @@ else:
|
||||
class _InstanceDep(Dependency[TI]):
|
||||
"""Fake stub we use to tell the type system we provide a type."""
|
||||
|
||||
# noinspection PyShadowingBuiltins
|
||||
def __get__(self, obj: Any, type: Any = None) -> Type[TI]:
|
||||
def __get__(self, obj: Any, cls: Any = None) -> Type[TI]:
|
||||
return cast(Type[TI], None)
|
||||
|
||||
class _StaticDep(Dependency[TS]):
|
||||
"""Fake stub we use to tell the type system we provide an instance."""
|
||||
|
||||
# noinspection PyShadowingBuiltins
|
||||
def __get__(self, obj: Any, type: Any = None) -> TS:
|
||||
def __get__(self, obj: Any, cls: Any = None) -> TS:
|
||||
return cast(TS, None)
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
@ -169,7 +165,7 @@ class BoundDepComponent:
|
||||
|
||||
|
||||
class DepComponent:
|
||||
"""Base class for all classes that can act as dependencies.
|
||||
"""Base class for all classes that can act as or use dependencies.
|
||||
|
||||
category: Dependency Classes
|
||||
"""
|
||||
@ -373,7 +369,7 @@ class InstancedDepComponent(DepComponent):
|
||||
|
||||
|
||||
class StaticDepComponent(DepComponent):
|
||||
"""Base for DepComponents intended to be instanced once and shared."""
|
||||
"""Base for DepComponents intended to be instantiated once and shared."""
|
||||
|
||||
@classmethod
|
||||
def dep_get_payload(cls, depdata: DepData) -> Any:
|
||||
|
||||
@ -30,6 +30,7 @@ import _ba
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Type
|
||||
from bafoundation import executils
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
@ -121,7 +122,7 @@ def get_type_name(cls: Type) -> str:
|
||||
return cls.__module__ + '.' + cls.__name__
|
||||
|
||||
|
||||
class WeakCall:
|
||||
class _WeakCall:
|
||||
"""Wrap a callable and arguments into a single callable object.
|
||||
|
||||
Category: General Utility Classes
|
||||
@ -159,11 +160,12 @@ class WeakCall:
|
||||
Instantiate a WeakCall; pass a callable as the first
|
||||
arg, followed by any number of arguments or keywords.
|
||||
|
||||
# example: wrap a method call with some positional and keyword args:
|
||||
# example: wrap a method call with some positional and
|
||||
# keyword args:
|
||||
myweakcall = ba.WeakCall(myobj.dostuff, argval1, namedarg=argval2)
|
||||
|
||||
# Now we have a single callable to run that whole mess.
|
||||
# This is the same as calling myobj.dostuff(argval1, namedarg=argval2)
|
||||
# The same as calling myobj.dostuff(argval1, namedarg=argval2)
|
||||
# (provided my_obj still exists; this will do nothing otherwise)
|
||||
myweakcall()
|
||||
"""
|
||||
@ -191,16 +193,18 @@ class WeakCall:
|
||||
str(self._args) + ' _keywds=' + str(self._keywds) + '>')
|
||||
|
||||
|
||||
class Call:
|
||||
class _Call:
|
||||
"""Wraps a callable and arguments into a single callable object.
|
||||
|
||||
Category: General Utility Classes
|
||||
|
||||
The callable is strong-referenced so it won't die until this object does.
|
||||
The callable is strong-referenced so it won't die until this
|
||||
object does.
|
||||
|
||||
Note that a bound method (ex: myobj.dosomething) contains a reference
|
||||
to 'self' (myobj in that case), so you will be keeping that object alive
|
||||
too. Use ba.WeakCall if you want to pass a method to callback without
|
||||
keeping its object alive.
|
||||
to 'self' (myobj in that case), so you will be keeping that object
|
||||
alive too. Use ba.WeakCall if you want to pass a method to callback
|
||||
without keeping its object alive.
|
||||
"""
|
||||
|
||||
def __init__(self, *args: Any, **keywds: Any):
|
||||
@ -208,11 +212,11 @@ class Call:
|
||||
Instantiate a Call; pass a callable as the first
|
||||
arg, followed by any number of arguments or keywords.
|
||||
|
||||
# example: wrap a method call with 1 positional and 1 keyword arg
|
||||
# Example: wrap a method call with 1 positional and 1 keyword arg.
|
||||
mycall = ba.Call(myobj.dostuff, argval1, namedarg=argval2)
|
||||
|
||||
# now we have a single callable to run that whole mess
|
||||
# this is the same as calling myobj.dostuff(argval1, namedarg=argval2)
|
||||
# Now we have a single callable to run that whole mess.
|
||||
# ..the same as calling myobj.dostuff(argval1, namedarg=argval2)
|
||||
mycall()
|
||||
"""
|
||||
self._call = args[0]
|
||||
@ -227,6 +231,16 @@ class Call:
|
||||
str(self._args) + ' _keywds=' + str(self._keywds) + '>')
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
WeakCall = executils.Call
|
||||
Call = executils.Call
|
||||
else:
|
||||
WeakCall = _WeakCall
|
||||
WeakCall.__name__ = 'WeakCall'
|
||||
Call = _Call
|
||||
Call.__name__ = 'Call'
|
||||
|
||||
|
||||
class WeakMethod:
|
||||
"""A weak-referenced bound method.
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ from typing import TYPE_CHECKING
|
||||
import _ba
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Callable, Any, List, Optional, Dict
|
||||
from typing import Callable, Any, List, Optional, Dict, Union
|
||||
|
||||
|
||||
class MusicPlayer:
|
||||
@ -141,7 +141,9 @@ class InternalMusicPlayer(MusicPlayer):
|
||||
|
||||
class _PickFolderSongThread(threading.Thread):
|
||||
|
||||
def __init__(self, path: str, callback: Callable):
|
||||
def __init__(self, path: str,
|
||||
callback: Callable[[Union[str, List[str]], Optional[str]],
|
||||
None]):
|
||||
super().__init__()
|
||||
self._callback = callback
|
||||
self._path = path
|
||||
@ -166,7 +168,7 @@ class InternalMusicPlayer(MusicPlayer):
|
||||
raise Exception(
|
||||
_lang.Lstr(resource='internal.noMusicFilesInFolderText'
|
||||
).evaluate())
|
||||
_ba.pushcall(Call(self._callback, result=all_files),
|
||||
_ba.pushcall(Call(self._callback, all_files, None),
|
||||
from_other_thread=True)
|
||||
except Exception as exc:
|
||||
from ba import _error
|
||||
@ -175,9 +177,7 @@ class InternalMusicPlayer(MusicPlayer):
|
||||
err_str = str(exc)
|
||||
except Exception:
|
||||
err_str = '<ENCERR4523>'
|
||||
_ba.pushcall(Call(self._callback,
|
||||
result=self._path,
|
||||
error=err_str),
|
||||
_ba.pushcall(Call(self._callback, self._path, err_str),
|
||||
from_other_thread=True)
|
||||
|
||||
def on_play(self, entry: Any) -> None:
|
||||
@ -195,14 +195,19 @@ class InternalMusicPlayer(MusicPlayer):
|
||||
self._actually_playing = False
|
||||
self._PickFolderSongThread(name, self._on_play_folder_cb).start()
|
||||
|
||||
def _on_play_folder_cb(self, result: str,
|
||||
def _on_play_folder_cb(self,
|
||||
result: Union[str, List[str]],
|
||||
error: Optional[str] = None) -> None:
|
||||
from ba import _lang
|
||||
if error is not None:
|
||||
rstr = (_lang.Lstr(
|
||||
resource='internal.errorPlayingMusicText').evaluate())
|
||||
err_str = (rstr.replace('${MUSIC}', os.path.basename(result)) +
|
||||
'; ' + str(error))
|
||||
if isinstance(result, str):
|
||||
err_str = (rstr.replace('${MUSIC}', os.path.basename(result)) +
|
||||
'; ' + str(error))
|
||||
else:
|
||||
err_str = (rstr.replace('${MUSIC}', '<multiple>') + '; ' +
|
||||
str(error))
|
||||
_ba.screenmessage(err_str, color=(1, 0, 0))
|
||||
return
|
||||
|
||||
@ -332,7 +337,8 @@ class ITunesThread(threading.Thread):
|
||||
self._commands.append(['GET_PLAYLISTS', callback])
|
||||
self._commands_available.set()
|
||||
|
||||
def _handle_get_playlists_command(self, target: str) -> None:
|
||||
def _handle_get_playlists_command(self, target: Callable[[List[str]], None]
|
||||
) -> None:
|
||||
from ba._general import Call
|
||||
try:
|
||||
playlists = _ba.itunes_get_playlists()
|
||||
|
||||
@ -32,7 +32,7 @@ import _ba
|
||||
if TYPE_CHECKING:
|
||||
import ba
|
||||
from weakref import ReferenceType
|
||||
from typing import Any, Dict, Optional, Sequence, Union
|
||||
from typing import Any, Dict, Optional, Sequence, Union, Tuple
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -210,9 +210,9 @@ class PlayerRecord:
|
||||
delay = 1000
|
||||
sound = stats.orchestrahitsound4
|
||||
|
||||
def _apply(name2: str, score2: int, showpoints2: bool,
|
||||
color2: Sequence[float], scale2: float,
|
||||
sound2: ba.Sound) -> None:
|
||||
def _apply(name2: Lstr, score2: int, showpoints2: bool,
|
||||
color2: Tuple[float, float, float, float], scale2: float,
|
||||
sound2: Optional[ba.Sound]) -> None:
|
||||
from bastd.actor.popuptext import PopupText
|
||||
|
||||
# Only award this if they're still alive and we can get
|
||||
@ -238,7 +238,8 @@ class PlayerRecord:
|
||||
color=color2,
|
||||
scale=scale2,
|
||||
position=our_pos).autoretain()
|
||||
_ba.playsound(sound2)
|
||||
if sound2:
|
||||
_ba.playsound(sound2)
|
||||
|
||||
self.score += score2
|
||||
self.accumscore += score2
|
||||
|
||||
@ -45,7 +45,7 @@ from ba._achievement import (get_achievement, set_completed_achievements,
|
||||
display_achievement_banner,
|
||||
get_achievements_for_coop_level)
|
||||
from ba._apputils import (is_browser_likely_available, get_remote_app_name,
|
||||
should_submit_debug_info, show_ad)
|
||||
should_submit_debug_info, show_ad, show_ad_2)
|
||||
from ba._benchmark import (run_gpu_benchmark, run_cpu_benchmark,
|
||||
run_media_reload_benchmark, run_stress_test)
|
||||
from ba._campaign import get_campaign
|
||||
|
||||
@ -25,20 +25,20 @@ from __future__ import annotations
|
||||
from typing import TYPE_CHECKING, TypeVar, Generic, Callable, cast
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
from typing import Any, overload
|
||||
|
||||
T = TypeVar('T', bound=Callable)
|
||||
CT = TypeVar('CT', bound=Callable)
|
||||
|
||||
|
||||
class _CallbackCall(Generic[T]):
|
||||
class _CallbackCall(Generic[CT]):
|
||||
"""Descriptor for exposing a call with a type defined by a TypeVar."""
|
||||
|
||||
def __get__(self, obj: Any, type_in: Any = None) -> T:
|
||||
return cast(T, None)
|
||||
def __get__(self, obj: Any, type_in: Any = None) -> CT:
|
||||
return cast(CT, None)
|
||||
|
||||
|
||||
class CallbackSet(Generic[T]):
|
||||
"""Wrangles callbacks for a particular event."""
|
||||
class CallbackSet(Generic[CT]):
|
||||
"""Wrangles callbacks for a particular event in a type-safe manner."""
|
||||
|
||||
# In the type-checker's eyes, our 'run' attr is a CallbackCall which
|
||||
# returns a callable with the type we were created with. This lets us
|
||||
@ -47,7 +47,7 @@ class CallbackSet(Generic[T]):
|
||||
# At runtime, run() simply passes its args verbatim to its registered
|
||||
# callbacks; no types are checked.
|
||||
if TYPE_CHECKING:
|
||||
run: _CallbackCall[T] = _CallbackCall()
|
||||
run: _CallbackCall[CT] = _CallbackCall()
|
||||
else:
|
||||
|
||||
def run(self, *args, **keywds):
|
||||
@ -60,6 +60,221 @@ class CallbackSet(Generic[T]):
|
||||
def __del__(self) -> None:
|
||||
print("~CallbackSet()")
|
||||
|
||||
def add(self, call: T) -> None:
|
||||
def add(self, call: CT) -> None:
|
||||
"""Add a callback to be run."""
|
||||
print("Would add call", call)
|
||||
|
||||
|
||||
# Define Call() which can be used in type-checking call-wrappers that behave
|
||||
# similarly to functools.partial (in that they take a callable and some
|
||||
# positional arguments to be passed to it)
|
||||
|
||||
# We define several different _CallXArg classes corresponding to different
|
||||
# argument counts and define Call() as an overloaded function which returns
|
||||
# one of them based on how many args are passed.
|
||||
|
||||
# To use this, simply assign your call type to this Call for type checking:
|
||||
# example:
|
||||
# class _MyCallWrapper:
|
||||
# <runtime class defined here>
|
||||
# if TYPE_CHECKING:
|
||||
# MyCallWrapper = bafoundation.executils.Call
|
||||
# else:
|
||||
# MyCallWrapper = _MyCallWrapper
|
||||
|
||||
# Note that this setup currently only works with positional arguments; if you
|
||||
# would like to pass args via keyword you can wrap a lambda or local function
|
||||
# which takes keyword args and converts to a call containing keywords.
|
||||
|
||||
if TYPE_CHECKING:
|
||||
In1T = TypeVar('In1T')
|
||||
In2T = TypeVar('In2T')
|
||||
In3T = TypeVar('In3T')
|
||||
In4T = TypeVar('In4T')
|
||||
In5T = TypeVar('In5T')
|
||||
In6T = TypeVar('In6T')
|
||||
In7T = TypeVar('In7T')
|
||||
OutT = TypeVar('OutT')
|
||||
|
||||
class _CallNoArgs(Generic[OutT]):
|
||||
"""Single argument variant of call wrapper."""
|
||||
|
||||
def __init__(self, _call: Callable[[], OutT]):
|
||||
...
|
||||
|
||||
def __call__(self) -> OutT:
|
||||
...
|
||||
|
||||
class _Call1Arg(Generic[In1T, OutT]):
|
||||
"""Single argument variant of call wrapper."""
|
||||
|
||||
def __init__(self, _call: Callable[[In1T], OutT]):
|
||||
...
|
||||
|
||||
def __call__(self, _arg1: In1T) -> OutT:
|
||||
...
|
||||
|
||||
class _Call2Args(Generic[In1T, In2T, OutT]):
|
||||
"""Two argument variant of call wrapper"""
|
||||
|
||||
def __init__(self, _call: Callable[[In1T, In2T], OutT]):
|
||||
...
|
||||
|
||||
def __call__(self, _arg1: In1T, _arg2: In2T) -> OutT:
|
||||
...
|
||||
|
||||
class _Call3Args(Generic[In1T, In2T, In3T, OutT]):
|
||||
"""Three argument variant of call wrapper"""
|
||||
|
||||
def __init__(self, _call: Callable[[In1T, In2T, In3T], OutT]):
|
||||
...
|
||||
|
||||
def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T) -> OutT:
|
||||
...
|
||||
|
||||
class _Call4Args(Generic[In1T, In2T, In3T, In4T, OutT]):
|
||||
"""Four argument variant of call wrapper"""
|
||||
|
||||
def __init__(self, _call: Callable[[In1T, In2T, In3T, In4T], OutT]):
|
||||
...
|
||||
|
||||
def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T,
|
||||
_arg4: In4T) -> OutT:
|
||||
...
|
||||
|
||||
class _Call5Args(Generic[In1T, In2T, In3T, In4T, In5T, OutT]):
|
||||
"""Five argument variant of call wrapper"""
|
||||
|
||||
def __init__(self,
|
||||
_call: Callable[[In1T, In2T, In3T, In4T, In5T], OutT]):
|
||||
...
|
||||
|
||||
def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T, _arg4: In4T,
|
||||
_arg5: In5T) -> OutT:
|
||||
...
|
||||
|
||||
class _Call6Args(Generic[In1T, In2T, In3T, In4T, In5T, In6T, OutT]):
|
||||
"""Six argument variant of call wrapper"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
_call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T], OutT]):
|
||||
...
|
||||
|
||||
def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T, _arg4: In4T,
|
||||
_arg5: In5T, _arg6: In6T) -> OutT:
|
||||
...
|
||||
|
||||
class _Call7Args(Generic[In1T, In2T, In3T, In4T, In5T, In6T, In7T, OutT]):
|
||||
"""Seven argument variant of call wrapper"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
_call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T, In7T],
|
||||
OutT]):
|
||||
...
|
||||
|
||||
def __call__(self, _arg1: In1T, _arg2: In2T, _arg3: In3T, _arg4: In4T,
|
||||
_arg5: In5T, _arg6: In6T, _arg7: In7T) -> OutT:
|
||||
...
|
||||
|
||||
# No arg call; no args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[], OutT]) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# 1 arg call; 1 arg bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T], OutT], arg1: In1T) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# 1 arg call; no args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T], OutT]) -> _Call1Arg[In1T, OutT]:
|
||||
...
|
||||
|
||||
# 2 arg call; 2 args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T], OutT], arg1: In1T,
|
||||
arg2: In2T) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# 2 arg call; 1 arg bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T], OutT],
|
||||
arg1: In1T) -> _Call1Arg[In2T, OutT]:
|
||||
...
|
||||
|
||||
# 2 arg call; no args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T], OutT]) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# 3 arg call; 3 args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T, In3T], OutT], arg1: In1T, arg2: In2T,
|
||||
arg3: In3T) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# 3 arg call; 2 args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T, In3T], OutT], arg1: In1T,
|
||||
arg2: In2T) -> _Call1Arg[In3T, OutT]:
|
||||
...
|
||||
|
||||
# 3 arg call; 1 arg bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T, In3T], OutT],
|
||||
arg1: In1T) -> _Call2Args[In2T, In3T, OutT]:
|
||||
...
|
||||
|
||||
# 3 arg call; no args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T, In3T], OutT]
|
||||
) -> _Call3Args[In1T, In2T, In3T, OutT]:
|
||||
...
|
||||
|
||||
# 4 arg call; 4 args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T, In3T, In4T], OutT], arg1: In1T,
|
||||
arg2: In2T, arg3: In3T, arg4: In4T) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# 5 arg call; 5 args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T, In3T, In4T, In5T], OutT], arg1: In1T,
|
||||
arg2: In2T, arg3: In3T, arg4: In4T,
|
||||
arg5: In5T) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# 6 arg call; 6 args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T], OutT],
|
||||
arg1: In1T, arg2: In2T, arg3: In3T, arg4: In4T, arg5: In5T,
|
||||
arg6: In6T) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# 7 arg call; 7 args bundled.
|
||||
# noinspection PyPep8Naming
|
||||
@overload
|
||||
def Call(call: Callable[[In1T, In2T, In3T, In4T, In5T, In6T, In7T], OutT],
|
||||
arg1: In1T, arg2: In2T, arg3: In3T, arg4: In4T, arg5: In5T,
|
||||
arg6: In6T, arg7: In7T) -> _CallNoArgs[OutT]:
|
||||
...
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
def Call(*_args: Any, **_keywds: Any) -> Any:
|
||||
...
|
||||
|
||||
@ -920,7 +920,7 @@ class BotSet:
|
||||
self._spawning_count += 1
|
||||
|
||||
def _spawn_bot(self, bot_type: Type[SpazBot], pos: Sequence[float],
|
||||
on_spawn_call: Callable[[SpazBot], Any]) -> None:
|
||||
on_spawn_call: Optional[Callable[[SpazBot], Any]]) -> None:
|
||||
spaz = bot_type()
|
||||
ba.playsound(self._spawn_sound, position=pos)
|
||||
assert spaz.node
|
||||
|
||||
@ -118,9 +118,10 @@ class KingOfTheHillGame(ba.TeamGameActivity):
|
||||
actions=(("modify_part_collision", "collide",
|
||||
True), ("modify_part_collision", "physical", False),
|
||||
("call", "at_connect",
|
||||
ba.Call(self._handle_player_flag_region_collide, 1)),
|
||||
ba.Call(self._handle_player_flag_region_collide, True)),
|
||||
("call", "at_disconnect",
|
||||
ba.Call(self._handle_player_flag_region_collide, 0))))
|
||||
ba.Call(self._handle_player_flag_region_collide,
|
||||
False))))
|
||||
|
||||
def get_instance_description(self) -> Union[str, Sequence]:
|
||||
return ('Secure the flag for ${ARG1} seconds.',
|
||||
|
||||
@ -104,46 +104,28 @@ class NinjaFightGame(ba.TeamGameActivity):
|
||||
|
||||
# Spawn some baddies.
|
||||
ba.timer(
|
||||
1.0,
|
||||
ba.Call(self._bots.spawn_bot,
|
||||
spazbot.ChargerBot,
|
||||
pos=(3, 3, -2),
|
||||
spawn_time=3.0))
|
||||
1.0, lambda: self._bots.spawn_bot(
|
||||
spazbot.ChargerBot, pos=(3, 3, -2), spawn_time=3.0))
|
||||
ba.timer(
|
||||
2.0,
|
||||
ba.Call(self._bots.spawn_bot,
|
||||
spazbot.ChargerBot,
|
||||
pos=(-3, 3, -2),
|
||||
spawn_time=3.0))
|
||||
2.0, lambda: self._bots.spawn_bot(
|
||||
spazbot.ChargerBot, pos=(-3, 3, -2), spawn_time=3.0))
|
||||
ba.timer(
|
||||
3.0,
|
||||
ba.Call(self._bots.spawn_bot,
|
||||
spazbot.ChargerBot,
|
||||
pos=(5, 3, -2),
|
||||
spawn_time=3.0))
|
||||
3.0, lambda: self._bots.spawn_bot(
|
||||
spazbot.ChargerBot, pos=(5, 3, -2), spawn_time=3.0))
|
||||
ba.timer(
|
||||
4.0,
|
||||
ba.Call(self._bots.spawn_bot,
|
||||
spazbot.ChargerBot,
|
||||
pos=(-5, 3, -2),
|
||||
spawn_time=3.0))
|
||||
4.0, lambda: self._bots.spawn_bot(
|
||||
spazbot.ChargerBot, pos=(-5, 3, -2), spawn_time=3.0))
|
||||
|
||||
# Add some extras for multiplayer or pro mode.
|
||||
assert self.initial_player_info is not None
|
||||
if len(self.initial_player_info) > 2 or is_pro:
|
||||
ba.timer(
|
||||
5.0,
|
||||
ba.Call(self._bots.spawn_bot,
|
||||
spazbot.ChargerBot,
|
||||
pos=(0, 3, -5),
|
||||
spawn_time=3.0))
|
||||
5.0, lambda: self._bots.spawn_bot(
|
||||
spazbot.ChargerBot, pos=(0, 3, -5), spawn_time=3.0))
|
||||
if len(self.initial_player_info) > 3 or is_pro:
|
||||
ba.timer(
|
||||
6.0,
|
||||
ba.Call(self._bots.spawn_bot,
|
||||
spazbot.ChargerBot,
|
||||
pos=(0, 3, 1),
|
||||
spawn_time=3.0))
|
||||
6.0, lambda: self._bots.spawn_bot(
|
||||
spazbot.ChargerBot, pos=(0, 3, 1), spawn_time=3.0))
|
||||
|
||||
# Called for each spawning player.
|
||||
def spawn_player(self, player: ba.Player) -> ba.Actor:
|
||||
|
||||
@ -152,7 +152,7 @@ class TheLastStandGame(ba.CoopGameActivity):
|
||||
|
||||
def _drop_powerups(self,
|
||||
standard_points: bool = False,
|
||||
force_first: bool = None) -> None:
|
||||
force_first: str = None) -> None:
|
||||
"""Generic powerup drop."""
|
||||
from bastd.actor import powerupbox
|
||||
if standard_points:
|
||||
|
||||
@ -40,9 +40,8 @@ def show_sign_in_prompt(account_type: str = None) -> None:
|
||||
else:
|
||||
confirm.ConfirmWindow(
|
||||
ba.Lstr(resource='notSignedInErrorText'),
|
||||
ba.Call(settings.AccountSettingsWindow,
|
||||
modal=True,
|
||||
close_once_signed_in=True),
|
||||
lambda: settings.AccountSettingsWindow(modal=True,
|
||||
close_once_signed_in=True),
|
||||
ok_text=ba.Lstr(resource='accountSettingsWindow.signInText'),
|
||||
width=460,
|
||||
height=130)
|
||||
|
||||
@ -774,11 +774,11 @@ class AccountSettingsWindow(ba.OldWindow):
|
||||
autoselect=True,
|
||||
size=(button_width, 60),
|
||||
label=ba.Lstr(resource=self._r + '.resetProgressText'),
|
||||
on_activate_call=ba.Call(confirm.ConfirmWindow,
|
||||
text=confirm_text,
|
||||
width=500,
|
||||
height=200,
|
||||
action=self._reset_progress))
|
||||
on_activate_call=lambda: confirm.ConfirmWindow(
|
||||
text=confirm_text,
|
||||
width=500,
|
||||
height=200,
|
||||
action=self._reset_progress))
|
||||
if first_selectable is None:
|
||||
first_selectable = btn
|
||||
if ba.app.toolbars:
|
||||
|
||||
@ -147,7 +147,8 @@ class QuitWindow:
|
||||
origin_widget: ba.Widget = None):
|
||||
app = ba.app
|
||||
self._back = back
|
||||
# if there's already one of us up somewhere, kill it
|
||||
|
||||
# If there's already one of us up somewhere, kill it.
|
||||
if app.quit_window is not None:
|
||||
app.quit_window.delete()
|
||||
app.quit_window = None
|
||||
@ -164,9 +165,10 @@ class QuitWindow:
|
||||
def _fade_and_quit(self) -> None:
|
||||
_ba.fade_screen(False,
|
||||
time=0.2,
|
||||
endcall=ba.Call(ba.quit, soft=True, back=self._back))
|
||||
endcall=lambda: ba.quit(soft=True, back=self._back))
|
||||
_ba.lock_all_input()
|
||||
# unlock and fade back in shortly.. just in case something goes wrong
|
||||
|
||||
# Unlock and fade back in shortly.. just in case something goes wrong
|
||||
# (or on android where quit just backs out of our activity and
|
||||
# we may come back)
|
||||
ba.timer(0.3, _ba.unlock_all_input, timetype=ba.TimeType.REAL)
|
||||
|
||||
@ -797,15 +797,15 @@ class CoopBrowserWindow(ba.OldWindow):
|
||||
row_v_show_buffer = 100
|
||||
v -= 198
|
||||
|
||||
h_scroll = ba.hscrollwidget(parent=w_parent,
|
||||
size=(self._scroll_width - 10, 205),
|
||||
position=(-5, v),
|
||||
simple_culling_h=70,
|
||||
highlight=False,
|
||||
border_opacity=0.0,
|
||||
color=(0.45, 0.4, 0.5),
|
||||
on_select_call=ba.Call(
|
||||
self._on_row_selected, 'campaign'))
|
||||
h_scroll = ba.hscrollwidget(
|
||||
parent=w_parent,
|
||||
size=(self._scroll_width - 10, 205),
|
||||
position=(-5, v),
|
||||
simple_culling_h=70,
|
||||
highlight=False,
|
||||
border_opacity=0.0,
|
||||
color=(0.45, 0.4, 0.5),
|
||||
on_select_call=lambda: self._on_row_selected('campaign'))
|
||||
self._campaign_h_scroll = h_scroll
|
||||
ba.widget(edit=h_scroll,
|
||||
show_buffer_top=row_v_show_buffer,
|
||||
@ -1021,7 +1021,7 @@ class CoopBrowserWindow(ba.OldWindow):
|
||||
# event queue.. we need to push ours too so we're enabled *after* them.
|
||||
ba.pushcall(self._enable_selectable_callback)
|
||||
|
||||
def _on_row_selected(self, row: int) -> None:
|
||||
def _on_row_selected(self, row: str) -> None:
|
||||
if self._do_selection_callbacks:
|
||||
if self._selected_row != row:
|
||||
self._selected_row = row
|
||||
@ -1039,16 +1039,14 @@ class CoopBrowserWindow(ba.OldWindow):
|
||||
'has_time_remaining': False,
|
||||
'leader': None
|
||||
}
|
||||
data['button'] = btn = ba.buttonwidget(parent=parent,
|
||||
position=(x + 23, y + 4),
|
||||
size=(sclx, scly),
|
||||
label='',
|
||||
button_type='square',
|
||||
autoselect=True,
|
||||
on_activate_call=ba.Call(
|
||||
self.run,
|
||||
None,
|
||||
tournament_button=data))
|
||||
data['button'] = btn = ba.buttonwidget(
|
||||
parent=parent,
|
||||
position=(x + 23, y + 4),
|
||||
size=(sclx, scly),
|
||||
label='',
|
||||
button_type='square',
|
||||
autoselect=True,
|
||||
on_activate_call=lambda: self.run(None, tournament_button=data))
|
||||
ba.widget(edit=btn,
|
||||
show_buffer_bottom=50,
|
||||
show_buffer_top=50,
|
||||
@ -1353,7 +1351,7 @@ class CoopBrowserWindow(ba.OldWindow):
|
||||
origin_widget=self._league_rank_button.get_button()).
|
||||
get_root_widget())
|
||||
|
||||
def _switch_to_score(self, show_tab: str = 'extras') -> None:
|
||||
def _switch_to_score(self, show_tab: Optional[str] = 'extras') -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from bastd.ui import account
|
||||
from bastd.ui.store import browser
|
||||
@ -1403,7 +1401,9 @@ class CoopBrowserWindow(ba.OldWindow):
|
||||
"""Return whether our tourney data is up to date."""
|
||||
return self._tourney_data_up_to_date
|
||||
|
||||
def run(self, game: str, tournament_button: Dict[str, Any] = None) -> None:
|
||||
def run(self,
|
||||
game: Optional[str],
|
||||
tournament_button: Dict[str, Any] = None) -> None:
|
||||
"""Run the provided game."""
|
||||
# pylint: disable=too-many-branches
|
||||
# pylint: disable=too-many-statements
|
||||
@ -1515,6 +1515,7 @@ class CoopBrowserWindow(ba.OldWindow):
|
||||
position=tournament_button['button'].get_screen_space_center())
|
||||
else:
|
||||
# Otherwise just dive right in.
|
||||
assert game is not None
|
||||
if ba.app.launch_coop_game(game, args=args):
|
||||
ba.containerwidget(edit=self._root_widget,
|
||||
transition='out_left')
|
||||
|
||||
@ -108,7 +108,7 @@ class FileSelectorWindow(ba.OldWindow):
|
||||
self._folder_color = (1.1, 0.8, 0.2)
|
||||
self._file_tex = ba.gettexture('file')
|
||||
self._file_color = (1, 1, 1)
|
||||
self._use_folder_button = None
|
||||
self._use_folder_button: Optional[ba.Widget] = None
|
||||
self._folder_center = self._width * 0.5 + 15
|
||||
self._folder_icon = ba.imagewidget(parent=self._root_widget,
|
||||
size=(40, 40),
|
||||
@ -189,7 +189,7 @@ class FileSelectorWindow(ba.OldWindow):
|
||||
class _RefreshThread(threading.Thread):
|
||||
|
||||
def __init__(self, path: str,
|
||||
callback: Callable[[List[str], str], Any]):
|
||||
callback: Callable[[List[str], Optional[str]], Any]):
|
||||
super().__init__()
|
||||
self._callback = callback
|
||||
self._path = path
|
||||
@ -200,17 +200,19 @@ class FileSelectorWindow(ba.OldWindow):
|
||||
files = os.listdir(self._path)
|
||||
duration = time.time() - starttime
|
||||
min_time = 0.1
|
||||
# make sure this takes at least 1/10 second so the user
|
||||
# has time to see the selection highlight
|
||||
|
||||
# Make sure this takes at least 1/10 second so the user
|
||||
# has time to see the selection highlight.
|
||||
if duration < min_time:
|
||||
time.sleep(min_time - duration)
|
||||
ba.pushcall(ba.Call(self._callback, file_names=files),
|
||||
ba.pushcall(ba.Call(self._callback, files, None),
|
||||
from_other_thread=True)
|
||||
except Exception as exc:
|
||||
# ignore permission-denied
|
||||
# Ignore permission-denied.
|
||||
if 'Errno 13' not in str(exc):
|
||||
ba.print_exception()
|
||||
ba.pushcall(ba.Call(self._callback, error=str(exc)),
|
||||
nofiles: List[str] = []
|
||||
ba.pushcall(ba.Call(self._callback, nofiles, str(exc)),
|
||||
from_other_thread=True)
|
||||
|
||||
def _set_path(self, path: str, add_to_recent: bool = True) -> None:
|
||||
@ -219,7 +221,7 @@ class FileSelectorWindow(ba.OldWindow):
|
||||
self._recent_paths.append(path)
|
||||
self._RefreshThread(path, self._refresh).start()
|
||||
|
||||
def _refresh(self, file_names: List[str], error: str) -> None:
|
||||
def _refresh(self, file_names: List[str], error: Optional[str]) -> None:
|
||||
# pylint: disable=too-many-statements
|
||||
# pylint: disable=too-many-branches
|
||||
# pylint: disable=too-many-locals
|
||||
@ -357,6 +359,7 @@ class FileSelectorWindow(ba.OldWindow):
|
||||
if num == 0:
|
||||
ba.widget(edit=cnt, up_widget=self._back_button)
|
||||
is_valid_file_path = self._is_valid_file_path(entry)
|
||||
assert self._path is not None
|
||||
is_dir = os.path.isdir(self._path + '/' + entry)
|
||||
if is_dir:
|
||||
ba.imagewidget(parent=cnt,
|
||||
|
||||
@ -218,17 +218,15 @@ class GatherWindow(ba.OldWindow):
|
||||
# that they will get disconnected.. otherwise just go ahead..
|
||||
google_player_count = (_ba.get_google_play_party_client_count())
|
||||
if google_player_count > 0:
|
||||
confirm.ConfirmWindow(ba.Lstr(
|
||||
resource=self._r + '.googlePlayReInviteText',
|
||||
subs=[('${COUNT}', str(google_player_count))]),
|
||||
ba.Call(ba.timer,
|
||||
0.2,
|
||||
_ba.invite_players,
|
||||
timetype='real'),
|
||||
width=500,
|
||||
height=150,
|
||||
ok_text=ba.Lstr(resource=self._r +
|
||||
'.googlePlayInviteText'))
|
||||
confirm.ConfirmWindow(
|
||||
ba.Lstr(resource=self._r + '.googlePlayReInviteText',
|
||||
subs=[('${COUNT}', str(google_player_count))]),
|
||||
lambda: ba.timer(
|
||||
0.2, _ba.invite_players, timetype=ba.TimeType.REAL),
|
||||
width=500,
|
||||
height=150,
|
||||
ok_text=ba.Lstr(resource=self._r +
|
||||
'.googlePlayInviteText'))
|
||||
else:
|
||||
ba.timer(0.1, _ba.invite_players, timetype=ba.TimeType.REAL)
|
||||
|
||||
@ -411,19 +409,19 @@ class GatherWindow(ba.OldWindow):
|
||||
h_align='center',
|
||||
v_align='center')
|
||||
v -= 180
|
||||
ba.buttonwidget(parent=cnt,
|
||||
label=ba.Lstr(resource=self._r +
|
||||
'.googlePlaySeeInvitesText'),
|
||||
color=(0.5, 0.5, 0.6),
|
||||
textcolor=(0.75, 0.7, 0.8),
|
||||
autoselect=True,
|
||||
position=(c_width * 0.5 - b_width2 * 0.5, v),
|
||||
size=(b_width2, 60),
|
||||
on_activate_call=ba.Call(
|
||||
ba.timer,
|
||||
0.1,
|
||||
self._on_google_play_show_invites_press,
|
||||
timetype='real'))
|
||||
ba.buttonwidget(
|
||||
parent=cnt,
|
||||
label=ba.Lstr(resource=self._r + '.googlePlaySeeInvitesText'),
|
||||
color=(0.5, 0.5, 0.6),
|
||||
textcolor=(0.75, 0.7, 0.8),
|
||||
autoselect=True,
|
||||
position=(c_width * 0.5 - b_width2 * 0.5, v),
|
||||
size=(b_width2, 60),
|
||||
on_activate_call=lambda: ba.timer(
|
||||
0.1,
|
||||
self._on_google_play_show_invites_press,
|
||||
timetype=ba.TimeType.REAL),
|
||||
)
|
||||
|
||||
elif tab == 'internet':
|
||||
c_width = self._scroll_width
|
||||
@ -448,9 +446,8 @@ class GatherWindow(ba.OldWindow):
|
||||
click_activate=True,
|
||||
selectable=True,
|
||||
autoselect=True,
|
||||
on_activate_call=ba.Call(self._set_internet_tab,
|
||||
'join',
|
||||
playsound=True),
|
||||
on_activate_call=lambda: self._set_internet_tab(
|
||||
'join', playsound=True),
|
||||
text=ba.Lstr(resource=self._r +
|
||||
'.joinPublicPartyDescriptionText'))
|
||||
ba.widget(edit=txt, up_widget=self._tab_buttons[tab])
|
||||
@ -466,9 +463,8 @@ class GatherWindow(ba.OldWindow):
|
||||
click_activate=True,
|
||||
selectable=True,
|
||||
autoselect=True,
|
||||
on_activate_call=ba.Call(self._set_internet_tab,
|
||||
'host',
|
||||
playsound=True),
|
||||
on_activate_call=lambda: self._set_internet_tab(
|
||||
'host', playsound=True),
|
||||
text=ba.Lstr(resource=self._r +
|
||||
'.hostPublicPartyDescriptionText'))
|
||||
ba.widget(edit=txt,
|
||||
@ -824,7 +820,8 @@ class GatherWindow(ba.OldWindow):
|
||||
class HostAddrFetchThread(threading.Thread):
|
||||
"""Thread to fetch an addr."""
|
||||
|
||||
def __init__(self, name: str, call: Callable[[str], Any]):
|
||||
def __init__(self, name: str,
|
||||
call: Callable[[Optional[str]], Any]):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._call = call
|
||||
@ -839,7 +836,7 @@ class GatherWindow(ba.OldWindow):
|
||||
ba.pushcall(ba.Call(self._call, None),
|
||||
from_other_thread=True)
|
||||
|
||||
def do_it_2(addr2: str) -> None:
|
||||
def do_it_2(addr2: Optional[str]) -> None:
|
||||
if addr2 is None:
|
||||
ba.screenmessage(ba.Lstr(
|
||||
resource='internal.unableToResolveHostText'),
|
||||
@ -1681,10 +1678,9 @@ class GatherWindow(ba.OldWindow):
|
||||
class PingThread(threading.Thread):
|
||||
"""Thread for sending out pings."""
|
||||
|
||||
def __init__(
|
||||
self, address: str, port: int,
|
||||
call: Callable[[str, int, Optional[int]], Any]
|
||||
):
|
||||
def __init__(self, address: str, port: int,
|
||||
call: Callable[[str, int, Optional[int]],
|
||||
Optional[int]]):
|
||||
super().__init__()
|
||||
# need utf8 here to avoid an error on our minimum
|
||||
# bundled python
|
||||
@ -1743,7 +1739,8 @@ class GatherWindow(ba.OldWindow):
|
||||
PingThread(party['address'], party['port'],
|
||||
ba.WeakCall(self._ping_callback)).start()
|
||||
|
||||
def _ping_callback(self, address: str, port: int, result: int) -> None:
|
||||
def _ping_callback(self, address: str, port: Optional[int],
|
||||
result: Optional[int]) -> None:
|
||||
# Look for a widget corresponding to this target; if we find one,
|
||||
# update our list.
|
||||
party = self._public_parties.get(address + '_' + str(port))
|
||||
|
||||
@ -609,7 +609,7 @@ def show_get_tickets_prompt() -> None:
|
||||
confirm.ConfirmWindow(
|
||||
ba.Lstr(translate=('serverResponses',
|
||||
'You don\'t have enough tickets for this!')),
|
||||
ba.Call(GetCurrencyWindow, modal=True),
|
||||
lambda: GetCurrencyWindow(modal=True),
|
||||
ok_text=ba.Lstr(resource='getTicketsWindow.titleText'),
|
||||
width=460,
|
||||
height=130)
|
||||
|
||||
@ -39,12 +39,16 @@ class KioskWindow(ba.OldWindow):
|
||||
from bastd.ui import confirm
|
||||
self._width = 720.0
|
||||
self._height = 340.0
|
||||
super().__init__(root_widget=ba.containerwidget(
|
||||
size=(self._width, self._height),
|
||||
transition=transition,
|
||||
on_cancel_call=ba.Call(confirm.QuitWindow, swish=True, back=True),
|
||||
background=False,
|
||||
stack_offset=(0, -130)))
|
||||
|
||||
def _do_cancel() -> None:
|
||||
confirm.QuitWindow(swish=True, back=True)
|
||||
|
||||
super().__init__(
|
||||
root_widget=ba.containerwidget(size=(self._width, self._height),
|
||||
transition=transition,
|
||||
on_cancel_call=_do_cancel,
|
||||
background=False,
|
||||
stack_offset=(0, -130)))
|
||||
|
||||
self._r = 'kioskWindow'
|
||||
|
||||
|
||||
@ -207,7 +207,9 @@ class LeagueRankButton:
|
||||
if widget:
|
||||
widget.delete()
|
||||
|
||||
ba.timer(2.0, ba.Call(safe_delete, diff_text, timetype='real'))
|
||||
ba.timer(2.0,
|
||||
ba.Call(safe_delete, diff_text),
|
||||
timetype=ba.TimeType.REAL)
|
||||
status_text: Union[str, ba.Lstr]
|
||||
if self._rank is not None:
|
||||
assert self._smooth_rank is not None
|
||||
|
||||
@ -320,10 +320,12 @@ class MainMenuWindow(ba.OldWindow):
|
||||
# we want back presses to quit our activity.
|
||||
if (not self._in_game and not self._have_quit_button
|
||||
and ba.app.platform == 'android'):
|
||||
|
||||
def _do_quit() -> None:
|
||||
confirm.QuitWindow(swish=True, back=True)
|
||||
|
||||
ba.containerwidget(edit=self._root_widget,
|
||||
on_cancel_call=ba.Call(confirm.QuitWindow,
|
||||
swish=True,
|
||||
back=True))
|
||||
on_cancel_call=_do_quit)
|
||||
|
||||
# Add speed-up/slow-down buttons for replays.
|
||||
# (ideally this should be part of a fading-out playback bar like most
|
||||
|
||||
@ -123,7 +123,7 @@ class PartyQueueWindow(ba.OldWindow):
|
||||
# need to push a deferred call to kill these as necessary instead.
|
||||
# (should bulletproof internal widget code to give a clean error
|
||||
# in this case)
|
||||
def kill_widgets(widgets: Sequence[ba.Widget]) -> None:
|
||||
def kill_widgets(widgets: Sequence[Optional[ba.Widget]]) -> None:
|
||||
for widget in widgets:
|
||||
if widget:
|
||||
widget.delete()
|
||||
|
||||
@ -152,22 +152,26 @@ class PlaylistAddGameWindow(ba.OldWindow):
|
||||
gametypes.sort(key=lambda g: g.get_display_string().evaluate())
|
||||
|
||||
for i, gametype in enumerate(gametypes):
|
||||
txt = ba.textwidget(
|
||||
parent=self._column,
|
||||
position=(0, 0),
|
||||
size=(self._width - 88, 24),
|
||||
text=gametype.get_display_string(),
|
||||
h_align="left",
|
||||
v_align="center",
|
||||
color=(0.8, 0.8, 0.8, 1.0),
|
||||
maxwidth=self._scroll_width * 0.8,
|
||||
on_select_call=ba.Call(self._set_selected_game_type, gametype),
|
||||
always_highlight=True,
|
||||
selectable=True,
|
||||
on_activate_call=ba.Call(ba.timer,
|
||||
0.1,
|
||||
self._select_button.activate,
|
||||
timetype='real'))
|
||||
|
||||
def _doit() -> None:
|
||||
if self._select_button:
|
||||
ba.timer(0.1,
|
||||
self._select_button.activate,
|
||||
timetype=ba.TimeType.REAL)
|
||||
|
||||
txt = ba.textwidget(parent=self._column,
|
||||
position=(0, 0),
|
||||
size=(self._width - 88, 24),
|
||||
text=gametype.get_display_string(),
|
||||
h_align="left",
|
||||
v_align="center",
|
||||
color=(0.8, 0.8, 0.8, 1.0),
|
||||
maxwidth=self._scroll_width * 0.8,
|
||||
on_select_call=ba.Call(
|
||||
self._set_selected_game_type, gametype),
|
||||
always_highlight=True,
|
||||
selectable=True,
|
||||
on_activate_call=_doit)
|
||||
if i == 0:
|
||||
ba.widget(edit=txt, up_widget=self._back_button)
|
||||
|
||||
|
||||
@ -350,6 +350,7 @@ class PlaylistBrowserWindow(ba.OldWindow):
|
||||
for y in range(rows):
|
||||
for x in range(columns):
|
||||
name = items[index][0]
|
||||
assert name is not None
|
||||
pos = (x * (button_width + 2 * button_buffer_h) +
|
||||
button_buffer_h + 8 + h_offs, self._sub_height - 47 -
|
||||
(y + 1) * (button_height + 2 * button_buffer_v))
|
||||
|
||||
@ -225,9 +225,8 @@ class PlayOptionsWindow(popup.PopupWindow):
|
||||
position=(h, v),
|
||||
texture=ba.gettexture(tex_name if owned else 'empty'),
|
||||
model_opaque=model_opaque if owned else None,
|
||||
on_activate_call=ba.Call(ba.screenmessage,
|
||||
desc,
|
||||
color=desc_color),
|
||||
on_activate_call=ba.Call(ba.screenmessage, desc,
|
||||
desc_color),
|
||||
label='',
|
||||
color=(1, 1, 1),
|
||||
autoselect=True,
|
||||
|
||||
@ -27,7 +27,7 @@ from typing import TYPE_CHECKING
|
||||
import ba
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Callable, Dict, Tuple, List, Sequence
|
||||
from typing import Any, Callable, Dict, Tuple, List, Sequence, Optional
|
||||
|
||||
|
||||
def create_tab_buttons(parent_widget: ba.Widget,
|
||||
@ -50,9 +50,11 @@ def create_tab_buttons(parent_widget: ba.Widget,
|
||||
h = pos[0]
|
||||
for _i, tab in enumerate(tabs):
|
||||
|
||||
def _tick_and_call(call: Callable[[Any], Any], arg: Any) -> None:
|
||||
def _tick_and_call(call: Optional[Callable[[Any], Any]],
|
||||
arg: Any) -> None:
|
||||
ba.playsound(ba.getsound('click01'))
|
||||
call(arg)
|
||||
if call is not None:
|
||||
call(arg)
|
||||
|
||||
pos = (h + tab_spacing * 0.5, tab_pos_v)
|
||||
size = (tab_button_width - tab_spacing, 50.0)
|
||||
|
||||
@ -541,7 +541,7 @@ class TournamentEntryWindow(popup.PopupWindow):
|
||||
self._launch()
|
||||
|
||||
def _on_pay_with_ad_press(self) -> None:
|
||||
from ba.internal import show_ad
|
||||
from ba.internal import show_ad_2
|
||||
|
||||
# If we're already entering, ignore.
|
||||
if self._entering:
|
||||
@ -563,9 +563,8 @@ class TournamentEntryWindow(popup.PopupWindow):
|
||||
cur_time = ba.time(ba.TimeType.REAL)
|
||||
if cur_time - self._last_ad_press_time > 5.0:
|
||||
self._last_ad_press_time = cur_time
|
||||
show_ad('tournament_entry',
|
||||
on_completion_call=ba.WeakCall(self._on_ad_complete),
|
||||
pass_actually_showed=True)
|
||||
show_ad_2('tournament_entry',
|
||||
on_completion_call=ba.WeakCall(self._on_ad_complete))
|
||||
|
||||
def _on_ad_complete(self, actually_showed: bool) -> None:
|
||||
|
||||
|
||||
@ -333,15 +333,15 @@ class WatchWindow(ba.OldWindow):
|
||||
autoselect=True,
|
||||
maxwidth=c_width * 0.7,
|
||||
max_chars=200)
|
||||
cbtn = ba.buttonwidget(parent=cnt,
|
||||
label=ba.Lstr(resource='cancelText'),
|
||||
on_activate_call=ba.Call(
|
||||
ba.containerwidget,
|
||||
edit=cnt,
|
||||
transition='out_scale'),
|
||||
size=(180, 60),
|
||||
position=(30, 30),
|
||||
autoselect=True)
|
||||
cbtn = ba.buttonwidget(
|
||||
parent=cnt,
|
||||
label=ba.Lstr(resource='cancelText'),
|
||||
on_activate_call=ba.Call(
|
||||
lambda c: ba.containerwidget(edit=c, transition='out_scale'),
|
||||
cnt),
|
||||
size=(180, 60),
|
||||
position=(30, 30),
|
||||
autoselect=True)
|
||||
okb = ba.buttonwidget(parent=cnt,
|
||||
label=ba.Lstr(resource=self._r + '.renameText'),
|
||||
size=(180, 60),
|
||||
|
||||
@ -85,7 +85,7 @@ def formatcode(projroot: Path, full: bool) -> None:
|
||||
flush=True)
|
||||
|
||||
|
||||
def cpplintcode(projroot: Path, full: bool) -> None:
|
||||
def cpplint(projroot: Path, full: bool) -> None:
|
||||
"""Run lint-checking on all code deemed lint-able."""
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from efrotools import get_config
|
||||
@ -230,7 +230,7 @@ def get_script_filenames(projroot: Path) -> List[str]:
|
||||
return sorted(list(f for f in filenames if 'flycheck_' not in f))
|
||||
|
||||
|
||||
def pylintscripts(projroot: Path, full: bool, fast: bool) -> None:
|
||||
def pylint(projroot: Path, full: bool, fast: bool) -> None:
|
||||
"""Run lint-checking on all scripts deemed lint-able."""
|
||||
from efrotools import get_files_hash
|
||||
pylintrc = Path(projroot, '.pylintrc')
|
||||
@ -516,7 +516,7 @@ def runmypy(filenames: List[str], full: bool = False,
|
||||
subprocess.run(args, check=check)
|
||||
|
||||
|
||||
def mypyscripts(projroot: Path, full: bool) -> None:
|
||||
def mypy(projroot: Path, full: bool) -> None:
|
||||
"""Run mypy on all of our scripts."""
|
||||
import time
|
||||
filenames = get_script_filenames(projroot)
|
||||
|
||||
@ -137,9 +137,9 @@ def build_apple(arch: str, debug: bool = False) -> None:
|
||||
txt = efrotools.replace_one(
|
||||
txt, '&& PATH=$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH) .',
|
||||
'&& PATH="$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH)" .')
|
||||
txt = efrotools.replace_one(
|
||||
txt, '&& PATH=$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH) m',
|
||||
'&& PATH="$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH)" m')
|
||||
# txt = efrotools.replace_one(
|
||||
# txt, '&& PATH=$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH) m',
|
||||
# '&& PATH="$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH)" m')
|
||||
|
||||
# Remove makefile dependencies so we don't build the
|
||||
# libs we're not using.
|
||||
|
||||
@ -226,11 +226,11 @@ def formatmakefile() -> None:
|
||||
outfile.write(formatted)
|
||||
|
||||
|
||||
def cpplintcode() -> None:
|
||||
def cpplint() -> None:
|
||||
"""Run lint-checking on all code deemed lint-able."""
|
||||
from efrotools import code
|
||||
full = '-full' in sys.argv
|
||||
code.cpplintcode(PROJROOT, full)
|
||||
code.cpplint(PROJROOT, full)
|
||||
|
||||
|
||||
def scriptfiles() -> None:
|
||||
@ -247,19 +247,19 @@ def scriptfiles() -> None:
|
||||
print(' '.join(paths))
|
||||
|
||||
|
||||
def pylintscripts() -> None:
|
||||
def pylint() -> None:
|
||||
"""Run pylint checks on our scripts."""
|
||||
from efrotools import code
|
||||
full = ('-full' in sys.argv)
|
||||
fast = ('-fast' in sys.argv)
|
||||
code.pylintscripts(PROJROOT, full, fast)
|
||||
code.pylint(PROJROOT, full, fast)
|
||||
|
||||
|
||||
def mypyscripts() -> None:
|
||||
def mypy() -> None:
|
||||
"""Run mypy checks on our scripts."""
|
||||
from efrotools import code
|
||||
full = ('-full' in sys.argv)
|
||||
code.mypyscripts(PROJROOT, full)
|
||||
code.mypy(PROJROOT, full)
|
||||
|
||||
|
||||
def pycharmscripts() -> None:
|
||||
|
||||
@ -43,10 +43,9 @@ import efrotools
|
||||
# noinspection PyUnresolvedReferences
|
||||
from efrotools.snippets import ( # pylint: disable=unused-import
|
||||
PROJROOT, CleanError, snippets_main, formatcode, formatscripts,
|
||||
formatmakefile, cpplintcode, pylintscripts, mypyscripts,
|
||||
tool_config_install, sync, sync_all, scriptfiles, pycharmscripts,
|
||||
clioncode, androidstudiocode, makefile_target_list, spelling, spelling_all,
|
||||
compile_python_files)
|
||||
formatmakefile, cpplint, pylint, mypy, tool_config_install, sync, sync_all,
|
||||
scriptfiles, pycharmscripts, clioncode, androidstudiocode,
|
||||
makefile_target_list, spelling, spelling_all, compile_python_files)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional, List, Sequence
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user