first part for phy simluation #34
17
.github/workflows/get_info.py
vendored
17
.github/workflows/get_info.py
vendored
@ -10,13 +10,10 @@ import rtoml
|
|||||||
|
|
||||||
sys.path.append(os.path.abspath(os.curdir))
|
sys.path.append(os.path.abspath(os.curdir))
|
||||||
|
|
||||||
from Difficult_Rocket import DR_runtime
|
from Difficult_Rocket import DR_status
|
||||||
|
|
||||||
args = ['-env', '-github-dev']
|
args = ['-env', '-github-dev']
|
||||||
|
|
||||||
# print(sys.argv)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if sys.argv == [__file__]: # 没有输入参数,直接输出默认信息并输出
|
if sys.argv == [__file__]: # 没有输入参数,直接输出默认信息并输出
|
||||||
print(sys.version)
|
print(sys.version)
|
||||||
@ -29,13 +26,9 @@ if sys.argv == [__file__]: # 没有输入参数,直接输出默认信息并
|
|||||||
|
|
||||||
elif os.path.abspath(os.curdir) in sys.path and '-env' in sys.argv:
|
elif os.path.abspath(os.curdir) in sys.path and '-env' in sys.argv:
|
||||||
with open('./.github/workflows/env.ps1', encoding='utf-8', mode='w') as env_file:
|
with open('./.github/workflows/env.ps1', encoding='utf-8', mode='w') as env_file:
|
||||||
print(f'$env:DR_version = "{DR_runtime.DR_version}"', file=env_file)
|
print(f'$env:DR_version = "{DR_status.DR_version}"', file=env_file)
|
||||||
print(f'$env:DR_language = "{DR_runtime.language}"', file=env_file)
|
print(f'$env:Build_version = "{DR_status.Build_version}"', file=env_file)
|
||||||
print(f'$env:DR_long_version = "{DR_runtime.DR_long_version}"', file=env_file)
|
|
||||||
print(f'$env:Build_version = "{DR_runtime.Build_version}"', file=env_file)
|
|
||||||
|
|
||||||
elif os.path.abspath(os.curdir) in sys.path and '-github' in sys.argv:
|
elif os.path.abspath(os.curdir) in sys.path and '-github' in sys.argv:
|
||||||
print(f'DR_version={DR_runtime.DR_version}')
|
print(f'DR_version={DR_status.DR_version}')
|
||||||
print(f'DR_language={DR_runtime.language}')
|
print(f'Build_version={DR_status.Build_version}')
|
||||||
print(f'DR_long_version={DR_runtime.DR_long_version}')
|
|
||||||
print(f'Build_version={DR_runtime.Build_version}')
|
|
||||||
|
15
DR.py
15
DR.py
@ -52,21 +52,14 @@ def main() -> int:
|
|||||||
|
|
||||||
from Difficult_Rocket.exception import TestError
|
from Difficult_Rocket.exception import TestError
|
||||||
from Difficult_Rocket import crash
|
from Difficult_Rocket import crash
|
||||||
from Difficult_Rocket import DR_option
|
from Difficult_Rocket import DR_status
|
||||||
try:
|
|
||||||
from libs.pyglet_rs import get_version_str, patch_vector
|
|
||||||
print('pyglet_rs available:', get_version_str())
|
|
||||||
print('trying to patch pyglet_rs')
|
|
||||||
patch_vector()
|
|
||||||
except ImportError:
|
|
||||||
print('pyglet_rs import error')
|
|
||||||
traceback.print_exc()
|
|
||||||
try:
|
try:
|
||||||
from libs import pyglet # 导入pyglet
|
from libs import pyglet # 导入pyglet
|
||||||
pyglet.resource.path = ['/textures/']
|
pyglet.resource.path = ['/textures/']
|
||||||
pyglet.resource.reindex()
|
pyglet.resource.reindex()
|
||||||
|
|
||||||
from Difficult_Rocket import main, DR_runtime
|
from Difficult_Rocket import main
|
||||||
|
from Difficult_Rocket.runtime import DR_runtime
|
||||||
DR_runtime.start_time_ns = start_time_ns
|
DR_runtime.start_time_ns = start_time_ns
|
||||||
|
|
||||||
# from pyglet.gl import glClearColor # 调整背景颜色
|
# from pyglet.gl import glClearColor # 调整背景颜色
|
||||||
@ -80,7 +73,7 @@ def main() -> int:
|
|||||||
cProfile.run('game.start()', sort='calls') # 使用 cprofile 启动
|
cProfile.run('game.start()', sort='calls') # 使用 cprofile 启动
|
||||||
else:
|
else:
|
||||||
game.start() # 直接启动
|
game.start() # 直接启动
|
||||||
if DR_option.crash_report_test:
|
if DR_status.crash_report_test:
|
||||||
raise TestError('debugging') # debug 嘛,试试crash
|
raise TestError('debugging') # debug 嘛,试试crash
|
||||||
except Exception as exp: # 出毛病了
|
except Exception as exp: # 出毛病了
|
||||||
# 解析错误信息
|
# 解析错误信息
|
||||||
|
@ -4,58 +4,46 @@
|
|||||||
# All rights reserved
|
# All rights reserved
|
||||||
# -------------------------------
|
# -------------------------------
|
||||||
|
|
||||||
import sys
|
|
||||||
import importlib
|
|
||||||
import traceback
|
|
||||||
import contextlib
|
|
||||||
import importlib.util
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Optional, List, Tuple
|
|
||||||
|
|
||||||
from Difficult_Rocket.api.types import Options, Version
|
from Difficult_Rocket.api.types import Options, Version
|
||||||
|
|
||||||
game_version = Version("0.8.2.0") # 游戏版本
|
game_version = Version("0.8.3.0") # 游戏版本
|
||||||
build_version = Version("2.1.0.0") # 编译文件版本(与游戏本体无关)
|
build_version = Version("2.1.0.0") # 编译文件版本(与游戏本体无关)
|
||||||
Api_version = Version("0.1.1.0") # API 版本
|
Api_version = Version("0.1.1.0") # API 版本
|
||||||
__version__ = game_version
|
__version__ = game_version
|
||||||
|
|
||||||
long_version: int = 15
|
|
||||||
"""
|
__all__ = [
|
||||||
long_version: 一个用于标记内部协议的整数
|
# __init__
|
||||||
15: 完全移除 DR_rust 相关内容 解耦完成
|
'DR_status',
|
||||||
14: BaseScreen 的每一个函数都添加了一个参数: window: "ClientWindow"
|
# folder
|
||||||
13: 为 DR_runtime 添加 API_version
|
'api',
|
||||||
12: 去除 DR_runtime 的 global_logger
|
'client',
|
||||||
要 logging 自己拿去(
|
'server',
|
||||||
11: 为 DR_option 添加 use_DR_rust
|
'command',
|
||||||
修复了一些拼写错误
|
'crash',
|
||||||
10: 为 DR_runtime 添加 DR_Rust_get_version
|
'exception',
|
||||||
9 : 为 DR_option 添加 pyglet_macosx_dev_test
|
'mod',
|
||||||
8 : 为 DR_runtime 添加 DR_rust_version
|
'utils',
|
||||||
为 DR_option 添加 DR_rust_available
|
# file
|
||||||
以后就有 DR_rust 了
|
'main',
|
||||||
7 : 为 DR_option 添加 std_font_size
|
'runtime',
|
||||||
6 : 事实证明, 不如直接用int
|
]
|
||||||
5 : 添加 build_version 信息,用于标记编译文件版本,
|
|
||||||
游戏版本改为四位数,终于有一个可以让我随便刷的版本号位数了
|
|
||||||
4 : 把 translate 的字体常量位置改了一下,顺便调换顺序
|
|
||||||
3 : 就是试试改一下,正好 compiler 要用
|
|
||||||
2 : 哦,对 longlong 好耶!
|
|
||||||
1 : 我可算想起来还有这回事了 v0.6.4
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class _DR_option(Options):
|
class _DR_status(Options):
|
||||||
"""
|
"""
|
||||||
DR 的一般配置/状态
|
DR 的特性开关 / 基本状态
|
||||||
"""
|
"""
|
||||||
name = 'DR Option'
|
name = 'DR Option'
|
||||||
# runtime options
|
# run status
|
||||||
|
client_running: bool = False
|
||||||
|
server_running: bool = False
|
||||||
|
|
||||||
|
# feature switch
|
||||||
InputBox_use_TextEntry: bool = True
|
InputBox_use_TextEntry: bool = True
|
||||||
record_threads: bool = True
|
record_threads: bool = True
|
||||||
report_translate_not_found: bool = True
|
report_translate_not_found: bool = True
|
||||||
use_multiprocess: bool = False
|
use_multiprocess: bool = False
|
||||||
DR_rust_available: bool = False
|
|
||||||
use_cProfile: bool = False
|
use_cProfile: bool = False
|
||||||
use_local_logging: bool = False
|
use_local_logging: bool = False
|
||||||
|
|
||||||
@ -64,6 +52,14 @@ class _DR_option(Options):
|
|||||||
debugging: bool = False
|
debugging: bool = False
|
||||||
crash_report_test: bool = False
|
crash_report_test: bool = False
|
||||||
|
|
||||||
|
# game version status
|
||||||
|
DR_version: Version = game_version # DR SDK 版本
|
||||||
|
Build_version: Version = build_version # DR 构建 版本
|
||||||
|
API_version: Version = Api_version # DR SDK API 版本
|
||||||
|
|
||||||
|
# game options
|
||||||
|
default_language: str = 'zh-CN'
|
||||||
|
|
||||||
# window option
|
# window option
|
||||||
gui_scale: float = 1.0 # default 1.0 2.0 -> 2x 3 -> 3x
|
gui_scale: float = 1.0 # default 1.0 2.0 -> 2x 3 -> 3x
|
||||||
|
|
||||||
@ -72,79 +68,9 @@ class _DR_option(Options):
|
|||||||
return round(12 * self.gui_scale)
|
return round(12 * self.gui_scale)
|
||||||
|
|
||||||
|
|
||||||
class _DR_runtime(Options):
|
DR_status = _DR_status()
|
||||||
"""
|
|
||||||
DR 的运行时配置/状态
|
|
||||||
"""
|
|
||||||
name = 'DR Runtime'
|
|
||||||
# game version status
|
|
||||||
DR_version: Version = game_version # DR SDK 版本
|
|
||||||
Build_version: Version = build_version # DR 构建 版本
|
|
||||||
|
|
||||||
API_version: Version = Api_version # DR SDK API 版本
|
if DR_status.playing:
|
||||||
DR_long_version: int = long_version # DR SDK 内部协议版本 (不要问我为什么不用 Version,我也在考虑)
|
|
||||||
|
|
||||||
DR_Mod_List: List[Tuple[str, Version]] = [] # DR Mod 列表 (name, version)
|
|
||||||
|
|
||||||
# run status
|
|
||||||
running: bool = False
|
|
||||||
start_time_ns: Optional[int] = None
|
|
||||||
client_setup_cause_ns: Optional[int] = None
|
|
||||||
server_setup_cause_ns: Optional[int] = None
|
|
||||||
|
|
||||||
# game runtimes
|
|
||||||
# global_logger: logging.Logger
|
|
||||||
|
|
||||||
# game options
|
|
||||||
mod_path: str = './mods'
|
|
||||||
language: str = 'zh-CN'
|
|
||||||
default_language: str = 'zh-CN'
|
|
||||||
|
|
||||||
def load_file(self) -> bool:
|
|
||||||
with contextlib.suppress(FileNotFoundError):
|
|
||||||
with open('./configs/main.toml', 'r', encoding='utf-8') as f:
|
|
||||||
import rtoml
|
|
||||||
config_file = rtoml.load(f)
|
|
||||||
self.language = config_file['runtime']['language']
|
|
||||||
self.mod_path = config_file['game']['mods']['path']
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def find_mods(self) -> List[str]:
|
|
||||||
mods = []
|
|
||||||
mod_path = Path(self.mod_path)
|
|
||||||
if not mod_path.exists():
|
|
||||||
mod_path.mkdir()
|
|
||||||
return []
|
|
||||||
paths = mod_path.iterdir()
|
|
||||||
sys.path.append(self.mod_path)
|
|
||||||
for mod_path in paths:
|
|
||||||
try:
|
|
||||||
if mod_path.is_dir() and mod_path.name != '__pycache__': # 处理文件夹 mod
|
|
||||||
if importlib.util.find_spec(mod_path.name) is not None:
|
|
||||||
mods.append(mod_path.name)
|
|
||||||
else:
|
|
||||||
print(f'can not import mod {mod_path} because importlib can not find spec')
|
|
||||||
elif mod_path.suffix in ('.pyz', '.zip'): # 处理压缩包 mod
|
|
||||||
if importlib.util.find_spec(mod_path.name) is not None:
|
|
||||||
mods.append(mod_path.name)
|
|
||||||
elif mod_path.suffix == '.pyd': # pyd 扩展 mod
|
|
||||||
if importlib.util.find_spec(mod_path.name) is not None:
|
|
||||||
mods.append(mod_path.name)
|
|
||||||
elif mod_path.suffix == '.py': # 处理单文件 mod
|
|
||||||
print(f'importing mod {mod_path=} {mod_path.stem}')
|
|
||||||
if importlib.util.find_spec(mod_path.stem) is not None:
|
|
||||||
mods.append(mod_path.stem)
|
|
||||||
except ImportError:
|
|
||||||
print(f'ImportError when loading mod {mod_path}')
|
|
||||||
traceback.print_exc()
|
|
||||||
return mods
|
|
||||||
|
|
||||||
|
|
||||||
DR_option = _DR_option()
|
|
||||||
DR_runtime = _DR_runtime()
|
|
||||||
|
|
||||||
if DR_option.playing:
|
|
||||||
from Difficult_Rocket.utils.thread import new_thread
|
from Difficult_Rocket.utils.thread import new_thread
|
||||||
|
|
||||||
def think_it(something):
|
def think_it(something):
|
||||||
|
@ -12,6 +12,13 @@ gitee: @shenjackyuanjie
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# from Difficult_Rocket.api import screen, mod, exception
|
__all__ = [
|
||||||
|
'exception',
|
||||||
__all__ = ['screen', 'mod', 'exception']
|
# 错误类定义
|
||||||
|
'screen',
|
||||||
|
# screen api
|
||||||
|
'types',
|
||||||
|
# 类型定义
|
||||||
|
'mod',
|
||||||
|
# mod api
|
||||||
|
]
|
||||||
|
@ -29,11 +29,12 @@ from pyglet.window import key, mouse
|
|||||||
# Difficult_Rocket function
|
# Difficult_Rocket function
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from Difficult_Rocket.main import Game
|
from Difficult_Rocket.main import Game
|
||||||
|
from Difficult_Rocket import DR_status
|
||||||
from Difficult_Rocket.utils import tools
|
from Difficult_Rocket.utils import tools
|
||||||
from Difficult_Rocket.api.types import Options
|
|
||||||
from Difficult_Rocket.command import line
|
from Difficult_Rocket.command import line
|
||||||
|
from Difficult_Rocket.api.types import Options
|
||||||
from Difficult_Rocket.utils.translate import tr
|
from Difficult_Rocket.utils.translate import tr
|
||||||
from Difficult_Rocket import DR_runtime
|
from Difficult_Rocket.runtime import DR_runtime
|
||||||
from Difficult_Rocket.api.screen import BaseScreen
|
from Difficult_Rocket.api.screen import BaseScreen
|
||||||
from Difficult_Rocket.utils.thread import new_thread
|
from Difficult_Rocket.utils.thread import new_thread
|
||||||
from Difficult_Rocket.client.fps.fps_log import FpsLogger
|
from Difficult_Rocket.client.fps.fps_log import FpsLogger
|
||||||
@ -42,6 +43,9 @@ from Difficult_Rocket.exception.language import LanguageNotFound
|
|||||||
from Difficult_Rocket.client.screen import DRScreen, DRDEBUGScreen
|
from Difficult_Rocket.client.screen import DRScreen, DRDEBUGScreen
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger('client')
|
||||||
|
|
||||||
|
|
||||||
class ClientOption(Options):
|
class ClientOption(Options):
|
||||||
fps: int = 60
|
fps: int = 60
|
||||||
width: int = 1024
|
width: int = 1024
|
||||||
@ -51,7 +55,7 @@ class ClientOption(Options):
|
|||||||
resizeable: bool = True
|
resizeable: bool = True
|
||||||
visible: bool = True
|
visible: bool = True
|
||||||
gui_scale: float = 1.0
|
gui_scale: float = 1.0
|
||||||
caption: str = "Difficult Rocket v{DR_version}|DR_rs v{DR_Rust_get_version}"
|
caption: str = "Difficult Rocket v{DR_version}"
|
||||||
|
|
||||||
def load_file(self) -> None:
|
def load_file(self) -> None:
|
||||||
file: dict = tools.load_file('./configs/main.toml')
|
file: dict = tools.load_file('./configs/main.toml')
|
||||||
@ -61,7 +65,8 @@ class ClientOption(Options):
|
|||||||
self.fullscreen = tools.format_bool(file['window']['full_screen'])
|
self.fullscreen = tools.format_bool(file['window']['full_screen'])
|
||||||
self.resizeable = tools.format_bool(file['window']['resizable'])
|
self.resizeable = tools.format_bool(file['window']['resizable'])
|
||||||
self.gui_scale = float(file['window']['gui_scale'])
|
self.gui_scale = float(file['window']['gui_scale'])
|
||||||
self.caption = DR_runtime.format(file['window']['caption'])
|
self.caption = DR_status.format(file['window']['caption'])
|
||||||
|
self.caption = DR_runtime.format(self.caption)
|
||||||
|
|
||||||
|
|
||||||
class Client:
|
class Client:
|
||||||
@ -105,9 +110,15 @@ def pyglet_load_fonts_folder(folder) -> None:
|
|||||||
file_folder_list = os.listdir(folder)
|
file_folder_list = os.listdir(folder)
|
||||||
for obj in file_folder_list:
|
for obj in file_folder_list:
|
||||||
if os.path.isfile(os.path.join(folder, obj)):
|
if os.path.isfile(os.path.join(folder, obj)):
|
||||||
if obj[-4:] == '.ttf':
|
if obj[-4:] == '.ttf' or obj[-4:] == '.otf':
|
||||||
pyglet.font.add_file(os.path.join(folder, obj))
|
logger.debug(f'loading font {os.path.join(folder, obj)}')
|
||||||
|
try:
|
||||||
|
pyglet.font.add_file(os.path.join(folder, obj))
|
||||||
|
except Exception:
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
logger.error(f'loading font {os.path.join(folder, obj)} failed')
|
||||||
else:
|
else:
|
||||||
|
logger.info(f'loading font folder {os.path.join(folder, obj)}')
|
||||||
pyglet_load_fonts_folder(os.path.join(folder, obj))
|
pyglet_load_fonts_folder(os.path.join(folder, obj))
|
||||||
|
|
||||||
|
|
||||||
@ -223,7 +234,7 @@ class ClientWindow(Window):
|
|||||||
print("==========client stop. KeyboardInterrupt info==========")
|
print("==========client stop. KeyboardInterrupt info==========")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
print("==========client stop. KeyboardInterrupt info end==========")
|
print("==========client stop. KeyboardInterrupt info end==========")
|
||||||
self.dispatch_event("on_close")
|
self.dispatch_event("on_close", 'input')
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
@new_thread('window save_info')
|
@new_thread('window save_info')
|
||||||
@ -388,7 +399,7 @@ class ClientWindow(Window):
|
|||||||
if symbol == key.ESCAPE and not (modifiers & ~(key.MOD_NUMLOCK |
|
if symbol == key.ESCAPE and not (modifiers & ~(key.MOD_NUMLOCK |
|
||||||
key.MOD_CAPSLOCK |
|
key.MOD_CAPSLOCK |
|
||||||
key.MOD_SCROLLLOCK)):
|
key.MOD_SCROLLLOCK)):
|
||||||
self.dispatch_event('on_close')
|
self.dispatch_event('on_close', 'window')
|
||||||
if symbol == key.SLASH:
|
if symbol == key.SLASH:
|
||||||
self.input_box._set_focus(True)
|
self.input_box._set_focus(True)
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
|
@ -31,7 +31,7 @@ from pyglet.text.layout import IncrementalTextLayout
|
|||||||
|
|
||||||
from Difficult_Rocket.api.types import FontData, Fonts
|
from Difficult_Rocket.api.types import FontData, Fonts
|
||||||
# from Difficult_Rocket.client.guis.format import html
|
# from Difficult_Rocket.client.guis.format import html
|
||||||
from Difficult_Rocket import DR_option
|
from Difficult_Rocket import DR_status
|
||||||
|
|
||||||
__all__ = ['InputBox']
|
__all__ = ['InputBox']
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ class TextButton(widgets.WidgetBase):
|
|||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
if not DR_option.InputBox_use_TextEntry:
|
if not DR_status.InputBox_use_TextEntry:
|
||||||
class InputBox(widgets.TextEntry):
|
class InputBox(widgets.TextEntry):
|
||||||
""" 自定义的输入框 """
|
""" 自定义的输入框 """
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ if not DR_option.InputBox_use_TextEntry:
|
|||||||
# dpi=font_dpi)
|
# dpi=font_dpi)
|
||||||
# self.font_height = self.font.ascent - self.font.descent
|
# self.font_height = self.font.ascent - self.font.descent
|
||||||
# self.out_bound = out_line
|
# self.out_bound = out_line
|
||||||
# if DR_option.InputBox_use_TextEntry:
|
# if DR_status.InputBox_use_TextEntry:
|
||||||
# # 基于IncrementalTextLayout的处理系统
|
# # 基于IncrementalTextLayout的处理系统
|
||||||
# self._doc = FormattedDocument(message)
|
# self._doc = FormattedDocument(message)
|
||||||
# # self._doc.set_style()
|
# # self._doc.set_style()
|
||||||
|
@ -99,14 +99,15 @@ def write_cache(cache_stream, crash_info):
|
|||||||
|
|
||||||
def write_info_to_cache(cache_stream):
|
def write_info_to_cache(cache_stream):
|
||||||
# 运行状态信息
|
# 运行状态信息
|
||||||
from Difficult_Rocket import DR_option, DR_runtime
|
from Difficult_Rocket import DR_status
|
||||||
|
from Difficult_Rocket.runtime import DR_runtime
|
||||||
cache_stream.write(Run_message)
|
cache_stream.write(Run_message)
|
||||||
cache_stream.write(markdown_line_handler(f'DR Version: {Difficult_Rocket.game_version}', level=1))
|
cache_stream.write(markdown_line_handler(f'DR Version: {Difficult_Rocket.game_version}', level=1))
|
||||||
cache_stream.write(markdown_line_handler(f'DR language: {DR_runtime.language}', level=1))
|
cache_stream.write(markdown_line_handler(f'DR language: {DR_runtime.language}', level=1))
|
||||||
cache_stream.write(markdown_line_handler(f'Running Dir: {Path(os.curdir).resolve()}', level=1))
|
cache_stream.write(markdown_line_handler(f'Running Dir: {Path(os.curdir).resolve()}', level=1))
|
||||||
cache_stream.write(f"\n{DR_runtime.as_markdown()}")
|
cache_stream.write(f"\n{DR_runtime.as_markdown()}")
|
||||||
cache_stream.write(DR_configs)
|
cache_stream.write(DR_configs)
|
||||||
cache_stream.write(f"\n{DR_option.as_markdown()}")
|
cache_stream.write(f"\n{DR_status.as_markdown()}")
|
||||||
cache_stream.write(Process_message)
|
cache_stream.write(Process_message)
|
||||||
for process in all_process:
|
for process in all_process:
|
||||||
process: multiprocessing.Process
|
process: multiprocessing.Process
|
||||||
|
@ -24,10 +24,6 @@ from io import StringIO
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, List, Optional, Dict, TypeVar
|
from typing import TYPE_CHECKING, List, Optional, Dict, TypeVar
|
||||||
|
|
||||||
if __name__ == '__main__': # been start will not run this
|
|
||||||
sys.path.append('/bin/libs')
|
|
||||||
sys.path.append('/bin')
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from Difficult_Rocket.api.mod import ModInfo
|
from Difficult_Rocket.api.mod import ModInfo
|
||||||
else:
|
else:
|
||||||
@ -35,9 +31,10 @@ else:
|
|||||||
from Difficult_Rocket.utils import tools
|
from Difficult_Rocket.utils import tools
|
||||||
from Difficult_Rocket.api.types import Options
|
from Difficult_Rocket.api.types import Options
|
||||||
from Difficult_Rocket.utils.translate import tr
|
from Difficult_Rocket.utils.translate import tr
|
||||||
|
from Difficult_Rocket.runtime import DR_runtime
|
||||||
from Difficult_Rocket.utils.thread import new_thread
|
from Difficult_Rocket.utils.thread import new_thread
|
||||||
from Difficult_Rocket.crash import write_info_to_cache
|
from Difficult_Rocket.crash import write_info_to_cache
|
||||||
from Difficult_Rocket import client, server, DR_option, DR_runtime
|
from Difficult_Rocket import client, server, DR_status
|
||||||
|
|
||||||
|
|
||||||
class Console(Options):
|
class Console(Options):
|
||||||
@ -154,7 +151,7 @@ class Game(Options):
|
|||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.server.run()
|
self.server.run()
|
||||||
if DR_option.use_multiprocess:
|
if DR_status.use_multiprocess:
|
||||||
try:
|
try:
|
||||||
game_process = multiprocessing.Process(target=self.client.start, name='pyglet app')
|
game_process = multiprocessing.Process(target=self.client.start, name='pyglet app')
|
||||||
game_process.start()
|
game_process.start()
|
||||||
|
@ -12,9 +12,9 @@ gitee: @shenjackyuanjie
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# system function
|
# system function
|
||||||
|
import warnings
|
||||||
from typing import Tuple, List, Optional, TypeVar, TYPE_CHECKING
|
from typing import Tuple, List, Optional, TypeVar, TYPE_CHECKING
|
||||||
|
|
||||||
|
|
||||||
# from DR
|
# from DR
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from Difficult_Rocket.main import Game
|
from Difficult_Rocket.main import Game
|
||||||
@ -22,7 +22,7 @@ if TYPE_CHECKING:
|
|||||||
else:
|
else:
|
||||||
Game = TypeVar("Game")
|
Game = TypeVar("Game")
|
||||||
ClientWindow = TypeVar("ClientWindow")
|
ClientWindow = TypeVar("ClientWindow")
|
||||||
from Difficult_Rocket import DR_runtime
|
from Difficult_Rocket import DR_status
|
||||||
from Difficult_Rocket.api.types import Options, Version
|
from Difficult_Rocket.api.types import Options, Version
|
||||||
|
|
||||||
RequireVersion = Tuple[Version, Version]
|
RequireVersion = Tuple[Version, Version]
|
||||||
@ -47,8 +47,8 @@ class ModInfo(Options):
|
|||||||
info: str = "" # 其他信息 (可以很多很多)
|
info: str = "" # 其他信息 (可以很多很多)
|
||||||
|
|
||||||
"""版本相关信息"""
|
"""版本相关信息"""
|
||||||
DR_version: RequireVersion = (DR_runtime.DR_version, DR_runtime.DR_version) # DR SDK 兼容版本
|
DR_version: RequireVersion = (DR_status.DR_version, DR_status.DR_version) # DR SDK 兼容版本
|
||||||
DR_Api_version: RequireVersion = (DR_runtime.API_version, DR_runtime.API_version) # DR Api版本
|
DR_Api_version: RequireVersion = (DR_status.API_version, DR_status.API_version) # DR Api版本
|
||||||
Mod_Require_version: List[Tuple[str, ForceRequire, RequireVersion]] = [] # mod 依赖版本
|
Mod_Require_version: List[Tuple[str, ForceRequire, RequireVersion]] = [] # mod 依赖版本
|
||||||
|
|
||||||
"""mod 状态"""
|
"""mod 状态"""
|
||||||
@ -59,9 +59,15 @@ class ModInfo(Options):
|
|||||||
config: Options = Options() # mod 配置存储
|
config: Options = Options() # mod 配置存储
|
||||||
old_mod: Optional["ModInfo"] = None # 旧的mod实例
|
old_mod: Optional["ModInfo"] = None # 旧的mod实例
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
if not self.DR_version[0] <= DR_status.DR_version <= self.DR_version[1]:
|
||||||
|
warnings.warn(f"mod {self.mod_id} version {self.version} is not support by DR {DR_status.DR_version}\nDR {self.DR_version} is required")
|
||||||
|
if not self.DR_Api_version[0] <= DR_status.API_version <= self.DR_Api_version[1]:
|
||||||
|
warnings.warn(f"mod {self.mod_id} version {self.version} is not support by DR {DR_status.API_version}\nDR {self.DR_Api_version} is required")
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
def on_load(self, game: Game, old_self: Optional["ModInfo"] = None) -> bool:
|
def on_load(self, game: Game, old_self: Optional["ModInfo"] = None) -> bool:
|
||||||
""" 加载时调用 """
|
""" 加载时调用 """
|
||||||
print(f'Mod {self.mod_id} loaded')
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def on_client_start(self, game: Game, client: ClientWindow):
|
def on_client_start(self, game: Game, client: ClientWindow):
|
||||||
|
@ -11,12 +11,11 @@ from typing import List, Dict, Optional
|
|||||||
from Difficult_Rocket.api.screen import BaseScreen
|
from Difficult_Rocket.api.screen import BaseScreen
|
||||||
from Difficult_Rocket.api.types import Options, Version
|
from Difficult_Rocket.api.types import Options, Version
|
||||||
from Difficult_Rocket.mod.api import ModInfo
|
from Difficult_Rocket.mod.api import ModInfo
|
||||||
# from Difficult_Rocket import DR_option, DR_runtime
|
# from Difficult_Rocket import DR_status, DR_runtime
|
||||||
|
|
||||||
|
|
||||||
class ModManager(Options):
|
class ModManager(Options):
|
||||||
name = 'Mod Manager'
|
name = 'Mod Manager'
|
||||||
logger: logging.Logger
|
|
||||||
|
|
||||||
mods_path: List[Path] = [Path('./mods')]
|
mods_path: List[Path] = [Path('./mods')]
|
||||||
loaded_mod_modules: Dict[str, ModInfo] = {}
|
loaded_mod_modules: Dict[str, ModInfo] = {}
|
||||||
|
79
Difficult_Rocket/runtime.py
Normal file
79
Difficult_Rocket/runtime.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# -------------------------------
|
||||||
|
# Difficult Rocket
|
||||||
|
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||||
|
# All rights reserved
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import importlib
|
||||||
|
import traceback
|
||||||
|
import contextlib
|
||||||
|
import importlib.util
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional, List, Tuple
|
||||||
|
|
||||||
|
from Difficult_Rocket.api.types import Options, Version
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'DR_runtime'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class _DR_runtime(Options):
|
||||||
|
"""
|
||||||
|
DR 的运行时配置 / 状态
|
||||||
|
"""
|
||||||
|
name = 'DR Runtime'
|
||||||
|
|
||||||
|
language: str = 'zh-CN'
|
||||||
|
mod_path: str = './mods'
|
||||||
|
DR_Mod_List: List[Tuple[str, Version]] = [] # DR Mod 列表 (name, version)
|
||||||
|
|
||||||
|
# run status
|
||||||
|
start_time_ns: Optional[int] = None
|
||||||
|
client_setup_cause_ns: Optional[int] = None
|
||||||
|
server_setup_cause_ns: Optional[int] = None
|
||||||
|
|
||||||
|
def load_file(self) -> bool:
|
||||||
|
with contextlib.suppress(FileNotFoundError):
|
||||||
|
with open('./configs/main.toml', 'r', encoding='utf-8') as f:
|
||||||
|
import rtoml
|
||||||
|
config_file = rtoml.load(f)
|
||||||
|
self.language = config_file['runtime']['language']
|
||||||
|
self.mod_path = config_file['game']['mods']['path']
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def find_mods(self) -> List[str]:
|
||||||
|
mods = []
|
||||||
|
mod_path = Path(self.mod_path)
|
||||||
|
if not mod_path.exists():
|
||||||
|
mod_path.mkdir()
|
||||||
|
return []
|
||||||
|
paths = mod_path.iterdir()
|
||||||
|
sys.path.append(self.mod_path)
|
||||||
|
for mod_path in paths:
|
||||||
|
try:
|
||||||
|
if mod_path.is_dir() and mod_path.name != '__pycache__': # 处理文件夹 mod
|
||||||
|
if importlib.util.find_spec(mod_path.name) is not None:
|
||||||
|
mods.append(mod_path.name)
|
||||||
|
else:
|
||||||
|
print(f'can not import mod {mod_path} because importlib can not find spec')
|
||||||
|
elif mod_path.suffix in ('.pyz', '.zip'): # 处理压缩包 mod
|
||||||
|
if importlib.util.find_spec(mod_path.name) is not None:
|
||||||
|
mods.append(mod_path.name)
|
||||||
|
elif mod_path.suffix == '.pyd': # pyd 扩展 mod
|
||||||
|
if importlib.util.find_spec(mod_path.name) is not None:
|
||||||
|
mods.append(mod_path.name)
|
||||||
|
elif mod_path.suffix == '.py': # 处理单文件 mod
|
||||||
|
print(f'importing mod {mod_path=} {mod_path.stem}')
|
||||||
|
if importlib.util.find_spec(mod_path.stem) is not None:
|
||||||
|
mods.append(mod_path.stem)
|
||||||
|
except ImportError:
|
||||||
|
print(f'ImportError when loading mod {mod_path}')
|
||||||
|
traceback.print_exc()
|
||||||
|
return mods
|
||||||
|
|
||||||
|
|
||||||
|
DR_runtime = _DR_runtime()
|
@ -9,13 +9,15 @@ from io import StringIO
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import get_type_hints, Type, List, Union, Dict, Any, Callable, Tuple, Optional, TYPE_CHECKING, Iterable
|
from typing import get_type_hints, Type, List, Union, Dict, Any, Callable, Tuple, Optional, TYPE_CHECKING, Iterable
|
||||||
|
|
||||||
__all__ = ['get_type_hints_',
|
__all__ = [
|
||||||
'Options',
|
'get_type_hints_',
|
||||||
'Fonts',
|
'Options',
|
||||||
'FontData',
|
'OptionsError',
|
||||||
'OptionsError',
|
'OptionNotFound',
|
||||||
'OptionNotFound',
|
'OptionNameNotDefined',
|
||||||
'OptionNameNotDefined']
|
'Fonts',
|
||||||
|
'FontData'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_type_hints_(cls: Type):
|
def get_type_hints_(cls: Type):
|
||||||
@ -137,13 +139,22 @@ class Options:
|
|||||||
raise OptionNotFound(f'Option {option} is not found in {self.name}') from None
|
raise OptionNotFound(f'Option {option} is not found in {self.name}') from None
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def str_option(self) -> Dict[str, Union[str, Any]]:
|
def str_option(self, shrink_to_long: Optional[int] = None) -> Dict[str, Union[str, Any]]:
|
||||||
"""
|
"""
|
||||||
获取配置类的所有配置 并将所有非 BuiltInType 的值转换为 str
|
获取配置类的所有配置 并将所有非 BuiltIn 类型的值转换为 str
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
raw_option = self.option()
|
raw_option = self.option()
|
||||||
return to_str_value_(raw_option)
|
str_option = to_str_value_(raw_option)
|
||||||
|
if shrink_to_long is None:
|
||||||
|
return str_option
|
||||||
|
if not isinstance(shrink_to_long, int) or shrink_to_long <= 0:
|
||||||
|
return str_option
|
||||||
|
for option, value in str_option.items():
|
||||||
|
if value is not None:
|
||||||
|
if len(str(value)) > shrink_to_long:
|
||||||
|
str_option[option] = str(value)[:shrink_to_long] + '...'
|
||||||
|
return str_option
|
||||||
|
|
||||||
def format(self, text: str) -> str:
|
def format(self, text: str) -> str:
|
||||||
"""
|
"""
|
||||||
@ -164,12 +175,15 @@ class Options:
|
|||||||
self.cached_options = self.option()
|
self.cached_options = self.option()
|
||||||
return self.cached_options
|
return self.cached_options
|
||||||
|
|
||||||
def option_with_len(self) -> Tuple[List[Tuple[str, Union[Any, Type], Type]], int, int, int]:
|
def option_with_len(self, longest: Optional[int] = None) -> Tuple[List[Tuple[str, Union[Any, Type], Type]], int, int, int]:
|
||||||
"""
|
"""
|
||||||
返回一个可以用于打印的 option 列表
|
返回一个可以用于打印的 option 列表
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
options = self.flush_option()
|
if longest is None:
|
||||||
|
options = self.flush_option()
|
||||||
|
else:
|
||||||
|
options = self.str_option(longest)
|
||||||
max_len_key = 1
|
max_len_key = 1
|
||||||
max_len_value = 1
|
max_len_value = 1
|
||||||
max_len_value_t = 1
|
max_len_value_t = 1
|
||||||
@ -182,12 +196,12 @@ class Options:
|
|||||||
option_list.append((key, value, value_t))
|
option_list.append((key, value, value_t))
|
||||||
return option_list, max_len_key, max_len_value, max_len_value_t
|
return option_list, max_len_key, max_len_value, max_len_value_t
|
||||||
|
|
||||||
def as_markdown(self) -> str:
|
def as_markdown(self, longest: Optional[int] = None) -> str:
|
||||||
"""
|
"""
|
||||||
返回一个 markdown 格式的 option 字符串
|
返回一个 markdown 格式的 option 字符串
|
||||||
:return: markdown 格式的 option 字符串
|
:return: markdown 格式的 option 字符串
|
||||||
"""
|
"""
|
||||||
value = self.option_with_len()
|
value = self.option_with_len(longest)
|
||||||
cache = StringIO()
|
cache = StringIO()
|
||||||
option_len = max(value[1], len('Option'))
|
option_len = max(value[1], len('Option'))
|
||||||
value_len = max(value[2], len('Value'))
|
value_len = max(value[2], len('Value'))
|
||||||
|
@ -17,8 +17,9 @@ import inspect
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Union, Tuple, Any, List, Dict, Hashable, Optional
|
from typing import Union, Tuple, Any, List, Dict, Hashable, Optional
|
||||||
|
|
||||||
from Difficult_Rocket import DR_runtime, DR_option
|
from Difficult_Rocket import DR_status
|
||||||
from Difficult_Rocket.utils import tools
|
from Difficult_Rocket.utils import tools
|
||||||
|
from Difficult_Rocket.runtime import DR_runtime
|
||||||
from Difficult_Rocket.exception.language import (LanguageNotFound,
|
from Difficult_Rocket.exception.language import (LanguageNotFound,
|
||||||
TranslateKeyNotFound)
|
TranslateKeyNotFound)
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ class Translates:
|
|||||||
def _raise_no_value(self, e: Exception, item: key_type):
|
def _raise_no_value(self, e: Exception, item: key_type):
|
||||||
if self._config.raise_error:
|
if self._config.raise_error:
|
||||||
raise TranslateKeyNotFound(self._value, [x[1] for x in self._get_list]) from None
|
raise TranslateKeyNotFound(self._value, [x[1] for x in self._get_list]) from None
|
||||||
elif DR_option.report_translate_not_found:
|
elif DR_status.report_translate_not_found:
|
||||||
frame = inspect.currentframe()
|
frame = inspect.currentframe()
|
||||||
if frame is not None:
|
if frame is not None:
|
||||||
frame = frame.f_back.f_back
|
frame = frame.f_back.f_back
|
||||||
@ -160,7 +161,7 @@ class Tr:
|
|||||||
"""
|
"""
|
||||||
self.language_name = language if language is not None else DR_runtime.language
|
self.language_name = language if language is not None else DR_runtime.language
|
||||||
self.translates: Dict[str, Union[str, Dict]] = tools.load_file(f'configs/lang/{self.language_name}.toml')
|
self.translates: Dict[str, Union[str, Dict]] = tools.load_file(f'configs/lang/{self.language_name}.toml')
|
||||||
self.default_translate: Dict = tools.load_file(f'configs/lang/{DR_runtime.default_language}.toml')
|
self.default_translate: Dict = tools.load_file(f'configs/lang/{DR_status.default_language}.toml')
|
||||||
self.default_config = config.set('source', self) if config is not None else TranslateConfig(source=self)
|
self.default_config = config.set('source', self) if config is not None else TranslateConfig(source=self)
|
||||||
self.translates_cache = Translates(value=self.translates, config=self.default_config.copy())
|
self.translates_cache = Translates(value=self.translates, config=self.default_config.copy())
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
[关于版本号的说明](./docs/src/version.md)
|
[关于版本号的说明](./docs/src/version.md)
|
||||||
|
|
||||||
[![Generic badge](https://img.shields.io/badge/Release-0.8.2.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
[![Generic badge](https://img.shields.io/badge/Release-0.8.3.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||||
[![Generic badge](https://img.shields.io/badge/Pre_Release-0.8.2.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
[![Generic badge](https://img.shields.io/badge/Pre_Release-0.8.3.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||||
[![Generic badge](https://img.shields.io/badge/Devloping-0.8.3-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
[![Generic badge](https://img.shields.io/badge/Devloping-0.8.4-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||||
|
|
||||||
[![language badge](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)
|
[![language badge](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ env.version.python = "Python version: {}"
|
|||||||
env.version.DR = "Difficult_Rocket version: {}"
|
env.version.DR = "Difficult_Rocket version: {}"
|
||||||
env.version.DR_rs = "Difficult_Rocket_rs version: {}"
|
env.version.DR_rs = "Difficult_Rocket_rs version: {}"
|
||||||
env.version.pyglet = "pyglet version: {}"
|
env.version.pyglet = "pyglet version: {}"
|
||||||
env.version.pyglet_rs = "pyglet_rs version: {}"
|
|
||||||
version.now_on = "Difficult Rocket is running on Python Vision"
|
version.now_on = "Difficult Rocket is running on Python Vision"
|
||||||
version.need3p = "Difficult Rocket depends on Python vision 3.0+"
|
version.need3p = "Difficult Rocket depends on Python vision 3.0+"
|
||||||
version.best38p = "Difficult Rocket is writen in Python {write_py_v}, and now is running on Python {py_v} may cause BUG"
|
version.best38p = "Difficult Rocket is writen in Python {write_py_v}, and now is running on Python {py_v} may cause BUG"
|
||||||
@ -30,6 +29,7 @@ mod.load.info = "mod id: {} version: {}"
|
|||||||
mod.load.faild.info = "Mod load failed: {} error info: {}"
|
mod.load.faild.info = "Mod load failed: {} error info: {}"
|
||||||
mod.load.faild.no_mod_class = "Can't find Mod class"
|
mod.load.faild.no_mod_class = "Can't find Mod class"
|
||||||
mod.load.done = "All Mod loaded"
|
mod.load.done = "All Mod loaded"
|
||||||
|
mod.event.error = "Mod evenet {} caught error: {} Mod: {}"
|
||||||
|
|
||||||
[client]
|
[client]
|
||||||
setup.start = "Client start loading"
|
setup.start = "Client start loading"
|
||||||
@ -72,8 +72,8 @@ os.pid_is = "Server PID: {} PPID: {}"
|
|||||||
|
|
||||||
[game]
|
[game]
|
||||||
input = "console"
|
input = "console"
|
||||||
command = "in game commands"
|
|
||||||
window = "window"
|
window = "window"
|
||||||
|
command = "in game commands"
|
||||||
require_DR_rs = "require DR_rs module"
|
require_DR_rs = "require DR_rs module"
|
||||||
|
|
||||||
[client.sr1_render]
|
[client.sr1_render]
|
||||||
|
@ -7,7 +7,6 @@ env.version.python = "Python 版本: {}"
|
|||||||
env.version.DR = "Difficult_Rocket 版本: {}"
|
env.version.DR = "Difficult_Rocket 版本: {}"
|
||||||
env.version.DR_rs = "Difficult_Rocket_rs 版本: {}"
|
env.version.DR_rs = "Difficult_Rocket_rs 版本: {}"
|
||||||
env.version.pyglet = "pyglet 版本: {}"
|
env.version.pyglet = "pyglet 版本: {}"
|
||||||
env.version.pyglet_rs = "pyglet_rs 版本: {}"
|
|
||||||
version.now_on = "困难火箭的运行 Python 环境为"
|
version.now_on = "困难火箭的运行 Python 环境为"
|
||||||
version.need3p = "困难火箭需要 Python3.0+ 的环境"
|
version.need3p = "困难火箭需要 Python3.0+ 的环境"
|
||||||
version.best38p = "困难火箭是在 Python {write_py_v} 的环境下编写的,目前正在运行在Python {py_v}的环境下,可能产生BUG"
|
version.best38p = "困难火箭是在 Python {write_py_v} 的环境下编写的,目前正在运行在Python {py_v}的环境下,可能产生BUG"
|
||||||
@ -73,8 +72,8 @@ os.pid_is = "服务端 PID: {} PPID: {}"
|
|||||||
|
|
||||||
[game]
|
[game]
|
||||||
input = "控制台"
|
input = "控制台"
|
||||||
command = "游戏内命令行"
|
|
||||||
window = "窗口"
|
window = "窗口"
|
||||||
|
command = "游戏内命令行"
|
||||||
require_DR_rs = "需要 DR_rs 模块"
|
require_DR_rs = "需要 DR_rs 模块"
|
||||||
|
|
||||||
[client.sr1_render]
|
[client.sr1_render]
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
'language': 'zh-cn',
|
|
||||||
'textures': {
|
|
||||||
'back_ground_space': 'back_ground_space.png',
|
|
||||||
'planet': {
|
|
||||||
'earth_ground': 'earth_ground.png'
|
|
||||||
},
|
|
||||||
'flame': {
|
|
||||||
'liquid': 'liquid_engine_flame.png',
|
|
||||||
'solid': 'solid_engine_flame.png',
|
|
||||||
'ion': 'ion_engine_flame.png'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'basic_number': {
|
|
||||||
'G': [
|
|
||||||
6.67,
|
|
||||||
-11,
|
|
||||||
[
|
|
||||||
'N',
|
|
||||||
'm',
|
|
||||||
'm'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'kg',
|
|
||||||
'kg'
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'default ship': [
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
{
|
|
||||||
/*
|
|
||||||
'part id': [
|
|
||||||
[
|
|
||||||
'part name', // part name can be reuse
|
|
||||||
'description', // 描述
|
|
||||||
], // about names and other
|
|
||||||
[ 'float', // mass
|
|
||||||
'bool', // hidden in part list
|
|
||||||
'bool', // hidden in mission (even thought that is not done yet)
|
|
||||||
'float' // buoyancy(浮力) in the water
|
|
||||||
], // about config
|
|
||||||
[ 'xxx.png', // texture file name
|
|
||||||
//可以为包含文件夹的 比如:./engine/xxx.png
|
|
||||||
[ 'float', // 贴图偏移量
|
|
||||||
'float' ] // 指的是部件的碰撞箱左上角到贴图左上角的距离
|
|
||||||
], // about texture
|
|
||||||
[ 'float',
|
|
||||||
'float' ],
|
|
||||||
// 碰撞箱大小 (暂时只支持方形碰撞箱)
|
|
||||||
// 坐标轴也是从左下开始
|
|
||||||
[
|
|
||||||
'特殊值(懒得写)'
|
|
||||||
]
|
|
||||||
],
|
|
||||||
*/
|
|
||||||
'test1': [
|
|
||||||
[
|
|
||||||
'test-1',
|
|
||||||
'一个测试用部件'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1.0,
|
|
||||||
false,
|
|
||||||
0.1
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'parts/Beam.png',
|
|
||||||
[
|
|
||||||
0.0,
|
|
||||||
0.0
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
3.0,
|
|
||||||
2.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
'Solar System': {
|
|
||||||
'description': '',
|
|
||||||
'planets': {
|
|
||||||
'earth': {
|
|
||||||
'description': '',
|
|
||||||
'gravity': 9.81,
|
|
||||||
'radius': 63710000,
|
|
||||||
'map_color': [
|
|
||||||
103,
|
|
||||||
157,
|
|
||||||
255
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
[Runtime]
|
|
||||||
|
|
||||||
[Parts]
|
|
||||||
battery = "Battery.png"
|
|
||||||
beam = "Beam.png"
|
|
||||||
cover_bottom = "CoverBottom.png"
|
|
||||||
nose_cone = "NoseCone.png"
|
|
||||||
|
|
||||||
[Editor]
|
|
||||||
[[runtime]]
|
|
||||||
"toolbar.dark" = "ToolbarDark.png"
|
|
||||||
"toolbar.light" = "ToolbarLight.png"
|
|
||||||
"button_side.dark" = "ButtonDarkSide.png"
|
|
||||||
"button_side.light" = "ButtonLightSide.png"
|
|
||||||
|
|
||||||
[[toggle_button]]
|
|
||||||
stage = "ToolbarIconStaging.png"
|
|
||||||
add_part = "ToolbarIconAddPart.png"
|
|
||||||
menu = "ToolbarIconMenu.png"
|
|
||||||
|
|
||||||
[[push_button]]
|
|
||||||
zoom = "ToolbarIconZoom.png"
|
|
||||||
"zoom.in" = "ToolbarIconZoomIn.png"
|
|
||||||
"zoom.out" = "ToolbarIconZoomOut.png"
|
|
||||||
play = "ToolbarIconPlay.png"
|
|
||||||
rotate = "RotateButton.png"
|
|
||||||
trash_can = "TrashCan.png"
|
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
[About Versions](src/version.md)
|
[About Versions](src/version.md)
|
||||||
|
|
||||||
[![Generic badge](https://img.shields.io/badge/Release-0.8.2.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
[![Generic badge](https://img.shields.io/badge/Release-0.8.3.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||||
[![Generic badge](https://img.shields.io/badge/Pre_Release-0.8.2.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
[![Generic badge](https://img.shields.io/badge/Pre_Release-0.8.3.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||||
[![Generic badge](https://img.shields.io/badge/Devloping-0.8.3-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
[![Generic badge](https://img.shields.io/badge/Devloping-0.8.4-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||||
|
|
||||||
[![language badge](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)
|
[![language badge](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
- [nuitka performents test](./nuitka/20221121_nuitka_performs.md)
|
- [nuitka performents test](./nuitka/20221121_nuitka_performs.md)
|
||||||
- [nuitka options](./nuitka/20230116_nuitka_options.md)
|
- [nuitka options](./nuitka/20230116_nuitka_options.md)
|
||||||
- [nuitka 1.3.7 compile options](./nuitka/nuitka_options_137.md)
|
- [nuitka 1.3.7 compile options](./nuitka/nuitka_options_137.md)
|
||||||
|
- [nuitka 1.6.1 compile options](./nuitka/nuitka_options_161.md)
|
||||||
|
|
||||||
- [计划特性](./plan_features/README.md)
|
- [计划特性](./plan_features/README.md)
|
||||||
- [格式](./plan_features/格式.md)
|
- [格式](./plan_features/格式.md)
|
||||||
|
@ -2,9 +2,15 @@
|
|||||||
# DR game/DR rs 更新日志
|
# DR game/DR rs 更新日志
|
||||||
|
|
||||||
- 最新版本号
|
- 最新版本号
|
||||||
- DR game: 0.1.1.0
|
- DR game: 0.2.0.0
|
||||||
- DR rs: 0.2.10.1
|
- DR rs: 0.2.10.1
|
||||||
|
|
||||||
|
## DR game 0.2.0.0
|
||||||
|
|
||||||
|
### 适配
|
||||||
|
|
||||||
|
- 适配了 `DR_sdk` `0.8.3.0` 的修改
|
||||||
|
|
||||||
## DR game 0.1.1.0
|
## DR game 0.1.1.0
|
||||||
|
|
||||||
### 添加
|
### 添加
|
||||||
|
@ -2,7 +2,86 @@
|
|||||||
# DR SDK 更新日志
|
# DR SDK 更新日志
|
||||||
|
|
||||||
- 最新版本号
|
- 最新版本号
|
||||||
- DR sdk: 0.8.2.0
|
- DR sdk: 0.8.3.0
|
||||||
|
|
||||||
|
## DR sdk 0.8.3.1
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- issue #33 (https://github.com/shenjackyuanjie/Difficult-Rocket/issues/33)
|
||||||
|
- 修复了实际上并不会加载 `.otf` 格式的字体文件的问题
|
||||||
|
|
||||||
|
## DR sdk 0.8.3.0
|
||||||
|
|
||||||
|
### 删除
|
||||||
|
|
||||||
|
- `pyglet_rs`
|
||||||
|
- 事实证明这玩意没啥用
|
||||||
|
- Removed pyglet_rs
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- issue #31 (https://github.com/shenjackyuanjie/Difficult-Rocket/issues/31)
|
||||||
|
- 窗口标题不正确 (实际上是因为只使用 `DR_runtime` 进行格式化)
|
||||||
|
- Window title is incorrect
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- `DR_status`
|
||||||
|
- 实际上就是 `DR_runtime`
|
||||||
|
- `DR_runtime` -> `DR_status`
|
||||||
|
- `client_running`
|
||||||
|
- 客户端是否在运行
|
||||||
|
- Is client running
|
||||||
|
- `server_running`
|
||||||
|
- 服务器是否在运行
|
||||||
|
- Is server running
|
||||||
|
- Mod loader
|
||||||
|
- 添加了对支持版本号的 warnings
|
||||||
|
- Added warnings for supporting version numbers
|
||||||
|
|
||||||
|
### 移动
|
||||||
|
|
||||||
|
- `Difficult_Rocket.DR_runtime`
|
||||||
|
- `DR_version` -> `DR_status.DR_version`
|
||||||
|
- `API_version` -> `DR_status.API_version`
|
||||||
|
- `Build_version` -> `DR_status.Build_version`
|
||||||
|
- `default_language` -> `DR_status.default_language`
|
||||||
|
|
||||||
|
### 删除
|
||||||
|
|
||||||
|
- `Diffiuclt_Rocket.long_version`
|
||||||
|
- 不再使用整数标记版本号 (反正 `Version` 有一个完整的版本号比较机制)
|
||||||
|
- No longer use integer to mark version number (since `Version` has a complete version comparison mechanism)
|
||||||
|
- `Difficult_Rocket.DR_rust_available`
|
||||||
|
- 似乎我忘记删掉这个 `DR_rs` 的耦合了
|
||||||
|
|
||||||
|
```python
|
||||||
|
long_version: int = 15
|
||||||
|
"""
|
||||||
|
long_version: 一个用于标记内部协议的整数
|
||||||
|
15: 完全移除 DR_rust 相关内容 解耦完成
|
||||||
|
14: BaseScreen 的每一个函数都添加了一个参数: window: "ClientWindow"
|
||||||
|
13: 为 DR_runtime 添加 API_version
|
||||||
|
12: 去除 DR_runtime 的 global_logger
|
||||||
|
要 logging 自己拿去(
|
||||||
|
11: 为 DR_option 添加 use_DR_rust
|
||||||
|
修复了一些拼写错误
|
||||||
|
10: 为 DR_runtime 添加 DR_Rust_get_version
|
||||||
|
9 : 为 DR_option 添加 pyglet_macosx_dev_test
|
||||||
|
8 : 为 DR_runtime 添加 DR_rust_version
|
||||||
|
为 DR_option 添加 DR_rust_available
|
||||||
|
以后就有 DR_rust 了
|
||||||
|
7 : 为 DR_option 添加 std_font_size
|
||||||
|
6 : 事实证明, 不如直接用int
|
||||||
|
5 : 添加 build_version 信息,用于标记编译文件版本,
|
||||||
|
游戏版本改为四位数,终于有一个可以让我随便刷的版本号位数了
|
||||||
|
4 : 把 translate 的字体常量位置改了一下,顺便调换顺序
|
||||||
|
3 : 就是试试改一下,正好 compiler 要用
|
||||||
|
2 : 哦,对 longlong 好耶!
|
||||||
|
1 : 我可算想起来还有这回事了 v0.6.4
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
## DR sdk 0.8.2.0
|
## DR sdk 0.8.2.0
|
||||||
|
|
||||||
|
629
docs/src/nuitka/nuitka_options_161.md
Normal file
629
docs/src/nuitka/nuitka_options_161.md
Normal file
@ -0,0 +1,629 @@
|
|||||||
|
# nuitka 1.6.1 --help
|
||||||
|
|
||||||
|
``` text
|
||||||
|
Usage: __main__.py [--module] [--run] [options] main_module.py
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help show this help message and exit
|
||||||
|
--version Show version information and important details for bug
|
||||||
|
reports, then exit. Defaults to off.
|
||||||
|
--module Create an extension module executable instead of a
|
||||||
|
program. Defaults to off.
|
||||||
|
--standalone Enable standalone mode for output. This allows you to
|
||||||
|
transfer the created binary to other machines without
|
||||||
|
it using an existing Python installation. This also
|
||||||
|
means it will become big. It implies these option: "--
|
||||||
|
follow-imports" and "--python-flag=no_site". Defaults
|
||||||
|
to off.
|
||||||
|
--onefile On top of standalone mode, enable onefile mode. This
|
||||||
|
means not a folder, but a compressed executable is
|
||||||
|
created and used. Defaults to off.
|
||||||
|
--python-debug Use debug version or not. Default uses what you are
|
||||||
|
using to run Nuitka, most likely a non-debug version.
|
||||||
|
--python-flag=FLAG Python flags to use. Default is what you are using to
|
||||||
|
run Nuitka, this enforces a specific mode. These are
|
||||||
|
options that also exist to standard Python executable.
|
||||||
|
Currently supported: "-S" (alias "no_site"),
|
||||||
|
"static_hashes" (do not use hash randomization),
|
||||||
|
"no_warnings" (do not give Python run time warnings),
|
||||||
|
"-O" (alias "no_asserts"), "no_docstrings" (do not use
|
||||||
|
doc strings), "-u" (alias "unbuffered") and "-m".
|
||||||
|
Default empty.
|
||||||
|
--python-for-scons=PATH
|
||||||
|
If using Python3.3 or Python3.4, provide the path of a
|
||||||
|
Python binary to use for Scons. Otherwise Nuitka can
|
||||||
|
use what you run Nuitka with or a Python installation
|
||||||
|
from Windows registry. On Windows Python 3.5 or higher
|
||||||
|
is needed. On non-Windows, Python 2.6 or 2.7 will do
|
||||||
|
as well.
|
||||||
|
|
||||||
|
Control the inclusion of modules and packages in result:
|
||||||
|
--include-package=PACKAGE
|
||||||
|
Include a whole package. Give as a Python namespace,
|
||||||
|
e.g. "some_package.sub_package" and Nuitka will then
|
||||||
|
find it and include it and all the modules found below
|
||||||
|
that disk location in the binary or extension module
|
||||||
|
it creates, and make it available for import by the
|
||||||
|
code. To avoid unwanted sub packages, e.g. tests you
|
||||||
|
can e.g. do this "--nofollow-import-to=*.tests".
|
||||||
|
Default empty.
|
||||||
|
--include-module=MODULE
|
||||||
|
Include a single module. Give as a Python namespace,
|
||||||
|
e.g. "some_package.some_module" and Nuitka will then
|
||||||
|
find it and include it in the binary or extension
|
||||||
|
module it creates, and make it available for import by
|
||||||
|
the code. Default empty.
|
||||||
|
--include-plugin-directory=MODULE/PACKAGE
|
||||||
|
Include also the code found in that directory,
|
||||||
|
considering as if they are each given as a main file.
|
||||||
|
Overrides all other inclusion options. You ought to
|
||||||
|
prefer other inclusion options, that go by names,
|
||||||
|
rather than filenames, those find things through being
|
||||||
|
in "sys.path". This option is for very special use
|
||||||
|
cases only. Can be given multiple times. Default
|
||||||
|
empty.
|
||||||
|
--include-plugin-files=PATTERN
|
||||||
|
Include into files matching the PATTERN. Overrides all
|
||||||
|
other follow options. Can be given multiple times.
|
||||||
|
Default empty.
|
||||||
|
--prefer-source-code
|
||||||
|
For already compiled extension modules, where there is
|
||||||
|
both a source file and an extension module, normally
|
||||||
|
the extension module is used, but it should be better
|
||||||
|
to compile the module from available source code for
|
||||||
|
best performance. If not desired, there is --no-
|
||||||
|
prefer-source-code to disable warnings about it.
|
||||||
|
Default off.
|
||||||
|
|
||||||
|
Control the following into imported modules:
|
||||||
|
--follow-imports Descend into all imported modules. Defaults to on in
|
||||||
|
standalone mode, otherwise off.
|
||||||
|
--follow-import-to=MODULE/PACKAGE
|
||||||
|
Follow to that module if used, or if a package, to the
|
||||||
|
whole package. Can be given multiple times. Default
|
||||||
|
empty.
|
||||||
|
--nofollow-import-to=MODULE/PACKAGE
|
||||||
|
Do not follow to that module name even if used, or if
|
||||||
|
a package name, to the whole package in any case,
|
||||||
|
overrides all other options. Can be given multiple
|
||||||
|
times. Default empty.
|
||||||
|
--nofollow-imports Do not descend into any imported modules at all,
|
||||||
|
overrides all other inclusion options and not usable
|
||||||
|
for standalone mode. Defaults to off.
|
||||||
|
--follow-stdlib Also descend into imported modules from standard
|
||||||
|
library. This will increase the compilation time by a
|
||||||
|
lot and is also not well tested at this time and
|
||||||
|
sometimes won't work. Defaults to off.
|
||||||
|
|
||||||
|
Onefile options:
|
||||||
|
--onefile-tempdir-spec=ONEFILE_TEMPDIR_SPEC
|
||||||
|
Use this as a folder to unpack to in onefile mode.
|
||||||
|
Defaults to '%TEMP%/onefile_%PID%_%TIME%', i.e. user
|
||||||
|
temporary directory and being non-static it's removed.
|
||||||
|
Use e.g. a string like
|
||||||
|
'%CACHE_DIR%/%COMPANY%/%PRODUCT%/%VERSION%' which is a
|
||||||
|
good static cache path, this will then not be removed.
|
||||||
|
--onefile-child-grace-time=GRACE_TIME_MS
|
||||||
|
When stopping the child, e.g. due to CTRL-C or
|
||||||
|
shutdown, etc. the Python code gets a
|
||||||
|
"KeyboardInterrupt", that it may handle e.g. to flush
|
||||||
|
data. This is the amount of time in ms, before the
|
||||||
|
child it killed in the hard way. Unit is ms, and
|
||||||
|
default 5000.
|
||||||
|
--onefile-no-compression
|
||||||
|
When creating the onefile, disable compression of the
|
||||||
|
payload. This is mostly for debug purposes, or to save
|
||||||
|
time. Default is off.
|
||||||
|
|
||||||
|
Data files:
|
||||||
|
--include-package-data=PACKAGE
|
||||||
|
Include data files for the given package name. DLLs
|
||||||
|
and extension modules are not data files and never
|
||||||
|
included like this. Can use patterns the filenames as
|
||||||
|
indicated below. Data files of packages are not
|
||||||
|
included by default, but package configuration can do
|
||||||
|
it. This will only include non-DLL, non-extension
|
||||||
|
modules, i.e. actual data files. After a ":"
|
||||||
|
optionally a filename pattern can be given as well,
|
||||||
|
selecting only matching files. Examples: "--include-
|
||||||
|
package-data=package_name" (all files) "--include-
|
||||||
|
package-data=package_name=*.txt" (only certain type) "
|
||||||
|
--include-package-data=package_name=some_filename.dat
|
||||||
|
(concrete file) Default empty.
|
||||||
|
--include-data-files=DESC
|
||||||
|
Include data files by filenames in the distribution.
|
||||||
|
There are many allowed forms. With '--include-data-
|
||||||
|
files=/path/to/file/*.txt=folder_name/some.txt' it
|
||||||
|
will copy a single file and complain if it's multiple.
|
||||||
|
With '--include-data-
|
||||||
|
files=/path/to/files/*.txt=folder_name/' it will put
|
||||||
|
all matching files into that folder. For recursive
|
||||||
|
copy there is a form with 3 values that '--include-
|
||||||
|
data-files=/path/to/scan=folder_name=**/*.txt' that
|
||||||
|
will preserve directory structure. Default empty.
|
||||||
|
--include-data-dir=DIRECTORY
|
||||||
|
Include data files from complete directory in the
|
||||||
|
distribution. This is recursive. Check '--include-
|
||||||
|
data-files' with patterns if you want non-recursive
|
||||||
|
inclusion. An example would be '--include-data-
|
||||||
|
dir=/path/some_dir=data/some_dir' for plain copy, of
|
||||||
|
the whole directory. All files are copied, if you want
|
||||||
|
to exclude files you need to remove them beforehand,
|
||||||
|
or use '--noinclude-data-files' option to remove them.
|
||||||
|
Default empty.
|
||||||
|
--noinclude-data-files=PATTERN
|
||||||
|
Do not include data files matching the filename
|
||||||
|
pattern given. This is against the target filename,
|
||||||
|
not source paths. So to ignore a file pattern from
|
||||||
|
package data for "package_name" should be matched as
|
||||||
|
"package_name/*.txt". Or for the whole directory
|
||||||
|
simply use "package_name". Default empty.
|
||||||
|
--list-package-data=LIST_PACKAGE_DATA
|
||||||
|
Output the data files found for a given package name.
|
||||||
|
Default not done.
|
||||||
|
|
||||||
|
Metadata support:
|
||||||
|
--include-distribution-metadata=DISTRIBUTION
|
||||||
|
Include metadata information for the given
|
||||||
|
distribution name. Some packages check metadata for
|
||||||
|
presence, version, entry points, etc. and without this
|
||||||
|
option given, it only works when it's recognized at
|
||||||
|
compile time which is not always happening. This of
|
||||||
|
course only makes sense for packages that are included
|
||||||
|
in the compilation. Default empty.
|
||||||
|
|
||||||
|
DLL files:
|
||||||
|
--noinclude-dlls=PATTERN
|
||||||
|
Do not include DLL files matching the filename pattern
|
||||||
|
given. This is against the target filename, not source
|
||||||
|
paths. So ignore a DLL "someDLL" contained in the
|
||||||
|
package "package_name" it should be matched as
|
||||||
|
"package_name/someDLL.*". Default empty.
|
||||||
|
--list-package-dlls=LIST_PACKAGE_DLLS
|
||||||
|
Output the DLLs found for a given package name.
|
||||||
|
Default not done.
|
||||||
|
|
||||||
|
Control the warnings to be given by Nuitka:
|
||||||
|
--warn-implicit-exceptions
|
||||||
|
Enable warnings for implicit exceptions detected at
|
||||||
|
compile time.
|
||||||
|
--warn-unusual-code
|
||||||
|
Enable warnings for unusual code detected at compile
|
||||||
|
time.
|
||||||
|
--assume-yes-for-downloads
|
||||||
|
Allow Nuitka to download external code if necessary,
|
||||||
|
e.g. dependency walker, ccache, and even gcc on
|
||||||
|
Windows. To disable, redirect input from nul device,
|
||||||
|
e.g. "</dev/null" or "<NUL:". Default is to prompt.
|
||||||
|
--nowarn-mnemonic=MNEMONIC
|
||||||
|
Disable warning for a given mnemonic. These are given
|
||||||
|
to make sure you are aware of certain topics, and
|
||||||
|
typically point to the Nuitka website. The mnemonic is
|
||||||
|
the part of the URL at the end, without the HTML
|
||||||
|
suffix. Can be given multiple times and accepts shell
|
||||||
|
pattern. Default empty.
|
||||||
|
|
||||||
|
Immediate execution after compilation:
|
||||||
|
--run Execute immediately the created binary (or import the
|
||||||
|
compiled module). Defaults to off.
|
||||||
|
--debugger Execute inside a debugger, e.g. "gdb" or "lldb" to
|
||||||
|
automatically get a stack trace. Defaults to off.
|
||||||
|
--execute-with-pythonpath
|
||||||
|
When immediately executing the created binary or
|
||||||
|
module using '--run', don't reset 'PYTHONPATH'
|
||||||
|
environment. When all modules are successfully
|
||||||
|
included, you ought to not need PYTHONPATH anymore,
|
||||||
|
and definitely not for standalone mode.
|
||||||
|
|
||||||
|
Compilation choices:
|
||||||
|
--user-package-configuration-file=YAML_FILENAME
|
||||||
|
User provided Yaml file with package configuration.
|
||||||
|
You can include DLLs, remove bloat, add hidden
|
||||||
|
dependencies. Check User Manual for a complete
|
||||||
|
description of the format to use. Can be given
|
||||||
|
multiple times. Defaults to empty.
|
||||||
|
--full-compat Enforce absolute compatibility with CPython. Do not
|
||||||
|
even allow minor deviations from CPython behavior,
|
||||||
|
e.g. not having better tracebacks or exception
|
||||||
|
messages which are not really incompatible, but only
|
||||||
|
different or worse. This is intended for tests only
|
||||||
|
and should *not* be used.
|
||||||
|
--file-reference-choice=MODE
|
||||||
|
Select what value "__file__" is going to be. With
|
||||||
|
"runtime" (default for standalone binary mode and
|
||||||
|
module mode), the created binaries and modules, use
|
||||||
|
the location of themselves to deduct the value of
|
||||||
|
"__file__". Included packages pretend to be in
|
||||||
|
directories below that location. This allows you to
|
||||||
|
include data files in deployments. If you merely seek
|
||||||
|
acceleration, it's better for you to use the
|
||||||
|
"original" value, where the source files location will
|
||||||
|
be used. With "frozen" a notation "<frozen
|
||||||
|
module_name>" is used. For compatibility reasons, the
|
||||||
|
"__file__" value will always have ".py" suffix
|
||||||
|
independent of what it really is.
|
||||||
|
--module-name-choice=MODE
|
||||||
|
Select what value "__name__" and "__package__" are
|
||||||
|
going to be. With "runtime" (default for module mode),
|
||||||
|
the created module uses the parent package to deduce
|
||||||
|
the value of "__package__", to be fully compatible.
|
||||||
|
The value "original" (default for other modes) allows
|
||||||
|
for more static optimization to happen, but is
|
||||||
|
incompatible for modules that normally can be loaded
|
||||||
|
into any package.
|
||||||
|
|
||||||
|
Output choices:
|
||||||
|
--output-filename=FILENAME
|
||||||
|
Specify how the executable should be named. For
|
||||||
|
extension modules there is no choice, also not for
|
||||||
|
standalone mode and using it will be an error. This
|
||||||
|
may include path information that needs to exist
|
||||||
|
though. Defaults to '<program_name>' on this platform.
|
||||||
|
.exe
|
||||||
|
--output-dir=DIRECTORY
|
||||||
|
Specify where intermediate and final output files
|
||||||
|
should be put. The DIRECTORY will be populated with
|
||||||
|
build folder, dist folder, binaries, etc. Defaults to
|
||||||
|
current directory.
|
||||||
|
--remove-output Removes the build directory after producing the module
|
||||||
|
or exe file. Defaults to off.
|
||||||
|
--no-pyi-file Do not create a ".pyi" file for extension modules
|
||||||
|
created by Nuitka. This is used to detect implicit
|
||||||
|
imports. Defaults to off.
|
||||||
|
|
||||||
|
Debug features:
|
||||||
|
--debug Executing all self checks possible to find errors in
|
||||||
|
Nuitka, do not use for production. Defaults to off.
|
||||||
|
--unstripped Keep debug info in the resulting object file for
|
||||||
|
better debugger interaction. Defaults to off.
|
||||||
|
--profile Enable vmprof based profiling of time spent. Not
|
||||||
|
working currently. Defaults to off.
|
||||||
|
--internal-graph Create graph of optimization process internals, do not
|
||||||
|
use for whole programs, but only for small test cases.
|
||||||
|
Defaults to off.
|
||||||
|
--trace-execution Traced execution output, output the line of code
|
||||||
|
before executing it. Defaults to off.
|
||||||
|
--recompile-c-only This is not incremental compilation, but for Nuitka
|
||||||
|
development only. Takes existing files and simply
|
||||||
|
compile them as C again. Allows compiling edited C
|
||||||
|
files for quick debugging changes to the generated
|
||||||
|
source, e.g. to see if code is passed by, values
|
||||||
|
output, etc, Defaults to off. Depends on compiling
|
||||||
|
Python source to determine which files it should look
|
||||||
|
at.
|
||||||
|
--xml=XML_FILENAME Write the internal program structure, result of
|
||||||
|
optimization in XML form to given filename.
|
||||||
|
--generate-c-only Generate only C source code, and do not compile it to
|
||||||
|
binary or module. This is for debugging and code
|
||||||
|
coverage analysis that doesn't waste CPU. Defaults to
|
||||||
|
off. Do not think you can use this directly.
|
||||||
|
--experimental=FLAG
|
||||||
|
Use features declared as 'experimental'. May have no
|
||||||
|
effect if no experimental features are present in the
|
||||||
|
code. Uses secret tags (check source) per experimented
|
||||||
|
feature.
|
||||||
|
--low-memory Attempt to use less memory, by forking less C
|
||||||
|
compilation jobs and using options that use less
|
||||||
|
memory. For use on embedded machines. Use this in case
|
||||||
|
of out of memory problems. Defaults to off.
|
||||||
|
--create-environment-from-report=CREATE_ENVIRONMENT_FROM_REPORT
|
||||||
|
Create a new virtualenv in that non-existing path from
|
||||||
|
the report file given with e.g. '--report=compilation-
|
||||||
|
report.xml'. Default not done.
|
||||||
|
|
||||||
|
Backend C compiler choice:
|
||||||
|
--clang Enforce the use of clang. On Windows this requires a
|
||||||
|
working Visual Studio version to piggy back on.
|
||||||
|
Defaults to off.
|
||||||
|
--mingw64 Enforce the use of MinGW64 on Windows. Defaults to off
|
||||||
|
unless MSYS2 with MinGW Python is used.
|
||||||
|
--msvc=MSVC_VERSION
|
||||||
|
Enforce the use of specific MSVC version on Windows.
|
||||||
|
Allowed values are e.g. "14.3" (MSVC 2022) and other
|
||||||
|
MSVC version numbers, specify "list" for a list of
|
||||||
|
installed compilers, or use "latest". Defaults to
|
||||||
|
latest MSVC being used if installed, otherwise MinGW64
|
||||||
|
is used.
|
||||||
|
--jobs=N Specify the allowed number of parallel C compiler
|
||||||
|
jobs. Defaults to the system CPU count.
|
||||||
|
--lto=choice Use link time optimizations (MSVC, gcc, clang).
|
||||||
|
Allowed values are "yes", "no", and "auto" (when it's
|
||||||
|
known to work). Defaults to "auto".
|
||||||
|
--static-libpython=choice
|
||||||
|
Use static link library of Python. Allowed values are
|
||||||
|
"yes", "no", and "auto" (when it's known to work).
|
||||||
|
Defaults to "auto".
|
||||||
|
|
||||||
|
Cache Control:
|
||||||
|
--disable-cache=DISABLED_CACHES
|
||||||
|
Disable selected caches, specify "all" for all cached.
|
||||||
|
Currently allowed values are:
|
||||||
|
"all","ccache","bytecode","dll-dependencies". can be
|
||||||
|
given multiple times or with comma separated values.
|
||||||
|
Default none.
|
||||||
|
--clean-cache=CLEAN_CACHES
|
||||||
|
Clean the given caches before executing, specify "all"
|
||||||
|
for all cached. Currently allowed values are:
|
||||||
|
"all","ccache","bytecode","dll-dependencies". can be
|
||||||
|
given multiple times or with comma separated values.
|
||||||
|
Default none.
|
||||||
|
--disable-bytecode-cache
|
||||||
|
Do not reuse dependency analysis results for modules,
|
||||||
|
esp. from standard library, that are included as
|
||||||
|
bytecode. Same as --disable-cache=bytecode.
|
||||||
|
--disable-ccache Do not attempt to use ccache (gcc, clang, etc.) or
|
||||||
|
clcache (MSVC, clangcl). Same as --disable-
|
||||||
|
cache=ccache.
|
||||||
|
--disable-dll-dependency-cache
|
||||||
|
Disable the dependency walker cache. Will result in
|
||||||
|
much longer times to create the distribution folder,
|
||||||
|
but might be used in case the cache is suspect to
|
||||||
|
cause errors. Same as --disable-cache=dll-
|
||||||
|
dependencies.
|
||||||
|
--force-dll-dependency-cache-update
|
||||||
|
For an update of the dependency walker cache. Will
|
||||||
|
result in much longer times to create the distribution
|
||||||
|
folder, but might be used in case the cache is suspect
|
||||||
|
to cause errors or known to need an update.
|
||||||
|
|
||||||
|
PGO compilation choices:
|
||||||
|
--pgo Enables C level profile guided optimization (PGO), by
|
||||||
|
executing a dedicated build first for a profiling run,
|
||||||
|
and then using the result to feedback into the C
|
||||||
|
compilation. Note: This is experimental and not
|
||||||
|
working with standalone modes of Nuitka yet. Defaults
|
||||||
|
to off.
|
||||||
|
--pgo-args=PGO_ARGS
|
||||||
|
Arguments to be passed in case of profile guided
|
||||||
|
optimization. These are passed to the special built
|
||||||
|
executable during the PGO profiling run. Default
|
||||||
|
empty.
|
||||||
|
--pgo-executable=PGO_EXECUTABLE
|
||||||
|
Command to execute when collecting profile
|
||||||
|
information. Use this only, if you need to launch it
|
||||||
|
through a script that prepares it to run. Default use
|
||||||
|
created program.
|
||||||
|
|
||||||
|
Tracing features:
|
||||||
|
--report=REPORT_FILENAME
|
||||||
|
Report module, data files, compilation, plugin, etc.
|
||||||
|
details in an XML output file. This is also super
|
||||||
|
useful for issue reporting. These reports can e.g. be
|
||||||
|
used to re-create the environment easily using it with
|
||||||
|
'--create-environment-from-report', but contain a lot
|
||||||
|
of information. Default is off.
|
||||||
|
--report-diffable Report data in diffable form, i.e. no timing or memory
|
||||||
|
usage values that vary from run to run. Default is
|
||||||
|
off.
|
||||||
|
--report-user-provided=KEY_VALUE
|
||||||
|
Report data from you. This can be given multiple times
|
||||||
|
and be anything in 'key=value' form, where key should
|
||||||
|
be an identifier, e.g. use '--report-user-
|
||||||
|
provided=pipenv-lock-hash=64a5e4' to track some input
|
||||||
|
values. Default is empty.
|
||||||
|
--report-template=REPORT_DESC
|
||||||
|
Report via template. Provide template and output
|
||||||
|
filename "template.rst.j2:output.rst". For built-in
|
||||||
|
templates, check the User Manual for what these are.
|
||||||
|
Can be given multiple times. Default is empty.
|
||||||
|
--quiet Disable all information outputs, but show warnings.
|
||||||
|
Defaults to off.
|
||||||
|
--show-scons Run the C building backend Scons with verbose
|
||||||
|
information, showing the executed commands, detected
|
||||||
|
compilers. Defaults to off.
|
||||||
|
--no-progressbar Disable progress bars. Defaults to off.
|
||||||
|
--show-progress Obsolete: Provide progress information and statistics.
|
||||||
|
Disables normal progress bar. Defaults to off.
|
||||||
|
--show-memory Provide memory information and statistics. Defaults to
|
||||||
|
off.
|
||||||
|
--show-modules Provide information for included modules and DLLs
|
||||||
|
Obsolete: You should use '--report' file instead.
|
||||||
|
Defaults to off.
|
||||||
|
--show-modules-output=PATH
|
||||||
|
Where to output '--show-modules', should be a
|
||||||
|
filename. Default is standard output.
|
||||||
|
--verbose Output details of actions taken, esp. in
|
||||||
|
optimizations. Can become a lot. Defaults to off.
|
||||||
|
--verbose-output=PATH
|
||||||
|
Where to output from '--verbose', should be a
|
||||||
|
filename. Default is standard output.
|
||||||
|
|
||||||
|
General OS controls:
|
||||||
|
--disable-console When compiling for Windows or macOS, disable the
|
||||||
|
console window and create a GUI application. Defaults
|
||||||
|
to off.
|
||||||
|
--enable-console When compiling for Windows or macOS, enable the
|
||||||
|
console window and create a console application. This
|
||||||
|
disables hints from certain modules, e.g. "PySide"
|
||||||
|
that suggest to disable it. Defaults to true.
|
||||||
|
--force-stdout-spec=FORCE_STDOUT_SPEC
|
||||||
|
Force standard output of the program to go to this
|
||||||
|
location. Useful for programs with disabled console
|
||||||
|
and programs using the Windows Services Plugin of
|
||||||
|
Nuitka commercial. Defaults to not active, use e.g.
|
||||||
|
'%PROGRAM%.out.txt', i.e. file near your program,
|
||||||
|
check User Manual for full list of available values.
|
||||||
|
--force-stderr-spec=FORCE_STDERR_SPEC
|
||||||
|
Force standard error of the program to go to this
|
||||||
|
location. Useful for programs with disabled console
|
||||||
|
and programs using the Windows Services Plugin of
|
||||||
|
Nuitka commercial. Defaults to not active, use e.g.
|
||||||
|
'%PROGRAM%.err.txt', i.e. file near your program,
|
||||||
|
check User Manual for full list of available values.
|
||||||
|
|
||||||
|
Windows specific controls:
|
||||||
|
--windows-icon-from-ico=ICON_PATH
|
||||||
|
Add executable icon. Can be given multiple times for
|
||||||
|
different resolutions or files with multiple icons
|
||||||
|
inside. In the later case, you may also suffix with
|
||||||
|
#<n> where n is an integer index starting from 1,
|
||||||
|
specifying a specific icon to be included, and all
|
||||||
|
others to be ignored.
|
||||||
|
--windows-icon-from-exe=ICON_EXE_PATH
|
||||||
|
Copy executable icons from this existing executable
|
||||||
|
(Windows only).
|
||||||
|
--onefile-windows-splash-screen-image=SPLASH_SCREEN_IMAGE
|
||||||
|
When compiling for Windows and onefile, show this
|
||||||
|
while loading the application. Defaults to off.
|
||||||
|
--windows-uac-admin
|
||||||
|
Request Windows User Control, to grant admin rights on
|
||||||
|
execution. (Windows only). Defaults to off.
|
||||||
|
--windows-uac-uiaccess
|
||||||
|
Request Windows User Control, to enforce running from
|
||||||
|
a few folders only, remote desktop access. (Windows
|
||||||
|
only). Defaults to off.
|
||||||
|
|
||||||
|
macOS specific controls:
|
||||||
|
--macos-target-arch=MACOS_TARGET_ARCH
|
||||||
|
What architectures is this to supposed to run on.
|
||||||
|
Default and limit is what the running Python allows
|
||||||
|
for. Default is "native" which is the architecture the
|
||||||
|
Python is run with.
|
||||||
|
--macos-create-app-bundle
|
||||||
|
When compiling for macOS, create a bundle rather than
|
||||||
|
a plain binary application. Currently experimental and
|
||||||
|
incomplete. Currently this is the only way to unlock
|
||||||
|
disabling of console.Defaults to off.
|
||||||
|
--macos-app-icon=ICON_PATH
|
||||||
|
Add icon for the application bundle to use. Can be
|
||||||
|
given only one time. Defaults to Python icon if
|
||||||
|
available.
|
||||||
|
--macos-signed-app-name=MACOS_SIGNED_APP_NAME
|
||||||
|
Name of the application to use for macOS signing.
|
||||||
|
Follow "com.YourCompany.AppName" naming results for
|
||||||
|
best results, as these have to be globally unique, and
|
||||||
|
will potentially grant protected API accesses.
|
||||||
|
--macos-app-name=MACOS_APP_NAME
|
||||||
|
Name of the product to use in macOS bundle
|
||||||
|
information. Defaults to base filename of the binary.
|
||||||
|
--macos-app-mode=MODE
|
||||||
|
Mode of application for the application bundle. When
|
||||||
|
launching a Window, and appearing in Docker is
|
||||||
|
desired, default value "gui" is a good fit. Without a
|
||||||
|
Window ever, the application is a "background"
|
||||||
|
application. For UI elements that get to display
|
||||||
|
later, "ui-element" is in-between. The application
|
||||||
|
will not appear in dock, but get full access to
|
||||||
|
desktop when it does open a Window later.
|
||||||
|
--macos-sign-identity=MACOS_APP_VERSION
|
||||||
|
When signing on macOS, by default an ad-hoc identify
|
||||||
|
will be used, but with this option your get to specify
|
||||||
|
another identity to use. The signing of code is now
|
||||||
|
mandatory on macOS and cannot be disabled. Default
|
||||||
|
"ad-hoc" if not given.
|
||||||
|
--macos-sign-notarization
|
||||||
|
When signing for notarization, using a proper TeamID
|
||||||
|
identity from Apple, use the required runtime signing
|
||||||
|
option, such that it can be accepted.
|
||||||
|
--macos-app-version=MACOS_APP_VERSION
|
||||||
|
Product version to use in macOS bundle information.
|
||||||
|
Defaults to "1.0" if not given.
|
||||||
|
--macos-app-protected-resource=RESOURCE_DESC
|
||||||
|
Request an entitlement for access to a macOS protected
|
||||||
|
resources, e.g.
|
||||||
|
"NSMicrophoneUsageDescription:Microphone access for
|
||||||
|
recording audio." requests access to the microphone
|
||||||
|
and provides an informative text for the user, why
|
||||||
|
that is needed. Before the colon, is an OS identifier
|
||||||
|
for an access right, then the informative text. Legal
|
||||||
|
values can be found on https://developer.apple.com/doc
|
||||||
|
umentation/bundleresources/information_property_list/p
|
||||||
|
rotected_resources and the option can be specified
|
||||||
|
multiple times. Default empty.
|
||||||
|
|
||||||
|
Linux specific controls:
|
||||||
|
--linux-icon=ICON_PATH
|
||||||
|
Add executable icon for onefile binary to use. Can be
|
||||||
|
given only one time. Defaults to Python icon if
|
||||||
|
available.
|
||||||
|
|
||||||
|
Binary Version Information:
|
||||||
|
--company-name=COMPANY_NAME
|
||||||
|
Name of the company to use in version information.
|
||||||
|
Defaults to unused.
|
||||||
|
--product-name=PRODUCT_NAME
|
||||||
|
Name of the product to use in version information.
|
||||||
|
Defaults to base filename of the binary.
|
||||||
|
--file-version=FILE_VERSION
|
||||||
|
File version to use in version information. Must be a
|
||||||
|
sequence of up to 4 numbers, e.g. 1.0 or 1.0.0.0, no
|
||||||
|
more digits are allowed, no strings are allowed.
|
||||||
|
Defaults to unused.
|
||||||
|
--product-version=PRODUCT_VERSION
|
||||||
|
Product version to use in version information. Same
|
||||||
|
rules as for file version. Defaults to unused.
|
||||||
|
--file-description=FILE_DESCRIPTION
|
||||||
|
Description of the file used in version information.
|
||||||
|
Windows only at this time. Defaults to binary
|
||||||
|
filename.
|
||||||
|
--copyright=COPYRIGHT_TEXT
|
||||||
|
Copyright used in version information. Windows only at
|
||||||
|
this time. Defaults to not present.
|
||||||
|
--trademarks=TRADEMARK_TEXT
|
||||||
|
Copyright used in version information. Windows only at
|
||||||
|
this time. Defaults to not present.
|
||||||
|
|
||||||
|
Plugin control:
|
||||||
|
--enable-plugin=PLUGIN_NAME
|
||||||
|
Enabled plugins. Must be plug-in names. Use '--plugin-
|
||||||
|
list' to query the full list and exit. Default empty.
|
||||||
|
--disable-plugin=PLUGIN_NAME
|
||||||
|
Disabled plugins. Must be plug-in names. Use '--
|
||||||
|
plugin-list' to query the full list and exit. Most
|
||||||
|
standard plugins are not a good idea to disable.
|
||||||
|
Default empty.
|
||||||
|
--plugin-no-detection
|
||||||
|
Plugins can detect if they might be used, and the you
|
||||||
|
can disable the warning via "--disable-plugin=plugin-
|
||||||
|
that-warned", or you can use this option to disable
|
||||||
|
the mechanism entirely, which also speeds up
|
||||||
|
compilation slightly of course as this detection code
|
||||||
|
is run in vain once you are certain of which plugins
|
||||||
|
to use. Defaults to off.
|
||||||
|
--plugin-list Show list of all available plugins and exit. Defaults
|
||||||
|
to off.
|
||||||
|
--user-plugin=PATH The file name of user plugin. Can be given multiple
|
||||||
|
times. Default empty.
|
||||||
|
--show-source-changes
|
||||||
|
Show source changes to original Python file content
|
||||||
|
before compilation. Mostly intended for developing
|
||||||
|
plugins. Default False.
|
||||||
|
|
||||||
|
Plugin options of 'anti-bloat':
|
||||||
|
--show-anti-bloat-changes
|
||||||
|
Annotate what changes are by the plugin done.
|
||||||
|
--noinclude-setuptools-mode=NOINCLUDE_SETUPTOOLS_MODE
|
||||||
|
What to do if a 'setuptools' or import is encountered.
|
||||||
|
This package can be big with dependencies, and should
|
||||||
|
definitely be avoided. Also handles 'setuptools_scm'.
|
||||||
|
--noinclude-pytest-mode=NOINCLUDE_PYTEST_MODE
|
||||||
|
What to do if a 'pytest' import is encountered. This
|
||||||
|
package can be big with dependencies, and should
|
||||||
|
definitely be avoided. Also handles 'nose' imports.
|
||||||
|
--noinclude-unittest-mode=NOINCLUDE_UNITTEST_MODE
|
||||||
|
What to do if a unittest import is encountered. This
|
||||||
|
package can be big with dependencies, and should
|
||||||
|
definitely be avoided.
|
||||||
|
--noinclude-IPython-mode=NOINCLUDE_IPYTHON_MODE
|
||||||
|
What to do if a IPython import is encountered. This
|
||||||
|
package can be big with dependencies, and should
|
||||||
|
definitely be avoided.
|
||||||
|
--noinclude-dask-mode=NOINCLUDE_DASK_MODE
|
||||||
|
What to do if a 'dask' import is encountered. This
|
||||||
|
package can be big with dependencies, and should
|
||||||
|
definitely be avoided.
|
||||||
|
--noinclude-numba-mode=NOINCLUDE_NUMBA_MODE
|
||||||
|
What to do if a 'numba' import is encountered. This
|
||||||
|
package can be big with dependencies, and is currently
|
||||||
|
not working for standalone. This package is big with
|
||||||
|
dependencies, and should definitely be avoided.
|
||||||
|
--noinclude-default-mode=NOINCLUDE_DEFAULT_MODE
|
||||||
|
This actually provides the default "warning" value for
|
||||||
|
above options, and can be used to turn all of these
|
||||||
|
on.
|
||||||
|
--noinclude-custom-mode=CUSTOM_CHOICES
|
||||||
|
What to do if a specific import is encountered. Format
|
||||||
|
is module name, which can and should be a top level
|
||||||
|
package and then one choice, "error", "warning",
|
||||||
|
"nofollow", e.g. PyQt5:error.
|
||||||
|
```
|
@ -7,11 +7,11 @@ Thanks a lot to Fallen_Breath and MCDR contributors
|
|||||||
GNU Lesser General Public License v3.0 (GNU LGPL v3)
|
GNU Lesser General Public License v3.0 (GNU LGPL v3)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from typing import List, Callable, Tuple, Optional, Union
|
||||||
"""
|
"""
|
||||||
Plugin Version
|
Plugin Version
|
||||||
"""
|
"""
|
||||||
import re
|
|
||||||
from typing import List, Callable, Tuple, Optional, Union
|
|
||||||
|
|
||||||
|
|
||||||
# beta.3 -> (beta, 3), random -> (random, None)
|
# beta.3 -> (beta, 3), random -> (random, None)
|
||||||
|
@ -19,12 +19,17 @@ by this package.
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import weakref
|
import weakref
|
||||||
|
from typing import Dict, Union, BinaryIO, Optional, List, Iterable
|
||||||
|
|
||||||
import pyglet
|
import pyglet
|
||||||
|
from pyglet.font.user import UserDefinedFont
|
||||||
from pyglet import gl
|
from pyglet import gl
|
||||||
|
|
||||||
|
|
||||||
if not getattr(sys, 'is_pyglet_doc_run', False):
|
def _get_system_font_class():
|
||||||
|
"""Get the appropriate class for the system being used.
|
||||||
|
Pyglet relies on OS dependent font systems for loading fonts and glyph creation.
|
||||||
|
"""
|
||||||
if pyglet.compat_platform == 'darwin':
|
if pyglet.compat_platform == 'darwin':
|
||||||
from pyglet.font.quartz import QuartzFont
|
from pyglet.font.quartz import QuartzFont
|
||||||
_font_class = QuartzFont
|
_font_class = QuartzFont
|
||||||
@ -37,18 +42,86 @@ if not getattr(sys, 'is_pyglet_doc_run', False):
|
|||||||
else:
|
else:
|
||||||
from pyglet.font.win32 import GDIPlusFont
|
from pyglet.font.win32 import GDIPlusFont
|
||||||
_font_class = GDIPlusFont
|
_font_class = GDIPlusFont
|
||||||
|
|
||||||
else:
|
else:
|
||||||
from pyglet.font.freetype import FreeTypeFont
|
from pyglet.font.freetype import FreeTypeFont
|
||||||
_font_class = FreeTypeFont
|
_font_class = FreeTypeFont
|
||||||
|
|
||||||
|
return _font_class
|
||||||
|
|
||||||
def have_font(name):
|
|
||||||
|
def create_font(name: str, mappings: Dict[str, pyglet.image.ImageData], default_char: str,
|
||||||
|
ascent: Optional[float] = None,
|
||||||
|
descent: Optional[float] = None, size: Optional[float] = None, bold: bool = False,
|
||||||
|
italic: bool = False, stretch: bool = False, dpi: Optional[float] = None,
|
||||||
|
font_class=UserDefinedFont):
|
||||||
|
"""
|
||||||
|
Create a custom font with the mappings provided.
|
||||||
|
|
||||||
|
If a character in a string is not mapped in the font, it will use the default_char as fallback.
|
||||||
|
|
||||||
|
Default size is 12.
|
||||||
|
Ascent and descent will use the image dimensions as default, but can be provided.
|
||||||
|
|
||||||
|
The rest of the font parameters are used for font lookups.
|
||||||
|
"""
|
||||||
|
# Arbitrary default size
|
||||||
|
if size is None:
|
||||||
|
size = 12
|
||||||
|
|
||||||
|
if dpi is None:
|
||||||
|
dpi = 96
|
||||||
|
|
||||||
|
# Locate or create font cache
|
||||||
|
shared_object_space = gl.current_context.object_space
|
||||||
|
if not hasattr(shared_object_space, 'pyglet_font_font_cache'):
|
||||||
|
shared_object_space.pyglet_font_font_cache = weakref.WeakValueDictionary()
|
||||||
|
shared_object_space.pyglet_font_font_hold = []
|
||||||
|
shared_object_space.pyglet_font_font_name_match = {} # Match a tuple to specific name to reduce lookups.
|
||||||
|
|
||||||
|
font_cache = shared_object_space.pyglet_font_font_cache
|
||||||
|
font_hold = shared_object_space.pyglet_font_font_hold
|
||||||
|
|
||||||
|
# Look for font name in font cache
|
||||||
|
descriptor = (name, size, bold, italic, stretch, dpi)
|
||||||
|
if descriptor in font_cache:
|
||||||
|
raise Exception("A font with these parameters has already been created.", descriptor)
|
||||||
|
|
||||||
|
if _system_font_class.have_font(name):
|
||||||
|
raise Exception(f"Font name: '{name}' already exists within the system fonts.")
|
||||||
|
|
||||||
|
# Not in cache, create from scratch
|
||||||
|
font = font_class(mappings, default_char, name, ascent, descent, size, bold, italic, stretch, dpi)
|
||||||
|
|
||||||
|
# Save parameters for new-style layout classes to recover
|
||||||
|
# TODO: add properties to the Font classes, so these can be queried:
|
||||||
|
font.size = size
|
||||||
|
font.bold = bold
|
||||||
|
font.italic = italic
|
||||||
|
font.stretch = stretch
|
||||||
|
font.dpi = dpi
|
||||||
|
|
||||||
|
if name not in _user_fonts:
|
||||||
|
_user_fonts.append(name)
|
||||||
|
|
||||||
|
# Cache font in weak-ref dictionary to avoid reloading while still in use
|
||||||
|
font_cache[descriptor] = font
|
||||||
|
|
||||||
|
# Hold onto refs of last three loaded fonts to prevent them being
|
||||||
|
# collected if momentarily dropped.
|
||||||
|
del font_hold[3:]
|
||||||
|
font_hold.insert(0, font)
|
||||||
|
|
||||||
|
return font
|
||||||
|
|
||||||
|
|
||||||
|
def have_font(name: str) -> bool:
|
||||||
"""Check if specified system font name is available."""
|
"""Check if specified system font name is available."""
|
||||||
return _font_class.have_font(name)
|
return name in _user_fonts or _system_font_class.have_font(name)
|
||||||
|
|
||||||
|
|
||||||
def load(name=None, size=None, bold=False, italic=False, stretch=False, dpi=None):
|
def load(name: Optional[Union[str, Iterable[str]]] = None, size: Optional[float] = None, bold: bool = False,
|
||||||
|
italic: bool = False,
|
||||||
|
stretch: bool = False, dpi: Optional[float] = None):
|
||||||
"""Load a font for rendering.
|
"""Load a font for rendering.
|
||||||
|
|
||||||
:Parameters:
|
:Parameters:
|
||||||
@ -101,7 +174,7 @@ def load(name=None, size=None, bold=False, italic=False, stretch=False, dpi=None
|
|||||||
# Find first matching name, cache it.
|
# Find first matching name, cache it.
|
||||||
found_name = None
|
found_name = None
|
||||||
for n in name:
|
for n in name:
|
||||||
if _font_class.have_font(n):
|
if n in _user_fonts or _system_font_class.have_font(n):
|
||||||
found_name = n
|
found_name = n
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -114,7 +187,7 @@ def load(name=None, size=None, bold=False, italic=False, stretch=False, dpi=None
|
|||||||
return font_cache[descriptor]
|
return font_cache[descriptor]
|
||||||
|
|
||||||
# Not in cache, create from scratch
|
# Not in cache, create from scratch
|
||||||
font = _font_class(name, size, bold=bold, italic=italic, stretch=stretch, dpi=dpi)
|
font = _system_font_class(name, size, bold=bold, italic=italic, stretch=stretch, dpi=dpi)
|
||||||
|
|
||||||
# Save parameters for new-style layout classes to recover
|
# Save parameters for new-style layout classes to recover
|
||||||
# TODO: add properties to the Font classes, so these can be queried:
|
# TODO: add properties to the Font classes, so these can be queried:
|
||||||
@ -135,7 +208,12 @@ def load(name=None, size=None, bold=False, italic=False, stretch=False, dpi=None
|
|||||||
return font
|
return font
|
||||||
|
|
||||||
|
|
||||||
def add_file(font):
|
if not getattr(sys, 'is_pyglet_doc_run', False):
|
||||||
|
_system_font_class = _get_system_font_class()
|
||||||
|
_user_fonts = []
|
||||||
|
|
||||||
|
|
||||||
|
def add_file(font: Union[str, BinaryIO]):
|
||||||
"""Add a font to pyglet's search path.
|
"""Add a font to pyglet's search path.
|
||||||
|
|
||||||
In order to load a font that is not installed on the system, you must
|
In order to load a font that is not installed on the system, you must
|
||||||
@ -156,7 +234,7 @@ def add_file(font):
|
|||||||
font = open(font, 'rb')
|
font = open(font, 'rb')
|
||||||
if hasattr(font, 'read'):
|
if hasattr(font, 'read'):
|
||||||
font = font.read()
|
font = font.read()
|
||||||
_font_class.add_font_data(font)
|
_system_font_class.add_font_data(font)
|
||||||
|
|
||||||
|
|
||||||
def add_directory(directory):
|
def add_directory(directory):
|
||||||
|
86
libs/pyglet/font/user.py
Normal file
86
libs/pyglet/font/user.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
from typing import Dict, Optional
|
||||||
|
|
||||||
|
import pyglet
|
||||||
|
from pyglet.font import base
|
||||||
|
|
||||||
|
|
||||||
|
class UserGlyphRenderer(base.GlyphRenderer):
|
||||||
|
def __init__(self, font: 'UserDefinedFont'):
|
||||||
|
self._font = font
|
||||||
|
self._font.glyphs[self._font.default_char] = self.render(self._font.default_char)
|
||||||
|
super().__init__(font)
|
||||||
|
|
||||||
|
def render(self, text: str):
|
||||||
|
image_data = self._font.mappings[text]
|
||||||
|
glyph = self._font.create_glyph(image_data)
|
||||||
|
glyph.set_bearings(-self._font.descent, 0, image_data.width)
|
||||||
|
return glyph
|
||||||
|
|
||||||
|
|
||||||
|
class UserDefinedFont(base.Font):
|
||||||
|
"""A basic UserDefinedFont, it takes a mappings of ImageData """
|
||||||
|
glyph_renderer_class = UserGlyphRenderer
|
||||||
|
|
||||||
|
def __init__(self, mappings: Dict[str, pyglet.image.ImageData], default_char: str, name: str, ascent: float,
|
||||||
|
descent: float, size: float, bold: bool = False, italic: bool = False, stretch: bool = False,
|
||||||
|
dpi: int = None,
|
||||||
|
locale: Optional[str] = None):
|
||||||
|
super().__init__()
|
||||||
|
self._name = name
|
||||||
|
self.mappings: Dict[str, pyglet.image.ImageData] = mappings
|
||||||
|
|
||||||
|
if default_char not in self.mappings:
|
||||||
|
raise Exception(f"Default character: '{default_char}' must exist within your mappings.")
|
||||||
|
|
||||||
|
if ascent is None or descent is None:
|
||||||
|
image = list(mappings.values())[0]
|
||||||
|
|
||||||
|
if ascent is None:
|
||||||
|
ascent = image.height
|
||||||
|
|
||||||
|
if descent is None:
|
||||||
|
descent = 0
|
||||||
|
|
||||||
|
self.ascent = ascent
|
||||||
|
self.descent = descent
|
||||||
|
self.default_char = default_char
|
||||||
|
|
||||||
|
self.bold = bold
|
||||||
|
self.italic = italic
|
||||||
|
self.stretch = stretch
|
||||||
|
self.dpi = dpi
|
||||||
|
self.size = size
|
||||||
|
self.locale = locale
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
def get_glyphs(self, text):
|
||||||
|
"""Create and return a list of Glyphs for `text`.
|
||||||
|
|
||||||
|
If any characters do not have a known glyph representation in this
|
||||||
|
font, a substitution will be made.
|
||||||
|
|
||||||
|
:Parameters:
|
||||||
|
`text` : str or unicode
|
||||||
|
Text to render.
|
||||||
|
|
||||||
|
:rtype: list of `Glyph`
|
||||||
|
"""
|
||||||
|
glyph_renderer = None
|
||||||
|
glyphs = [] # glyphs that are committed.
|
||||||
|
for c in base.get_grapheme_clusters(str(text)):
|
||||||
|
# Get the glyph for 'c'. Hide tabs (Windows and Linux render
|
||||||
|
# boxes)
|
||||||
|
if c == '\t':
|
||||||
|
c = ' '
|
||||||
|
if c not in self.glyphs:
|
||||||
|
if not glyph_renderer:
|
||||||
|
glyph_renderer = self.glyph_renderer_class(self)
|
||||||
|
if c not in self.mappings:
|
||||||
|
c = self.default_char
|
||||||
|
else:
|
||||||
|
self.glyphs[c] = glyph_renderer.render(c)
|
||||||
|
glyphs.append(self.glyphs[c])
|
||||||
|
return glyphs
|
@ -1,64 +0,0 @@
|
|||||||
# pyglet_rs
|
|
||||||
|
|
||||||
This is a folder about pyglet_rs.
|
|
||||||
|
|
||||||
## What is pyglet_rs?
|
|
||||||
|
|
||||||
pyglet_rs is a python library that patches pyglet to use rust to make it faster!
|
|
||||||
|
|
||||||
## Notice
|
|
||||||
|
|
||||||
**This Folder may be move to an individual repo. here is just a temp location**
|
|
||||||
|
|
||||||
## requirements
|
|
||||||
- `python 3.8+`
|
|
||||||
- `pyglet 2.0+`
|
|
||||||
- `rustc 1.68.1+`
|
|
||||||
- no more
|
|
||||||
|
|
||||||
## status
|
|
||||||
- still writing
|
|
||||||
|
|
||||||
## usage
|
|
||||||
|
|
||||||
```python
|
|
||||||
import pyglet_rs
|
|
||||||
pyglet_rs.patch_sprite()
|
|
||||||
|
|
||||||
import pyglet
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
## how to build
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
cd src
|
|
||||||
./build.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
## roadmap
|
|
||||||
|
|
||||||
- [ ] `pyglet.sprite.Sprite` patch
|
|
||||||
|
|
||||||
- [ ] `pyglet.math.Vec2` patch (doing)
|
|
||||||
- [ ] main Calculate protocol
|
|
||||||
- [ ] other protocols
|
|
||||||
- [ ] `pyglet.math.Vec3` patch (doing)
|
|
||||||
- [ ] main Calculate protocol
|
|
||||||
- [ ] other protocols
|
|
||||||
- [ ] `pyglet.math.Vec4` patch (doing)
|
|
||||||
- [ ] main Calculate protocol
|
|
||||||
- [ ] other protocols
|
|
||||||
- [ ] `pyglet.math.Mat3(tuple)` patch (doing)
|
|
||||||
- [ ] main Calculate protocol
|
|
||||||
- [ ] other protocols
|
|
||||||
- [ ] `pyglet.math.Mat4(tuple)` patch (doing)
|
|
||||||
- [ ] main Calculate protocol
|
|
||||||
- [ ] other protocols
|
|
||||||
|
|
||||||
## Thanks
|
|
||||||
|
|
||||||
Great thanks to Github Copilot!
|
|
||||||
It helps me a lot in Vector and Matrix calculation and protocol implementation.
|
|
||||||
(there are A LOT of code generated by copilot)
|
|
||||||
(even this sentence is generated by copilot)
|
|
@ -1,112 +0,0 @@
|
|||||||
# -------------------------------
|
|
||||||
# Difficult Rocket
|
|
||||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
# All rights reserved
|
|
||||||
# -------------------------------
|
|
||||||
|
|
||||||
"""
|
|
||||||
from .lib import (get_version_str)
|
|
||||||
|
|
||||||
from .lib import (Sprite_rs,
|
|
||||||
Vector2_rs, Vector3_rs, Vector4_rs,
|
|
||||||
Matrix3_rs, Matrix4_rs)
|
|
||||||
"""
|
|
||||||
from .lib import *
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Union
|
|
||||||
|
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
__version__ = get_version_str()
|
|
||||||
__all__ = ['patch_sprite', 'patch_vector', 'patch_matrix', 'patch_all',
|
|
||||||
'Sprite_rs',
|
|
||||||
'Vector2_rs', 'Vector3_rs', 'Vector4_rs',
|
|
||||||
'Matrix3_rs', 'Matrix4_rs']
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from pyglet.event import EventDispatcher
|
|
||||||
|
|
||||||
Number = Union[int, float]
|
|
||||||
|
|
||||||
|
|
||||||
def get_version_str() -> str: ...
|
|
||||||
|
|
||||||
|
|
||||||
class Sprite_rs(EventDispatcher): ...
|
|
||||||
|
|
||||||
|
|
||||||
class Vector2_rs:
|
|
||||||
def __init__(self, x: Number, y: Number): ...
|
|
||||||
def __add__(self, other: "Vector2_rs") -> "Vector2_rs": ...
|
|
||||||
def __sub__(self, other: "Vector2_rs") -> "Vector2_rs": ...
|
|
||||||
def __mul__(self, other: "Vector2_rs") -> "Vector2_rs": ...
|
|
||||||
def __truediv__(self, other: "Vector2_rs") -> "Vector2_rs": ...
|
|
||||||
def __floordiv__(self, other: "Vector2_rs") -> "Vector2_rs": ...
|
|
||||||
def __repr__(self) -> str: ...
|
|
||||||
@property
|
|
||||||
def x(self) -> float: ...
|
|
||||||
@property
|
|
||||||
def y(self) -> float: ...
|
|
||||||
|
|
||||||
|
|
||||||
class Vector3_rs:
|
|
||||||
def __init__(self, x: Number, y: Number, z: Number): ...
|
|
||||||
def __add__(self, other: "Vector3_rs") -> "Vector3_rs": ...
|
|
||||||
def __sub__(self, other: "Vector3_rs") -> "Vector3_rs": ...
|
|
||||||
def __mul__(self, other: "Vector3_rs") -> "Vector3_rs": ...
|
|
||||||
def __truediv__(self, other: "Vector3_rs") -> "Vector3_rs": ...
|
|
||||||
def __floordiv__(self, other: "Vector3_rs") -> "Vector3_rs": ...
|
|
||||||
def __repr__(self) -> str: ...
|
|
||||||
@property
|
|
||||||
def x(self) -> float: ...
|
|
||||||
@property
|
|
||||||
def y(self) -> float: ...
|
|
||||||
@property
|
|
||||||
def z(self) -> float: ...
|
|
||||||
|
|
||||||
|
|
||||||
class Vector4_rs:
|
|
||||||
def __init__(self, x: Number, y: Number, z: Number, w: Number): ...
|
|
||||||
def __add__(self, other: "Vector4_rs") -> "Vector4_rs": ...
|
|
||||||
def __sub__(self, other: "Vector4_rs") -> "Vector4_rs": ...
|
|
||||||
def __mul__(self, other: "Vector4_rs") -> "Vector4_rs": ...
|
|
||||||
def __truediv__(self, other: "Vector4_rs") -> "Vector4_rs": ...
|
|
||||||
def __floordiv__(self, other: "Vector4_rs") -> "Vector4_rs": ...
|
|
||||||
def __repr__(self) -> str: ...
|
|
||||||
@property
|
|
||||||
def x(self) -> float: ...
|
|
||||||
@property
|
|
||||||
def y(self) -> float: ...
|
|
||||||
@property
|
|
||||||
def z(self) -> float: ...
|
|
||||||
@property
|
|
||||||
def w(self) -> float: ...
|
|
||||||
|
|
||||||
|
|
||||||
class Matrix3_rs: ...
|
|
||||||
|
|
||||||
|
|
||||||
class Matrix4_rs: ...
|
|
||||||
|
|
||||||
|
|
||||||
def patch_sprite():
|
|
||||||
from pyglet import sprite
|
|
||||||
sprite.Sprite = Sprite_rs
|
|
||||||
|
|
||||||
|
|
||||||
def patch_vector():
|
|
||||||
from pyglet import math
|
|
||||||
math.Vector2 = Vector2_rs
|
|
||||||
math.Vector3 = Vector3_rs
|
|
||||||
math.Vector4 = Vector4_rs
|
|
||||||
|
|
||||||
|
|
||||||
def patch_matrix():
|
|
||||||
from pyglet import math
|
|
||||||
math.Matrix3 = Matrix3_rs
|
|
||||||
math.Matrix4 = Matrix4_rs
|
|
||||||
|
|
||||||
|
|
||||||
def patch_all():
|
|
||||||
patch_sprite()
|
|
||||||
patch_vector()
|
|
||||||
patch_matrix()
|
|
325
libs/pyglet_rs/src/Cargo.lock
generated
325
libs/pyglet_rs/src/Cargo.lock
generated
@ -1,325 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitflags"
|
|
||||||
version = "1.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ctor"
|
|
||||||
version = "0.1.26"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ghost"
|
|
||||||
version = "0.1.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "indoc"
|
|
||||||
version = "1.0.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "inventory"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "498ae1c9c329c7972b917506239b557a60386839192f1cf0ca034f345b65db99"
|
|
||||||
dependencies = [
|
|
||||||
"ctor",
|
|
||||||
"ghost",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.140"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lock_api"
|
|
||||||
version = "0.4.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memoffset"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell"
|
|
||||||
version = "1.17.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
|
||||||
dependencies = [
|
|
||||||
"lock_api",
|
|
||||||
"parking_lot_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot_core"
|
|
||||||
version = "0.9.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"redox_syscall",
|
|
||||||
"smallvec",
|
|
||||||
"windows-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.53"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyglet_rs"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"pyo3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyo3"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "06a3d8e8a46ab2738109347433cb7b96dffda2e4a218b03ef27090238886b147"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"indoc",
|
|
||||||
"inventory",
|
|
||||||
"libc",
|
|
||||||
"memoffset",
|
|
||||||
"parking_lot",
|
|
||||||
"pyo3-build-config",
|
|
||||||
"pyo3-ffi",
|
|
||||||
"pyo3-macros",
|
|
||||||
"unindent",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyo3-build-config"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75439f995d07ddfad42b192dfcf3bc66a7ecfd8b4a1f5f6f046aa5c2c5d7677d"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
"target-lexicon",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyo3-ffi"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "839526a5c07a17ff44823679b68add4a58004de00512a95b6c1c98a6dcac0ee5"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"pyo3-build-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyo3-macros"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bd44cf207476c6a9760c4653559be4f206efafb924d3e4cbf2721475fc0d6cc5"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"pyo3-macros-backend",
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyo3-macros-backend"
|
|
||||||
version = "0.18.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dc1f43d8e30460f36350d18631ccf85ded64c059829208fe680904c65bcd0a4c"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.26"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.2.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smallvec"
|
|
||||||
version = "1.10.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.109"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "2.0.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "89c2d1c76a26822187a1fbb5964e3fff108bc208f02e820ab9dac1234f6b388a"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "target-lexicon"
|
|
||||||
version = "0.12.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unindent"
|
|
||||||
version = "0.1.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.45.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm",
|
|
||||||
"windows_aarch64_msvc",
|
|
||||||
"windows_i686_gnu",
|
|
||||||
"windows_i686_msvc",
|
|
||||||
"windows_x86_64_gnu",
|
|
||||||
"windows_x86_64_gnullvm",
|
|
||||||
"windows_x86_64_msvc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
|
@ -1,17 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "pyglet_rs"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = 'pyglet_rs'
|
|
||||||
crate-type = ["cdylib"]
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
codegen-units = 1
|
|
||||||
|
|
||||||
[dependencies.pyo3]
|
|
||||||
version = "0.18.1"
|
|
||||||
features = ["extension-module", "multiple-pymethods"]
|
|
@ -1 +0,0 @@
|
|||||||
cargo fmt;python3.8 .\setup.py build; python .\post_build.py
|
|
@ -1,41 +0,0 @@
|
|||||||
# -------------------------------
|
|
||||||
# Difficult Rocket
|
|
||||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
# All rights reserved
|
|
||||||
# -------------------------------
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import warnings
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
package_path = 'pyglet_rs'
|
|
||||||
lib_path = '../lib'
|
|
||||||
build_path = 'build'
|
|
||||||
|
|
||||||
if not os.path.exists(lib_path):
|
|
||||||
os.mkdir(lib_path)
|
|
||||||
|
|
||||||
builds = os.listdir(build_path)
|
|
||||||
print(os.path.abspath('.'))
|
|
||||||
|
|
||||||
try:
|
|
||||||
shutil.copy('src/__init__.py', os.path.join(lib_path, '__init__.py'))
|
|
||||||
except shutil.SameFileError:
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
for build_dir in builds:
|
|
||||||
if not os.path.exists(os.path.join(build_path, build_dir, package_path)):
|
|
||||||
warnings.warn(f'package not found at {build_path}/{build_dir}')
|
|
||||||
continue
|
|
||||||
for file in os.listdir(os.path.join(build_path, build_dir, package_path)):
|
|
||||||
# file_name = os.path.join(lib_path, file.replace(package_path, f'{package_path}.{DR_runtime.DR_Rust_version}'))
|
|
||||||
file_name = os.path.join(lib_path, file)
|
|
||||||
shutil.rmtree(file_name, ignore_errors=True)
|
|
||||||
try:
|
|
||||||
shutil.copy(os.path.join(build_path, build_dir, package_path, file), file_name)
|
|
||||||
except (shutil.SameFileError, PermissionError):
|
|
||||||
# print(os.path.exists(os.path))
|
|
||||||
print(os.listdir(lib_path))
|
|
||||||
traceback.print_exc()
|
|
||||||
continue
|
|
||||||
print(os.path.abspath(file_name))
|
|
@ -1,39 +0,0 @@
|
|||||||
# -------------------------------
|
|
||||||
# Difficult Rocket
|
|
||||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
# All rights reserved
|
|
||||||
# -------------------------------
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import rtoml
|
|
||||||
import shutil
|
|
||||||
from setuptools import setup
|
|
||||||
from setuptools_rust import Binding, RustExtension
|
|
||||||
|
|
||||||
sys.path.append('../../../')
|
|
||||||
sys.path.append(os.curdir)
|
|
||||||
|
|
||||||
package_path = 'pyglet_rs'
|
|
||||||
|
|
||||||
# 版本号从 cargo.toml 中读取
|
|
||||||
with open(f'Cargo.toml', 'r') as f:
|
|
||||||
cargo_toml = rtoml.load(f)
|
|
||||||
version = cargo_toml['package']['version']
|
|
||||||
|
|
||||||
setup(
|
|
||||||
name='pyglet_rs',
|
|
||||||
version=version,
|
|
||||||
author='shenjackyuanjie',
|
|
||||||
author_email='3695888@qq.com',
|
|
||||||
rust_extensions=[RustExtension(target="pyglet_rs.pyglet_rs",
|
|
||||||
binding=Binding.PyO3)],
|
|
||||||
zip_safe=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
lib_path = '../lib'
|
|
||||||
build_path = 'build'
|
|
||||||
|
|
||||||
if 'clean' in sys.argv:
|
|
||||||
shutil.rmtree(build_path, ignore_errors=True)
|
|
||||||
shutil.rmtree(f'{package_path}.egg-info', ignore_errors=True)
|
|
||||||
sys.exit(0)
|
|
@ -1,10 +0,0 @@
|
|||||||
# -------------------------------
|
|
||||||
# Difficult Rocket
|
|
||||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
# All rights reserved
|
|
||||||
# -------------------------------
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if not TYPE_CHECKING:
|
|
||||||
from .pyglet_rs import *
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* -------------------------------
|
|
||||||
* Difficult Rocket
|
|
||||||
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
* All rights reserved
|
|
||||||
* -------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
mod math;
|
|
||||||
mod pymath;
|
|
||||||
mod sprite;
|
|
||||||
|
|
||||||
use pyo3::prelude::*;
|
|
||||||
|
|
||||||
#[pyfunction]
|
|
||||||
fn get_version_str() -> String {
|
|
||||||
return "0.1.0".to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymodule]
|
|
||||||
#[pyo3(name = "pyglet_rs")]
|
|
||||||
fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|
||||||
m.add_function(wrap_pyfunction!(get_version_str, m)?)?;
|
|
||||||
m.add_class::<sprite::Sprite>()?;
|
|
||||||
// vector
|
|
||||||
m.add_class::<pymath::python_class::PyVector2>()?;
|
|
||||||
m.add_class::<pymath::python_class::PyVector3>()?;
|
|
||||||
m.add_class::<pymath::python_class::PyVector4>()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@ -1,395 +0,0 @@
|
|||||||
/*
|
|
||||||
* -------------------------------
|
|
||||||
* Difficult Rocket
|
|
||||||
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
* All rights reserved
|
|
||||||
* -------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub mod vector {
|
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
|
||||||
pub struct Vector2 {
|
|
||||||
pub x: f64,
|
|
||||||
pub y: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
|
||||||
pub struct Vector3 {
|
|
||||||
pub x: f64,
|
|
||||||
pub y: f64,
|
|
||||||
pub z: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
|
||||||
pub struct Vector4 {
|
|
||||||
pub x: f64,
|
|
||||||
pub y: f64,
|
|
||||||
pub z: f64,
|
|
||||||
pub w: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait VectorTrait {
|
|
||||||
fn len(&self) -> i8; // use short int to save memory (even if its not going to save a lot)
|
|
||||||
fn floordiv(&self, other: &Self) -> Self;
|
|
||||||
fn abs(&self) -> f64;
|
|
||||||
fn neg(&self) -> Self;
|
|
||||||
fn dot(&self, other: &Self) -> f64;
|
|
||||||
fn round(&self, ndigits: Option<i64>) -> Self;
|
|
||||||
fn clamp(&self, min: f64, max: f64) -> Self;
|
|
||||||
fn distance(&self, other: &Self) -> f64;
|
|
||||||
fn normalize(&self) -> Self;
|
|
||||||
// from
|
|
||||||
fn from_same(len: f64) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Add for Vector2 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(self.x + rhs.x, self.y + rhs.y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub for Vector2 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(self.x - rhs.x, self.y - rhs.y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mul for Vector2 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn mul(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(self.x * rhs.x, self.y * rhs.y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Div for Vector2 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn div(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(self.x / rhs.x, self.y / rhs.y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Add for Vector3 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub for Vector3 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mul for Vector3 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn mul(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(self.x * rhs.x, self.y * rhs.y, self.z * rhs.z)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Div for Vector3 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn div(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Add for Vector4 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(
|
|
||||||
self.x + rhs.x,
|
|
||||||
self.y + rhs.y,
|
|
||||||
self.z + rhs.z,
|
|
||||||
self.w + rhs.w,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub for Vector4 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(
|
|
||||||
self.x - rhs.x,
|
|
||||||
self.y - rhs.y,
|
|
||||||
self.z - rhs.z,
|
|
||||||
self.w - rhs.w,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mul for Vector4 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn mul(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(
|
|
||||||
self.x * rhs.x,
|
|
||||||
self.y * rhs.y,
|
|
||||||
self.z * rhs.z,
|
|
||||||
self.w * rhs.w,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Div for Vector4 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn div(self, rhs: Self) -> Self::Output {
|
|
||||||
Self::new(
|
|
||||||
self.x / rhs.x,
|
|
||||||
self.y / rhs.y,
|
|
||||||
self.z / rhs.z,
|
|
||||||
self.w / rhs.w,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VectorTrait for Vector2 {
|
|
||||||
fn len(&self) -> i8 {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
fn floordiv(&self, other: &Self) -> Self {
|
|
||||||
// 手动模拟python的//运算符
|
|
||||||
Self::new((self.x / other.x).floor(), (self.y / other.y).floor())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn abs(&self) -> f64 {
|
|
||||||
return (self.x.powi(2) + self.y.powi(2)).sqrt();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn neg(&self) -> Self {
|
|
||||||
Self::new(-self.x, -self.y)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dot(&self, other: &Self) -> f64 {
|
|
||||||
self.x * other.x + self.y * other.y
|
|
||||||
}
|
|
||||||
|
|
||||||
fn round(&self, ndigits: Option<i64>) -> Self {
|
|
||||||
match ndigits {
|
|
||||||
Some(ndigits) => {
|
|
||||||
let ndigits = ndigits as i32;
|
|
||||||
Self::new(
|
|
||||||
self.x.round() * 10.0_f64.powi(ndigits),
|
|
||||||
self.y.round() * 10.0_f64.powi(ndigits),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
None => Self::new(self.x.round(), self.y.round()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clamp(&self, min: f64, max: f64) -> Self {
|
|
||||||
Self::new(self.x.clamp(min, max), self.y.clamp(min, max))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn distance(&self, other: &Self) -> f64 {
|
|
||||||
(*self - *other).abs()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn normalize(&self) -> Self {
|
|
||||||
let d = self.abs();
|
|
||||||
return if d != 0.0 {
|
|
||||||
Self::new(self.x / d, self.y / d)
|
|
||||||
} else {
|
|
||||||
self.clone()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_same(len: f64) -> Self {
|
|
||||||
Self::new(len, len)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VectorTrait for Vector3 {
|
|
||||||
fn len(&self) -> i8 {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn floordiv(&self, other: &Self) -> Self {
|
|
||||||
// 手动模拟python的//运算符
|
|
||||||
Self::new(
|
|
||||||
(self.x / other.x).floor(),
|
|
||||||
(self.y / other.y).floor(),
|
|
||||||
(self.z / other.z).floor(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn abs(&self) -> f64 {
|
|
||||||
return (self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn neg(&self) -> Self {
|
|
||||||
Self::new(-self.x, -self.y, -self.z)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dot(&self, other: &Self) -> f64 {
|
|
||||||
self.x * other.x + self.y * other.y + self.z * other.z
|
|
||||||
}
|
|
||||||
|
|
||||||
fn round(&self, ndigits: Option<i64>) -> Self {
|
|
||||||
match ndigits {
|
|
||||||
Some(ndigits) => {
|
|
||||||
let ndigits = ndigits as i32;
|
|
||||||
Self::new(
|
|
||||||
self.x.round() * 10.0_f64.powi(ndigits),
|
|
||||||
self.y.round() * 10.0_f64.powi(ndigits),
|
|
||||||
self.z.round() * 10.0_f64.powi(ndigits),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
None => Self::new(self.x.round(), self.y.round(), self.z.round()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clamp(&self, min: f64, max: f64) -> Self {
|
|
||||||
Self::new(
|
|
||||||
self.x.clamp(min, max),
|
|
||||||
self.y.clamp(min, max),
|
|
||||||
self.z.clamp(min, max),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn distance(&self, other: &Self) -> f64 {
|
|
||||||
(*self - *other).abs()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn normalize(&self) -> Self {
|
|
||||||
let d = self.abs();
|
|
||||||
return if d != 0.0 {
|
|
||||||
Self::new(self.x / d, self.y / d, self.z / d)
|
|
||||||
} else {
|
|
||||||
self.clone()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_same(len: f64) -> Self {
|
|
||||||
Self::new(len, len, len)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VectorTrait for Vector4 {
|
|
||||||
fn len(&self) -> i8 {
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn floordiv(&self, other: &Self) -> Self {
|
|
||||||
// 手动模拟python的//运算符
|
|
||||||
Self::new(
|
|
||||||
(self.x / other.x).floor(),
|
|
||||||
(self.y / other.y).floor(),
|
|
||||||
(self.z / other.z).floor(),
|
|
||||||
(self.w / other.w).floor(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn abs(&self) -> f64 {
|
|
||||||
return (self.x.powi(2) + self.y.powi(2) + self.z.powi(2) + self.w.powi(2)).sqrt();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn neg(&self) -> Self {
|
|
||||||
Self::new(-self.x, -self.y, -self.z, -self.w)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dot(&self, other: &Self) -> f64 {
|
|
||||||
self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
|
|
||||||
}
|
|
||||||
|
|
||||||
fn round(&self, ndigits: Option<i64>) -> Self {
|
|
||||||
match ndigits {
|
|
||||||
Some(ndigits) => {
|
|
||||||
let ndigits = ndigits as i32;
|
|
||||||
Self::new(
|
|
||||||
self.x.round() * 10.0_f64.powi(ndigits),
|
|
||||||
self.y.round() * 10.0_f64.powi(ndigits),
|
|
||||||
self.z.round() * 10.0_f64.powi(ndigits),
|
|
||||||
self.w.round() * 10.0_f64.powi(ndigits),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
None => Self::new(
|
|
||||||
self.x.round(),
|
|
||||||
self.y.round(),
|
|
||||||
self.z.round(),
|
|
||||||
self.w.round(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clamp(&self, min: f64, max: f64) -> Self {
|
|
||||||
Self::new(
|
|
||||||
self.x.clamp(min, max),
|
|
||||||
self.y.clamp(min, max),
|
|
||||||
self.z.clamp(min, max),
|
|
||||||
self.w.clamp(min, max),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn distance(&self, other: &Self) -> f64 {
|
|
||||||
(*self - *other).abs()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn normalize(&self) -> Self {
|
|
||||||
let d = self.abs();
|
|
||||||
return if d != 0.0 {
|
|
||||||
Self::new(self.x / d, self.y / d, self.z / d, self.w / d)
|
|
||||||
} else {
|
|
||||||
self.clone()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_same(len: f64) -> Self {
|
|
||||||
Self::new(len, len, len, len)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Vector2 {
|
|
||||||
pub fn new(x: f64, y: f64) -> Self {
|
|
||||||
Self { x, y }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Vector3 {
|
|
||||||
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
|
||||||
Self { x, y, z }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Vector4 {
|
|
||||||
pub fn new(x: f64, y: f64, z: f64, w: f64) -> Self {
|
|
||||||
Self { x, y, z, w }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod matrix {
|
|
||||||
use super::vector::{Vector3, Vector4};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
|
||||||
pub struct Matrix3 {
|
|
||||||
pub line1: Vector3,
|
|
||||||
pub line2: Vector3,
|
|
||||||
pub line3: Vector3,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
|
||||||
pub struct Matrix4 {
|
|
||||||
pub line1: Vector4,
|
|
||||||
pub line2: Vector4,
|
|
||||||
pub line3: Vector4,
|
|
||||||
pub line4: Vector4,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,354 +0,0 @@
|
|||||||
/*
|
|
||||||
* -------------------------------
|
|
||||||
* Difficult Rocket
|
|
||||||
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
* All rights reserved
|
|
||||||
* -------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub mod python_class {
|
|
||||||
use pyo3::class::basic::CompareOp;
|
|
||||||
use pyo3::prelude::*;
|
|
||||||
use pyo3::types::PySlice;
|
|
||||||
|
|
||||||
use crate::math::matrix::{Matrix3, Matrix4};
|
|
||||||
use crate::math::vector::{Vector2, Vector3, Vector4, VectorTrait};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
#[pyclass(name = "Vector2_rs")]
|
|
||||||
pub struct PyVector2 {
|
|
||||||
pub data: Vector2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
#[pyclass(name = "Vector3_rs")]
|
|
||||||
pub struct PyVector3 {
|
|
||||||
pub data: Vector3,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
#[pyclass(name = "Vector4_rs")]
|
|
||||||
pub struct PyVector4 {
|
|
||||||
pub data: Vector4,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
#[pyclass(name = "Matrix3_rs")]
|
|
||||||
pub struct PyMatrix3 {
|
|
||||||
pub data: Matrix3,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
#[pyclass(name = "Matrix4_rs")]
|
|
||||||
pub struct PyMatrix4 {
|
|
||||||
pub data: Matrix4,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub trait PyCalc {
|
|
||||||
fn __add__(&self, other: &Self) -> Self;
|
|
||||||
fn __sub__(&self, other: &Self) -> Self;
|
|
||||||
fn __mul__(&self, other: &Self) -> Self;
|
|
||||||
fn __truediv__(&self, other: &Self) -> Self;
|
|
||||||
fn __floordiv__(&self, other: &Self) -> Self;
|
|
||||||
fn __abs__(&self) -> f64;
|
|
||||||
fn __neg__(&self) -> Self;
|
|
||||||
fn __round__(&self, ndigits: Option<i64>) -> Self;
|
|
||||||
fn __radd__(&self, other: &PyAny) -> Self;
|
|
||||||
// fn rotate
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 这是一个用来自动给 impl xxx for xxx 的块去掉 trait 部分的宏
|
|
||||||
/// 用于在为 pyclass 实现
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl PyVector2 {
|
|
||||||
#[new]
|
|
||||||
fn py_new(x: f64, y: f64) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: Vector2::new(x, y),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __add__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data + other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __radd__(&self, other: &PyAny) -> Self {
|
|
||||||
return if other.is_instance_of::<PyVector2>().unwrap() {
|
|
||||||
Self {
|
|
||||||
data: self.data + other.extract::<PyVector2>().unwrap().data,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if other == 0
|
|
||||||
if other.is_none() {
|
|
||||||
self.clone()
|
|
||||||
} else {
|
|
||||||
Self {
|
|
||||||
data: self.data + Vector2::from_same(other.extract::<f64>().unwrap()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __sub__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data - other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __mul__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data * other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __truediv__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data / other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __floordiv__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data.floordiv(&other.data),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult<bool> {
|
|
||||||
match op {
|
|
||||||
CompareOp::Lt => Ok(self.data < other.data),
|
|
||||||
CompareOp::Le => Ok(self.data <= other.data),
|
|
||||||
CompareOp::Eq => Ok(self.data == other.data),
|
|
||||||
CompareOp::Ne => Ok(self.data != other.data),
|
|
||||||
CompareOp::Gt => Ok(self.data > other.data),
|
|
||||||
CompareOp::Ge => Ok(self.data >= other.data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __repr__(&self) -> String {
|
|
||||||
return format!("Vector2_rs({}, {})", self.data.x, self.data.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn __getitem__(&self, item: &PyAny) -> PyResult<&PyAny> {
|
|
||||||
// if item.is_instance_of::<PySlice>().unwrap() {
|
|
||||||
// let item = item.extract::<PySlice>().unwrap();
|
|
||||||
// let indices = item.indices().unwrap();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// getter and setter
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_x(&self) -> f64 {
|
|
||||||
return self.data.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_y(&self) -> f64 {
|
|
||||||
return self.data.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_x(&mut self, x: f64) {
|
|
||||||
self.data.x = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_y(&mut self, y: f64) {
|
|
||||||
self.data.y = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl PyVector3 {
|
|
||||||
#[new]
|
|
||||||
fn py_new(x: f64, y: f64, z: f64) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: Vector3::new(x, y, z),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __add__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data + other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __sub__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data - other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __mul__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data * other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __truediv__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data / other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __floordiv__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data.floordiv(&other.data),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult<bool> {
|
|
||||||
match op {
|
|
||||||
CompareOp::Lt => Ok(self.data < other.data),
|
|
||||||
CompareOp::Le => Ok(self.data <= other.data),
|
|
||||||
CompareOp::Eq => Ok(self.data == other.data),
|
|
||||||
CompareOp::Ne => Ok(self.data != other.data),
|
|
||||||
CompareOp::Gt => Ok(self.data > other.data),
|
|
||||||
CompareOp::Ge => Ok(self.data >= other.data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __repr__(&self) -> String {
|
|
||||||
return format!(
|
|
||||||
"Vector3_rs({}, {}, {})",
|
|
||||||
self.data.x, self.data.y, self.data.z
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// getter and setter
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_x(&self) -> f64 {
|
|
||||||
return self.data.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_y(&self) -> f64 {
|
|
||||||
return self.data.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_z(&self) -> f64 {
|
|
||||||
return self.data.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_x(&mut self, x: f64) {
|
|
||||||
self.data.x = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_y(&mut self, y: f64) {
|
|
||||||
self.data.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_z(&mut self, z: f64) {
|
|
||||||
self.data.z = z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl PyVector4 {
|
|
||||||
#[new]
|
|
||||||
fn py_new(x: f64, y: f64, z: f64, w: f64) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: Vector4::new(x, y, z, w),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __add__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data + other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __sub__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data - other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __mul__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data * other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __truediv__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data / other.data,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __floordiv__(&self, other: &Self) -> Self {
|
|
||||||
return Self {
|
|
||||||
data: self.data.floordiv(&other.data),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult<bool> {
|
|
||||||
match op {
|
|
||||||
CompareOp::Lt => Ok(self.data < other.data),
|
|
||||||
CompareOp::Le => Ok(self.data <= other.data),
|
|
||||||
CompareOp::Eq => Ok(self.data == other.data),
|
|
||||||
CompareOp::Ne => Ok(self.data != other.data),
|
|
||||||
CompareOp::Gt => Ok(self.data > other.data),
|
|
||||||
CompareOp::Ge => Ok(self.data >= other.data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __repr__(&self) -> String {
|
|
||||||
return format!(
|
|
||||||
"Vector4_rs({}, {}, {}, {})",
|
|
||||||
self.data.x, self.data.y, self.data.z, self.data.w
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// getter and setter
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_x(&self) -> f64 {
|
|
||||||
return self.data.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_y(&self) -> f64 {
|
|
||||||
return self.data.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_z(&self) -> f64 {
|
|
||||||
return self.data.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn get_w(&self) -> f64 {
|
|
||||||
return self.data.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_x(&mut self, x: f64) {
|
|
||||||
self.data.x = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_y(&mut self, y: f64) {
|
|
||||||
self.data.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_z(&mut self, z: f64) {
|
|
||||||
self.data.z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[setter]
|
|
||||||
fn set_w(&mut self, w: f64) {
|
|
||||||
self.data.w = w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,226 +0,0 @@
|
|||||||
/*
|
|
||||||
* -------------------------------
|
|
||||||
* Difficult Rocket
|
|
||||||
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
* All rights reserved
|
|
||||||
* -------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
use pyo3::intern;
|
|
||||||
use pyo3::prelude::*;
|
|
||||||
// use pyo3::types::PyDict;
|
|
||||||
|
|
||||||
/// Instance of an on-screen image
|
|
||||||
/// See the module documentation for usage.
|
|
||||||
#[pyclass(name = "Sprite_rs", subclass)]
|
|
||||||
#[pyo3(text_signature = "(img, x=0.0, y=0.0, z=0.0, \
|
|
||||||
blend_src=770, blend_dest=771, \
|
|
||||||
batch=None, group=None, \
|
|
||||||
subpixel=False, program=None)")]
|
|
||||||
pub struct Sprite {
|
|
||||||
// render
|
|
||||||
pub subpixel: bool,
|
|
||||||
pub batch: Py<PyAny>,
|
|
||||||
pub group: Option<Py<PyAny>>,
|
|
||||||
pub user_group: Option<Py<PyAny>>,
|
|
||||||
pub group_class: Py<PyAny>,
|
|
||||||
// view
|
|
||||||
pub x: f64,
|
|
||||||
pub y: f64,
|
|
||||||
pub z: f64,
|
|
||||||
pub scale: f64,
|
|
||||||
pub scale_x: f64,
|
|
||||||
pub scale_y: f64,
|
|
||||||
pub visible: bool,
|
|
||||||
pub vertex_list: Option<Vec<()>>,
|
|
||||||
// frame
|
|
||||||
pub frame_index: u32,
|
|
||||||
pub next_dt: f64,
|
|
||||||
#[pyo3(get)]
|
|
||||||
pub program: Option<Py<PyAny>>,
|
|
||||||
pub animation: Option<Py<PyAny>>,
|
|
||||||
pub texture: Option<Py<PyAny>>,
|
|
||||||
pub paused: bool,
|
|
||||||
// other
|
|
||||||
pub rotation: f64,
|
|
||||||
pub rgba: (u8, u8, u8, u8),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl Sprite {
|
|
||||||
/// python code:
|
|
||||||
/// 366:
|
|
||||||
/// if isinstance(img, image.Animation):
|
|
||||||
/// self._animation = img
|
|
||||||
/// self._texture = img.frames[0].image.get_texture()
|
|
||||||
/// self._next_dt = img.frames[0].duration
|
|
||||||
/// if self._next_dt:
|
|
||||||
/// clock.schedule_once(self._animate, self._next_dt)
|
|
||||||
/// else:
|
|
||||||
/// self._texture = img.get_texture()
|
|
||||||
/// 375:
|
|
||||||
/// if not program:
|
|
||||||
/// if isinstance(img, image.TextureArrayRegion):
|
|
||||||
/// self._program = get_default_array_shader()
|
|
||||||
/// else:
|
|
||||||
/// self._program = get_default_shader()
|
|
||||||
/// else:
|
|
||||||
/// self._program = program
|
|
||||||
/// 383:
|
|
||||||
/// self._batch = batch or graphics.get_default_batch()
|
|
||||||
/// self._user_group = group
|
|
||||||
/// self._group = self.group_class(self._texture, blend_src, blend_dest, self.program, group)
|
|
||||||
/// self._subpixel = subpixel
|
|
||||||
/// 387:
|
|
||||||
/// self._create_vertex_list()
|
|
||||||
#[new]
|
|
||||||
fn new(
|
|
||||||
py_: Python,
|
|
||||||
img: &PyAny,
|
|
||||||
x: f64,
|
|
||||||
y: f64,
|
|
||||||
z: f64,
|
|
||||||
blend_src: u32, // default 770 (GL_SRC_ALPHA)
|
|
||||||
blend_dest: u32, // default 771 (GL_ONE_MINUS_SRC_ALPHA)
|
|
||||||
batch_: &PyAny,
|
|
||||||
group: &PyAny,
|
|
||||||
subpixel: bool,
|
|
||||||
program_: &PyAny,
|
|
||||||
) -> Self {
|
|
||||||
let texture;
|
|
||||||
let batch;
|
|
||||||
let mut next_dt = 0.0;
|
|
||||||
let mut animation = None;
|
|
||||||
let mut program = program_;
|
|
||||||
let sprite_group_class = PyModule::import(py_, "pyglet.sprite")
|
|
||||||
.unwrap()
|
|
||||||
.getattr("SpriteGroup")
|
|
||||||
.unwrap();
|
|
||||||
// 366
|
|
||||||
let animation_class = PyModule::import(py_, "pyglet.image.Animation")
|
|
||||||
.unwrap()
|
|
||||||
.getattr("Animation")
|
|
||||||
.unwrap();
|
|
||||||
if img.is_instance(animation_class).unwrap() {
|
|
||||||
animation = Some(img.into());
|
|
||||||
texture = img
|
|
||||||
.getattr(intern!(img.py(), "frames"))
|
|
||||||
.unwrap()
|
|
||||||
.get_item(0)
|
|
||||||
.unwrap()
|
|
||||||
.getattr(intern!(img.py(), "image"))
|
|
||||||
.unwrap()
|
|
||||||
.call_method0(intern!(img.py(), "get_texture"))
|
|
||||||
.unwrap();
|
|
||||||
let _next_dt = img
|
|
||||||
.getattr(intern!(img.py(), "frames"))
|
|
||||||
.unwrap()
|
|
||||||
.get_item(0)
|
|
||||||
.unwrap()
|
|
||||||
.getattr(intern!(img.py(), "duration"));
|
|
||||||
next_dt = match _next_dt {
|
|
||||||
Ok(v) => v.extract().unwrap(),
|
|
||||||
Err(_) => 0.0,
|
|
||||||
}
|
|
||||||
// 372
|
|
||||||
} else {
|
|
||||||
texture = img.call_method0(intern!(img.py(), "get_texture")).unwrap();
|
|
||||||
}
|
|
||||||
// 375
|
|
||||||
if !program.is_true().unwrap() {
|
|
||||||
let texture_array_region_class =
|
|
||||||
PyModule::import(py_, "pyglet.image.TextureArrayRegion")
|
|
||||||
.unwrap()
|
|
||||||
.getattr("TextureArrayRegion")
|
|
||||||
.unwrap();
|
|
||||||
if img.is_instance(texture_array_region_class).unwrap() {
|
|
||||||
// self._program = get_default_array_shader()
|
|
||||||
let get_default_array_shader = PyModule::import(py_, "pyglet.sprite")
|
|
||||||
.unwrap()
|
|
||||||
.getattr("get_default_array_shader")
|
|
||||||
.unwrap();
|
|
||||||
program = get_default_array_shader.call0().unwrap();
|
|
||||||
} else {
|
|
||||||
// self._program = get_default_shader()
|
|
||||||
let get_default_shader = PyModule::import(py_, "pyglet.sprite")
|
|
||||||
.unwrap()
|
|
||||||
.getattr("get_default_shader")
|
|
||||||
.unwrap();
|
|
||||||
program = get_default_shader.call0().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 383
|
|
||||||
if !batch_.is_none() {
|
|
||||||
batch = PyModule::import(py_, "pyglet.graphics")
|
|
||||||
.unwrap()
|
|
||||||
.getattr("get_default_batch")
|
|
||||||
.unwrap()
|
|
||||||
.call0()
|
|
||||||
.unwrap();
|
|
||||||
} else {
|
|
||||||
batch = batch_;
|
|
||||||
}
|
|
||||||
// 385
|
|
||||||
let group = sprite_group_class
|
|
||||||
.call1((texture, blend_src, blend_dest, program, group))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Sprite {
|
|
||||||
subpixel,
|
|
||||||
batch: batch.into(),
|
|
||||||
group: Some(group.into()),
|
|
||||||
user_group: Some(group.into()),
|
|
||||||
group_class: group.into(),
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
z,
|
|
||||||
scale: 1.0,
|
|
||||||
scale_x: 1.0,
|
|
||||||
scale_y: 1.0,
|
|
||||||
visible: true,
|
|
||||||
vertex_list: None,
|
|
||||||
frame_index: 0,
|
|
||||||
next_dt,
|
|
||||||
program: Some(program.into()),
|
|
||||||
animation: animation,
|
|
||||||
texture: Some(texture.into()),
|
|
||||||
paused: false,
|
|
||||||
rotation: 0.0,
|
|
||||||
rgba: (255, 255, 255, 255),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// python code:
|
|
||||||
// 390:
|
|
||||||
// def _create_vertex_list(self):
|
|
||||||
// texture = self._texture
|
|
||||||
// self._vertex_list = self.program.vertex_list(
|
|
||||||
// 1, GL_POINTS, self._batch, self._group,
|
|
||||||
// position=('f', (self._x, self._y, self._z)),
|
|
||||||
// size=('f', (texture.width, texture.height, 1, 1)),
|
|
||||||
// color=('Bn', self._rgba),
|
|
||||||
// texture_uv=('f', texture.uv),
|
|
||||||
// rotation=('f', (self._rotation,)))
|
|
||||||
|
|
||||||
// pub fn _create_vertex_list(&mut self) -> PyResult<()> {
|
|
||||||
// let texture = self.texture.as_ref()?;
|
|
||||||
// Python::with_gil(|py| -> PyResult<()> {
|
|
||||||
// let args = PyDict::new(py);
|
|
||||||
// args.set_item("position", (self.x, self.y, self.z))?;
|
|
||||||
// args.set_item(
|
|
||||||
// "size",
|
|
||||||
// (
|
|
||||||
// texture.getattr(py, "width")?,
|
|
||||||
// texture.getattr(py, "height")?,
|
|
||||||
// 1,
|
|
||||||
// 1,
|
|
||||||
// ),
|
|
||||||
// )?;
|
|
||||||
// args.set_item("color", ("Bn", self.rgba))?;
|
|
||||||
// args.set_item("texture_uv", texture.getattr(py, "uv")?)?;
|
|
||||||
// args.set_item("rotation", (self.rotation,))?;
|
|
||||||
// Ok(())
|
|
||||||
// })?;
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
# -------------------------------
|
|
||||||
# Difficult Rocket
|
|
||||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
# All rights reserved
|
|
||||||
# -------------------------------
|
|
||||||
|
|
||||||
import random
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
from libs.pyglet_rs import Vector2_rs, Vector3_rs, Vector4_rs
|
|
||||||
|
|
||||||
|
|
||||||
# 用于自动在测试运行前后输出测试信息的装饰器
|
|
||||||
def print_test_info(func):
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
print(f"{'=' * 20} {func.__name__} {'=' * 20}")
|
|
||||||
func(*args, **kwargs)
|
|
||||||
print(f"{'=' * 20} {func.__name__} {'=' * 20}")
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
def gen_random_vector() -> Tuple[Vector2_rs, Vector3_rs, Vector4_rs]:
|
|
||||||
vec2 = Vector2_rs(random.randint(1, 100), random.randint(1, 100))
|
|
||||||
vec3 = Vector3_rs(random.randint(1, 100), random.randint(1, 100), random.randint(1, 100))
|
|
||||||
vec4 = Vector4_rs(random.randint(1, 100), random.randint(1, 100), random.randint(1, 100), random.randint(1, 100))
|
|
||||||
return vec2, vec3, vec4
|
|
||||||
|
|
||||||
|
|
||||||
class TestVector(unittest.TestCase):
|
|
||||||
|
|
||||||
@print_test_info
|
|
||||||
def test1_create_print_vector(self):
|
|
||||||
vec2, vec3, vec4 = gen_random_vector()
|
|
||||||
|
|
||||||
print(f"{vec2=}")
|
|
||||||
print(f"{vec3=}")
|
|
||||||
print(f"{vec4=}")
|
|
||||||
|
|
||||||
@print_test_info
|
|
||||||
def test2_calculate_vector(self):
|
|
||||||
vec2, vec3, vec4 = gen_random_vector()
|
|
||||||
vec2_1, vec3_1, vec4_1 = gen_random_vector()
|
|
||||||
|
|
||||||
print('test add')
|
|
||||||
self.assertEqual(vec2 + vec2_1, Vector2_rs(vec2.x + vec2_1.x, vec2.y + vec2_1.y))
|
|
||||||
self.assertEqual(vec3 + vec3_1, Vector3_rs(vec3.x + vec3_1.x, vec3.y + vec3_1.y, vec3.z + vec3_1.z))
|
|
||||||
self.assertEqual(vec4 + vec4_1, Vector4_rs(vec4.x + vec4_1.x, vec4.y + vec4_1.y, vec4.z + vec4_1.z, vec4.w + vec4_1.w))
|
|
||||||
|
|
||||||
print('test sub')
|
|
||||||
self.assertEqual(vec2 - vec2_1, Vector2_rs(vec2.x - vec2_1.x, vec2.y - vec2_1.y))
|
|
||||||
self.assertEqual(vec3 - vec3_1, Vector3_rs(vec3.x - vec3_1.x, vec3.y - vec3_1.y, vec3.z - vec3_1.z))
|
|
||||||
self.assertEqual(vec4 - vec4_1, Vector4_rs(vec4.x - vec4_1.x, vec4.y - vec4_1.y, vec4.z - vec4_1.z, vec4.w - vec4_1.w))
|
|
||||||
|
|
||||||
print('test mul')
|
|
||||||
self.assertEqual(vec2 * vec2_1, Vector2_rs(vec2.x * vec2_1.x, vec2.y * vec2_1.y))
|
|
||||||
self.assertEqual(vec3 * vec3_1, Vector3_rs(vec3.x * vec3_1.x, vec3.y * vec3_1.y, vec3.z * vec3_1.z))
|
|
||||||
self.assertEqual(vec4 * vec4_1, Vector4_rs(vec4.x * vec4_1.x, vec4.y * vec4_1.y, vec4.z * vec4_1.z, vec4.w * vec4_1.w))
|
|
||||||
|
|
||||||
print('test true_div')
|
|
||||||
self.assertEqual(vec2 / vec2_1, Vector2_rs(vec2.x / vec2_1.x, vec2.y / vec2_1.y))
|
|
||||||
self.assertEqual(vec3 / vec3_1, Vector3_rs(vec3.x / vec3_1.x, vec3.y / vec3_1.y, vec3.z / vec3_1.z))
|
|
||||||
self.assertEqual(vec4 / vec4_1, Vector4_rs(vec4.x / vec4_1.x, vec4.y / vec4_1.y, vec4.z / vec4_1.z, vec4.w / vec4_1.w))
|
|
||||||
|
|
||||||
print('test floor_div')
|
|
||||||
self.assertEqual(vec2 // vec2_1, Vector2_rs(vec2.x // vec2_1.x, vec2.y // vec2_1.y))
|
|
||||||
self.assertEqual(vec3 // vec3_1, Vector3_rs(vec3.x // vec3_1.x, vec3.y // vec3_1.y, vec3.z // vec3_1.z))
|
|
||||||
self.assertEqual(vec4 // vec4_1, Vector4_rs(vec4.x // vec4_1.x, vec4.y // vec4_1.y, vec4.z // vec4_1.z, vec4.w // vec4_1.w))
|
|
||||||
|
|
@ -8,11 +8,17 @@
|
|||||||
import platform
|
import platform
|
||||||
import traceback
|
import traceback
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple, Optional, Any
|
||||||
|
|
||||||
from Difficult_Rocket.api.types import Options, Version
|
from Difficult_Rocket.api.types import Options, Version
|
||||||
|
|
||||||
|
|
||||||
|
def _add_cmd(cmd: List[str], string: Optional[Any]) -> List[str]:
|
||||||
|
if string is not None and string:
|
||||||
|
cmd.append(string)
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
class CompilerHelper(Options):
|
class CompilerHelper(Options):
|
||||||
name = 'Nuitka Compiler Helper'
|
name = 'Nuitka Compiler Helper'
|
||||||
|
|
||||||
@ -28,6 +34,7 @@ class CompilerHelper(Options):
|
|||||||
use_mingw: bool = False # --mingw64
|
use_mingw: bool = False # --mingw64
|
||||||
standalone: bool = True # --standalone
|
standalone: bool = True # --standalone
|
||||||
use_ccache: bool = True # not --disable-ccache
|
use_ccache: bool = True # not --disable-ccache
|
||||||
|
enable_console: bool = True # --enable-console / --disable-console
|
||||||
|
|
||||||
show_progress: bool = True # --show-progress
|
show_progress: bool = True # --show-progress
|
||||||
show_memory: bool = False # --show-memory
|
show_memory: bool = False # --show-memory
|
||||||
@ -38,8 +45,11 @@ class CompilerHelper(Options):
|
|||||||
|
|
||||||
company_name: str = 'tool-shenjack-workshop'
|
company_name: str = 'tool-shenjack-workshop'
|
||||||
product_name: str = 'Difficult-Rocket'
|
product_name: str = 'Difficult-Rocket'
|
||||||
product_version: Version
|
|
||||||
file_version: Version
|
file_version: Version
|
||||||
|
product_version: Version
|
||||||
|
file_description: str = 'Difficult Rocket' # --file-description
|
||||||
|
|
||||||
|
copy_right: str = 'Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com' # --copyright
|
||||||
|
|
||||||
icon_path: Path = Path('textures/icon.png')
|
icon_path: Path = Path('textures/icon.png')
|
||||||
|
|
||||||
@ -51,6 +61,9 @@ class CompilerHelper(Options):
|
|||||||
('./configs', './configs')]
|
('./configs', './configs')]
|
||||||
include_packages: List[str] = ['Difficult_Rocket.api']
|
include_packages: List[str] = ['Difficult_Rocket.api']
|
||||||
|
|
||||||
|
enable_plugin: List[str] = [] # --enable-plugin=xxx,xxx
|
||||||
|
disable_plugin: List[str] = [] # --disable-plugin=xxx,xxx
|
||||||
|
|
||||||
def init(self, **kwargs) -> None:
|
def init(self, **kwargs) -> None:
|
||||||
# 非 windows 平台不使用 msvc
|
# 非 windows 平台不使用 msvc
|
||||||
if platform.system() != 'Windows':
|
if platform.system() != 'Windows':
|
||||||
@ -62,9 +75,9 @@ class CompilerHelper(Options):
|
|||||||
|
|
||||||
def load_file(self) -> bool:
|
def load_file(self) -> bool:
|
||||||
try:
|
try:
|
||||||
from Difficult_Rocket import DR_runtime
|
from Difficult_Rocket import DR_status
|
||||||
self.product_version = DR_runtime.DR_version
|
self.product_version = DR_status.DR_version
|
||||||
self.file_version = DR_runtime.Build_version
|
self.file_version = DR_status.Build_version
|
||||||
return True
|
return True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@ -73,57 +86,52 @@ class CompilerHelper(Options):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.as_markdown()
|
return self.as_markdown()
|
||||||
|
|
||||||
def as_markdown(self) -> str:
|
def as_markdown(self, longest: Optional[int] = None) -> str:
|
||||||
front = super().as_markdown()
|
front = super().as_markdown(longest)
|
||||||
gen_cmd = self.gen_subprocess_cmd()
|
gen_cmd = self.gen_subprocess_cmd()
|
||||||
return f"{front}\n\n```bash\n{' '.join(gen_cmd)}\n```"
|
return f"{front}\n\n```bash\n{' '.join(gen_cmd)}\n```"
|
||||||
|
|
||||||
def gen_subprocess_cmd(self) -> List[str]:
|
def gen_subprocess_cmd(self) -> List[str]:
|
||||||
cmd_list = [self.python_cmd, '-m', 'nuitka']
|
cmd_list = [self.python_cmd, '-m', 'nuitka']
|
||||||
# macos 和 非 macos icon 参数不同
|
# macos 和 非 macos icon 参数不同
|
||||||
icon_cmd = ""
|
|
||||||
if platform.system() == 'Darwin':
|
if platform.system() == 'Darwin':
|
||||||
icon_cmd = f"--macos-app-icon={self.icon_path.absolute()}"
|
cmd_list.append(f"--macos-app-version={self.product_version}")
|
||||||
|
_add_cmd(cmd_list, f'--macos-app-icon={self.icon_path.absolute()}' if self.icon_path else None)
|
||||||
elif platform.system() == 'Windows':
|
elif platform.system() == 'Windows':
|
||||||
icon_cmd = f"--windows-icon-from-ico={self.icon_path.absolute()}"
|
_add_cmd(cmd_list, f'--windows-icon-from-ico={self.icon_path.absolute()}' if self.icon_path else None)
|
||||||
|
elif platform.system() == 'Linux':
|
||||||
|
_add_cmd(cmd_list, f'--linux-icon={self.icon_path.absolute()}' if self.icon_path else None)
|
||||||
|
|
||||||
if self.use_lto:
|
_add_cmd(cmd_list, '--lto=yes' if self.use_lto else '--lto=no')
|
||||||
cmd_list.append('--lto=yes')
|
_add_cmd(cmd_list, '--clang' if self.use_clang else None)
|
||||||
else:
|
_add_cmd(cmd_list, '--msvc=latest' if self.use_msvc else None)
|
||||||
cmd_list.append('--lto=no')
|
_add_cmd(cmd_list, '--mingw64' if self.use_mingw else None)
|
||||||
|
_add_cmd(cmd_list, '--standalone' if self.standalone else None)
|
||||||
|
|
||||||
if self.use_clang:
|
_add_cmd(cmd_list, '--disable-ccache' if not self.use_ccache else None)
|
||||||
cmd_list.append('--clang')
|
_add_cmd(cmd_list, '--show-progress' if self.show_progress else None)
|
||||||
if self.use_msvc:
|
_add_cmd(cmd_list, '--show-memory' if self.show_memory else None)
|
||||||
cmd_list.append('--msvc=latest')
|
_add_cmd(cmd_list, '--assume-yes-for-download' if self.download_confirm else None)
|
||||||
if self.standalone:
|
_add_cmd(cmd_list, '--enable-console' if self.enable_console else '--disable-console')
|
||||||
cmd_list.append('--standalone')
|
|
||||||
if not self.use_ccache:
|
|
||||||
cmd_list.append('--disable-ccache')
|
|
||||||
if self.show_progress:
|
|
||||||
cmd_list.append('--show-progress')
|
|
||||||
if self.show_memory:
|
|
||||||
cmd_list.append('--show-memory')
|
|
||||||
if self.download_confirm:
|
|
||||||
cmd_list.append('--assume-yes-for-download')
|
|
||||||
if self.save_xml:
|
|
||||||
cmd_list.append(f'--xml={self.xml_path.absolute()}')
|
|
||||||
|
|
||||||
cmd_list.append(f"--output-dir={self.output_path.absolute()}")
|
_add_cmd(cmd_list, f'--xml={self.xml_path.absolute()}' if self.save_xml else None)
|
||||||
|
_add_cmd(cmd_list, f'--output-dir={self.output_path.absolute()}' if self.output_path else None)
|
||||||
|
_add_cmd(cmd_list, f'--company-name={self.company_name}' if self.company_name else None)
|
||||||
|
_add_cmd(cmd_list, f'--product-name={self.product_name}' if self.product_name else None)
|
||||||
|
_add_cmd(cmd_list, f'--file-version={self.file_version}' if self.file_version else None)
|
||||||
|
_add_cmd(cmd_list, f'--product-version={self.product_version}' if self.product_version else None)
|
||||||
|
_add_cmd(cmd_list, f'--file-description={self.file_description}' if self.file_description else None)
|
||||||
|
_add_cmd(cmd_list, f'--copyright={self.copy_right}' if self.copy_right else None)
|
||||||
|
|
||||||
cmd_list.append(f"--company-name={self.company_name}")
|
_add_cmd(cmd_list, f'--follow-import-to={",".join(self.follow_import)}' if self.follow_import else None)
|
||||||
cmd_list.append(f"--product-name={self.product_name}")
|
_add_cmd(cmd_list, f'--nofollow-import-to={",".join(self.no_follow_import)}' if self.no_follow_import else None)
|
||||||
cmd_list.append(f"--product-version={self.product_version}")
|
_add_cmd(cmd_list, f'--enable-plugin={",".join(self.enable_plugin)}' if self.enable_plugin else None)
|
||||||
cmd_list.append(f"--file-version={self.file_version}")
|
_add_cmd(cmd_list, f'--disable-plugin={",".join(self.disable_plugin)}' if self.disable_plugin else None)
|
||||||
|
|
||||||
if icon_cmd:
|
if self.include_data_dir:
|
||||||
cmd_list.append(icon_cmd)
|
cmd_list += [f"--include-data-dir={src}={dst}" for src, dst in self.include_data_dir]
|
||||||
|
if self.include_packages:
|
||||||
cmd_list += [f"--include-data-dir={src}={dst}" for src, dst in self.include_data_dir]
|
cmd_list += [f"--include-package={package}" for package in self.include_packages]
|
||||||
cmd_list += [f"--include-package={package}" for package in self.include_packages]
|
|
||||||
|
|
||||||
cmd_list.append(f"--follow-import-to={','.join(self.follow_import)}")
|
|
||||||
cmd_list.append(f"--nofollow-import-to={','.join(self.no_follow_import)}")
|
|
||||||
|
|
||||||
cmd_list.append(f"{self.src_file}")
|
cmd_list.append(f"{self.src_file}")
|
||||||
return cmd_list
|
return cmd_list
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
python3.8 setup.py build
|
|
||||||
python3.9 setup.py build
|
|
||||||
python3.9 post_build.py
|
|
@ -4,18 +4,23 @@
|
|||||||
# All rights reserved
|
# All rights reserved
|
||||||
# -------------------------------
|
# -------------------------------
|
||||||
|
|
||||||
|
import logging
|
||||||
import warnings
|
import warnings
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from Difficult_Rocket import DR_status
|
||||||
from Difficult_Rocket.main import Game
|
from Difficult_Rocket.main import Game
|
||||||
|
from Difficult_Rocket.main import Console
|
||||||
from Difficult_Rocket.api.mod import ModInfo
|
from Difficult_Rocket.api.mod import ModInfo
|
||||||
from Difficult_Rocket.api.types import Options, Version
|
|
||||||
from Difficult_Rocket.client import ClientWindow
|
from Difficult_Rocket.client import ClientWindow
|
||||||
|
from Difficult_Rocket.api.types import Options, Version
|
||||||
|
|
||||||
DR_rust_version = Version("0.2.10.1") # DR_mod 的 Rust 编写部分的兼容版本
|
DR_rust_version = Version("0.2.10.1") # DR_mod 的 Rust 编写部分的兼容版本
|
||||||
|
|
||||||
|
logger = logging.getLogger('client.dr_game')
|
||||||
|
|
||||||
|
|
||||||
class _DR_mod_runtime(Options):
|
class _DR_mod_runtime(Options):
|
||||||
name = 'DR mod runtime'
|
name = 'DR mod runtime'
|
||||||
@ -32,8 +37,9 @@ class _DR_mod_runtime(Options):
|
|||||||
self.DR_rust_available = True
|
self.DR_rust_available = True
|
||||||
if self.DR_rust_get_version != self.DR_rust_version:
|
if self.DR_rust_get_version != self.DR_rust_version:
|
||||||
relationship = 'larger' if self.DR_rust_version > self.DR_rust_version else 'smaller'
|
relationship = 'larger' if self.DR_rust_version > self.DR_rust_version else 'smaller'
|
||||||
warnings.warn(f'DR_rust builtin version is {self.DR_rust_version} but true version is {get_version_str()}.\n'
|
warnings.warn(
|
||||||
f'Builtin version {relationship} than true version')
|
f'DR_rust builtin version is {self.DR_rust_version} but true version is {get_version_str()}.\n'
|
||||||
|
f'Builtin version {relationship} than true version')
|
||||||
self.use_DR_rust = self.use_DR_rust and self.DR_rust_available
|
self.use_DR_rust = self.use_DR_rust and self.DR_rust_available
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@ -46,10 +52,9 @@ DR_mod_runtime = _DR_mod_runtime()
|
|||||||
|
|
||||||
|
|
||||||
class DR_mod(ModInfo):
|
class DR_mod(ModInfo):
|
||||||
|
|
||||||
mod_id = "difficult_rocket_mod"
|
mod_id = "difficult_rocket_mod"
|
||||||
name = "Difficult Rocket mod"
|
name = "Difficult Rocket mod"
|
||||||
version = Version("0.1.0.0")
|
version = Version("0.2.0.0")
|
||||||
|
|
||||||
writer = "shenjackyuanjie"
|
writer = "shenjackyuanjie"
|
||||||
link = "shenjack.top"
|
link = "shenjack.top"
|
||||||
@ -58,7 +63,8 @@ class DR_mod(ModInfo):
|
|||||||
|
|
||||||
config = DR_mod_runtime
|
config = DR_mod_runtime
|
||||||
|
|
||||||
# DR_version = # DR SDK 兼容版本
|
DR_version = (DR_status.DR_version, DR_status.DR_version) # DR SDK 兼容版本
|
||||||
|
|
||||||
# 反正是内置 mod 跟着最新版本的 DR 走就行了
|
# 反正是内置 mod 跟着最新版本的 DR 走就行了
|
||||||
# DR_Api_version = # DR Api版本
|
# DR_Api_version = # DR Api版本
|
||||||
# 同理 不管 API 版本 这东西要是不兼容了才是大问题
|
# 同理 不管 API 版本 这东西要是不兼容了才是大问题
|
||||||
@ -74,15 +80,23 @@ class DR_mod(ModInfo):
|
|||||||
game.client.window.add_sub_screen("SR1_ship", old_self.screen)
|
game.client.window.add_sub_screen("SR1_ship", old_self.screen)
|
||||||
else:
|
else:
|
||||||
self.config.flush_option()
|
self.config.flush_option()
|
||||||
print("DR_mod: on_load")
|
logger.info("on_load")
|
||||||
print(self.as_markdown())
|
logger.info(self.as_markdown())
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def on_client_start(self, game: Game, client: ClientWindow):
|
def on_client_start(self, game: Game, client: ClientWindow):
|
||||||
from .sr1_ship import SR1ShipRender
|
from .sr1_ship import SR1ShipRender
|
||||||
self.screen = SR1ShipRender
|
self.screen = SR1ShipRender
|
||||||
print('DR_mod: on_client_start')
|
|
||||||
client.add_sub_screen("SR1_ship", SR1ShipRender)
|
client.add_sub_screen("SR1_ship", SR1ShipRender)
|
||||||
|
logger.info('on_client_start added sub screen')
|
||||||
|
|
||||||
|
def on_unload(self, game: Game):
|
||||||
|
if DR_mod_runtime.DR_rust_available:
|
||||||
|
game.console.stop()
|
||||||
|
game.console_class = Console
|
||||||
|
logger.info('replace Console class')
|
||||||
|
game.init_console()
|
||||||
|
logger.info('reinit console')
|
||||||
|
|
||||||
|
|
||||||
mod_class = DR_mod
|
mod_class = DR_mod
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
# All rights reserved
|
# All rights reserved
|
||||||
# -------------------------------
|
# -------------------------------
|
||||||
|
|
||||||
import math
|
# import math
|
||||||
import time
|
import time
|
||||||
import random
|
import random
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
from xml.etree import ElementTree
|
# from xml.etree import ElementTree
|
||||||
from xml.etree.ElementTree import Element
|
from xml.etree.ElementTree import Element
|
||||||
from typing import List, TYPE_CHECKING, Union, Dict, Optional, Generator
|
from typing import List, TYPE_CHECKING, Union, Dict, Optional, Generator
|
||||||
|
|
||||||
@ -21,13 +21,13 @@ from pyglet.math import Vec4
|
|||||||
from pyglet.text import Label
|
from pyglet.text import Label
|
||||||
from pyglet.shapes import Line, Rectangle
|
from pyglet.shapes import Line, Rectangle
|
||||||
from pyglet.sprite import Sprite
|
from pyglet.sprite import Sprite
|
||||||
from pyglet.image import Texture
|
# from pyglet.image import Texture
|
||||||
from pyglet.graphics import Batch, Group
|
from pyglet.graphics import Batch, Group
|
||||||
|
|
||||||
from . import DR_mod_runtime
|
from . import DR_mod_runtime
|
||||||
|
|
||||||
# Difficult Rocket
|
# Difficult Rocket
|
||||||
from Difficult_Rocket import DR_option
|
from Difficult_Rocket import DR_status
|
||||||
from Difficult_Rocket.utils.translate import tr
|
from Difficult_Rocket.utils.translate import tr
|
||||||
from Difficult_Rocket.api.types import Fonts, Options
|
from Difficult_Rocket.api.types import Fonts, Options
|
||||||
from Difficult_Rocket.command.line import CommandText
|
from Difficult_Rocket.command.line import CommandText
|
||||||
@ -40,7 +40,7 @@ if TYPE_CHECKING:
|
|||||||
if DR_mod_runtime.use_DR_rust:
|
if DR_mod_runtime.use_DR_rust:
|
||||||
from .Difficult_Rocket_rs import CenterCamera_rs, SR1PartList_rs, SR1Ship_rs
|
from .Difficult_Rocket_rs import CenterCamera_rs, SR1PartList_rs, SR1Ship_rs
|
||||||
|
|
||||||
logger = logging.getLogger('client')
|
logger = logging.getLogger('client.dr_game_sr1_ship')
|
||||||
|
|
||||||
|
|
||||||
def get_sr1_part(part_xml: Element) -> Optional[SR1PartData]:
|
def get_sr1_part(part_xml: Element) -> Optional[SR1PartData]:
|
||||||
@ -124,7 +124,7 @@ class SR1ShipRender(BaseScreen):
|
|||||||
self.part_box_batch = Batch()
|
self.part_box_batch = Batch()
|
||||||
self.part_batch = Batch()
|
self.part_batch = Batch()
|
||||||
self.part_group = Group()
|
self.part_group = Group()
|
||||||
self.debug_label = Label(x=20, y=main_window.height - 20, font_size=DR_option.std_font_size,
|
self.debug_label = Label(x=20, y=main_window.height - 20, font_size=DR_status.std_font_size,
|
||||||
text='SR1 render!', font_name=Fonts.微软等宽无线,
|
text='SR1 render!', font_name=Fonts.微软等宽无线,
|
||||||
width=main_window.width - 20, height=20,
|
width=main_window.width - 20, height=20,
|
||||||
anchor_x='left', anchor_y='top')
|
anchor_x='left', anchor_y='top')
|
||||||
@ -171,7 +171,7 @@ class SR1ShipRender(BaseScreen):
|
|||||||
self.drawing = True
|
self.drawing = True
|
||||||
for part_id, part in part_datas.items():
|
for part_id, part in part_datas.items():
|
||||||
# 下面就是调用 pyglet 去渲染的部分
|
# 下面就是调用 pyglet 去渲染的部分
|
||||||
# render_scale = DR_option.gui_scale # 这个是 DR 的缩放比例 可以调节的(
|
# render_scale = DR_status.gui_scale # 这个是 DR 的缩放比例 可以调节的(
|
||||||
# 主要是 Windows 下有一个缩放系数嘛,我待会试试这玩意能不能获取(估计得 ctypes
|
# 主要是 Windows 下有一个缩放系数嘛,我待会试试这玩意能不能获取(估计得 ctypes
|
||||||
# 在不缩放的情况下,XML的1个单位长度对应60个像素
|
# 在不缩放的情况下,XML的1个单位长度对应60个像素
|
||||||
render_x = part.x * 60
|
render_x = part.x * 60
|
||||||
|
@ -79,9 +79,11 @@ if __name__ == '__main__':
|
|||||||
if f'pyglet.{lib}.{name}' in compiler.no_follow_import:
|
if f'pyglet.{lib}.{name}' in compiler.no_follow_import:
|
||||||
compiler.no_follow_import.remove(f'pyglet.{lib}.{name}')
|
compiler.no_follow_import.remove(f'pyglet.{lib}.{name}')
|
||||||
|
|
||||||
print(compiler.output_path)
|
print(compiler.as_markdown(longest=70))
|
||||||
|
|
||||||
print(compiler)
|
if is_github:
|
||||||
|
from pprint import pprint
|
||||||
|
pprint(compiler.option())
|
||||||
|
|
||||||
print(compiler.gen_subprocess_cmd())
|
print(compiler.gen_subprocess_cmd())
|
||||||
|
|
||||||
@ -133,7 +135,7 @@ if __name__ == '__main__':
|
|||||||
'dist_size_mb': dist_dir_size / 1024 / 1024,
|
'dist_size_mb': dist_dir_size / 1024 / 1024,
|
||||||
'compiler_data': compiler.str_option(),
|
'compiler_data': compiler.str_option(),
|
||||||
'dist_file_size': dist_file_size}
|
'dist_file_size': dist_file_size}
|
||||||
with open(compiler.output_path / f'../compile_data-{time.time()}.toml', 'w') as compile_data_file:
|
with open(compiler.output_path / f'../compile_data-{time.time()}.toml', 'w', encoding='utf-8') as compile_data_file:
|
||||||
tomlkit.dump(compile_data, compile_data_file)
|
tomlkit.dump(compile_data, compile_data_file)
|
||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
@ -6,7 +6,7 @@ build-backend = "pdm.pep517.api"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "difficult-rocket"
|
name = "difficult-rocket"
|
||||||
version = "0.8.2.0"
|
version = "0.8.3.0"
|
||||||
description = "A rocket game"
|
description = "A rocket game"
|
||||||
authors = [
|
authors = [
|
||||||
{name = "shenjackyuanjie", email = "3695888@qq.com"}
|
{name = "shenjackyuanjie", email = "3695888@qq.com"}
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
# DR build (by nuitka)
|
# DR build (by nuitka)
|
||||||
|
|
||||||
# for images
|
# for images
|
||||||
pillow >= 9.5.0
|
# not for pypy >= 3.10
|
||||||
|
pillow >= 9.5.0; (platform_python_implementation == "PyPy" and python_version < "3.10") or platform_python_implementation == "CPython"
|
||||||
|
|
||||||
# for sys info
|
# for sys info
|
||||||
psutil >= 5.9.5
|
psutil >= 5.9.5
|
||||||
@ -17,9 +18,9 @@ defusedxml >= 0.7.1
|
|||||||
objprint >= 0.2.2
|
objprint >= 0.2.2
|
||||||
|
|
||||||
# for compile
|
# for compile
|
||||||
nuitka >= 1.6.1
|
nuitka >= 1.6.3
|
||||||
ordered-set >= 4.1.0
|
ordered-set >= 4.1.0
|
||||||
imageio >= 2.31.0
|
imageio >= 2.31.0; (platform_python_implementation == "PyPy" and python_version < "3.10") or platform_python_implementation == "CPython"
|
||||||
wheel >= 0.40.0
|
wheel >= 0.40.0
|
||||||
setuptools >= 67.8.0
|
setuptools >= 67.8.0
|
||||||
setuptools-rust >= 1.6.0
|
setuptools-rust >= 1.6.0
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
# DR contributing
|
# DR contributing
|
||||||
|
|
||||||
# for images
|
# for images
|
||||||
pillow >= 9.5.0
|
# not for pypy >= 3.10
|
||||||
|
pillow >= 9.5.0; (platform_python_implementation == "PyPy" and python_version < "3.10") or platform_python_implementation == "CPython"
|
||||||
|
|
||||||
# for sys info
|
# for sys info
|
||||||
psutil >= 5.9.5
|
psutil >= 5.9.5
|
||||||
@ -16,13 +17,13 @@ defusedxml >= 0.7.1
|
|||||||
|
|
||||||
# for debug
|
# for debug
|
||||||
objprint >= 0.2.2
|
objprint >= 0.2.2
|
||||||
viztracer >= 0.15.6
|
viztracer >= 0.15.6; platform_python_implementation != "PyPy"
|
||||||
vizplugins >= 0.1.3
|
vizplugins >= 0.1.3; platform_python_implementation != "PyPy"
|
||||||
|
|
||||||
# for compile
|
# for compile
|
||||||
nuitka >= 1.6.1
|
nuitka >= 1.6.3
|
||||||
ordered-set >= 4.1.0
|
ordered-set >= 4.1.0
|
||||||
imageio >= 2.31.0
|
imageio >= 2.31.0; (platform_python_implementation == "PyPy" and python_version < "3.10") or platform_python_implementation == "CPython"
|
||||||
wheel >= 0.40.0
|
wheel >= 0.40.0
|
||||||
setuptools >= 67.8.0
|
setuptools >= 67.8.0
|
||||||
setuptools-rust >= 1.6.0
|
setuptools-rust >= 1.6.0
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
# DR basic running from source
|
# DR basic running from source
|
||||||
|
|
||||||
# for images
|
# for images
|
||||||
pillow >= 9.5.0
|
# not for pypy >= 3.10
|
||||||
|
pillow >= 9.5.0; platform_python_implementation == "PyPy" and python_version < "3.10"
|
||||||
|
|
||||||
# for sys info
|
# for sys info
|
||||||
psutil >= 5.9.5
|
psutil >= 5.9.5
|
||||||
|
Loading…
Reference in New Issue
Block a user