import argparse
import simplepbr
-import gltf
+#import gltf
from glob import glob
from importlib import import_module
from inspect import isclass
from logging import info, debug
from os.path import exists
from os import makedirs
+from multiprocessing import cpu_count
from panda3d.core import Filename, load_prc_file_data, AntialiasAttrib, \
- Texture, WindowProperties, LVector2i
+ Texture, WindowProperties, LVector2i, TextNode
from panda3d.bullet import BulletWorld, BulletDebugNode
from direct.showbase.ShowBase import ShowBase
+from direct.gui.OnscreenText import OnscreenText
from direct.fsm.FSM import FSM
-from pmachines.music import MusicMgr
+from pmachines.audio.music import MusicMgr
from pmachines.items.background import Background
-from pmachines.menu import Menu
+from pmachines.gui.menu import Menu
from pmachines.scene import Scene
-from lib.dictfile import DctFile
-from lib.lib.p3d.p3d import LibP3d
-from lib.engine.lang import LangMgr
+from pmachines.scenes.scene_basketball import SceneBasketBall
+from pmachines.scenes.scene_box import SceneBox
+from pmachines.scenes.scene_domino_box_basketball import SceneDominoBoxBasketball
+from pmachines.scenes.scene_domino_box import SceneDominoBox
+from pmachines.scenes.scene_domino import SceneDomino
+from pmachines.scenes.scene_teeter_domino_box_basketball import SceneTeeterDominoBoxBasketball
+from pmachines.scenes.scene_teeter_tooter import SceneTeeterTooter
+from pmachines.posmgr import PositionMgr
+from ya2.utils.dictfile import DctFile
+from ya2.p3d.p3d import LibP3d
+from ya2.utils.lang import LangMgr
+from ya2.utils.log import LogMgr
+from ya2.utils.functional import FunctionalTest
+from ya2.p3d.asserts import assert_threads, assert_tasks, assert_render3d, \
+ assert_render2d, assert_aspect2d, assert_events, assert_buffers
class MainFsm(FSM):
def exitMenu(self):
self._pmachines.on_menu_exit()
+ self.__do_asserts()
def enterScene(self, cls):
self._pmachines.on_scene_enter(cls)
def exitScene(self):
self._pmachines.on_scene_exit()
+ self.__do_asserts()
+
+ def __do_asserts(self):
+ args = self._pmachines._args
+ if not LibP3d.runtime() or args.functional_test or args.functional_ref:
+ assert_threads()
+ assert_tasks()
+ assert_render3d()
+ assert_render2d()
+ assert_aspect2d()
+ assert_events()
+ assert_buffers()
class PmachinesApp:
+ scenes = [
+ SceneDomino,
+ SceneBox,
+ SceneDominoBox,
+ SceneBasketBall,
+ SceneDominoBoxBasketball,
+ SceneTeeterTooter,
+ SceneTeeterDominoBoxBasketball]
+
def __init__(self):
info('platform: %s' % platform)
info('exists main.py: %s' % exists('main.py'))
- args = self._parse_args()
+ self._args = args = self._parse_args()
self._configure(args)
self.base = ShowBase()
- self._prepare_window(args)
+ self._pipeline = None
self.updating = args.update
self.version = args.version
+ self.log_mgr = LogMgr.init_cls()()
+ self._pos_mgr = PositionMgr()
+ self._prepare_window(args)
if args.update:
return
+ if args.functional_test:
+ self._options['settings']['volume'] = 0
self._music = MusicMgr(self._options['settings']['volume'])
self.lang_mgr = LangMgr(self._options['settings']['language'],
'pmachines',
'assets/locale/')
self._fsm = MainFsm(self)
- if args.screenshots:
- scene_classes = []
- for _file in glob('pmachines/scenes/*.py'):
- _fn = _file.replace('.py', '').replace('/', '.')
- for member in import_module(_fn).__dict__.values():
- if isclass(member) and issubclass(member, Scene) and \
- member != Scene:
- scene_classes += [member]
- for cls in scene_classes:
- scene = cls(BulletWorld(), None, True, False, lambda: None)
- scene.screenshot()
- scene.destroy()
+ if args.screenshot:
+ cls = [cls for cls in self.scenes if cls.__name__ == args.screenshot][0]
+ scene = cls(BulletWorld(), None, True, False, lambda: None, self.scenes)
+ scene.screenshot()
+ scene.destroy()
exit()
elif self._options['development']['auto_start']:
mod_name = 'pmachines.scenes.scene_' + self._options['development']['auto_start']
self._fsm.demand('Scene', cls)
else:
self._fsm.demand('Menu')
+ if args.functional_test or args.functional_ref:
+ FunctionalTest(args.functional_ref, self._pos_mgr)
+ if not LibP3d.runtime() or args.functional_test or args.functional_ref:
+ self.__fps_lst = []
+ taskMgr.do_method_later(1.0, self.__assert_fps, 'assert_fps')
def on_menu_enter(self):
self._menu_bg = Background()
self._menu = Menu(
self._fsm, self.lang_mgr, self._options, self._music,
- self._pipeline)
+ self._pipeline, self.scenes, self._args.functional_test or self._args.functional_ref,
+ self._pos_mgr)
def on_home(self):
self._fsm.demand('Menu')
self.world, self.on_home,
self._options['development']['auto_close_instructions'],
self._options['development']['debug_items'],
- self.reload)
+ self.reload,
+ self.scenes,
+ self._pos_mgr,
+ self._args.functional_test or self._args.functional_ref,
+ self._options['development']['mouse_coords'])
def on_scene_exit(self):
self._unset_physics()
load_prc_file_data('', 'window-title pmachines')
load_prc_file_data('', 'framebuffer-srgb true')
load_prc_file_data('', 'sync-video true')
+ if args.functional_test or args.functional_ref:
+ load_prc_file_data('', 'win-size 1360 768')
+ # otherwise it is not centered in exwm
# load_prc_file_data('', 'threading-model Cull/Draw')
# it freezes when you go to the next scene
- if args.screenshots:
+ if args.screenshot:
load_prc_file_data('', 'window-type offscreen')
load_prc_file_data('', 'audio-library-name null')
parser.add_argument('--update', action='store_true')
parser.add_argument('--version', action='store_true')
parser.add_argument('--optfile')
- parser.add_argument('--screenshots', action='store_true')
+ parser.add_argument('--screenshot')
+ parser.add_argument('--functional-test', action='store_true')
+ parser.add_argument('--functional-ref', action='store_true')
cmd_line = [arg for arg in iter(argv[1:]) if not arg.startswith('-psn_')]
args = parser.parse_args(cmd_line)
return args
'auto_close_instructions': 0,
'show_buffers': 0,
'debug_items': 0,
+ 'mouse_coords': 0,
'fps': 0}}
opt_path = LibP3d.fixpath(data_path + '/' + optfile) if data_path else optfile
opt_exists = exists(opt_path)
if res:
res = LVector2i(*[int(_res) for _res in res.split('x')])
else:
- d_i = base.pipe.get_display_information()
- def _res(idx):
- return d_i.get_display_mode_width(idx), \
- d_i.get_display_mode_height(idx)
- resolutions = [
- _res(idx) for idx in range(d_i.get_total_display_modes())]
+ resolutions = []
+ if not self.version:
+ d_i = base.pipe.get_display_information()
+ def _res(idx):
+ return d_i.get_display_mode_width(idx), \
+ d_i.get_display_mode_height(idx)
+ resolutions = [
+ _res(idx) for idx in range(d_i.get_total_display_modes())]
res = sorted(resolutions)[-1]
+ fullscreen = self._options['settings']['fullscreen']
props = WindowProperties()
- props.set_size(res)
- props.set_fullscreen(self._options['settings']['fullscreen'])
- props.set_icon_filename('assets/icon/pmachines.ico')
- if not args.screenshots:
+ if args.functional_test or args.functional_ref:
+ fullscreen = False
+ else:
+ props.set_size(res)
+ props.set_fullscreen(fullscreen)
+ props.set_icon_filename('assets/images/icon/pmachines.ico')
+ if not args.screenshot and not self.version:
base.win.request_properties(props)
- gltf.patch_loader(base.loader)
- if self._options['development']['simplepbr']:
+ #gltf.patch_loader(base.loader)
+ if self._options['development']['simplepbr'] and not self.version:
self._pipeline = simplepbr.init(
use_normal_maps=True,
use_emission_maps=False,
base.set_frame_rate_meter(True)
#self.base.accept('window-event', self._on_win_evt)
self.base.accept('aspectRatioChanged', self._on_aspect_ratio_changed)
+ if self._options['development']['mouse_coords']:
+ coords_txt = OnscreenText(
+ '', parent=base.a2dTopRight, scale=0.04,
+ pos=(-.03, -.06), fg=(.9, .9, .9, 1), align=TextNode.A_right)
+ def update_coords(task):
+ txt = '%s %s' % (int(base.win.get_pointer(0).x),
+ int(base.win.get_pointer(0).y))
+ coords_txt['text'] = txt
+ return task.cont
+ taskMgr.add(update_coords, 'update_coords')
def _set_physics(self):
if self._options['development']['physics_debug']:
self.world.set_debug_node(self._debug_np.node())
def update(task):
dt = globalClock.get_dt()
- self.world.do_physics(dt)
+ self.world.do_physics(dt, 10, 1/180)
return task.cont
self._phys_tsk = taskMgr.add(update, 'update')
def _on_aspect_ratio_changed(self):
if self._fsm.state == 'Scene':
self._scene.on_aspect_ratio_changed()
+
+ def __assert_fps(self, task):
+ if len(self.__fps_lst) > 3:
+ self.__fps_lst.pop(0)
+ self.__fps_lst += [globalClock.average_frame_rate]
+ if len(self.__fps_lst) == 4:
+ fps_threshold = 55 if cpu_count() >= 4 else 25
+ assert(any(fps > fps_threshold for fps in self.__fps_lst), 'low fps %s' % self.__fps_lst)
+ return task.again