mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-01 20:33:46 +08:00
More work on plugins
This commit is contained in:
parent
42c7bb17f5
commit
0356b0b0e0
@ -4135,16 +4135,16 @@
|
||||
"assets/build/windows/x64/vc_redist.x64.exe": "https://files.ballistica.net/cache/ba1/ea/19/8b8787d81abcdce158ba608cd24f",
|
||||
"assets/build/windows/x64/vcruntime140_1d.dll": "https://files.ballistica.net/cache/ba1/11/d8/ff6344b429b00c24d9a1930d4338",
|
||||
"assets/build/windows/x64/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/20/33/0825e11e6518f87ece3009309933",
|
||||
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ff/36/ca09cc3913ae40382d73340f62ab",
|
||||
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ca/30/613d0c5acf97d7eb7770c4138a3b",
|
||||
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/cb/58/e668468c6ebe7b3b1bacc7079f16",
|
||||
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3a/93/215ba8579ffc8bc5fc67aa6d1bfc",
|
||||
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/c5/b0be277a5324eccf97218644f429",
|
||||
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7c/f3/f82f3a29652ed279447dc5b1c4a5",
|
||||
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/21/aa/312efa59677ebd9a97b8f7f48796",
|
||||
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7c/de/c926cf39c972f1084762c917bb9c",
|
||||
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/bd/bb/bfb59d70d101eefd14987007225d",
|
||||
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/df/d3/3e91ec5117fe359c2e94818b9788",
|
||||
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/20/c0/cad3a08df13d190bbeff26bb901f",
|
||||
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ea/28/efe665eddea710871da829ad2dce"
|
||||
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/e9/3cc27e1957894e2926093efaf419",
|
||||
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cc/6d/523557326436bb1f2c79b40db30f",
|
||||
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/59/b5/cd299564c2795a47f19253121289",
|
||||
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/90/15/400a238c241f4baaf593338c2f0e",
|
||||
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4a/17/9c657df88fcf1aa529a6d57c1c63",
|
||||
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2c/14/4af6ef9f9452c10d3dbc7b864045",
|
||||
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/11/05/2d5de66e04958be2440d10c96694",
|
||||
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/89/c8/2e9218badd4259e480c3b3315bf6",
|
||||
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/7e/7b/173c424cd6548670163304241161",
|
||||
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/bc/d9/52268ba89bf9e6821fd95d4b6852",
|
||||
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e3/49/f6b920cf41705a40f7c00ad2cd26",
|
||||
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d4/9f/365187c2ebdeffdfba74a35cf4f7"
|
||||
}
|
||||
3
.idea/dictionaries/ericf.xml
generated
3
.idea/dictionaries/ericf.xml
generated
@ -137,6 +137,7 @@
|
||||
<w>autoretain</w>
|
||||
<w>autoselect</w>
|
||||
<w>autotools</w>
|
||||
<w>availplug</w>
|
||||
<w>aval</w>
|
||||
<w>axismotion</w>
|
||||
<w>bacfg</w>
|
||||
@ -628,6 +629,7 @@
|
||||
<w>extrascale</w>
|
||||
<w>exts</w>
|
||||
<w>factoryclass</w>
|
||||
<w>fakemodule</w>
|
||||
<w>fallbacks</w>
|
||||
<w>farthestpt</w>
|
||||
<w>fback</w>
|
||||
@ -1452,6 +1454,7 @@
|
||||
<w>plpt</w>
|
||||
<w>plst</w>
|
||||
<w>pluglist</w>
|
||||
<w>plugstates</w>
|
||||
<w>plusbutton</w>
|
||||
<w>plvel</w>
|
||||
<w>pmats</w>
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
"ba_data/python/ba/__pycache__/_nodeactor.cpython-37.opt-1.pyc",
|
||||
"ba_data/python/ba/__pycache__/_player.cpython-37.opt-1.pyc",
|
||||
"ba_data/python/ba/__pycache__/_playlist.cpython-37.opt-1.pyc",
|
||||
"ba_data/python/ba/__pycache__/_plugin.cpython-37.opt-1.pyc",
|
||||
"ba_data/python/ba/__pycache__/_powerup.cpython-37.opt-1.pyc",
|
||||
"ba_data/python/ba/__pycache__/_profile.cpython-37.opt-1.pyc",
|
||||
"ba_data/python/ba/__pycache__/_score.cpython-37.opt-1.pyc",
|
||||
@ -99,6 +100,7 @@
|
||||
"ba_data/python/ba/_nodeactor.py",
|
||||
"ba_data/python/ba/_player.py",
|
||||
"ba_data/python/ba/_playlist.py",
|
||||
"ba_data/python/ba/_plugin.py",
|
||||
"ba_data/python/ba/_powerup.py",
|
||||
"ba_data/python/ba/_profile.py",
|
||||
"ba_data/python/ba/_score.py",
|
||||
|
||||
@ -190,6 +190,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
||||
build/ba_data/python/ba/_nodeactor.py \
|
||||
build/ba_data/python/ba/_player.py \
|
||||
build/ba_data/python/ba/_playlist.py \
|
||||
build/ba_data/python/ba/_plugin.py \
|
||||
build/ba_data/python/ba/_powerup.py \
|
||||
build/ba_data/python/ba/_profile.py \
|
||||
build/ba_data/python/ba/_score.py \
|
||||
@ -423,6 +424,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
||||
build/ba_data/python/ba/__pycache__/_nodeactor.cpython-37.opt-1.pyc \
|
||||
build/ba_data/python/ba/__pycache__/_player.cpython-37.opt-1.pyc \
|
||||
build/ba_data/python/ba/__pycache__/_playlist.cpython-37.opt-1.pyc \
|
||||
build/ba_data/python/ba/__pycache__/_plugin.cpython-37.opt-1.pyc \
|
||||
build/ba_data/python/ba/__pycache__/_powerup.cpython-37.opt-1.pyc \
|
||||
build/ba_data/python/ba/__pycache__/_profile.cpython-37.opt-1.pyc \
|
||||
build/ba_data/python/ba/__pycache__/_score.cpython-37.opt-1.pyc \
|
||||
|
||||
@ -38,6 +38,7 @@ from _ba import (CollideModel, Context, ContextCall, Data, InputDevice,
|
||||
set_analytics_screen, charstr, textwidget, time, timer,
|
||||
open_url, widget)
|
||||
from ba._activity import Activity
|
||||
from ba._plugin import AvailablePlugin, Plugin
|
||||
from ba._actor import Actor
|
||||
from ba._player import PlayerInfo, Player, EmptyPlayer, StandLocation
|
||||
from ba._nodeactor import NodeActor
|
||||
|
||||
@ -37,7 +37,7 @@ if TYPE_CHECKING:
|
||||
class App:
|
||||
"""A class for high level app functionality and state.
|
||||
|
||||
category: App Classes
|
||||
Category: App Classes
|
||||
|
||||
Use ba.app to access the single shared instance of this class.
|
||||
|
||||
@ -305,6 +305,10 @@ class App:
|
||||
self.headless_build: bool = env['headless_build']
|
||||
assert isinstance(self.headless_build, bool)
|
||||
|
||||
# Plugins.
|
||||
self.loaded_plugins: List[ba.Plugin] = []
|
||||
self.available_plugins: List[ba.AvailablePlugin] = []
|
||||
|
||||
# Misc.
|
||||
self.default_language = self._get_default_language()
|
||||
self.metascan: Optional[_meta.ScanResults] = None
|
||||
|
||||
@ -45,6 +45,7 @@ CURRENT_API_VERSION = 6
|
||||
class ScanResults:
|
||||
"""Final results from a metadata scan."""
|
||||
games: List[str] = field(default_factory=list)
|
||||
plugins: List[str] = field(default_factory=list)
|
||||
errors: str = ''
|
||||
warnings: str = ''
|
||||
|
||||
@ -64,6 +65,8 @@ def start_scan() -> None:
|
||||
def handle_scan_results(results: ScanResults) -> None:
|
||||
"""Called in the game thread with results of a completed scan."""
|
||||
|
||||
from ba._lang import Lstr
|
||||
|
||||
# Warnings generally only get printed locally for users' benefit
|
||||
# (things like out-of-date scripts being ignored, etc.)
|
||||
# Errors are more serious and will get included in the regular log
|
||||
@ -71,7 +74,6 @@ def handle_scan_results(results: ScanResults) -> None:
|
||||
# errors = results.get('errors', '')
|
||||
if results.warnings != '' or results.errors != '':
|
||||
import textwrap
|
||||
from ba._lang import Lstr
|
||||
_ba.screenmessage(Lstr(resource='scanScriptsErrorText'),
|
||||
color=(1, 0, 0))
|
||||
_ba.playsound(_ba.getsound('error'))
|
||||
@ -81,6 +83,31 @@ def handle_scan_results(results: ScanResults) -> None:
|
||||
if results.errors != '':
|
||||
_ba.log(textwrap.indent(results.errors, 'Error (meta-scan): '))
|
||||
|
||||
# Handle plugins.
|
||||
config_changed = False
|
||||
found_new = False
|
||||
plugstates: Dict[str, Dict] = _ba.app.config.setdefault('Plugins', {})
|
||||
if not isinstance(plugstates, dict):
|
||||
print('Warning; found non-dict for "Plugins" in config.')
|
||||
plugstates = {}
|
||||
config_changed = True
|
||||
|
||||
for plug in results.plugins:
|
||||
if plug not in plugstates:
|
||||
print('found new plugin:', plug)
|
||||
plugstates[plug] = {'enabled': False}
|
||||
config_changed = True
|
||||
found_new = True
|
||||
|
||||
if found_new:
|
||||
_ba.screenmessage(Lstr(resource='pluginsDetectedText'),
|
||||
color=(0, 1, 0))
|
||||
_ba.playsound(_ba.getsound('ding'))
|
||||
|
||||
if config_changed:
|
||||
_ba.app.config.commit()
|
||||
# print(f'would check {len(results.plugins)} plugs')
|
||||
|
||||
|
||||
class ScanThread(threading.Thread):
|
||||
"""Thread to scan script dirs for metadata."""
|
||||
@ -90,7 +117,7 @@ class ScanThread(threading.Thread):
|
||||
self._dirs = dirs
|
||||
|
||||
def run(self) -> None:
|
||||
from ba import _general
|
||||
from ba._general import Call
|
||||
try:
|
||||
scan = DirectoryScan(self._dirs)
|
||||
scan.scan()
|
||||
@ -100,7 +127,7 @@ class ScanThread(threading.Thread):
|
||||
|
||||
# Push a call to the game thread to print warnings/errors
|
||||
# or otherwise deal with scan results.
|
||||
_ba.pushcall(_general.Call(handle_scan_results, results),
|
||||
_ba.pushcall(Call(handle_scan_results, results),
|
||||
from_other_thread=True)
|
||||
|
||||
# We also, however, immediately make results available.
|
||||
@ -117,14 +144,6 @@ class DirectoryScan:
|
||||
|
||||
It is assumed that these paths are also in PYTHONPATH.
|
||||
It is also assumed that any subdirectories are Python packages.
|
||||
The returned dict contains the following:
|
||||
'powerups': list of ba.Powerup classes found.
|
||||
'campaigns': list of ba.Campaign classes found.
|
||||
'modifiers': list of ba.Modifier classes found.
|
||||
'maps': list of ba.Map classes found.
|
||||
'games': list of ba.GameActivity classes found.
|
||||
'warnings': warnings from scan; should be printed for local feedback
|
||||
'errors': errors encountered during scan; should be fully logged
|
||||
"""
|
||||
|
||||
# Skip non-existent paths completely.
|
||||
@ -251,6 +270,8 @@ class DirectoryScan:
|
||||
classname = modulename + '.' + export_class_name
|
||||
if exporttype == 'game':
|
||||
self.results.games.append(classname)
|
||||
elif exporttype == 'plugin':
|
||||
self.results.plugins.append(classname)
|
||||
else:
|
||||
self.results.warnings += (
|
||||
'Warning: ' + str(subpath) +
|
||||
|
||||
48
assets/src/ba_data/python/ba/_plugin.py
Normal file
48
assets/src/ba_data/python/ba/_plugin.py
Normal file
@ -0,0 +1,48 @@
|
||||
# Copyright (c) 2011-2020 Eric Froemling
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# -----------------------------------------------------------------------------
|
||||
"""Plugin related functionality."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from dataclasses import dataclass
|
||||
|
||||
if TYPE_CHECKING:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class AvailablePlugin:
|
||||
"""Defines a plugin which can potentially be loaded.
|
||||
|
||||
Category: App Classes
|
||||
"""
|
||||
display_name: str
|
||||
class_path: str
|
||||
|
||||
|
||||
class Plugin:
|
||||
"""A plugin to alter app behavior in some way.
|
||||
|
||||
Category: App Classes
|
||||
"""
|
||||
|
||||
name: str
|
||||
@ -161,3 +161,13 @@ class SharedObjects:
|
||||
),
|
||||
)
|
||||
return self._railing_material
|
||||
|
||||
|
||||
# ba _meta export plugin
|
||||
class TestPlug1(ba.Plugin):
|
||||
"""Just Testing."""
|
||||
|
||||
|
||||
# ba _meta export plugin
|
||||
class TestPlug2(ba.Plugin):
|
||||
"""Just Testing 2."""
|
||||
|
||||
@ -164,7 +164,7 @@ class ControlsSettingsWindow(ba.Window):
|
||||
on_activate_call=self._back)
|
||||
ba.containerwidget(edit=self._root_widget, cancel_button=btn)
|
||||
|
||||
# need these vars to exist even if the buttons don't
|
||||
# We need these vars to exist even if the buttons don't.
|
||||
self._gamepads_button: Optional[ba.Widget] = None
|
||||
self._touch_button: Optional[ba.Widget] = None
|
||||
self._keyboard_button: Optional[ba.Widget] = None
|
||||
|
||||
@ -33,9 +33,13 @@ if TYPE_CHECKING:
|
||||
class PluginSettingsWindow(ba.Window):
|
||||
"""Window for configuring plugins."""
|
||||
|
||||
def __del__(self) -> None:
|
||||
print('~PluginSettingsWindow()')
|
||||
|
||||
def __init__(self,
|
||||
transition: str = 'in_right',
|
||||
origin_widget: ba.Widget = None):
|
||||
print('PluginSettingsWindow()')
|
||||
|
||||
app = ba.app
|
||||
|
||||
@ -111,11 +115,22 @@ class PluginSettingsWindow(ba.Window):
|
||||
self._subcontainer = ba.columnwidget(parent=self._scrollwidget,
|
||||
selection_loops_to_parent=True)
|
||||
|
||||
pluglist = [f'Test {i}' for i in range(10)]
|
||||
for i, plug in enumerate(pluglist):
|
||||
pluglist = [
|
||||
ba.AvailablePlugin(display_name=f'Test {i}',
|
||||
class_path='fakemodule') for i in range(10)
|
||||
]
|
||||
for i, availplug in enumerate(pluglist):
|
||||
active = i % 3 < 2
|
||||
check = ba.checkboxwidget(parent=self._subcontainer,
|
||||
text=plug,
|
||||
size=(self._scroll_width - 40, 50))
|
||||
text=availplug.display_name,
|
||||
value=active,
|
||||
maxwidth=self._scroll_width - 100,
|
||||
size=(self._scroll_width - 40, 50),
|
||||
on_value_change_call=ba.Call(
|
||||
self._check_value_changed,
|
||||
availplug),
|
||||
textcolor=((0, 1, 0) if active else
|
||||
(0.6, 0.6, 0.6)))
|
||||
|
||||
# Make sure we scroll all the way to the end when using
|
||||
# keyboard/button nav.
|
||||
@ -129,6 +144,13 @@ class PluginSettingsWindow(ba.Window):
|
||||
|
||||
self._restore_state()
|
||||
|
||||
def _check_value_changed(self, plug: ba.AvailablePlugin,
|
||||
value: bool) -> None:
|
||||
ba.screenmessage(
|
||||
ba.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
|
||||
color=(1.0, 0.5, 0.0))
|
||||
print(f'check value changed for {plug} to {value}')
|
||||
|
||||
def _save_state(self) -> None:
|
||||
pass
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
|
||||
<h4><em>last updated on 2020-07-21 for Ballistica version 1.5.23 build 20150</em></h4>
|
||||
<h4><em>last updated on 2020-07-21 for Ballistica version 1.5.23 build 20151</em></h4>
|
||||
<p>This page documents the Python classes and functions in the 'ba' module,
|
||||
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
|
||||
<hr>
|
||||
@ -150,8 +150,10 @@
|
||||
<li><a href="#class_ba_App">ba.App</a></li>
|
||||
<li><a href="#class_ba_AppConfig">ba.AppConfig</a></li>
|
||||
<li><a href="#class_ba_AppDelegate">ba.AppDelegate</a></li>
|
||||
<li><a href="#class_ba_AvailablePlugin">ba.AvailablePlugin</a></li>
|
||||
<li><a href="#class_ba_Campaign">ba.Campaign</a></li>
|
||||
<li><a href="#class_ba_MusicPlayer">ba.MusicPlayer</a></li>
|
||||
<li><a href="#class_ba_Plugin">ba.Plugin</a></li>
|
||||
<li><a href="#class_ba_ServerController">ba.ServerController</a></li>
|
||||
</ul>
|
||||
<h4><a name="class_category_User_Interface_Classes">User Interface Classes</a></h4>
|
||||
@ -1164,6 +1166,22 @@ when done.</p>
|
||||
|
||||
<p>Behavior is similar to <a href="#function_ba_gettexture">ba.gettexture</a>()</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
<h2><strong><a name="class_ba_AvailablePlugin">ba.AvailablePlugin</a></strong></h3>
|
||||
<p><em><top level class></em>
|
||||
</p>
|
||||
<p>Defines a plugin which can potentially be loaded.</p>
|
||||
|
||||
<p>Category: <a href="#class_category_App_Classes">App Classes</a>
|
||||
</p>
|
||||
|
||||
<h3>Methods:</h3>
|
||||
<dl>
|
||||
<dt><h4><a name="method_ba_AvailablePlugin____init__"><constructor></a></dt></h4><dd>
|
||||
<p><span>ba.AvailablePlugin(display_name: str, class_path: str)</span></p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
@ -4485,6 +4503,15 @@ the type-checker properly identifies the returned value as one.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
<h2><strong><a name="class_ba_Plugin">ba.Plugin</a></strong></h3>
|
||||
<p><em><top level class></em>
|
||||
</p>
|
||||
<p>A plugin to alter app behavior in some way.</p>
|
||||
|
||||
<p>Category: <a href="#class_category_App_Classes">App Classes</a>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<h2><strong><a name="class_ba_PowerupAcceptMessage">ba.PowerupAcceptMessage</a></strong></h3>
|
||||
<p><em><top level class></em>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user