ya2 · news · projects · code · about

removed unused code
authorFlavio Calva <f.calva@gmail.com>
Tue, 7 Jun 2022 17:39:41 +0000 (18:39 +0100)
committerFlavio Calva <f.calva@gmail.com>
Tue, 7 Jun 2022 17:39:41 +0000 (18:39 +0100)
59 files changed:
prj.org
setup.py
tests/lib/test_computer_proxy.py
tests/lib/test_game.py
tests/lib/test_gameobject.py
ya2/build/build.py
ya2/build/docs.py [deleted file]
ya2/build/in_venv.sh [deleted file]
ya2/engine/audio.py
ya2/engine/cbmux.py
ya2/engine/clock.py
ya2/engine/configuration.py
ya2/engine/engine.py
ya2/engine/enginefacade.py
ya2/engine/event.py
ya2/engine/font.py
ya2/engine/gfx.py
ya2/engine/gui/browser.py
ya2/engine/gui/circle.py
ya2/engine/gui/gui.py
ya2/engine/gui/imgbtn.py
ya2/engine/gui/mainpage.py
ya2/engine/gui/menu.py
ya2/engine/gui/page.py
ya2/engine/joystick.py
ya2/engine/logic.py
ya2/engine/network/binary.py
ya2/engine/network/client.py
ya2/engine/network/network.py
ya2/engine/network/server.py
ya2/engine/particle.py
ya2/engine/pause.py
ya2/engine/phys.py
ya2/engine/profiler.py
ya2/engine/shader.py
ya2/engine/vec.py
ya2/game.py
ya2/lib/builder.py
ya2/lib/bullet/bullet.py
ya2/lib/gui.py
ya2/lib/ivals.py
ya2/lib/p3d/audio.py
ya2/lib/p3d/gfx.py
ya2/lib/p3d/gui.py
ya2/lib/p3d/ivals.py
ya2/lib/p3d/joystick.py
ya2/lib/p3d/p3d.py
ya2/lib/p3d/particle.py
ya2/lib/p3d/pause.py
ya2/lib/p3d/shader.py
ya2/lib/p3d/vec.py
ya2/lib/p3d/widget.py
ya2/tools/apply_gloss.py [deleted file]
ya2/tools/build_metal_texture.py [deleted file]
ya2/tools/fix_mask_texture.py [deleted file]
ya2/tools/kill_yorg.py [deleted file]
ya2/tools/kill_yorg_server.py [deleted file]
ya2/tools/process_models.py [deleted file]
ya2/tools/set_diffuse.py [deleted file]

diff --git a/prj.org b/prj.org
index 9cbfad8b6086c356d0bd2b2ad7b9733fb767b6b3..a5d1842c391089e96d321241cf5617cf9a5b791c 100644 (file)
--- a/prj.org
+++ b/prj.org
@@ -3,8 +3,7 @@
 #+CATEGORY: pmachines
 #+TAGS: bug(b) calendar(c) waiting(w)
 
-* RED remove unused code
-* READY refactoring
+* RED refactoring
 * BACKLOG improve level domino box basketball: it can be solved trivially
 * BACKLOG do intro video with moviepy
 * BACKLOG optimize slow tests
index 6a8e971bab1f8c82c3bc78e7ac7406fbbde37c24..3e23b3839382227acf86dfe5dc182eeb362d9496 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@ from setuptools.command.develop import develop
 from multiprocessing import cpu_count
 from direct.dist.commands import bdist_apps
 from ya2.build.build import branch, files, ver, files, bld_dpath
-from ya2.build.docs import bld_docs
+#from ya2.build.docs import bld_docs
 from ya2.build.models import ModelsBuilder
 from ya2.build.images import bld_images
 from ya2.build.screenshots import bld_screenshots
@@ -56,12 +56,12 @@ class AbsCmd(Command):
         pass
 
 
-class DocsCmd(AbsCmd):
-    '''Command for building the docs.'''
+#class DocsCmd(AbsCmd):
+#    '''Command for building the docs.'''
 
-    def run(self):
-        '''Builds the docs.'''
-        bld_docs()
+#    def run(self):
+#        '''Builds the docs.'''
+#        bld_docs()
 
 
 class ModelsCmd(AbsCmd):
@@ -158,7 +158,7 @@ if __name__ == '__main__':
         version=ver,
         cmdclass={
             'develop': DevelopPyCmd,
-            'docs': DocsCmd,
+            'docs': DocsCmd,
             'models': ModelsCmd,
             'images': ImagesCmd,
             'lang': LangCmd,
index 9b98c3d95059d73731a0133f5b1aa48145a09f2c..8f14195d7cf05ce1081842c02180886ac1fdfbad 100644 (file)
@@ -1,57 +1,57 @@
-from pathlib import Path
-import sys
-if '' in sys.path: sys.path.remove('')
-sys.path.append(str(Path(__file__).parent.parent.parent))
-from unittest import TestCase
-from panda3d.core import loadPrcFileData
-from ya2.gameobject import GameObject
-from ya2.engine.engine import Engine
-from ya2.computer_proxy import ComputerProxy, compute_once, once_a_frame
-
-
-class ExampleProxy(GameObject, ComputerProxy):
-
-    def __init__(self):
-        GameObject.__init__(self)
-        ComputerProxy.__init__(self)
-        self.reset()
-
-    def reset(self): self.cnt = 0
-
-    @compute_once
-    def inc_cnt(self): self.cnt += 1
-
-    @once_a_frame
-    def inc_cnt_frame(self): self.cnt += 1
-
-
-class ComputerProxyTests(TestCase):
-
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
-        self.engine = Engine()
-        self.example_proxy = ExampleProxy()
-
-    def tearDown(self):
-        self.engine.destroy()
-
-    def test_init(self):
-        self.assertIsInstance(self.example_proxy, ExampleProxy)
-
-    def test_compute_once(self):
-        self.example_proxy.reset()
-        self.example_proxy.inc_cnt()
-        self.example_proxy.inc_cnt()
-        self.assertEqual(self.example_proxy.cnt, 1)
-
-    def test_compute_once_a_frame(self):
-        self.example_proxy.reset()
-        self.example_proxy.on_start_frame()
-        self.example_proxy.inc_cnt_frame()
-        self.example_proxy.inc_cnt_frame()
-        self.assertEqual(self.example_proxy.cnt, 1)
-        self.example_proxy.on_start_frame()
-        self.example_proxy.inc_cnt_frame()
-        self.example_proxy.inc_cnt_frame()
-        self.assertEqual(self.example_proxy.cnt, 2)
+from pathlib import Path
+import sys
+if '' in sys.path: sys.path.remove('')
+sys.path.append(str(Path(__file__).parent.parent.parent))
+from unittest import TestCase
+from panda3d.core import loadPrcFileData
+from ya2.gameobject import GameObject
+from ya2.engine.engine import Engine
+from ya2.computer_proxy import ComputerProxy, compute_once, once_a_frame
+
+
+class ExampleProxy(GameObject, ComputerProxy):
+
+    def __init__(self):
+        GameObject.__init__(self)
+        ComputerProxy.__init__(self)
+        self.reset()
+
+    def reset(self): self.cnt = 0
+
+    @compute_once
+    def inc_cnt(self): self.cnt += 1
+
+    @once_a_frame
+    def inc_cnt_frame(self): self.cnt += 1
+
+
+class ComputerProxyTests(TestCase):
+
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
+        self.engine = Engine()
+        self.example_proxy = ExampleProxy()
+
+    def tearDown(self):
+        self.engine.destroy()
+
+    def test_init(self):
+        self.assertIsInstance(self.example_proxy, ExampleProxy)
+
+    def test_compute_once(self):
+        self.example_proxy.reset()
+        self.example_proxy.inc_cnt()
+        self.example_proxy.inc_cnt()
+        self.assertEqual(self.example_proxy.cnt, 1)
+
+    def test_compute_once_a_frame(self):
+        self.example_proxy.reset()
+        self.example_proxy.on_start_frame()
+        self.example_proxy.inc_cnt_frame()
+        self.example_proxy.inc_cnt_frame()
+        self.assertEqual(self.example_proxy.cnt, 1)
+        self.example_proxy.on_start_frame()
+        self.example_proxy.inc_cnt_frame()
+        self.example_proxy.inc_cnt_frame()
+        self.assertEqual(self.example_proxy.cnt, 2)
index 89e23ccd519a9a382cbacb37d32e0a3326fcc1cf..8f50a50e6c371a455c21d9fe228f818672d6072d 100644 (file)
@@ -1,59 +1,59 @@
-from pathlib import Path
-import sys
-if '' in sys.path: sys.path.remove('')
-sys.path.append(str(Path(__file__).parent.parent.parent))
-from unittest import TestCase
-from panda3d.core import loadPrcFileData
-from ya2.engine.engine import Engine
-from ya2.engine.configuration import Cfg
-from ya2.game import GameLogic, Game
-from ya2.gameobject import GameObject, FsmColleague, AudioColleague, \
-    EventColleague, LogicColleague
+from pathlib import Path
+import sys
+if '' in sys.path: sys.path.remove('')
+sys.path.append(str(Path(__file__).parent.parent.parent))
+from unittest import TestCase
+from panda3d.core import loadPrcFileData
+from ya2.engine.engine import Engine
+from ya2.engine.configuration import Cfg
+from ya2.game import GameLogic, Game
+from ya2.gameobject import GameObject, FsmColleague, AudioColleague, \
+    EventColleague, LogicColleague
 
 
-class LogicTests(TestCase):
+class LogicTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.eng.destroy()
+    def tearDown(self):
+        self.eng.destroy()
 
-    def test_init(self):
-        self.eng = Engine()
-        game_obj = GameObject()
-        logic = GameLogic(game_obj)
-        self.assertIsInstance(logic, GameLogic)
+    def test_init(self):
+        self.eng = Engine()
+        game_obj = GameObject()
+        logic = GameLogic(game_obj)
+        self.assertIsInstance(logic, GameLogic)
 
 
-class GameInstance(Game):
+class GameInstance(Game):
 
-    def __init__(self):
-        conf = Cfg()
-        Game.__init__(self, conf)
-        self.fsm = FsmColleague(self)
-        self.logic = LogicColleague(self)
-        self.audio = AudioColleague(self)
-        self.event = EventColleague(self)
+    def __init__(self):
+        conf = Cfg()
+        Game.__init__(self, conf)
+        self.fsm = FsmColleague(self)
+        self.logic = LogicColleague(self)
+        self.audio = AudioColleague(self)
+        self.event = EventColleague(self)
 
-    def destroy(self):
-        self.fsm.destroy()
-        self.logic.destroy()
-        self.audio.destroy()
-        self.event.destroy()
+    def destroy(self):
+        self.fsm.destroy()
+        self.logic.destroy()
+        self.audio.destroy()
+        self.event.destroy()
 
 
-class GameTests(TestCase):
+class GameTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def test_init(self):
-        self.game = GameInstance()
-        self.assertIsInstance(self.game, Game)
-        self.game.destroy()
+    def test_init(self):
+        self.game = GameInstance()
+        self.assertIsInstance(self.game, Game)
+        self.game.destroy()
 
-    def tearDown(self):
-        self.game.eng.destroy()
+    def tearDown(self):
+        self.game.eng.destroy()
index c80f4df669c621a76cb505638254713b4364cf4e..2e5a2a0ca2436fa6e779dff29d62cb721ba0e191 100644 (file)
-from pathlib import Path
-import sys
-if '' in sys.path: sys.path.remove('')
-sys.path.append(str(Path(__file__).parent.parent.parent))
-from unittest.mock import patch
-from unittest import TestCase
-from panda3d.core import loadPrcFileData
-from ya2.engine.engine import Engine
-from ya2.gameobject import AiColleague, AudioColleague, EventColleague, \
-    FsmColleague, GameObject, GfxColleague, GuiColleague, LogicColleague, \
-    PhysColleague, Colleague
+from pathlib import Path
+import sys
+if '' in sys.path: sys.path.remove('')
+sys.path.append(str(Path(__file__).parent.parent.parent))
+from unittest.mock import patch
+from unittest import TestCase
+from panda3d.core import loadPrcFileData
+from ya2.engine.engine import Engine
+from ya2.gameobject import AiColleague, AudioColleague, EventColleague, \
+    FsmColleague, GameObject, GfxColleague, GuiColleague, LogicColleague, \
+    PhysColleague, Colleague
 
 
-class AiTests(TestCase):
+class AiTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
+    def tearDown(self):
+        self.engine.destroy()
 
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        ai = AiColleague(game_obj)
-        self.assertIsInstance(ai, AiColleague)
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        ai = AiColleague(game_obj)
+        self.assertIsInstance(ai, AiColleague)
 
 
-class AudioTests(TestCase):
+class AudioTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
+    def tearDown(self):
+        self.engine.destroy()
 
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        audio = AudioColleague(game_obj)
-        self.assertIsInstance(audio, AudioColleague)
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        audio = AudioColleague(game_obj)
+        self.assertIsInstance(audio, AudioColleague)
 
 
-class ColleagueTests(TestCase):
+class ColleagueTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
+    def tearDown(self):
+        self.engine.destroy()
 
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        colleague = Colleague(game_obj)
-        self.assertIsInstance(colleague, Colleague)
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        colleague = Colleague(game_obj)
+        self.assertIsInstance(colleague, Colleague)
 
 
-class EventTests(TestCase):
+class EventTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
+    def tearDown(self):
+        self.engine.destroy()
 
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        event = EventColleague(game_obj)
-        self.assertIsInstance(event, EventColleague)
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        event = EventColleague(game_obj)
+        self.assertIsInstance(event, EventColleague)
 
 
-class FsmTests(TestCase):
+class FsmTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
+    def tearDown(self):
+        self.engine.destroy()
 
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        fsm = FsmColleague(game_obj)
-        self.assertIsInstance(fsm, FsmColleague)
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        fsm = FsmColleague(game_obj)
+        self.assertIsInstance(fsm, FsmColleague)
 
 
-class GfxTests(TestCase):
+class GfxTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
+    def tearDown(self):
+        self.engine.destroy()
 
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        gfx = GfxColleague(game_obj)
-        self.assertIsInstance(gfx, GfxColleague)
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        gfx = GfxColleague(game_obj)
+        self.assertIsInstance(gfx, GfxColleague)
 
 
-class GuiTests(TestCase):
+class GuiTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
+    def tearDown(self):
+        self.engine.destroy()
 
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        gui = GuiColleague(game_obj)
-        self.assertIsInstance(gui, GuiColleague)
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        gui = GuiColleague(game_obj)
+        self.assertIsInstance(gui, GuiColleague)
 
 
-class LogicTests(TestCase):
+class LogicTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
+    def tearDown(self):
+        self.engine.destroy()
 
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        logic = LogicColleague(game_obj)
-        self.assertIsInstance(logic, LogicColleague)
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        logic = LogicColleague(game_obj)
+        self.assertIsInstance(logic, LogicColleague)
 
 
-class PhysicsTests(TestCase):
+class PhysicsTests(TestCase):
 
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
 
-    def tearDown(self):
-        self.engine.destroy()
-
-    def test_init(self):
-        self.engine = Engine()
-        game_obj = GameObject()
-        phys = PhysColleague(game_obj)
-        self.assertIsInstance(phys, PhysColleague)
+    def tearDown(self):
+        self.engine.destroy()
+
+    def test_init(self):
+        self.engine = Engine()
+        game_obj = GameObject()
+        phys = PhysColleague(game_obj)
+        self.assertIsInstance(phys, PhysColleague)
 
 
-class GameObjectInstance(GameObject):
+class GameObjectInstance(GameObject):
 
-    def __init__(self):
-        GameObject.__init__(self)
-        self.fsm = FsmColleague(self)
-        self.event = EventColleague(self)
-        self.ai = AiColleague(self)
-        self.phys = PhysColleague(self)
-        self.audio = AudioColleague(self)
-        self.logic = LogicColleague(self)
-        self.gui = GuiColleague(self)
-        self.gfx = GfxColleague(self)
-
-    def destroy(self):
-        self.fsm.destroy()
-        self.event.destroy()
-        self.ai.destroy()
-        self.phys.destroy()
-        self.audio.destroy()
-        self.logic.destroy()
-        self.gui.destroy()
-        self.gfx.destroy()
-
-
-class GameObjectTests(TestCase):
-
-    def setUp(self):
-        loadPrcFileData('', 'window-type none')
-        loadPrcFileData('', 'audio-library-name null')
-
-    def tearDown(self):
-        self.engine.destroy()
-
-    @patch.object(GfxColleague, 'destroy')
-    @patch.object(GuiColleague, 'destroy')
-    @patch.object(LogicColleague, 'destroy')
-    @patch.object(AudioColleague, 'destroy')
-    @patch.object(PhysColleague, 'destroy')
-    @patch.object(AiColleague, 'destroy')
-    @patch.object(EventColleague, 'destroy')
-    @patch.object(FsmColleague, 'destroy')
-    def test_init(
-            self, mock_fsm_destroy, mock_event_destroy, mock_ai_destroy,
-            mock_phys_destroy, mock_audio_destroy, mock_logic_destroy,
-            mock_gui_destroy, mock_gfx_destroy):
-        self.engine = Engine()
-        mock_event_destroy.__name__ = 'destroy'
-        game_obj = GameObjectInstance()
-        self.assertIsInstance(game_obj, GameObject)
-        game_obj.destroy()
-        assert mock_fsm_destroy.called
-        assert mock_event_destroy.called
-        assert mock_ai_destroy.called
-        assert mock_phys_destroy.called
-        assert mock_audio_destroy.called
-        assert mock_logic_destroy.called
-        assert mock_gui_destroy.called
-        assert mock_gfx_destroy.called
+    def __init__(self):
+        GameObject.__init__(self)
+        self.fsm = FsmColleague(self)
+        self.event = EventColleague(self)
+        self.ai = AiColleague(self)
+        self.phys = PhysColleague(self)
+        self.audio = AudioColleague(self)
+        self.logic = LogicColleague(self)
+        self.gui = GuiColleague(self)
+        self.gfx = GfxColleague(self)
+
+    def destroy(self):
+        self.fsm.destroy()
+        self.event.destroy()
+        self.ai.destroy()
+        self.phys.destroy()
+        self.audio.destroy()
+        self.logic.destroy()
+        self.gui.destroy()
+        self.gfx.destroy()
+
+
+class GameObjectTests(TestCase):
+
+    def setUp(self):
+        loadPrcFileData('', 'window-type none')
+        loadPrcFileData('', 'audio-library-name null')
+
+    def tearDown(self):
+        self.engine.destroy()
+
+    @patch.object(GfxColleague, 'destroy')
+    @patch.object(GuiColleague, 'destroy')
+    @patch.object(LogicColleague, 'destroy')
+    @patch.object(AudioColleague, 'destroy')
+    @patch.object(PhysColleague, 'destroy')
+    @patch.object(AiColleague, 'destroy')
+    @patch.object(EventColleague, 'destroy')
+    @patch.object(FsmColleague, 'destroy')
+    def test_init(
+            self, mock_fsm_destroy, mock_event_destroy, mock_ai_destroy,
+            mock_phys_destroy, mock_audio_destroy, mock_logic_destroy,
+            mock_gui_destroy, mock_gfx_destroy):
+        self.engine = Engine()
+        mock_event_destroy.__name__ = 'destroy'
+        game_obj = GameObjectInstance()
+        self.assertIsInstance(game_obj, GameObject)
+        game_obj.destroy()
+        assert mock_fsm_destroy.called
+        assert mock_event_destroy.called
+        assert mock_ai_destroy.called
+        assert mock_phys_destroy.called
+        assert mock_audio_destroy.called
+        assert mock_logic_destroy.called
+        assert mock_gui_destroy.called
+        assert mock_gfx_destroy.called
index 9fdd8cb435956c6c5f2fad4c2c509a36b259bb24..420a7eb7f63ae633dd22c29045f5ca825ef799e9 100644 (file)
@@ -168,4 +168,4 @@ win_fpath = '{dst_dir}{appname}-%s-windows.exe' % branch
 #osx_fpath = '{dst_dir}{appname}-%s-osx.zip' % branch
 #flatpak_fpath = '{dst_dir}{appname}-%s-flatpak' % branch
 appimage_fpath = '{dst_dir}{appname}-%s-appimage' % branch
-docs_fpath = '{dst_dir}{appname}-%s-docs.tar.gz' % branch
+#docs_fpath = '{dst_dir}{appname}-%s-docs.tar.gz' % branch
diff --git a/ya2/build/docs.py b/ya2/build/docs.py
deleted file mode 100644 (file)
index f926e28..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-'''This module creates the documentation using pydoc.'''
-from os import system, mkdir, remove, rename
-from os.path import exists
-from shutil import rmtree, make_archive
-from ya2.build.build import InsideDir
-from pathlib import Path
-from re import match, findall, sub
-from glob import glob
-
-
-#TODO refactor: make class DocsBuilder
-
-
-def bld_docs():
-    '''Builds the docs (inside a zip file).'''
-    system('python -m pydoc -w ./')
-    rmtree('docs', ignore_errors=True)
-    Path('docs').mkdir(exist_ok=True)
-    [rename(fname, 'docs/' + fname) for fname in glob('*.html')]
-    for fname in glob('docs/*.html'):
-        out_lines = []
-        with open(fname) as fhtml:
-            lines = fhtml.readlines()
-        for line in lines:
-            occurs = findall('"#[0-9A-Fa-f]{6}"', line)
-            new_line = line
-            for occur in occurs:
-                red = int(occur[2:4], 16) / 255
-                green = int(occur[4:6], 16) / 255
-                blue = int(occur[6:8], 16) / 255
-                new_col = .2989 * red + .5870 * green + .1140 * blue
-                new_col = hex(int(round(new_col * 255)))[2:]
-                new_col = '"#%s%s%s"' %  (new_col, new_col, new_col)
-                new_line = sub('"#[0-9A-Fa-f]{6}"', new_col, new_line)
-            out_lines += [new_line]
-        with open(fname, 'w') as fhtml:
-            fhtml.write(''.join(out_lines))
-    Path('build').mkdir(exist_ok=True)
-    rmtree('build/docs', ignore_errors=True)
-    rename('docs', 'build/docs')
-    with InsideDir('build'):
-        exists('docs.zip') and remove('docs.zip')
-        make_archive('docs', 'zip', '.', 'docs')
-        rmtree('docs')
diff --git a/ya2/build/in_venv.sh b/ya2/build/in_venv.sh
deleted file mode 100755 (executable)
index 89665dd..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-#virtualenv venv
-#. ./venv/bin/activate
-#pip install --upgrade pip
-#pip install --upgrade setuptools
-#pip install panda3d -i https://archive.panda3d.org/branches/deploy-ng --upgrade
-python setup.py "$@"
index 9a70dea8e455186f0d097997810ac7bd5f1d8a10..9b95eb9f38e178fd88e8316e052b5023cf59656d 100644 (file)
@@ -1,14 +1,14 @@
-from ya2.gameobject import AudioColleague
-from ya2.lib.p3d.audio import P3dSound
+from ya2.gameobject import AudioColleague
+from ya2.lib.p3d.audio import P3dSound
 
 
-AudioSound = P3dSound
+AudioSound = P3dSound
 
 
-class EngineAudio(AudioColleague):
+class EngineAudio(AudioColleague):
 
-    def __init__(self, mediator, vol=1.0):
-        AudioColleague.__init__(self, mediator)
-        self.set_volume(vol)
+    def __init__(self, mediator, vol=1.0):
+        AudioColleague.__init__(self, mediator)
+        self.set_volume(vol)
 
-    def set_volume(self, vol): self.eng.lib.volume = vol
+    def set_volume(self, vol): self.eng.lib.volume = vol
index 50047572672b6126eca644dd5b60be36014f418d..7b59c6a3aac54594e56377fbb14c5cebbc78b48f 100644 (file)
@@ -1,22 +1,22 @@
-from threading import Lock
+from threading import Lock
 
 
-class CallbackMux:
-    # this is a sort of "multiplexer" i.e. it manages callbacks from threads
-    # and redirect them to the main thread (this prevents deadlocks)
+class CallbackMux:
+    # this is a sort of "multiplexer" i.e. it manages callbacks from threads
+    # and redirect them to the main thread (this prevents deadlocks)
 
-    def __init__(self):
-        self.lock = Lock()
-        self.callbacks = []
-        taskMgr.add(self.process_callbacks, 'processing callbacks')
+    def __init__(self):
+        self.lock = Lock()
+        self.callbacks = []
+        taskMgr.add(self.process_callbacks, 'processing callbacks')
 
-    def add_cb(self, func, args=None):
-        args = args or []
-        with self.lock: self.callbacks += [(func, args)]
+    def add_cb(self, func, args=None):
+        args = args or []
+        with self.lock: self.callbacks += [(func, args)]
 
-    def process_callbacks(self, task):
-        with self.lock:
-            callbacks = self.callbacks[:]
-            self.callbacks = []
-        for func, args in callbacks: func(*args)
-        return task.cont
+    def process_callbacks(self, task):
+        with self.lock:
+            callbacks = self.callbacks[:]
+            self.callbacks = []
+        for func, args in callbacks: func(*args)
+        return task.cont
index feefaa2b75b85d7a9a170eb26327cc05e01c6b0b..38499ab0a8de8e6920b91955c17b3c57c45d3989 100644 (file)
@@ -1,16 +1,16 @@
-class Clock:
+class Clock:
 
-    def __init__(self, pause):
-        self.__paused_time = 0
-        self.__curr_stopped_time = 0
-        pause.logic.attach(self.on_pause)
-        pause.logic.attach(self.on_resume)
+    def __init__(self, pause):
+        self.__paused_time = 0
+        self.__curr_stopped_time = 0
+        pause.logic.attach(self.on_pause)
+        pause.logic.attach(self.on_resume)
 
-    @property
-    def time(self): return globalClock.get_frame_time() - self.__paused_time
+    @property
+    def time(self): return globalClock.get_frame_time() - self.__paused_time
 
-    def on_pause(self): self.__curr_stopped_time = globalClock.get_frame_time()
+    def on_pause(self): self.__curr_stopped_time = globalClock.get_frame_time()
 
-    def on_resume(self):
-        self.__paused_time += \
-            globalClock.get_frame_time() - self.__curr_stopped_time
+    def on_resume(self):
+        self.__paused_time += \
+            globalClock.get_frame_time() - self.__curr_stopped_time
index e99c230c4eb97f0bf5525a3e11f2f932fab41a3f..0f798180dddda225c327e3d1a2028a042cbd3505 100644 (file)
-from panda3d.core import load_prc_file_data
-from ya2.lib.builder import LibP3d
-
-
-class GuiCfg:
-
-    def __init__(self, fps=False, win_size='1280 720', win_orig=None,
-                 win_title='lib', fullscreen=False, sync_video=None,
-                 antialiasing=False, shaders=True, volume=1, fixed_fps=0):
-        self.fps = fps
-        self.win_size = win_size
-        self.win_title = win_title
-        self.win_orig = win_orig
-        self.fullscreen = fullscreen
-        self.sync_video = LibP3d.runtime() if sync_video is None \
-            else sync_video
-        self.antialiasing = antialiasing
-        self.shaders = shaders
-        self.volume = volume
-        self.fixed_fps = fixed_fps
-
-
-class ProfilingCfg:
-
-    def __init__(self, profiling=False, pyprof_percall=False):
-        self.profiling = profiling  # profiling with panda3d's tools
-        self.pyprof_percall = pyprof_percall
-
-
-class LangCfg:
-
-    def __init__(self, lang='en', lang_path='assets/locale',
-                 lang_domain='lib_game', languages=[('English', 'en')]):
-        self.lang = lang
-        self.lang_path = lang_path
-        self.lang_domain = lang_domain
-        self.languages = languages
-
-
-class CursorCfg:
-
-    def __init__(self, cursor_hidden=False, cursor_path='',
-                 cursor_scale=(1, 1, 1), cursor_color=(1, 1, 1, 1),
-                 cursor_hotspot=(0, 0)):
-        self.cursor_hidden = cursor_hidden
-        self.cursor_path = cursor_path
-        self.cursor_scale = cursor_scale
-        self.cursor_color = cursor_color
-        self.cursor_hotspot = cursor_hotspot
-
-
-class DevCfg:
-
-    def __init__(
-            self, mt_render=False, model_path='assets/models', excluded='',
-            shaders_dev=False, pbr=False, gamma=1.0, menu_joypad=True,
-            verbose='', verbose_log=False, xmpp_server='', start_wp='',
-            port=9099, server='localhost:9098', srgb=False, opengl_3_2=False,
-            gl_debug=False, async_textures=False, show_buffers=False,
-            anisotropic=8, pbr_normal=True, pbr_occlusion=True,
-            pbr_shadows=True, pbr_exposure=True, pbr_msaa_samples=4,
-            pbr_fog=True, offscreen=False, directx=False,
-            functional_test=False, functional_ref=False):
-        self.multithreaded_render = mt_render  # multithreaded rendering
-        self.model_path = model_path
-        self.excluded = excluded
-        self.shaders_dev = shaders_dev
-        self.pbr = pbr
-        self.pbr_normal = pbr_normal
-        self.pbr_occlusion = pbr_occlusion
-        self.pbr_shadows = pbr_shadows
-        self.pbr_exposure = pbr_exposure
-        self.pbr_msaa_samples = pbr_msaa_samples
-        self.pbr_fog = pbr_fog
-        self.gamma = gamma
-        self.directx = directx
-        self.menu_joypad = menu_joypad
-        self.verbose = verbose
-        self.verbose_log = verbose_log
-        self.xmpp_server = xmpp_server
-        self.port = port
-        self.server = server
-        self.start_wp = start_wp
-        self.srgb = srgb
-        self.opengl_3_2 = opengl_3_2
-        self.gl_debug = gl_debug
-        self.async_textures = async_textures
-        self.show_buffers = show_buffers
-        self.anisotropic = anisotropic
-        self.offscreen = offscreen
-        self.functional_test = functional_test
-        self.functional_ref = functional_ref
-
-
-class Cfg:
-
-    def __init__(self, gui_cfg=None, profiling_cfg=None, lang_cfg=None,
-                 cursor_cfg=None, dev_cfg=None):
-        self.gui_cfg = gui_cfg or GuiCfg()
-        self.profiling_cfg = profiling_cfg or ProfilingCfg()
-        self.lang_cfg = lang_cfg or LangCfg()
-        self.cursor_cfg = cursor_cfg or CursorCfg()
-        self.dev_cfg = dev_cfg or DevCfg()
-        self.__configure()
-
-    @staticmethod
-    def __set(key, val): load_prc_file_data('', key + ' ' + str(val))
-
-    def __configure(self):
-        cfginfo = [
-            ('texture-anisotropic-degree', self.dev_cfg.anisotropic),
-            # ('client-sleep', 0.001),
-            ('texture-minfilter', 'linear_mipmap_linear'),
-            ('gl-coordinate-system', 'default'),
-            ('textures-power-2', 'down'),
-            ('textures-auto-power-2', 1),
-            ('show-frame-rate-meter', int(self.gui_cfg.fps)),
-            ('hardware-animated-vertices', 'true'),
-            ('x-init-threads', 'true'),
-            # temp workaround for mtrendering (linux)
-            ('basic-shaders-only', 'false'),
-            ('default-model-extension', '.bam'),
-            #('compressed-textures',  1),  # particles don't work
-            #('model-cache-textures', 1),
-            #('model-cache-compressed-textures', 1),
-            #('bam-version', '6 45'),
-            ('audio-ouput-rate', 44100)]
-        if self.gui_cfg.win_size:
-            cfginfo += [('win-size', self.gui_cfg.win_size)]
-        if self.gui_cfg.win_orig:
-            cfginfo += [('win-origin', self.gui_cfg.win_orig)]
-        if self.dev_cfg.srgb:
-            cfginfo += [('framebuffer-srgb', 'true')]
-        if self.dev_cfg.opengl_3_2:
-            cfginfo += [('gl-version', '3 2')]
-        if self.dev_cfg.gl_debug:
-            cfginfo += [('gl-debug', 1)]
-        if self.dev_cfg.show_buffers:
-            cfginfo += [('show-buffers', 'true')]
-        if self.dev_cfg.async_textures:
-            cfginfo += [
-                ('preload-textures', 0),
-                ('preload-simple-textures', 1),
-                ('texture-compression', 1),
-                ('allow-incomplete-render', 1)]
-        if self.dev_cfg.directx:
-            cfginfo += [
-                ('load-display', 'pandadx9')]
-        cfginfo += [
-            ('window-title', self.gui_cfg.win_title),
-            ('cursor-hidden', int(self.cursor_cfg.cursor_hidden)),
-            ('sync-video', int(self.gui_cfg.sync_video)),
-            ('framebuffer-multisample', 1),
-            ('multisamples', 2)]
-        if self.dev_cfg.multithreaded_render:
-            cfginfo += [('threading-model', '/Draw')]
-        if self.dev_cfg.offscreen:
-            cfginfo += [('window-type', 'offscreen')]
-        if self.profiling_cfg.profiling:
-            cfginfo += [
-                ('want-pstats', 1),
-                ('task-timer-verbose', 1),
-                ('pstats-tasks', 1),
-                ('gl-finish', 1),
-                ('pstats-host', '127.0.0.1')]
-        for verb in self.dev_cfg.verbose.split(';'):
-            if not verb: continue
-            verb_el = verb.strip().split()
-            if verb_el[0] == 'direct':
-                cfginfo += [
-                    ('default-directnotify-level', verb_el[1])]
-            elif verb_el[0] == 'panda':
-                cfginfo += [
-                    ('notify-level', verb_el[1])]
-            else:
-                cfginfo += [
-                    ('notify-level-' + verb_el[0], verb_el[1])]
-        list(map(lambda args: self.__set(*args), cfginfo))
+from panda3d.core import load_prc_file_data
+from ya2.lib.builder import LibP3d
+
+
+class GuiCfg:
+
+    def __init__(self, fps=False, win_size='1280 720', win_orig=None,
+                 win_title='lib', fullscreen=False, sync_video=None,
+                 antialiasing=False, shaders=True, volume=1, fixed_fps=0):
+        self.fps = fps
+        self.win_size = win_size
+        self.win_title = win_title
+        self.win_orig = win_orig
+        self.fullscreen = fullscreen
+        self.sync_video = LibP3d.runtime() if sync_video is None \
+            else sync_video
+        self.antialiasing = antialiasing
+        self.shaders = shaders
+        self.volume = volume
+        self.fixed_fps = fixed_fps
+
+
+class ProfilingCfg:
+
+    def __init__(self, profiling=False, pyprof_percall=False):
+        self.profiling = profiling  # profiling with panda3d's tools
+        self.pyprof_percall = pyprof_percall
+
+
+class LangCfg:
+
+    def __init__(self, lang='en', lang_path='assets/locale',
+                 lang_domain='lib_game', languages=[('English', 'en')]):
+        self.lang = lang
+        self.lang_path = lang_path
+        self.lang_domain = lang_domain
+        self.languages = languages
+
+
+class CursorCfg:
+
+    def __init__(self, cursor_hidden=False, cursor_path='',
+                 cursor_scale=(1, 1, 1), cursor_color=(1, 1, 1, 1),
+                 cursor_hotspot=(0, 0)):
+        self.cursor_hidden = cursor_hidden
+        self.cursor_path = cursor_path
+        self.cursor_scale = cursor_scale
+        self.cursor_color = cursor_color
+        self.cursor_hotspot = cursor_hotspot
+
+
+class DevCfg:
+
+    def __init__(
+            self, mt_render=False, model_path='assets/models', excluded='',
+            shaders_dev=False, pbr=False, gamma=1.0, menu_joypad=True,
+            verbose='', verbose_log=False, xmpp_server='', start_wp='',
+            port=9099, server='localhost:9098', srgb=False, opengl_3_2=False,
+            gl_debug=False, async_textures=False, show_buffers=False,
+            anisotropic=8, pbr_normal=True, pbr_occlusion=True,
+            pbr_shadows=True, pbr_exposure=True, pbr_msaa_samples=4,
+            pbr_fog=True, offscreen=False, directx=False,
+            functional_test=False, functional_ref=False):
+        self.multithreaded_render = mt_render  # multithreaded rendering
+        self.model_path = model_path
+        self.excluded = excluded
+        self.shaders_dev = shaders_dev
+        self.pbr = pbr
+        self.pbr_normal = pbr_normal
+        self.pbr_occlusion = pbr_occlusion
+        self.pbr_shadows = pbr_shadows
+        self.pbr_exposure = pbr_exposure
+        self.pbr_msaa_samples = pbr_msaa_samples
+        self.pbr_fog = pbr_fog
+        self.gamma = gamma
+        self.directx = directx
+        self.menu_joypad = menu_joypad
+        self.verbose = verbose
+        self.verbose_log = verbose_log
+        self.xmpp_server = xmpp_server
+        self.port = port
+        self.server = server
+        self.start_wp = start_wp
+        self.srgb = srgb
+        self.opengl_3_2 = opengl_3_2
+        self.gl_debug = gl_debug
+        self.async_textures = async_textures
+        self.show_buffers = show_buffers
+        self.anisotropic = anisotropic
+        self.offscreen = offscreen
+        self.functional_test = functional_test
+        self.functional_ref = functional_ref
+
+
+class Cfg:
+
+    def __init__(self, gui_cfg=None, profiling_cfg=None, lang_cfg=None,
+                 cursor_cfg=None, dev_cfg=None):
+        self.gui_cfg = gui_cfg or GuiCfg()
+        self.profiling_cfg = profiling_cfg or ProfilingCfg()
+        self.lang_cfg = lang_cfg or LangCfg()
+        self.cursor_cfg = cursor_cfg or CursorCfg()
+        self.dev_cfg = dev_cfg or DevCfg()
+        self.__configure()
+
+    @staticmethod
+    def __set(key, val): load_prc_file_data('', key + ' ' + str(val))
+
+    def __configure(self):
+        cfginfo = [
+            ('texture-anisotropic-degree', self.dev_cfg.anisotropic),
+            # ('client-sleep', 0.001),
+            ('texture-minfilter', 'linear_mipmap_linear'),
+            ('gl-coordinate-system', 'default'),
+            ('textures-power-2', 'down'),
+            ('textures-auto-power-2', 1),
+            ('show-frame-rate-meter', int(self.gui_cfg.fps)),
+            ('hardware-animated-vertices', 'true'),
+            ('x-init-threads', 'true'),
+            # temp workaround for mtrendering (linux)
+            ('basic-shaders-only', 'false'),
+            ('default-model-extension', '.bam'),
+            #('compressed-textures',  1),  # particles don't work
+            #('model-cache-textures', 1),
+            #('model-cache-compressed-textures', 1),
+            #('bam-version', '6 45'),
+            ('audio-ouput-rate', 44100)]
+        if self.gui_cfg.win_size:
+            cfginfo += [('win-size', self.gui_cfg.win_size)]
+        if self.gui_cfg.win_orig:
+            cfginfo += [('win-origin', self.gui_cfg.win_orig)]
+        if self.dev_cfg.srgb:
+            cfginfo += [('framebuffer-srgb', 'true')]
+        if self.dev_cfg.opengl_3_2:
+            cfginfo += [('gl-version', '3 2')]
+        if self.dev_cfg.gl_debug:
+            cfginfo += [('gl-debug', 1)]
+        if self.dev_cfg.show_buffers:
+            cfginfo += [('show-buffers', 'true')]
+        if self.dev_cfg.async_textures:
+            cfginfo += [
+                ('preload-textures', 0),
+                ('preload-simple-textures', 1),
+                ('texture-compression', 1),
+                ('allow-incomplete-render', 1)]
+        if self.dev_cfg.directx:
+            cfginfo += [
+                ('load-display', 'pandadx9')]
+        cfginfo += [
+            ('window-title', self.gui_cfg.win_title),
+            ('cursor-hidden', int(self.cursor_cfg.cursor_hidden)),
+            ('sync-video', int(self.gui_cfg.sync_video)),
+            ('framebuffer-multisample', 1),
+            ('multisamples', 2)]
+        if self.dev_cfg.multithreaded_render:
+            cfginfo += [('threading-model', '/Draw')]
+        if self.dev_cfg.offscreen:
+            cfginfo += [('window-type', 'offscreen')]
+        if self.profiling_cfg.profiling:
+            cfginfo += [
+                ('want-pstats', 1),
+                ('task-timer-verbose', 1),
+                ('pstats-tasks', 1),
+                ('gl-finish', 1),
+                ('pstats-host', '127.0.0.1')]
+        for verb in self.dev_cfg.verbose.split(';'):
+            if not verb: continue
+            verb_el = verb.strip().split()
+            if verb_el[0] == 'direct':
+                cfginfo += [
+                    ('default-directnotify-level', verb_el[1])]
+            elif verb_el[0] == 'panda':
+                cfginfo += [
+                    ('notify-level', verb_el[1])]
+            else:
+                cfginfo += [
+                    ('notify-level-' + verb_el[0], verb_el[1])]
+        list(map(lambda args: self.__set(*args), cfginfo))
index fed72da631224932ba67fe7e32e70282ebba2b59..045a38619c1035586186d7e263f5c2039d02327c 100644 (file)
@@ -1,83 +1,83 @@
-from sys import path
-from os.path import dirname, realpath
-path.append(dirname(realpath(__file__)) + '/../thirdparty')
+from sys import path
+from os.path import dirname, realpath
+path.append(dirname(realpath(__file__)) + '/../thirdparty')
 
-from ya2.lib.builder import LibBuilder
-from ya2.engine.pause import PauseMgr
-from ya2.engine.profiler import AbsProfiler
-from ya2.engine.shader import ShaderMgr
-from ya2.engine.log import LogMgr
-from ya2.engine.font import FontMgr
-from ya2.engine.phys import PhysMgr
-from ya2.engine.gfx import EngineGfx
-from ya2.engine.network.server import Server
-from ya2.engine.network.client import Client
-from ya2.engine.gui.gui import EngineGui
-from ya2.engine.logic import EngineLogic
-from ya2.engine.event import EngineEvent
-from ya2.engine.audio import EngineAudio
-from ya2.engine.lang import LangMgr
-from ya2.gameobject import GameObject, Colleague
-from ya2.engine.enginefacade import EngineFacade
-from ya2.engine.configuration import Cfg
-from ya2.engine.cbmux import CallbackMux
-from ya2.engine.clock import Clock
+from ya2.lib.builder import LibBuilder
+from ya2.engine.pause import PauseMgr
+from ya2.engine.profiler import AbsProfiler
+from ya2.engine.shader import ShaderMgr
+from ya2.engine.log import LogMgr
+from ya2.engine.font import FontMgr
+from ya2.engine.phys import PhysMgr
+from ya2.engine.gfx import EngineGfx
+from ya2.engine.network.server import Server
+from ya2.engine.network.client import Client
+from ya2.engine.gui.gui import EngineGui
+from ya2.engine.logic import EngineLogic
+from ya2.engine.event import EngineEvent
+from ya2.engine.audio import EngineAudio
+from ya2.engine.lang import LangMgr
+from ya2.gameobject import GameObject, Colleague
+from ya2.engine.enginefacade import EngineFacade
+from ya2.engine.configuration import Cfg
+from ya2.engine.cbmux import CallbackMux
+from ya2.engine.clock import Clock
 
 
-class Engine(GameObject, EngineFacade):
+class Engine(GameObject, EngineFacade):
 
-    network_priority = -39
+    network_priority = -39
 
-    def __init__(self, cfg=None, end_cb=None, client_cls=None):
-        self.lib = LibBuilder.build()
-        self.lib.configure()
-        self.lib.init(end_cb=end_cb)
-        Colleague.eng = GameObject.eng = self
-        cfg = cfg or Cfg()  # use a default conf if not provided
-        self.shader_mgr = ShaderMgr(cfg.dev_cfg.shaders_dev, cfg.dev_cfg.gamma)
-        self.profiler = AbsProfiler.build(cfg.profiling_cfg.pyprof_percall)
-        self.font_mgr = FontMgr()
-        self.server = Server(cfg.dev_cfg.port)
-        client_cls = client_cls or Client
-        self.client = client_cls(cfg.dev_cfg.port, cfg.dev_cfg.server)
-        self.cb_mux = CallbackMux()
-        self.logic = EngineLogic(self, cfg)
-        self.log_mgr = LogMgr.init_cls()(self)
-        self.gfx = EngineGfx(self, cfg.dev_cfg.model_path,
-                             cfg.gui_cfg.antialiasing,
-                             cfg.gui_cfg.shaders,
-                             cfg.gui_cfg.fixed_fps,
-                             cfg.dev_cfg.srgb)
-        self.phys_mgr = PhysMgr(self)
-        self.event = EngineEvent(self, cfg.dev_cfg.menu_joypad,
-                                 cfg.dev_cfg.functional_test)
-        self.gui = EngineGui.init_cls()(self)
-        self.audio = EngineAudio(self, cfg.gui_cfg.volume)
-        self.pause = PauseMgr(self)
-        self.lang_mgr = LangMgr(cfg.lang_cfg.lang,
-                                cfg.lang_cfg.lang_domain,
-                                cfg.lang_cfg.lang_path)
-        GameObject.__init__(self)
-        self.clock = Clock(self.pause)
+    def __init__(self, cfg=None, end_cb=None, client_cls=None):
+        self.lib = LibBuilder.build()
+        self.lib.configure()
+        self.lib.init(end_cb=end_cb)
+        Colleague.eng = GameObject.eng = self
+        cfg = cfg or Cfg()  # use a default conf if not provided
+        self.shader_mgr = ShaderMgr(cfg.dev_cfg.shaders_dev, cfg.dev_cfg.gamma)
+        self.profiler = AbsProfiler.build(cfg.profiling_cfg.pyprof_percall)
+        self.font_mgr = FontMgr()
+        self.server = Server(cfg.dev_cfg.port)
+        client_cls = client_cls or Client
+        self.client = client_cls(cfg.dev_cfg.port, cfg.dev_cfg.server)
+        self.cb_mux = CallbackMux()
+        self.logic = EngineLogic(self, cfg)
+        self.log_mgr = LogMgr.init_cls()(self)
+        self.gfx = EngineGfx(self, cfg.dev_cfg.model_path,
+                             cfg.gui_cfg.antialiasing,
+                             cfg.gui_cfg.shaders,
+                             cfg.gui_cfg.fixed_fps,
+                             cfg.dev_cfg.srgb)
+        self.phys_mgr = PhysMgr(self)
+        self.event = EngineEvent(self, cfg.dev_cfg.menu_joypad,
+                                 cfg.dev_cfg.functional_test)
+        self.gui = EngineGui.init_cls()(self)
+        self.audio = EngineAudio(self, cfg.gui_cfg.volume)
+        self.pause = PauseMgr(self)
+        self.lang_mgr = LangMgr(cfg.lang_cfg.lang,
+                                cfg.lang_cfg.lang_domain,
+                                cfg.lang_cfg.lang_path)
+        GameObject.__init__(self)
+        self.clock = Clock(self.pause)
 
-    def destroy(self):
-        GameObject.destroy(self)
-        self.lib.destroy()
-        self.shader_mgr.destroy()
-        self.profiler.destroy()
-        self.font_mgr.destroy()
-        self.server.destroy()
-        self.client.destroy()
-        # self.xmpp.destroy()
-        self.logic.destroy()
-        self.log_mgr.destroy()
-        self.gfx.destroy()
-        self.phys_mgr.destroy()
-        self.event.destroy()
-        self.gui.destroy()
-        self.audio.destroy()
-        self.pause.destroy()
-        self.lang_mgr.destroy()
-        self.lib = self.shader_mgr = self.profiler = self.font_mgr = \
-            self.server = self.client = None
-        base.destroy()
+    def destroy(self):
+        GameObject.destroy(self)
+        self.lib.destroy()
+        self.shader_mgr.destroy()
+        self.profiler.destroy()
+        self.font_mgr.destroy()
+        self.server.destroy()
+        self.client.destroy()
+        # self.xmpp.destroy()
+        self.logic.destroy()
+        self.log_mgr.destroy()
+        self.gfx.destroy()
+        self.phys_mgr.destroy()
+        self.event.destroy()
+        self.gui.destroy()
+        self.audio.destroy()
+        self.pause.destroy()
+        self.lang_mgr.destroy()
+        self.lib = self.shader_mgr = self.profiler = self.font_mgr = \
+            self.server = self.client = None
+        base.destroy()
index 9a76f5a0dc8a746e60bba7b1e30551d0fc3e0bd9..e8fcaf563b8f68b92386e6b66e4b8584d9e47d10 100644 (file)
-from math import pi
+from math import pi
 
 
-class EngineFacade:
+class EngineFacade:
 
-    @property
-    def version(self): return self.logic.version
+    @property
+    def version(self): return self.logic.version
 
-    @property
-    def curr_path(self): return self.logic.curr_path
+    @property
+    def curr_path(self): return self.logic.curr_path
 
-    @property
-    def is_appimage(self): return self.logic.is_appimage
+    @property
+    def is_appimage(self): return self.logic.is_appimage
 
-    @property
-    def cfg(self): return self.logic.cfg
+    @property
+    def cfg(self): return self.logic.cfg
 
-    @property
-    def is_runtime(self): return self.logic.is_runtime
+    @property
+    def is_runtime(self): return self.logic.is_runtime
 
-    @property
-    def languages(self): return self.logic.cfg.lang_cfg.languages
+    @property
+    def languages(self): return self.logic.cfg.lang_cfg.languages
 
-    @property
-    def resolutions(self): return self.gui.resolutions
+    @property
+    def resolutions(self): return self.gui.resolutions
 
-    @property
-    def closest_resolution(self): return self.gui.closest_resolution
+    @property
+    def closest_resolution(self): return self.gui.closest_resolution
 
-    @property
-    def joystick_mgr(self): return self.event.joystick_mgr
+    @property
+    def joystick_mgr(self): return self.event.joystick_mgr
 
-    @property
-    def curr_time(self): return self.clock.time
+    @property
+    def curr_time(self): return self.clock.time
 
-    def attach_obs(self, obs_meth, sort=10, rename='', args=None):
-        args = args or []
-        return self.event.attach(obs_meth, sort, rename, args)
+    def attach_obs(self, obs_meth, sort=10, rename='', args=None):
+        args = args or []
+        return self.event.attach(obs_meth, sort, rename, args)
 
-    def detach_obs(self, obs_meth, lambda_call=None):
-        return self.event.detach(obs_meth, lambda_call)
-    def attach_node(self, name): return self.gfx.root.attach_node(name)
-    def particle(
-            self, parent, texture, color=(1, 1, 1, 1), ampl=pi/6, ray=.5,
-            rate=.0001, gravity=-.85, vel=3.8, part_duration=1.0,
-            autodestroy=None, size=10):
-        return self.gfx.particle(
-            parent, texture, color, ampl, ray, rate, gravity, vel,
-            part_duration, autodestroy, size)
-    def init_gfx(self): return self.gfx.init()
-    def clean_gfx(self): return self.gfx.clean()
+    def detach_obs(self, obs_meth, lambda_call=None):
+        return self.event.detach(obs_meth, lambda_call)
+    def attach_node(self, name): return self.gfx.root.attach_node(name)
+    def particle(
+            self, parent, texture, color=(1, 1, 1, 1), ampl=pi/6, ray=.5,
+            rate=.0001, gravity=-.85, vel=3.8, part_duration=1.0,
+            autodestroy=None, size=10):
+        return self.gfx.particle(
+            parent, texture, color, ampl, ray, rate, gravity, vel,
+            part_duration, autodestroy, size)
+    def init_gfx(self): return self.gfx.init()
+    def clean_gfx(self): return self.gfx.clean()
 
-    @staticmethod
-    def set_cam_pos(pos): return base.camera.set_pos(pos)
+    @staticmethod
+    def set_cam_pos(pos): return base.camera.set_pos(pos)
 
-    def load_font(self, fpath, outline=True):
-        return self.eng.font_mgr.load_font(fpath, outline)
-    def open_browser(self, url): return self.gui.open_browser(url)
+    def load_font(self, fpath, outline=True):
+        return self.eng.font_mgr.load_font(fpath, outline)
+    def open_browser(self, url): return self.gui.open_browser(url)
 
-    def toggle_pause(self, show_frm=True):
-        return self.pause.logic.toggle(show_frm)
+    def toggle_pause(self, show_frm=True):
+        return self.pause.logic.toggle(show_frm)
 
-    def play(self): return self.audio.play()
-    def set_volume(self, vol): return self.audio.set_volume(vol)
-    def show_cursor(self): return self.gui.cursor.show()
-    def show_standard_cursor(self): return self.gui.cursor.show_standard()
-    def hide_cursor(self): return self.gui.cursor.hide()
-    def hide_standard_cursor(self): return self.gui.cursor.hide_standard()
-    def cursor_top(self): return self.gui.cursor.cursor_top()
-    def set_amb_lgt(self, col): return self.shader_mgr.set_amb_lgt(col)
+    def play(self): return self.audio.play()
+    def set_volume(self, vol): return self.audio.set_volume(vol)
+    def show_cursor(self): return self.gui.cursor.show()
+    def show_standard_cursor(self): return self.gui.cursor.show_standard()
+    def hide_cursor(self): return self.gui.cursor.hide()
+    def hide_standard_cursor(self): return self.gui.cursor.hide_standard()
+    def cursor_top(self): return self.gui.cursor.cursor_top()
+    def set_amb_lgt(self, col): return self.shader_mgr.set_amb_lgt(col)
 
-    def set_dir_lgt(self, col, direction):
-        return self.shader_mgr.set_dir_lgt(col, direction)
+    def set_dir_lgt(self, col, direction):
+        return self.shader_mgr.set_dir_lgt(col, direction)
 
-    def set_shadow_lgt(self, direction):
-        return self.shader_mgr.set_shadow_lgt(direction)
+    def set_shadow_lgt(self, direction):
+        return self.shader_mgr.set_shadow_lgt(direction)
 
-    def clear_lights(self): return self.shader_mgr.clear_lights()
-    def toggle_shader(self): return self.shader_mgr.toggle_shader()
+    def clear_lights(self): return self.shader_mgr.clear_lights()
+    def toggle_shader(self): return self.shader_mgr.toggle_shader()
 
-    def set_resolution(self, res, fullscreen=None):
-        return self.gui.set_resolution(res, fullscreen)
+    def set_resolution(self, res, fullscreen=None):
+        return self.gui.set_resolution(res, fullscreen)
 
-    def toggle_fullscreen(self): return self.gui.toggle_fullscreen()
-    def send(self, msg): return self.lib.send(msg)
+    def toggle_fullscreen(self): return self.gui.toggle_fullscreen()
+    def send(self, msg): return self.lib.send(msg)
 
-    def do_later(self, time, meth, args=None):
-        return self.lib.do_later(time, meth, args)
+    def do_later(self, time, meth, args=None):
+        return self.lib.do_later(time, meth, args)
 
-    def add_task(self, mth, priority=0):
-        return self.lib.add_task(mth, priority)
+    def add_task(self, mth, priority=0):
+        return self.lib.add_task(mth, priority)
 
-    def remove_task(self, tsk): return self.lib.remove_task(tsk)
-    def log(self, msg, verbose=False): return self.log_mgr.log(msg, verbose)
-    def log_tasks(self): return self.log_mgr.log_tasks()
+    def remove_task(self, tsk): return self.lib.remove_task(tsk)
+    def log(self, msg, verbose=False): return self.log_mgr.log(msg, verbose)
+    def log_tasks(self): return self.log_mgr.log_tasks()
 
-    def rm_do_later(self, tsk):
-        self.pause.remove_task(tsk)
-        return self.lib.remove_task(tsk)
+    def rm_do_later(self, tsk):
+        self.pause.remove_task(tsk)
+        return self.lib.remove_task(tsk)
 
-    def load_model(self, filename, callback=None, anim=None):
-        return self.gfx.load_model(filename, callback, anim)
+    def load_model(self, filename, callback=None, anim=None):
+        return self.gfx.load_model(filename, callback, anim)
index 8a57a24cd00a70c353494a84600707d769ef422b..592bae0f727c928e93da9103cc197a414dcc95d6 100644 (file)
@@ -1,51 +1,51 @@
-from time import time
-from logging import info
-from ya2.gameobject import EventColleague
-from ya2.engine.joystick import JoystickMgr
-
-
-class EngineEvent(EventColleague):
-
-    def __init__(self, mediator, emulate_keyboard, functional_test):
-        EventColleague.__init__(self, mediator)
-        self.unpaused_time = 0
-        self._prev_time = time()
-        self.eng.add_task(self.__on_frame)
-        taskMgr.setupTaskChain('unpausable')
-        mth = self.__on_frame_unpausable
-        taskMgr.add(mth, 'unpausable', taskChain='unpausable')
-        self.joystick_mgr = JoystickMgr(emulate_keyboard, functional_test)
-
-    def __on_frame(self, task):  # unused task
-        self.notify('on_start_frame')
-        self.notify('on_frame')
-        self.notify('on_end_frame')
-        return self.eng.lib.task_cont
-
-    def __on_frame_unpausable(self, task):
-        self.unpaused_time += time() - self._prev_time
-        self._prev_time = time()
-        try:
-            self.notify('on_frame_unpausable')
-            return task.cont
-        except AttributeError: info("engine has been destroyed")
-
-    @staticmethod
-    def key2desc(keystr):
-        if not keystr.startswith('raw-'): return keystr
-        keystr = keystr[4:]
-        kmap = base.win.get_keyboard_map()
-        virt_key = kmap.get_mapped_button(keystr)
-        return (kmap.get_mapped_button_label(keystr) or str(virt_key)).lower()
-
-    @staticmethod
-    def desc2key(desc):
-        kmap = base.win.get_keyboard_map()
-        for i in range(kmap.get_num_buttons()):
-            if kmap.get_mapped_button_label(i).lower() == desc:
-                return str(kmap.get_mapped_button(i))
-            return desc
-
-    def destroy(self):
-        self.joystick_mgr.destroy()
-        EventColleague.destroy(self)
+from time import time
+from logging import info
+from ya2.gameobject import EventColleague
+from ya2.engine.joystick import JoystickMgr
+
+
+class EngineEvent(EventColleague):
+
+    def __init__(self, mediator, emulate_keyboard, functional_test):
+        EventColleague.__init__(self, mediator)
+        self.unpaused_time = 0
+        self._prev_time = time()
+        self.eng.add_task(self.__on_frame)
+        taskMgr.setupTaskChain('unpausable')
+        mth = self.__on_frame_unpausable
+        taskMgr.add(mth, 'unpausable', taskChain='unpausable')
+        self.joystick_mgr = JoystickMgr(emulate_keyboard, functional_test)
+
+    def __on_frame(self, task):  # unused task
+        self.notify('on_start_frame')
+        self.notify('on_frame')
+        self.notify('on_end_frame')
+        return self.eng.lib.task_cont
+
+    def __on_frame_unpausable(self, task):
+        self.unpaused_time += time() - self._prev_time
+        self._prev_time = time()
+        try:
+            self.notify('on_frame_unpausable')
+            return task.cont
+        except AttributeError: info("engine has been destroyed")
+
+    @staticmethod
+    def key2desc(keystr):
+        if not keystr.startswith('raw-'): return keystr
+        keystr = keystr[4:]
+        kmap = base.win.get_keyboard_map()
+        virt_key = kmap.get_mapped_button(keystr)
+        return (kmap.get_mapped_button_label(keystr) or str(virt_key)).lower()
+
+    @staticmethod
+    def desc2key(desc):
+        kmap = base.win.get_keyboard_map()
+        for i in range(kmap.get_num_buttons()):
+            if kmap.get_mapped_button_label(i).lower() == desc:
+                return str(kmap.get_mapped_button(i))
+            return desc
+
+    def destroy(self):
+        self.joystick_mgr.destroy()
+        EventColleague.destroy(self)
index 855e06c9648ca1c1c46bb10087b0f251e5f21004..117ae6040d3eacacc61ac2261d8f557003a096ef 100644 (file)
@@ -1,17 +1,17 @@
-from ya2.gameobject import GameObject
+from ya2.gameobject import GameObject
 
 
-class FontMgr(GameObject):
+class FontMgr(GameObject):
 
-    def __init__(self):
-        GameObject.__init__(self)
-        self.__fonts = {}
+    def __init__(self):
+        GameObject.__init__(self)
+        self.__fonts = {}
 
-    def load_font(self, fpath, outline=True):
-        if fpath not in self.__fonts:
-            self.__fonts[fpath] = self.eng.lib.load_font(fpath, outline)
-        return self.__fonts[fpath]
+    def load_font(self, fpath, outline=True):
+        if fpath not in self.__fonts:
+            self.__fonts[fpath] = self.eng.lib.load_font(fpath, outline)
+        return self.__fonts[fpath]
 
-    def destroy(self):
-        self.__fonts = None
-        GameObject.destroy(self)
+    def destroy(self):
+        self.__fonts = None
+        GameObject.destroy(self)
index 9b320ea7d0620b72c9e5eb24f582d29c8976745f..c21040039dcfb9f2edec153d4bc5c6d82a324778 100755 (executable)
@@ -1,56 +1,56 @@
-from math import pi
-from panda3d.core import ClockObject
-from ya2.gameobject import GfxColleague
-from ya2.engine.particle import Particle
-from ya2.lib.p3d.gfx import P3dGfxMgr, P3dAnimNode, P3dAmbientLight, \
-    P3dSpotlight
-
-
-GfxMgr = P3dGfxMgr
-AnimNode = P3dAnimNode
-AmbientLight = P3dAmbientLight
-Spotlight = P3dSpotlight
-
-
-class EngineGfx(GfxColleague):
-
-    def __init__(self, mediator, model_path, antialiasing, shaders, fps, srgb):
-        GfxColleague.__init__(self, mediator)
-        self.gfx_mgr = GfxMgr(model_path, antialiasing, shaders, srgb)
-        self.root = None
-        self.part2eff = {}
-        if fps: self.set_frame_rate(fps)
-        # if self.mediator.cfg.gui_cfg.shaders and \
-        #         self.eng.lib.version.startswith('1.10'):
-        #     self.set_toon()
-        #     self.set_bloom()
-
-    def init(self):
-        self.root = self.gfx_mgr.root.attach_node('world')
-
-    def clean(self): self.root.remove_node()
-
-    def load_model(self, filename, callback=None, anim=None):
-        try: return self.gfx_mgr.load_model(filename, callback, anim)
-        except OSError:
-            return self.gfx_mgr.load_model(filename + '.bam', callback, anim)
-
-    def set_toon(self): self.gfx_mgr.set_toon()
-
-    def set_bloom(self): self.gfx_mgr.set_bloom()
-
-    def print_stats(self, two_d=True, three_d=True, analyze=True, ls=True):
-        self.gfx_mgr.print_stats(two_d, three_d, analyze, ls)
-
-    @staticmethod
-    def set_frame_rate(fps):
-        globalClock.setMode(ClockObject.MLimited)
-        globalClock.set_frame_rate(fps)
-        # base.set_sleep(.01)
-
-    @staticmethod
-    def particle(parent, texture, color=(1, 1, 1, 1), ampl=pi/6, ray=.5,
-                 rate=.0001, gravity=-.85, vel=3.8, part_duration=1.0,
-                 autodestroy=None, size=10):
-        return Particle(parent, texture, color, ampl, ray, rate, gravity, vel,
-                        part_duration, autodestroy, size)
+from math import pi
+from panda3d.core import ClockObject
+from ya2.gameobject import GfxColleague
+from ya2.engine.particle import Particle
+from ya2.lib.p3d.gfx import P3dGfxMgr, P3dAnimNode, P3dAmbientLight, \
+    P3dSpotlight
+
+
+GfxMgr = P3dGfxMgr
+AnimNode = P3dAnimNode
+AmbientLight = P3dAmbientLight
+Spotlight = P3dSpotlight
+
+
+class EngineGfx(GfxColleague):
+
+    def __init__(self, mediator, model_path, antialiasing, shaders, fps, srgb):
+        GfxColleague.__init__(self, mediator)
+        self.gfx_mgr = GfxMgr(model_path, antialiasing, shaders, srgb)
+        self.root = None
+        self.part2eff = {}
+        if fps: self.set_frame_rate(fps)
+        # if self.mediator.cfg.gui_cfg.shaders and \
+        #         self.eng.lib.version.startswith('1.10'):
+        #     self.set_toon()
+        #     self.set_bloom()
+
+    def init(self):
+        self.root = self.gfx_mgr.root.attach_node('world')
+
+    def clean(self): self.root.remove_node()
+
+    def load_model(self, filename, callback=None, anim=None):
+        try: return self.gfx_mgr.load_model(filename, callback, anim)
+        except OSError:
+            return self.gfx_mgr.load_model(filename + '.bam', callback, anim)
+
+    def set_toon(self): self.gfx_mgr.set_toon()
+
+    def set_bloom(self): self.gfx_mgr.set_bloom()
+
+    def print_stats(self, two_d=True, three_d=True, analyze=True, ls=True):
+        self.gfx_mgr.print_stats(two_d, three_d, analyze, ls)
+
+    @staticmethod
+    def set_frame_rate(fps):
+        globalClock.setMode(ClockObject.MLimited)
+        globalClock.set_frame_rate(fps)
+        # base.set_sleep(.01)
+
+    @staticmethod
+    def particle(parent, texture, color=(1, 1, 1, 1), ampl=pi/6, ray=.5,
+                 rate=.0001, gravity=-.85, vel=3.8, part_duration=1.0,
+                 autodestroy=None, size=10):
+        return Particle(parent, texture, color, ampl, ray, rate, gravity, vel,
+                        part_duration, autodestroy, size)
index 15ae5d1fc02e20ff74a48296104e555eaf44a2a2..076060cb131b5cc6122aaa0fe25b50229a41ebb0 100644 (file)
@@ -1,26 +1,26 @@
-from sys import platform
-from os import environ, system
-from webbrowser import open_new_tab
+from sys import platform
+from os import environ, system
+from webbrowser import open_new_tab
 
 
-class BrowserStrategy:
+class BrowserStrategy:
 
-    @staticmethod
-    def open(url): open_new_tab(url)
+    @staticmethod
+    def open(url): open_new_tab(url)
 
 
-class BrowserStrategyLinux(BrowserStrategy):
+class BrowserStrategyLinux(BrowserStrategy):
 
-    @staticmethod
-    def open(url):
-        environ['LD_LIBRARY_PATH'] = ''
-        system('xdg-open ' + url)
+    @staticmethod
+    def open(url):
+        environ['LD_LIBRARY_PATH'] = ''
+        system('xdg-open ' + url)
 
 
-class Browser:
+class Browser:
 
-    @staticmethod
-    def open(url):
-        cls = BrowserStrategyLinux if platform.startswith('linux') else \
-            BrowserStrategy
-        cls.open(url)
+    @staticmethod
+    def open(url):
+        cls = BrowserStrategyLinux if platform.startswith('linux') else \
+            BrowserStrategy
+        cls.open(url)
index df45cce7ef6043256404a4362e699c87f271b8e8..e5cd7446eb46685b446e82e80c0d37b48ac50fce 100644 (file)
@@ -1,35 +1,35 @@
-from os import name
-from ya2.lib.gui import Frame
-from ya2.lib.p3d.shader import load_shader
-from ya2.gameobject import GameObject
+from os import name
+from ya2.lib.gui import Frame
+from ya2.lib.p3d.shader import load_shader
+from ya2.gameobject import GameObject
 
 
-class Circle(Frame, GameObject):
+class Circle(Frame, GameObject):
 
-    def __init__(self, size=.4, pos=(0, 0), parent=None, ray=.4, thickness=.05,
-                 col_start=(1, 1, 1, 1), col_end=(1, 1, 1, 1)):
-        GameObject.__init__(self)
-        Frame.__init__(self, pos=(pos[0], pos[1]), texture_coord=True,
-                       frame_size=(-size, size, -size, size), parent=parent)
-        path = 'assets/shaders/'
-        shader = load_shader(path + 'filter.vert', path + 'circle.frag')
-        drv_lst = [self.eng.lib.driver_vendor, self.eng.lib.driver_renderer,
-                   self.eng.lib.driver_version]
-        is_nvidia = any('nvidia' in drv.lower() for drv in drv_lst)
-        if shader and not (name == 'nt' and is_nvidia):
-            self.set_shader(shader)
-            args = [('ray', ray), ('width', thickness), ('progress', 0),
-                    ('color_start', col_start), ('color_end', col_end)]
-            list(map(lambda arg: self.set_shader_input(*arg), args))
-        else: self['frameColor'] = (1, 1, 1, 0)
-        self.set_transparency(True)
+    def __init__(self, size=.4, pos=(0, 0), parent=None, ray=.4, thickness=.05,
+                 col_start=(1, 1, 1, 1), col_end=(1, 1, 1, 1)):
+        GameObject.__init__(self)
+        Frame.__init__(self, pos=(pos[0], pos[1]), texture_coord=True,
+                       frame_size=(-size, size, -size, size), parent=parent)
+        path = 'assets/shaders/'
+        shader = load_shader(path + 'filter.vert', path + 'circle.frag')
+        drv_lst = [self.eng.lib.driver_vendor, self.eng.lib.driver_renderer,
+                   self.eng.lib.driver_version]
+        is_nvidia = any('nvidia' in drv.lower() for drv in drv_lst)
+        if shader and not (name == 'nt' and is_nvidia):
+            self.set_shader(shader)
+            args = [('ray', ray), ('width', thickness), ('progress', 0),
+                    ('color_start', col_start), ('color_end', col_end)]
+            list(map(lambda arg: self.set_shader_input(*arg), args))
+        else: self['frameColor'] = (1, 1, 1, 0)
+        self.set_transparency(True)
 
-    @property
-    def progress(self): return self.get_shader_input('progress')
+    @property
+    def progress(self): return self.get_shader_input('progress')
 
-    @progress.setter
-    def progress(self, val): self.set_shader_input('progress', val)
+    @progress.setter
+    def progress(self, val): self.set_shader_input('progress', val)
 
-    def destroy(self):
-        Frame.destroy(self)
-        GameObject.destroy(self)
+    def destroy(self):
+        Frame.destroy(self)
+        GameObject.destroy(self)
index 699cce610a1dc7f69c26bd3f4d63579f68160bd6..6faaa19762045276283632603469d3042afcf058 100755 (executable)
@@ -1,66 +1,66 @@
-from logging import info
-from ya2.gameobject import GuiColleague
-from ya2.engine.gui.cursor import MouseCursor
-from ya2.engine.gui.browser import Browser
+from logging import info
+from ya2.gameobject import GuiColleague
+from ya2.engine.gui.cursor import MouseCursor
+from ya2.engine.gui.browser import Browser
 
 
-up = (0, 1)
-down = (0, -1)
-left = (-1, 0)
-right = (1, 0)
+up = (0, 1)
+down = (0, -1)
+left = (-1, 0)
+right = (1, 0)
 
 
-class EngineGuiBase(GuiColleague):  # no win: EngineGui strictly manages win
+class EngineGuiBase(GuiColleague):  # no win: EngineGui strictly manages win
 
-    @staticmethod
-    def init_cls():
-        return EngineGui if EngineGuiBase.eng.lib.has_window else EngineGuiBase
+    @staticmethod
+    def init_cls():
+        return EngineGui if EngineGuiBase.eng.lib.has_window else EngineGuiBase
 
-    @staticmethod
-    def open_browser(url): Browser.open(url)
+    @staticmethod
+    def open_browser(url): Browser.open(url)
 
-    @property
-    def resolutions(self):
-        return sorted(list(set(self.eng.lib.resolutions)))
+    @property
+    def resolutions(self):
+        return sorted(list(set(self.eng.lib.resolutions)))
 
-    @property
-    def closest_resolution(self):
-        def distance(res):
-            curr_res = self.eng.lib.resolution
-            return abs(res[0] - curr_res[0]) + abs(res[1] - curr_res[1])
+    @property
+    def closest_resolution(self):
+        def distance(res):
+            curr_res = self.eng.lib.resolution
+            return abs(res[0] - curr_res[0]) + abs(res[1] - curr_res[1])
 
-        try:
-            return min(self.resolutions, key=distance)
-        except ValueError:  # sometimes we have empty resolutions
-            return self.eng.lib.resolution
+        try:
+            return min(self.resolutions, key=distance)
+        except ValueError:  # sometimes we have empty resolutions
+            return self.eng.lib.resolution
 
-    def set_resolution_check(self, res):
-        res_msg = 'resolutions: {curr} (current), {res} (wanted)'
-        info(res_msg.format(curr=self.eng.lib.resolution, res=res))
-        if self.eng.lib.resolution == res: return
-        retry = 'second attempt: {curr} (current) {res} (wanted)'
-        info(retry.format(curr=self.eng.lib.resolution, res=res))
-        self.set_resolution(res, False)
+    def set_resolution_check(self, res):
+        res_msg = 'resolutions: {curr} (current), {res} (wanted)'
+        info(res_msg.format(curr=self.eng.lib.resolution, res=res))
+        if self.eng.lib.resolution == res: return
+        retry = 'second attempt: {curr} (current) {res} (wanted)'
+        info(retry.format(curr=self.eng.lib.resolution, res=res))
+        self.set_resolution(res, False)
 
-    def toggle_fullscreen(self):
-        self.set_resolution(self.closest_resolution)
-        self.eng.lib.toggle_fullscreen()
+    def toggle_fullscreen(self):
+        self.set_resolution(self.closest_resolution)
+        self.eng.lib.toggle_fullscreen()
 
 
-class EngineGui(EngineGuiBase):
+class EngineGui(EngineGuiBase):
 
-    def __init__(self, mediator):
-        EngineGuiBase.__init__(self, mediator)
-        cfg = self.eng.cfg
-        res_strings = cfg.gui_cfg.win_size.split()
-        res_ints = tuple(int(size) for size in res_strings)
-        self.set_resolution(res_ints, fullscreen=cfg.gui_cfg.fullscreen)
-        cur_cfg = cfg.cursor_cfg
-        self.cursor = MouseCursor(
-            cur_cfg.cursor_path, cur_cfg.cursor_scale, cur_cfg.cursor_color,
-            cur_cfg.cursor_hotspot)
+    def __init__(self, mediator):
+        EngineGuiBase.__init__(self, mediator)
+        cfg = self.eng.cfg
+        res_strings = cfg.gui_cfg.win_size.split()
+        res_ints = tuple(int(size) for size in res_strings)
+        self.set_resolution(res_ints, fullscreen=cfg.gui_cfg.fullscreen)
+        cur_cfg = cfg.cursor_cfg
+        self.cursor = MouseCursor(
+            cur_cfg.cursor_path, cur_cfg.cursor_scale, cur_cfg.cursor_color,
+            cur_cfg.cursor_hotspot)
 
-    def set_resolution(self, res, check=True, fullscreen=None):
-        info('setting resolution ' + str(res))
-        self.eng.lib.set_resolution(res, fullscreen)
-        if check: self.eng.do_later(3.0, self.set_resolution_check, [res])
+    def set_resolution(self, res, check=True, fullscreen=None):
+        info('setting resolution ' + str(res))
+        self.eng.lib.set_resolution(res, fullscreen)
+        if check: self.eng.do_later(3.0, self.set_resolution_check, [res])
index 467d752f36ac1d66019541c565df12ee04b45a6a..43a6cf33ff387953566f2ab56c4ab657e2361924 100644 (file)
@@ -1,30 +1,30 @@
-from ya2.lib.gui import Btn
-from ya2.lib.p3d.shader import load_shader
+from ya2.lib.gui import Btn
+from ya2.lib.p3d.shader import load_shader
 
 
-class ImgBtn(Btn):
+class ImgBtn(Btn):
 
-    def __init__(self, *args, **kwargs):
-        Btn.__init__(self, *args, **kwargs)
-        shader_dirpath = 'assets/shaders/'
-        shader = load_shader(shader_dirpath + 'filter.vert',
-                             shader_dirpath + 'imgbtn.frag')
-        if shader:
-            self.set_shader(shader)
-            shader_args = [('col_offset', 0), ('enable', 1)]
-            list(map(lambda args: self.set_shader_input(*args), shader_args))
-        self.set_transparency(True)
+    def __init__(self, *args, **kwargs):
+        Btn.__init__(self, *args, **kwargs)
+        shader_dirpath = 'assets/shaders/'
+        shader = load_shader(shader_dirpath + 'filter.vert',
+                             shader_dirpath + 'imgbtn.frag')
+        if shader:
+            self.set_shader(shader)
+            shader_args = [('col_offset', 0), ('enable', 1)]
+            list(map(lambda args: self.set_shader_input(*args), shader_args))
+        self.set_transparency(True)
 
-    def _on_enter(self, pos):  # pos comes from mouse
-        self.set_shader_input('col_offset', .25)
+    def _on_enter(self, pos):  # pos comes from mouse
+        self.set_shader_input('col_offset', .25)
 
-    def _on_exit(self, pos):  # pos comes from mouse
-        self.set_shader_input('col_offset', 0)
+    def _on_exit(self, pos):  # pos comes from mouse
+        self.set_shader_input('col_offset', 0)
 
-    def enable(self):
-        super().enable()
-        self.set_shader_input('enable', 1)
+    def enable(self):
+        super().enable()
+        self.set_shader_input('enable', 1)
 
-    def disable(self):
-        super().disable()
-        self.set_shader_input('enable', .2)
+    def disable(self):
+        super().disable()
+        self.set_shader_input('enable', .2)
index 1868329c3f8753f34be1bb2cb65359ff794acf51..934e2ef110e40360e1991fa980222dc4297da6fe 100644 (file)
@@ -1,56 +1,56 @@
-from ya2.lib.gui import Text, Img
-from ya2.engine.gui.page import Page, PageGui, PageFacade
-from ya2.engine.gui.imgbtn import ImgBtn
-
-
-class MainPageGui(PageGui):
-
-    def build(self, back_btn=True, exit_behav=False):
-        #self.__build_social()
-        self.__build_version()
-        self.__build_dependencies()
-        self._set_widgets()
-        self.transition_enter()
-
-    def __build_social(self):
-        sites = self.props.gameprops.social_sites
-        menu_props = self.props.gameprops.menu_props
-        left = (len(sites) - 1) / 2.0 * .15
-        buttons = [
-            ImgBtn(
-                parent='bottomcenter',
-                scale=(.06, .06),
-                pos=(-left + i*.15, .1),
-                frame_col=(1, 1, 1, 1),
-                frame_texture=menu_props.social_imgs_dirpath % site[0],
-                cmd=self.eng.open_browser,
-                extra_args=[site[1]],
-                **menu_props.imgbtn_args)
-            for i, site in enumerate(sites)]
-        self.add_widgets(buttons)
-
-    def __build_version(self):
-        txt = Text(
-            _('version: ') + self.eng.version, parent='bottomleft',
-            pos=(.02, .02), scale=.04, fg=(.8, .8, .8, 1), align='left',
-            font=self.props.gameprops.menu_props.font, wordwrap=256)
-        self.add_widgets([txt])
-
-    def __build_dependencies(self):
-        txt = Text(
-            _('made with heart with panda3d, panda3d-simplepbr, panda3d-gltf'),
-            parent='bottomright', pos=(-.09, .02), scale=.04, wordwrap=128,
-            fg=(.8, .8, .8, 1), align='right',
-            font=self.props.gameprops.menu_props.font)
-        img = Img(
-            'assets/images/gui/p3d.dds', scale=.04,
-            parent=base.a2dBottomRight, pos=(-.04, .04))
-        self.add_widgets([txt, img])
-
-
-class MainPage(Page, PageFacade):
-    gui_cls = MainPageGui
-
-    def __init__(self, mainpage_props):
-        Page.__init__(self, mainpage_props)
-        PageFacade.__init__(self)
+from ya2.lib.gui import Text, Img
+from ya2.engine.gui.page import Page, PageGui, PageFacade
+from ya2.engine.gui.imgbtn import ImgBtn
+
+
+class MainPageGui(PageGui):
+
+    def build(self, back_btn=True, exit_behav=False):
+        #self.__build_social()
+        self.__build_version()
+        self.__build_dependencies()
+        self._set_widgets()
+        self.transition_enter()
+
+    def __build_social(self):
+        sites = self.props.gameprops.social_sites
+        menu_props = self.props.gameprops.menu_props
+        left = (len(sites) - 1) / 2.0 * .15
+        buttons = [
+            ImgBtn(
+                parent='bottomcenter',
+                scale=(.06, .06),
+                pos=(-left + i*.15, .1),
+                frame_col=(1, 1, 1, 1),
+                frame_texture=menu_props.social_imgs_dirpath % site[0],
+                cmd=self.eng.open_browser,
+                extra_args=[site[1]],
+                **menu_props.imgbtn_args)
+            for i, site in enumerate(sites)]
+        self.add_widgets(buttons)
+
+    def __build_version(self):
+        txt = Text(
+            _('version: ') + self.eng.version, parent='bottomleft',
+            pos=(.02, .02), scale=.04, fg=(.8, .8, .8, 1), align='left',
+            font=self.props.gameprops.menu_props.font, wordwrap=256)
+        self.add_widgets([txt])
+
+    def __build_dependencies(self):
+        txt = Text(
+            _('made with heart with panda3d, panda3d-simplepbr, panda3d-gltf'),
+            parent='bottomright', pos=(-.09, .02), scale=.04, wordwrap=128,
+            fg=(.8, .8, .8, 1), align='right',
+            font=self.props.gameprops.menu_props.font)
+        img = Img(
+            'assets/images/gui/p3d.dds', scale=.04,
+            parent=base.a2dBottomRight, pos=(-.04, .04))
+        self.add_widgets([txt, img])
+
+
+class MainPage(Page, PageFacade):
+    gui_cls = MainPageGui
+
+    def __init__(self, mainpage_props):
+        Page.__init__(self, mainpage_props)
+        PageFacade.__init__(self)
index bc848aa11a8d9768f4c7a88f14e38ed930f1a356..79756d34aaa475f012ce3efd331e1ac9962340ac 100644 (file)
-from direct.gui.DirectGuiGlobals import FLAT
-from ya2.gameobject import GuiColleague, LogicColleague, GameObject
-from ya2.lib.gui import Img
-from ya2.engine.audio import AudioSound
-
-
-class NavInfoPerPlayer:
-
-    def __init__(self, left, right, up, down, fire):
-        self.left = left
-        self.right = right
-        self.up = up
-        self.down = down
-        self.fire = fire
-
-
-class NavInfo:
-
-    def __init__(self, navinfo_lst):
-        self.navinfo_lst = navinfo_lst
-
-
-class MenuProps(GameObject):
-
-    def __init__(
-            self, font_path, text_active_col, text_normal_col, text_err_col,
-            text_scale, btn_size, btn_col, background_img_path, over_sfx_path,
-            click_sfx_path, social_imgs_dirpath, nav):
-        GameObject.__init__(self)
-        self.__font_path = font_path
-        self.text_active_col = text_active_col
-        self.text_normal_col = text_normal_col
-        self.text_err_col = text_err_col
-        self.text_scale = text_scale
-        self.btn_size = btn_size
-        self.btn_col = btn_col
-        self.background_img_path = background_img_path
-        self.__over_sfx_path = over_sfx_path
-        self.__click_sfx_path = click_sfx_path
-        self.social_imgs_dirpath = social_imgs_dirpath
-        self.nav = nav
-
-    @property
-    def font(self): return self.eng.font_mgr.load_font(self.__font_path)
-
-    @property
-    def over_sfx(self): return AudioSound(self.__over_sfx_path).snd
-
-    @property
-    def click_sfx(self): return AudioSound(self.__click_sfx_path).snd
-
-    @property
-    def btn_args(self):  # it may be used without a menu e.g. results
-        return {
-            'scale': (self.text_scale, self.text_scale),
-            'text_font': self.font,
-            'text_fg': self.text_active_col,
-            'frame_col': self.btn_col,
-            'frame_size': self.btn_size,
-            'over_snd': self.over_sfx,
-            'click_snd': self.click_sfx}
-
-    @property
-    def imgbtn_args(self):
-        return {
-            'over_snd': self.over_sfx,
-            'click_snd': self.click_sfx}
-
-    @property
-    def label_args(self):
-        return {
-            'scale': self.text_scale,
-            'text_fg': self.text_normal_col,
-            'text_font': self.font,
-            'frame_col': (1, 1, 1, 0)}
-
-    @property
-    def option_args(self):
-        tfg = self.text_active_col
-        return {
-            'scale': self.text_scale,
-            'text_font': self.font,
-            'text_fg': tfg,
-            'frame_col': self.btn_col,
-            'frame_size': self.btn_size,
-            'over_snd': self.over_sfx,
-            'click_snd': self.click_sfx,
-            'text_scale': .85,
-            'item_text_font': self.font,
-            'item_frame_col': tfg,
-            'item_relief': FLAT,
-            'popup_marker_col': self.btn_col,
-            'text_may_change': 1,
-            'highlight_col': (tfg[0] * 1.2, tfg[1] * 1.2, tfg[2] * 1.2, .2)}
-
-    @property
-    def checkbtn_args(self):
-        return {
-            'scale': self.text_scale,
-            'text_font': self.font,
-            'text_fg': self.text_active_col,
-            'frame_col': self.btn_col,
-            'over_snd': self.over_sfx,
-            'click_snd': self.click_sfx}
-
-    @property
-    def text_args(self):
-        return {
-            'scale': self.text_scale,
-            'fg': self.text_normal_col,
-            'font': self.font}
-
-
-class MenuGui(GuiColleague):
-
-    def __init__(self, mediator, menu_props):
-        GuiColleague.__init__(self, mediator)
-        self.menu_props = menu_props
-        self.background = None
-        if not self.menu_props.background_img_path: return
-        self.background = Img(self.menu_props.background_img_path,
-                              scale=(1.77778, 1, 1.0),
-                              background=True)
-
-    def destroy(self):
-        if self.background: self.background.destroy()
-        self.menu_props = self.background = None
-        GuiColleague.destroy(self)
-
-
-class MenuLogic(LogicColleague):
-
-    def __init__(self, mediator):
-        LogicColleague.__init__(self, mediator)
-        self.pages = []
-
-    def push_page(self, page):
-        if self.pages:
-            self.pages[-1].hide()
-            if len(self.pages) > 1:  # first page doesn't go back
-                self.pages[-1].detach_obs(self.on_back)
-                self.pages[-1].detach_obs(self.on_quit)
-        self.pages += [page]
-        list(map(
-            page.attach_obs, [self.on_back, self.on_quit, self.on_push_page]))
-
-    def enable(self): self.pages[-1].enable()
-
-    def enable_navigation(self): self.pages[-1].enable_navigation()
-
-    def disable(self): self.pages[-1].disable()
-
-    def disable_navigation(self): self.pages[-1].disable_navigation()
-
-    def on_push_page(self, page_code, args=None): pass
-
-    def __back_quit_tmpl(self, idx, fun):
-        page = self.pages.pop()
-        list(map(page.detach_obs, [self.on_back, self.on_quit]))
-        page.destroy()
-        fun()
-        self.pages[idx].show()
-        list(map(self.pages[idx].attach_obs, [self.on_back, self.on_quit]))
-
-    def on_back(self):
-        self.__back_quit_tmpl(-1, lambda: None)
-
-    def on_quit(self):
-        def __on_quit():
-            while len(self.pages) > 1:
-                page = self.pages.pop()
-                page.destroy()
-        self.__back_quit_tmpl(0, __on_quit)
-
-    def destroy(self):
-        list(map(lambda page: page.destroy(), self.pages))
-        self.pages = None
-        LogicColleague.destroy(self)
-
-
-class MenuFacade:
-
-    def push_page(self, page): return self.logic.push_page(page)
-    def attach_obs(self, obs_meth, sort=10, rename='', args=None):
-        return self.gui.attach(obs_meth, sort, rename, args or [])
-    def detach_obs(self, obs_meth, lambda_call=None):
-        return self.gui.detach(obs_meth, lambda_call)
-    def enable(self): return self.gui.enable()
-    def enable_navigation(self): return self.gui.enable_navigation()
-
-
-class Menu(GameObject, MenuFacade):
-    gui_cls = MenuGui
-    logic_cls = MenuLogic
-
-    def __init__(self, menu_props):
-        GameObject.__init__(self)
-        self.logic = self.logic_cls(self)
-        self.__menu_props = menu_props
-        self._build_gui()
-
-    def _build_gui(self):
-        self.gui = self.gui_cls(self, self.__menu_props)
+from direct.gui.DirectGuiGlobals import FLAT
+from ya2.gameobject import GuiColleague, LogicColleague, GameObject
+from ya2.lib.gui import Img
+from ya2.engine.audio import AudioSound
+
+
+class NavInfoPerPlayer:
+
+    def __init__(self, left, right, up, down, fire):
+        self.left = left
+        self.right = right
+        self.up = up
+        self.down = down
+        self.fire = fire
+
+
+class NavInfo:
+
+    def __init__(self, navinfo_lst):
+        self.navinfo_lst = navinfo_lst
+
+
+class MenuProps(GameObject):
+
+    def __init__(
+            self, font_path, text_active_col, text_normal_col, text_err_col,
+            text_scale, btn_size, btn_col, background_img_path, over_sfx_path,
+            click_sfx_path, social_imgs_dirpath, nav):
+        GameObject.__init__(self)
+        self.__font_path = font_path
+        self.text_active_col = text_active_col
+        self.text_normal_col = text_normal_col
+        self.text_err_col = text_err_col
+        self.text_scale = text_scale
+        self.btn_size = btn_size
+        self.btn_col = btn_col
+        self.background_img_path = background_img_path
+        self.__over_sfx_path = over_sfx_path
+        self.__click_sfx_path = click_sfx_path
+        self.social_imgs_dirpath = social_imgs_dirpath
+        self.nav = nav
+
+    @property
+    def font(self): return self.eng.font_mgr.load_font(self.__font_path)
+
+    @property
+    def over_sfx(self): return AudioSound(self.__over_sfx_path).snd
+
+    @property
+    def click_sfx(self): return AudioSound(self.__click_sfx_path).snd
+
+    @property
+    def btn_args(self):  # it may be used without a menu e.g. results
+        return {
+            'scale': (self.text_scale, self.text_scale),
+            'text_font': self.font,
+            'text_fg': self.text_active_col,
+            'frame_col': self.btn_col,
+            'frame_size': self.btn_size,
+            'over_snd': self.over_sfx,
+            'click_snd': self.click_sfx}
+
+    @property
+    def imgbtn_args(self):
+        return {
+            'over_snd': self.over_sfx,
+            'click_snd': self.click_sfx}
+
+    @property
+    def label_args(self):
+        return {
+            'scale': self.text_scale,
+            'text_fg': self.text_normal_col,
+            'text_font': self.font,
+            'frame_col': (1, 1, 1, 0)}
+
+    @property
+    def option_args(self):
+        tfg = self.text_active_col
+        return {
+            'scale': self.text_scale,
+            'text_font': self.font,
+            'text_fg': tfg,
+            'frame_col': self.btn_col,
+            'frame_size': self.btn_size,
+            'over_snd': self.over_sfx,
+            'click_snd': self.click_sfx,
+            'text_scale': .85,
+            'item_text_font': self.font,
+            'item_frame_col': tfg,
+            'item_relief': FLAT,
+            'popup_marker_col': self.btn_col,
+            'text_may_change': 1,
+            'highlight_col': (tfg[0] * 1.2, tfg[1] * 1.2, tfg[2] * 1.2, .2)}
+
+    @property
+    def checkbtn_args(self):
+        return {
+            'scale': self.text_scale,
+            'text_font': self.font,
+            'text_fg': self.text_active_col,
+            'frame_col': self.btn_col,
+            'over_snd': self.over_sfx,
+            'click_snd': self.click_sfx}
+
+    @property
+    def text_args(self):
+        return {
+            'scale': self.text_scale,
+            'fg': self.text_normal_col,
+            'font': self.font}
+
+
+class MenuGui(GuiColleague):
+
+    def __init__(self, mediator, menu_props):
+        GuiColleague.__init__(self, mediator)
+        self.menu_props = menu_props
+        self.background = None
+        if not self.menu_props.background_img_path: return
+        self.background = Img(self.menu_props.background_img_path,
+                              scale=(1.77778, 1, 1.0),
+                              background=True)
+
+    def destroy(self):
+        if self.background: self.background.destroy()
+        self.menu_props = self.background = None
+        GuiColleague.destroy(self)
+
+
+class MenuLogic(LogicColleague):
+
+    def __init__(self, mediator):
+        LogicColleague.__init__(self, mediator)
+        self.pages = []
+
+    def push_page(self, page):
+        if self.pages:
+            self.pages[-1].hide()
+            if len(self.pages) > 1:  # first page doesn't go back
+                self.pages[-1].detach_obs(self.on_back)
+                self.pages[-1].detach_obs(self.on_quit)
+        self.pages += [page]
+        list(map(
+            page.attach_obs, [self.on_back, self.on_quit, self.on_push_page]))
+
+    def enable(self): self.pages[-1].enable()
+
+    def enable_navigation(self): self.pages[-1].enable_navigation()
+
+    def disable(self): self.pages[-1].disable()
+
+    def disable_navigation(self): self.pages[-1].disable_navigation()
+
+    def on_push_page(self, page_code, args=None): pass
+
+    def __back_quit_tmpl(self, idx, fun):
+        page = self.pages.pop()
+        list(map(page.detach_obs, [self.on_back, self.on_quit]))
+        page.destroy()
+        fun()
+        self.pages[idx].show()
+        list(map(self.pages[idx].attach_obs, [self.on_back, self.on_quit]))
+
+    def on_back(self):
+        self.__back_quit_tmpl(-1, lambda: None)
+
+    def on_quit(self):
+        def __on_quit():
+            while len(self.pages) > 1:
+                page = self.pages.pop()
+                page.destroy()
+        self.__back_quit_tmpl(0, __on_quit)
+
+    def destroy(self):
+        list(map(lambda page: page.destroy(), self.pages))
+        self.pages = None
+        LogicColleague.destroy(self)
+
+
+class MenuFacade:
+
+    def push_page(self, page): return self.logic.push_page(page)
+    def attach_obs(self, obs_meth, sort=10, rename='', args=None):
+        return self.gui.attach(obs_meth, sort, rename, args or [])
+    def detach_obs(self, obs_meth, lambda_call=None):
+        return self.gui.detach(obs_meth, lambda_call)
+    def enable(self): return self.gui.enable()
+    def enable_navigation(self): return self.gui.enable_navigation()
+
+
+class Menu(GameObject, MenuFacade):
+    gui_cls = MenuGui
+    logic_cls = MenuLogic
+
+    def __init__(self, menu_props):
+        GameObject.__init__(self)
+        self.logic = self.logic_cls(self)
+        self.__menu_props = menu_props
+        self._build_gui()
+
+    def _build_gui(self):
+        self.gui = self.gui_cls(self, self.__menu_props)
 
-    def destroy(self):
-        self.logic.destroy()
-        self.gui.destroy()
-        GameObject.destroy(self)
+    def destroy(self):
+        self.logic.destroy()
+        self.gui.destroy()
+        GameObject.destroy(self)
index 1912797485ae08ae15fdab5460d2bab4fabfb4cf..8cef27fe1a510e3c60cc1bbe682fbd2f01b7e102 100755 (executable)
-from inspect import getmro
-from ya2.lib.gui import Btn, Slider, CheckBtn, OptionMenu, Entry
-from ya2.engine.vec import Vec2
-from ya2.engine.gui.gui import left, right, up, down
-from ya2.gameobject import GameObject, GuiColleague, EventColleague
-from ya2.engine.gui.imgbtn import ImgBtn
-
-
-class PageGui(GuiColleague):
-
-    def __init__(self, mediator, menu_props, players=[0]):
-        GuiColleague.__init__(self, mediator)
-        self.enable_tsk = None
-        self._back_btn = None
-        self.menu_props = menu_props
-        self.players = players
-        self.widgets = []
-        self.build()
-        self.translate()
-        self.curr_wdgs = []
-        for player in players:
-            self.curr_wdgs += [
-                self.__next_wdg((-.1, -1), player, Vec2(-3.6, 1))]
-            if self.curr_wdgs[-1]:
-                self.curr_wdgs[-1].on_wdg_enter(None, player)
-
-    def build(self, back_btn=True, exit_behav=False):
-        if back_btn: self.__build_back_btn(exit_behav)
-        self._set_widgets()
-        self._set_entries()
-        self.transition_enter()
-        self.eng.cursor_top()
-
-    def add_widgets(self, widgets): self.widgets += widgets
-
-    def on_arrow(self, direction, player):
-        if not self.curr_wdgs[player]: return
-        if self.curr_wdgs[player].__class__.__name__ == 'P3dEntryWidget' and \
-            self.curr_wdgs[player].focused: return
-        processed_cmd = self.curr_wdgs[player].on_arrow(direction)
-        # e.g. up/down in a combobox or left/right in a slider
-        if processed_cmd: return
-        next_wdg = self.__next_wdg(direction, player)
-        if not next_wdg: return
-        self.focus(next_wdg, player)
-
-    def on_enter(self, player):
-        if not self.curr_wdgs[player]: return
-        arg = player if len(self.players) > 1 else None
-        if self.curr_wdgs[player].on_enter(arg): self.enable([player])
-        # wdg.on_enter returns True when it is an option widget
-
-    @property
-    def buttons(self):
-        is_btn = lambda wdg: Btn in getmro(wdg.__class__)
-        return [wdg for wdg in self.widgets if is_btn(wdg)]
-
-    def focus(self, wdg, player):
-        self.curr_wdgs[player].on_wdg_exit(None, player)
-        self.curr_wdgs[player] = wdg
-        self.curr_wdgs[player].on_wdg_enter(None, player)
-
-    def __direction_dot_dwg(self, wdg, direction, player, start=None):
-        if start: start_pos = start
-        else: start_pos = self.curr_wdgs[player].pos
-        return (wdg.pos - start_pos).normalized.dot(direction)
-
-    def __next_weight(self, wdg, direction, player, start=None):
-        if start: start_pos = start
-        else: start_pos = self.curr_wdgs[player].global_pos
-        dot = self.__direction_dot_dwg(wdg, direction, player, start)
-        if direction in [(-1, 0), (1, 0)]:
-            proj_dist = abs(wdg.global_pos.x - start_pos.x)
-        else: proj_dist = abs(wdg.global_pos.y - start_pos.y)
-        weights = [.5, .5] if direction in [left, right] else [.1, .9]
-        return weights[0] * (dot * dot) + weights[1] * (1 - proj_dist)
-
-    def __next_wdg(self, direction, player, start=None):
-        # interactive classes
-        iclss = [Btn, CheckBtn, Slider, OptionMenu, ImgBtn, Entry]
-        inter = lambda wdg: any(pcl in iclss for pcl in getmro(wdg.__class__))
-        allwdgs = [wdg for wdg in self.widgets if inter(wdg)]
-        wdgs = list(filter(lambda wdg: wdg.is_enabled, allwdgs))
-        if player < len(self.curr_wdgs) and self.curr_wdgs[player] \
-                and self.curr_wdgs[player] in wdgs:
-                # the last check for this case: multiple players appear on the
-                # same button, one player clicks it, another moves from it
-            wdgs.remove(self.curr_wdgs[player])
-        mth = self.__direction_dot_dwg
-        in_direction = lambda wdg: mth(wdg, direction, player, start) > .1
-        dirwdgs = list(filter(in_direction, wdgs))
-        if not dirwdgs: return None
-        nextweight = lambda wdg: \
-                     self.__next_weight(wdg, direction, player, start)
-        return max(dirwdgs, key=nextweight)
-
-    def _set_widgets(self):
-        list(map(lambda wdg: wdg.set_widget(), self.widgets))
-
-    def _set_entries(self):
-        for wdg in self.widgets:
-            if wdg.__class__.__name__ == 'P3dEntryWidget':
-                wdg.attach(self.on_entry_enter)
-                wdg.attach(self.on_entry_exit)
-
-    def on_entry_enter(self):
-        if self.menu_props:  # i.e. not destroyed
-            self.disable_navigation(self.players)
-
-    def on_entry_exit(self):
-        if self.menu_props:  # i.e. not destroyed
-            self.enable_navigation(self.players)
-
-    def transition_enter(self):
-        self.translate()
-        list(map(lambda wdg: wdg.set_enter_transition(), self.widgets))
-        self.enable(self.players)
-
-    def translate(self): list(map(lambda wdg: wdg.translate(), self.widgets))
-
-    def enable_navigation(self, players):
-        if self.enable_tsk: self.eng.rm_do_later(self.enable_tsk)
-        self.enable_tsk = self.eng.do_later(
-            .01, self.enable_navigation_aux, [players])
-
-    def update_navigation(self):
-        self.disable_navigation(self.players)
-        self.enable_navigation(self.players)
-
-    def enable_navigation_aux(self, players):
-        navs = []
-        for player in players:
-            nav = self.menu_props.nav.navinfo_lst[player]
-            evts = [
-                (self.eng.lib.remap_str(nav.left), self.on_arrow,
-                 [left, player]),
-                (self.eng.lib.remap_str(nav.right), self.on_arrow,
-                 [right, player]),
-                (self.eng.lib.remap_str(nav.up), self.on_arrow, [up, player]),
-                (self.eng.lib.remap_str(nav.down), self.on_arrow,
-                 [down, player]),
-                (self.eng.lib.remap_str(nav.fire), self.on_enter, [player])]
-            def append_up(evt): return evt + ('' if evt.endswith('-up') else '-up')
-            evts = [(append_up(evt[0]), evt[1], evt[2]) for evt in evts]
-            navs += [nav]
-            list(map(lambda args: self.mediator.event.accept(*args), evts))
-        self.eng.joystick_mgr.bind_keyboard(navs)
-        if self.eng.cfg.dev_cfg.menu_joypad and self._back_btn:
-            self.mediator.event.accept('joypad0-face_b-up', self.__back_wrapper)
-
-    def __back_wrapper(self):
-        if not self.eng.joystick_mgr.is_recording: self._back_btn['command']()
-
-    def disable_navigation(self, players):
-        if self.enable_tsk:
-            self.enable_tsk = self.eng.rm_do_later(self.enable_tsk)
-        for player in players:
-            nav = self.menu_props.nav.navinfo_lst[player]
-            # evts = [nav.left, nav.right, nav.up, nav.down, nav.fire]
-            evts = [
-                self.eng.lib.remap_str(nav.left),
-                self.eng.lib.remap_str(nav.right),
-                self.eng.lib.remap_str(nav.up),
-                self.eng.lib.remap_str(nav.down),
-                self.eng.lib.remap_str(nav.fire)]
-            def append_up(evt): return evt + ('' if evt.endswith('-up') else '-up')
-            evts = [append_up(evt) for evt in evts]
-            self.eng.joystick_mgr.unbind_keyboard()
-            list(map(self.mediator.event.ignore, evts))
-        self.mediator.event.ignore('joypad0-face_b-up')
-
-    def enable(self, players):
-        self.enable_navigation(players)
-        list(map(lambda wdg: wdg.enable(), self.widgets))
-
-    def disable(self, players):
-        if self.enable_tsk:
-            self.enable_tsk = self.eng.rm_do_later(self.enable_tsk)
-        self.disable_navigation(players)
-        list(map(lambda wdg: wdg.disable(), self.widgets))
-
-    def transition_exit(self, destroy=True):
-        list(map(lambda wdg: wdg.set_exit_transition(destroy), self.widgets))
-        self.disable(self.players)
-
-    def __build_back_btn(self, exit_behav):
-        tra_src = 'Quit' if exit_behav else 'Back'
-        tra_tra = _('Quit') if exit_behav else _('Back')
-        callback = self._on_quit if exit_behav else self._on_back
-        btn = Btn(text='', pos=(0, -.85), cmd=callback,
-                  tra_src=tra_src, tra_tra=tra_tra, **self.menu_props.btn_args)
-        self.widgets += [btn]
-        self._back_btn = btn
-
-    def _on_back(self, player=0):
-        self.notify('on_back', self.__class__.__name__)
-
-    def _on_quit(self): self.notify('on_quit', self.__class__.__name__)
-
-    def show(self):
-        visible_widgets = [wdg for wdg in self.widgets if wdg.was_visible]
-        list(map(lambda wdg: wdg.show(), visible_widgets))
-        self.transition_enter()
-
-    def hide(self):
-        for wdg in self.widgets: wdg.was_visible = not wdg.hidden
-        self.transition_exit(False)
-        self.notify('on_hide')
-
-    def destroy(self):
-        self.transition_exit()
-        self.menu_props = None
-
-
-class PageEvent(EventColleague):
-
-    def on_back(self): pass
-
-    def on_quit(self): pass
-
-
-class PageFacade:
-
-    def show(self): return self.gui.show()
-    def hide(self): return self.gui.hide()
-    def enable(self, players): return self.gui.enable(players)
-    def disable(self, players): return self.gui.disable(players)
-
-    def enable_navigation(self, players):
-        return self.gui.enable_navigation(players)
-
-    def disable_navigation(self, players):
-        return self.gui.disable_navigation(players)
-
-    def attach_obs(self, obs_meth, sort=10, rename='', args=None):
-        return self.gui.attach(obs_meth, sort, rename, args or [])
-
-    def detach_obs(self, obs_meth, lambda_call=None):
-        return self.gui.detach(obs_meth, lambda_call)
-
-
-class Page(GameObject, PageFacade):
+from inspect import getmro
+from ya2.lib.gui import Btn, Slider, CheckBtn, OptionMenu, Entry
+from ya2.engine.vec import Vec2
+from ya2.engine.gui.gui import left, right, up, down
+from ya2.gameobject import GameObject, GuiColleague, EventColleague
+from ya2.engine.gui.imgbtn import ImgBtn
+
+
+class PageGui(GuiColleague):
+
+    def __init__(self, mediator, menu_props, players=[0]):
+        GuiColleague.__init__(self, mediator)
+        self.enable_tsk = None
+        self._back_btn = None
+        self.menu_props = menu_props
+        self.players = players
+        self.widgets = []
+        self.build()
+        self.translate()
+        self.curr_wdgs = []
+        for player in players:
+            self.curr_wdgs += [
+                self.__next_wdg((-.1, -1), player, Vec2(-3.6, 1))]
+            if self.curr_wdgs[-1]:
+                self.curr_wdgs[-1].on_wdg_enter(None, player)
+
+    def build(self, back_btn=True, exit_behav=False):
+        if back_btn: self.__build_back_btn(exit_behav)
+        self._set_widgets()
+        self._set_entries()
+        self.transition_enter()
+        self.eng.cursor_top()
+
+    def add_widgets(self, widgets): self.widgets += widgets
+
+    def on_arrow(self, direction, player):
+        if not self.curr_wdgs[player]: return
+        if self.curr_wdgs[player].__class__.__name__ == 'P3dEntryWidget' and \
+            self.curr_wdgs[player].focused: return
+        processed_cmd = self.curr_wdgs[player].on_arrow(direction)
+        # e.g. up/down in a combobox or left/right in a slider
+        if processed_cmd: return
+        next_wdg = self.__next_wdg(direction, player)
+        if not next_wdg: return
+        self.focus(next_wdg, player)
+
+    def on_enter(self, player):
+        if not self.curr_wdgs[player]: return
+        arg = player if len(self.players) > 1 else None
+        if self.curr_wdgs[player].on_enter(arg): self.enable([player])
+        # wdg.on_enter returns True when it is an option widget
+
+    @property
+    def buttons(self):
+        is_btn = lambda wdg: Btn in getmro(wdg.__class__)
+        return [wdg for wdg in self.widgets if is_btn(wdg)]
+
+    def focus(self, wdg, player):
+        self.curr_wdgs[player].on_wdg_exit(None, player)
+        self.curr_wdgs[player] = wdg
+        self.curr_wdgs[player].on_wdg_enter(None, player)
+
+    def __direction_dot_dwg(self, wdg, direction, player, start=None):
+        if start: start_pos = start
+        else: start_pos = self.curr_wdgs[player].pos
+        return (wdg.pos - start_pos).normalized.dot(direction)
+
+    def __next_weight(self, wdg, direction, player, start=None):
+        if start: start_pos = start
+        else: start_pos = self.curr_wdgs[player].global_pos
+        dot = self.__direction_dot_dwg(wdg, direction, player, start)
+        if direction in [(-1, 0), (1, 0)]:
+            proj_dist = abs(wdg.global_pos.x - start_pos.x)
+        else: proj_dist = abs(wdg.global_pos.y - start_pos.y)
+        weights = [.5, .5] if direction in [left, right] else [.1, .9]
+        return weights[0] * (dot * dot) + weights[1] * (1 - proj_dist)
+
+    def __next_wdg(self, direction, player, start=None):
+        # interactive classes
+        iclss = [Btn, CheckBtn, Slider, OptionMenu, ImgBtn, Entry]
+        inter = lambda wdg: any(pcl in iclss for pcl in getmro(wdg.__class__))
+        allwdgs = [wdg for wdg in self.widgets if inter(wdg)]
+        wdgs = list(filter(lambda wdg: wdg.is_enabled, allwdgs))
+        if player < len(self.curr_wdgs) and self.curr_wdgs[player] \
+                and self.curr_wdgs[player] in wdgs:
+                # the last check for this case: multiple players appear on the
+                # same button, one player clicks it, another moves from it
+            wdgs.remove(self.curr_wdgs[player])
+        mth = self.__direction_dot_dwg
+        in_direction = lambda wdg: mth(wdg, direction, player, start) > .1
+        dirwdgs = list(filter(in_direction, wdgs))
+        if not dirwdgs: return None
+        nextweight = lambda wdg: \
+                     self.__next_weight(wdg, direction, player, start)
+        return max(dirwdgs, key=nextweight)
+
+    def _set_widgets(self):
+        list(map(lambda wdg: wdg.set_widget(), self.widgets))
+
+    def _set_entries(self):
+        for wdg in self.widgets:
+            if wdg.__class__.__name__ == 'P3dEntryWidget':
+                wdg.attach(self.on_entry_enter)
+                wdg.attach(self.on_entry_exit)
+
+    def on_entry_enter(self):
+        if self.menu_props:  # i.e. not destroyed
+            self.disable_navigation(self.players)
+
+    def on_entry_exit(self):
+        if self.menu_props:  # i.e. not destroyed
+            self.enable_navigation(self.players)
+
+    def transition_enter(self):
+        self.translate()
+        list(map(lambda wdg: wdg.set_enter_transition(), self.widgets))
+        self.enable(self.players)
+
+    def translate(self): list(map(lambda wdg: wdg.translate(), self.widgets))
+
+    def enable_navigation(self, players):
+        if self.enable_tsk: self.eng.rm_do_later(self.enable_tsk)
+        self.enable_tsk = self.eng.do_later(
+            .01, self.enable_navigation_aux, [players])
+
+    def update_navigation(self):
+        self.disable_navigation(self.players)
+        self.enable_navigation(self.players)
+
+    def enable_navigation_aux(self, players):
+        navs = []
+        for player in players:
+            nav = self.menu_props.nav.navinfo_lst[player]
+            evts = [
+                (self.eng.lib.remap_str(nav.left), self.on_arrow,
+                 [left, player]),
+                (self.eng.lib.remap_str(nav.right), self.on_arrow,
+                 [right, player]),
+                (self.eng.lib.remap_str(nav.up), self.on_arrow, [up, player]),
+                (self.eng.lib.remap_str(nav.down), self.on_arrow,
+                 [down, player]),
+                (self.eng.lib.remap_str(nav.fire), self.on_enter, [player])]
+            def append_up(evt): return evt + ('' if evt.endswith('-up') else '-up')
+            evts = [(append_up(evt[0]), evt[1], evt[2]) for evt in evts]
+            navs += [nav]
+            list(map(lambda args: self.mediator.event.accept(*args), evts))
+        self.eng.joystick_mgr.bind_keyboard(navs)
+        if self.eng.cfg.dev_cfg.menu_joypad and self._back_btn:
+            self.mediator.event.accept('joypad0-face_b-up', self.__back_wrapper)
+
+    def __back_wrapper(self):
+        if not self.eng.joystick_mgr.is_recording: self._back_btn['command']()
+
+    def disable_navigation(self, players):
+        if self.enable_tsk:
+            self.enable_tsk = self.eng.rm_do_later(self.enable_tsk)
+        for player in players:
+            nav = self.menu_props.nav.navinfo_lst[player]
+            # evts = [nav.left, nav.right, nav.up, nav.down, nav.fire]
+            evts = [
+                self.eng.lib.remap_str(nav.left),
+                self.eng.lib.remap_str(nav.right),
+                self.eng.lib.remap_str(nav.up),
+                self.eng.lib.remap_str(nav.down),
+                self.eng.lib.remap_str(nav.fire)]
+            def append_up(evt): return evt + ('' if evt.endswith('-up') else '-up')
+            evts = [append_up(evt) for evt in evts]
+            self.eng.joystick_mgr.unbind_keyboard()
+            list(map(self.mediator.event.ignore, evts))
+        self.mediator.event.ignore('joypad0-face_b-up')
+
+    def enable(self, players):
+        self.enable_navigation(players)
+        list(map(lambda wdg: wdg.enable(), self.widgets))
+
+    def disable(self, players):
+        if self.enable_tsk:
+            self.enable_tsk = self.eng.rm_do_later(self.enable_tsk)
+        self.disable_navigation(players)
+        list(map(lambda wdg: wdg.disable(), self.widgets))
+
+    def transition_exit(self, destroy=True):
+        list(map(lambda wdg: wdg.set_exit_transition(destroy), self.widgets))
+        self.disable(self.players)
+
+    def __build_back_btn(self, exit_behav):
+        tra_src = 'Quit' if exit_behav else 'Back'
+        tra_tra = _('Quit') if exit_behav else _('Back')
+        callback = self._on_quit if exit_behav else self._on_back
+        btn = Btn(text='', pos=(0, -.85), cmd=callback,
+                  tra_src=tra_src, tra_tra=tra_tra, **self.menu_props.btn_args)
+        self.widgets += [btn]
+        self._back_btn = btn
+
+    def _on_back(self, player=0):
+        self.notify('on_back', self.__class__.__name__)
+
+    def _on_quit(self): self.notify('on_quit', self.__class__.__name__)
+
+    def show(self):
+        visible_widgets = [wdg for wdg in self.widgets if wdg.was_visible]
+        list(map(lambda wdg: wdg.show(), visible_widgets))
+        self.transition_enter()
+
+    def hide(self):
+        for wdg in self.widgets: wdg.was_visible = not wdg.hidden
+        self.transition_exit(False)
+        self.notify('on_hide')
+
+    def destroy(self):
+        self.transition_exit()
+        self.menu_props = None
+
+
+class PageEvent(EventColleague):
+
+    def on_back(self): pass
+
+    def on_quit(self): pass
+
+
+class PageFacade:
+
+    def show(self): return self.gui.show()
+    def hide(self): return self.gui.hide()
+    def enable(self, players): return self.gui.enable(players)
+    def disable(self, players): return self.gui.disable(players)
+
+    def enable_navigation(self, players):
+        return self.gui.enable_navigation(players)
+
+    def disable_navigation(self, players):
+        return self.gui.disable_navigation(players)
+
+    def attach_obs(self, obs_meth, sort=10, rename='', args=None):
+        return self.gui.attach(obs_meth, sort, rename, args or [])
+
+    def detach_obs(self, obs_meth, lambda_call=None):
+        return self.gui.detach(obs_meth, lambda_call)
+
+
+class Page(GameObject, PageFacade):
 
-    gui_cls = PageGui
-    event_cls = PageEvent
+    gui_cls = PageGui
+    event_cls = PageEvent
 
-    def __init__(self, menu_props, players=[0]):
-        PageFacade.__init__(self)
-        self.menu_props = menu_props
-        self.players = players
-        GameObject.__init__(self)
-        self._build_event()
-        self._build_gui()
-        list(map(self.gui.attach, [self.on_hide, self.on_back, self.on_quit]))
+    def __init__(self, menu_props, players=[0]):
+        PageFacade.__init__(self)
+        self.menu_props = menu_props
+        self.players = players
+        GameObject.__init__(self)
+        self._build_event()
+        self._build_gui()
+        list(map(self.gui.attach, [self.on_hide, self.on_back, self.on_quit]))
 
-    def _build_event(self):
-        self.event = self.event_cls(self)
+    def _build_event(self):
+        self.event = self.event_cls(self)
 
-    def _build_gui(self):
-        self.gui = self.gui_cls(self, self.menu_props, self.players)
+    def _build_gui(self):
+        self.gui = self.gui_cls(self, self.menu_props, self.players)
 
-    def on_hide(self): self.event.ignoreAll()
+    def on_hide(self): self.event.ignoreAll()
 
-    def on_back(self, cls_name, args=None): self.event.on_back()  # unused arg
+    def on_back(self, cls_name, args=None): self.event.on_back()  # unused arg
 
-    def on_quit(self, cls_name): self.event.on_quit()  # unused arg
+    def on_quit(self, cls_name): self.event.on_quit()  # unused arg
 
-    def destroy(self):
-        self.event.destroy()
-        self.gui.destroy()
-        bases = [basecls for basecls in Page.__bases__
-                 if basecls != PageFacade]
-        for cls in bases: cls.destroy(self)
+    def destroy(self):
+        self.event.destroy()
+        self.gui.destroy()
+        bases = [basecls for basecls in Page.__bases__
+                 if basecls != PageFacade]
+        for cls in bases: cls.destroy(self)
index 008943e474410ea828b22f21d326d55b713c3faa..674551dc90b9f3b91fe25c4a1c6f09b779164439 100644 (file)
-from ya2.gameobject import GameObject
-from ya2.lib.p3d.joystick import P3dJoystickMgr as JoystickMgrLib
+from ya2.gameobject import GameObject
+from ya2.lib.p3d.joystick import P3dJoystickMgr as JoystickMgrLib
 
 
-class JoystickState:
+class JoystickState:
 
-    def __init__(self):
-        self.x = self.y = self.b0 = self.b1 = self.b2 = self.b3 = \
-            self.dpad_l = self.dpad_r = self.dpad_u = self.dpad_d = \
-            self.ltrigger = self.rtrigger = self.ltrigger_known = \
-            self.rtrigger_known = self.lshoulder = self.rshoulder = \
-            self.lstick = self.rstick = 0
-        #TODO: rename bi to btni
+    def __init__(self):
+        self.x = self.y = self.b0 = self.b1 = self.b2 = self.b3 = \
+            self.dpad_l = self.dpad_r = self.dpad_u = self.dpad_d = \
+            self.ltrigger = self.rtrigger = self.ltrigger_known = \
+            self.rtrigger_known = self.lshoulder = self.rshoulder = \
+            self.lstick = self.rstick = 0
+        #TODO: rename bi to btni
 
 
-class JoystickMgr(GameObject):
+class JoystickMgr(GameObject):
 
-    def __init__(self, emulate_keyboard, functional_test):
-        GameObject.__init__(self)
-        self.emulate_keyboard = emulate_keyboard
-        self._fun_tst = functional_test
-        self.old = [JoystickState() for i in range(3)]
-        self.nav = None
-        self.is_recording = False
-        self.joystick_lib = JoystickMgrLib()
-        self.joystick_lib.init_joystick()
-        self.eng.do_later(.01, self.eng.attach_obs, [self.on_frame])
-        # eng.event doesn't exist
-        #if self.emulate_keyboard:
-        self.set_keyboard_emulation()
+    def __init__(self, emulate_keyboard, functional_test):
+        GameObject.__init__(self)
+        self.emulate_keyboard = emulate_keyboard
+        self._fun_tst = functional_test
+        self.old = [JoystickState() for i in range(3)]
+        self.nav = None
+        self.is_recording = False
+        self.joystick_lib = JoystickMgrLib()
+        self.joystick_lib.init_joystick()
+        self.eng.do_later(.01, self.eng.attach_obs, [self.on_frame])
+        # eng.event doesn't exist
+        #if self.emulate_keyboard:
+        self.set_keyboard_emulation()
 
-    def set_keyboard_emulation(self):
-        num_joysticks =1 if self._fun_tst else self.joystick_lib.num_joysticks
-        for i in range(num_joysticks):
-            base.accept('joypad%s-dpad_left-up' % i, self.__keyb_evt, [i, 'left'])
-            base.accept('joypad%s-dpad_right-up' % i, self.__keyb_evt, [i, 'right'])
-            base.accept('joypad%s-dpad_up-up' % i, self.__keyb_evt, [i, 'up'])
-            base.accept('joypad%s-dpad_down-up' % i, self.__keyb_evt, [i, 'down'])
-            base.accept('joypad%s-face_a-up' % i, self.__keyb_evt, [i, 'fire'])
+    def set_keyboard_emulation(self):
+        num_joysticks =1 if self._fun_tst else self.joystick_lib.num_joysticks
+        for i in range(num_joysticks):
+            base.accept('joypad%s-dpad_left-up' % i, self.__keyb_evt, [i, 'left'])
+            base.accept('joypad%s-dpad_right-up' % i, self.__keyb_evt, [i, 'right'])
+            base.accept('joypad%s-dpad_up-up' % i, self.__keyb_evt, [i, 'up'])
+            base.accept('joypad%s-dpad_down-up' % i, self.__keyb_evt, [i, 'down'])
+            base.accept('joypad%s-face_a-up' % i, self.__keyb_evt, [i, 'fire'])
 
-    def __keyb_evt(self, i, evt):
-        if not self.is_recording and self.nav:
-            self.eng.send(str(getattr(self.nav[i], evt)) + '-up')
-            # if the user chose a number
+    def __keyb_evt(self, i, evt):
+        if not self.is_recording and self.nav:
+            self.eng.send(str(getattr(self.nav[i], evt)) + '-up')
+            # if the user chose a number
 
-    def on_frame(self):
-        #if not self.emulate_keyboard: return
-        for i in range(self.joystick_lib.num_joysticks): self.__process(i)
+    def on_frame(self):
+        #if not self.emulate_keyboard: return
+        for i in range(self.joystick_lib.num_joysticks): self.__process(i)
 
-    def __process(self, i):
-        j_x, j_y, btn0, btn1, btn2, btn3, dpad_l, dpad_r, dpad_u, dpad_d, \
-            trigger_l, trigger_r, shoulder_l, shoulder_r, stick_l, stick_r, \
-            trigger_l_known, trigger_r_known = \
-            self.joystick_lib.get_joystick(i)
-        # if not self.is_recording:
-        #     if self.old[i].x <= -.4 <= j_x or self.old[i].dpad_l and \
-        #             not dpad_l:
-        #         if self.nav and i < len(self.nav) and self.nav[i]:
-        #             self.eng.send(self.nav[i].left)
-        #     if self.old[i].x >= .4 >= j_x or self.old[i].dpad_r and not dpad_r:
-        #         if self.nav and i < len(self.nav) and self.nav[i]:
-        #             self.eng.send(self.nav[i].right)
-        #     if self.old[i].y >= .4 >= j_y or self.old[i].dpad_d and not dpad_d:
-        #         if self.nav and i < len(self.nav) and self.nav[i]:
-        #             self.eng.send(self.nav[i].down)
-        #     if self.old[i].y <= -.4 <= j_y or self.old[i].dpad_u and not dpad_u:
-        #         if self.nav and i < len(self.nav) and self.nav[i]:
-        #             self.eng.send(self.nav[i].up)
-        # if self.old[i].b0 and not btn0:
-        #     if self.nav and i < len(self.nav) and self.nav[i] and \
-        #             not self.is_recording:
-        #         self.eng.send(self.nav[i].fire)
-        #     self.eng.send('joypad%s_face_x' % i)
-        # if self.old[i].b1 and not btn1:
-        #     self.eng.send('joypad%s_face_y' % i)
-        # if self.old[i].b2 and not btn2:
-        #     self.eng.send('joypad%s_face_a' % i)
-        # if self.old[i].b3 and not btn3:
-        #     self.eng.send('joypad%s_face_b' % i)
-        if self.old[i].ltrigger and not trigger_l and not trigger_l_known:
-            #self.eng.send('joypad_trigger_l')
-            self.eng.send('joypad%s-ltrigger-up' % i)
-        if self.old[i].rtrigger and not trigger_r and not trigger_r_known:
-            #self.eng.send('joypad_trigger_r')
-            self.eng.send('joypad%s-rtrigger-up' % i)
-        # if self.old[i].shoulder_l and not shoulder_l:
-        #     self.eng.send('joypad_shoulder_l')
-        #     self.eng.send('joypad%s_shoulder_l' % i)
-        # if self.old[i].shoulder_r and not shoulder_r:
-        #     self.eng.send('joypad_shoulder_r')
-        #     self.eng.send('joypad%s_shoulder_r' % i)
-        # if self.old[i].stick_l and not stick_l:
-        #     self.eng.send('joypad_stick_l')
-        #     self.eng.send('joypad%s_stick_l' % i)
-        # if self.old[i].stick_r and not stick_r:
-        #     self.eng.send('joypad_stick_r')
-        #     self.eng.send('joypad%s_stick_r' % i)
-        self.old[i].x, self.old[i].y, self.old[i].b0, self.old[i].b1, \
-            self.old[i].b2, self.old[i].b3, self.old[i].dpad_l, \
-            self.old[i].dpad_r, self.old[i].dpad_u, self.old[i].dpad_d, \
-            self.old[i].ltrigger, self.old[i].rtrigger, \
-            self.old[i].lshoulder, self.old[i].rshoulder, \
-            self.old[i].lstick, self.old[i].rstick = \
-            j_x, j_y, btn0, btn1, btn2, btn3, dpad_l, dpad_r, dpad_u, dpad_d, \
-            trigger_l, trigger_r, shoulder_l, shoulder_r, stick_l, stick_r
+    def __process(self, i):
+        j_x, j_y, btn0, btn1, btn2, btn3, dpad_l, dpad_r, dpad_u, dpad_d, \
+            trigger_l, trigger_r, shoulder_l, shoulder_r, stick_l, stick_r, \
+            trigger_l_known, trigger_r_known = \
+            self.joystick_lib.get_joystick(i)
+        # if not self.is_recording:
+        #     if self.old[i].x <= -.4 <= j_x or self.old[i].dpad_l and \
+        #             not dpad_l:
+        #         if self.nav and i < len(self.nav) and self.nav[i]:
+        #             self.eng.send(self.nav[i].left)
+        #     if self.old[i].x >= .4 >= j_x or self.old[i].dpad_r and not dpad_r:
+        #         if self.nav and i < len(self.nav) and self.nav[i]:
+        #             self.eng.send(self.nav[i].right)
+        #     if self.old[i].y >= .4 >= j_y or self.old[i].dpad_d and not dpad_d:
+        #         if self.nav and i < len(self.nav) and self.nav[i]:
+        #             self.eng.send(self.nav[i].down)
+        #     if self.old[i].y <= -.4 <= j_y or self.old[i].dpad_u and not dpad_u:
+        #         if self.nav and i < len(self.nav) and self.nav[i]:
+        #             self.eng.send(self.nav[i].up)
+        # if self.old[i].b0 and not btn0:
+        #     if self.nav and i < len(self.nav) and self.nav[i] and \
+        #             not self.is_recording:
+        #         self.eng.send(self.nav[i].fire)
+        #     self.eng.send('joypad%s_face_x' % i)
+        # if self.old[i].b1 and not btn1:
+        #     self.eng.send('joypad%s_face_y' % i)
+        # if self.old[i].b2 and not btn2:
+        #     self.eng.send('joypad%s_face_a' % i)
+        # if self.old[i].b3 and not btn3:
+        #     self.eng.send('joypad%s_face_b' % i)
+        if self.old[i].ltrigger and not trigger_l and not trigger_l_known:
+            #self.eng.send('joypad_trigger_l')
+            self.eng.send('joypad%s-ltrigger-up' % i)
+        if self.old[i].rtrigger and not trigger_r and not trigger_r_known:
+            #self.eng.send('joypad_trigger_r')
+            self.eng.send('joypad%s-rtrigger-up' % i)
+        # if self.old[i].shoulder_l and not shoulder_l:
+        #     self.eng.send('joypad_shoulder_l')
+        #     self.eng.send('joypad%s_shoulder_l' % i)
+        # if self.old[i].shoulder_r and not shoulder_r:
+        #     self.eng.send('joypad_shoulder_r')
+        #     self.eng.send('joypad%s_shoulder_r' % i)
+        # if self.old[i].stick_l and not stick_l:
+        #     self.eng.send('joypad_stick_l')
+        #     self.eng.send('joypad%s_stick_l' % i)
+        # if self.old[i].stick_r and not stick_r:
+        #     self.eng.send('joypad_stick_r')
+        #     self.eng.send('joypad%s_stick_r' % i)
+        self.old[i].x, self.old[i].y, self.old[i].b0, self.old[i].b1, \
+            self.old[i].b2, self.old[i].b3, self.old[i].dpad_l, \
+            self.old[i].dpad_r, self.old[i].dpad_u, self.old[i].dpad_d, \
+            self.old[i].ltrigger, self.old[i].rtrigger, \
+            self.old[i].lshoulder, self.old[i].rshoulder, \
+            self.old[i].lstick, self.old[i].rstick = \
+            j_x, j_y, btn0, btn1, btn2, btn3, dpad_l, dpad_r, dpad_u, dpad_d, \
+            trigger_l, trigger_r, shoulder_l, shoulder_r, stick_l, stick_r
 
-    def get_joystick(self, player_idx):
-        x, y, face_a, face_b, face_x, face_y, dpadl, dpadr, dpadu, dpadd, triggl, \
-            triggr, shl, shr, st_l, st_r, trl_k, trr_k= \
-            self.joystick_lib.get_joystick(player_idx)
-        jstate = JoystickState()
-        jstate.x = x
-        jstate.y = y
-        jstate.face_a = face_a
-        jstate.face_b = face_b
-        jstate.face_x = face_x
-        jstate.face_y = face_y
-        jstate.dpad_l = dpadl
-        jstate.dpad_r = dpadr
-        jstate.dpad_u = dpadu
-        jstate.dpad_d = dpadd
-        jstate.ltrigger = triggl
-        jstate.ltrigger_known = trl_k
-        jstate.rtrigger = triggr
-        jstate.rtrigger_known = trr_k
-        jstate.lshoulder = shl
-        jstate.rshoulder = shr
-        jstate.lstick = st_l
-        jstate.rstick = st_r
-        return jstate
+    def get_joystick(self, player_idx):
+        x, y, face_a, face_b, face_x, face_y, dpadl, dpadr, dpadu, dpadd, triggl, \
+            triggr, shl, shr, st_l, st_r, trl_k, trr_k= \
+            self.joystick_lib.get_joystick(player_idx)
+        jstate = JoystickState()
+        jstate.x = x
+        jstate.y = y
+        jstate.face_a = face_a
+        jstate.face_b = face_b
+        jstate.face_x = face_x
+        jstate.face_y = face_y
+        jstate.dpad_l = dpadl
+        jstate.dpad_r = dpadr
+        jstate.dpad_u = dpadu
+        jstate.dpad_d = dpadd
+        jstate.ltrigger = triggl
+        jstate.ltrigger_known = trl_k
+        jstate.rtrigger = triggr
+        jstate.rtrigger_known = trr_k
+        jstate.lshoulder = shl
+        jstate.rshoulder = shr
+        jstate.lstick = st_l
+        jstate.rstick = st_r
+        return jstate
 
-    def get_joystick_val(self, player_idx, code):
-        j_x, j_y, btn0, btn1, btn2, btn3, dpad_l, dpad_r, dpad_u, dpad_d, \
-            trigger_l, trigger_r, shoulder_l, shoulder_r, stick_l, stick_r = \
-            self.joystick_lib.get_joystick(player_idx)
-        code2val = {
-            'face_x': btn0,
-            'face_y': btn1,
-            'face_a': btn2,
-            'face_b': btn3,
-            'dpad_l': dpad_l,
-            'dpad_r': dpad_r,
-            'dpad_u': dpad_u,
-            'dpad_d': dpad_d,
-            'trigger_l': trigger_l,
-            'trigger_r': trigger_r,
-            'shoulder_l': shoulder_l,
-            'shoulder_r': shoulder_r,
-            'stick_l': stick_l,
-            'stick_r': stick_r}
-        return code2val[code]
+    def get_joystick_val(self, player_idx, code):
+        j_x, j_y, btn0, btn1, btn2, btn3, dpad_l, dpad_r, dpad_u, dpad_d, \
+            trigger_l, trigger_r, shoulder_l, shoulder_r, stick_l, stick_r = \
+            self.joystick_lib.get_joystick(player_idx)
+        code2val = {
+            'face_x': btn0,
+            'face_y': btn1,
+            'face_a': btn2,
+            'face_b': btn3,
+            'dpad_l': dpad_l,
+            'dpad_r': dpad_r,
+            'dpad_u': dpad_u,
+            'dpad_d': dpad_d,
+            'trigger_l': trigger_l,
+            'trigger_r': trigger_r,
+            'shoulder_l': shoulder_l,
+            'shoulder_r': shoulder_r,
+            'stick_l': stick_l,
+            'stick_r': stick_r}
+        return code2val[code]
 
-    def bind_keyboard(self, nav): self.nav = nav
+    def bind_keyboard(self, nav): self.nav = nav
 
-    def unbind_keyboard(self): self.nav = None
+    def unbind_keyboard(self): self.nav = None
 
-    def destroy(self):
-        try: self.eng.detach_obs(self.on_frame)
-        except KeyError: pass
-        # it happens in unit tests since it destroys in the same frame
-        # remove this catch when i've refactored the object's building
-        # and i don't use the director anymore
-        self.joystick_lib.destroy()
-        GameObject.destroy(self)
+    def destroy(self):
+        try: self.eng.detach_obs(self.on_frame)
+        except KeyError: pass
+        # it happens in unit tests since it destroys in the same frame
+        # remove this catch when i've refactored the object's building
+        # and i don't use the director anymore
+        self.joystick_lib.destroy()
+        GameObject.destroy(self)
index 347429199044ea2e1bc5be55c462a380599f76f0..87aecd37111a5dcf3c978dc8b46033c1d472203f 100755 (executable)
@@ -1,77 +1,77 @@
-from os.path import exists
-from logging import info
-from sys import argv
-from ya2.gameobject import LogicColleague
-from ya2.engine.configuration import Cfg
-from ya2.gameobject import GameObject
-from ya2.computer_proxy import ComputerProxy, compute_once
+from os.path import exists
+from logging import info
+from sys import argv
+from ya2.gameobject import LogicColleague
+from ya2.engine.configuration import Cfg
+from ya2.gameobject import GameObject
+from ya2.computer_proxy import ComputerProxy, compute_once
 
 
-class VersionChecker(GameObject, ComputerProxy):
+class VersionChecker(GameObject, ComputerProxy):
 
-    def __init__(self):
-        GameObject.__init__(self)
-        ComputerProxy.__init__(self)
+    def __init__(self):
+        GameObject.__init__(self)
+        ComputerProxy.__init__(self)
 
-    @compute_once
-    def is_uptodate(self):
-        return True  # currently the server part is not active
-        self.eng.client.register_rpc('srv_version')
-        try: ver = self.eng.client.srv_version()
-        except AttributeError:
-            print("can't retrieve the version")
-            return True
-        major, minor, build = ver.split('.')
-        major, minor, build = int(major), int(minor), int(build)
-        curr_ver = self.eng.version
-        if curr_ver == 'deploy-ng': return True
-        info('versions: %s %s' % (curr_ver, ver))
-        return curr_ver >= ver
-        # curr_major, curr_minor, curr_build = curr_ver.split('-')[0].split('.')
-        # curr_major = int(curr_major)
-        # curr_minor = int(curr_minor)
-        # curr_build = int(curr_build)
-        # return curr_major > major or \
-        #     curr_major == major and curr_minor > minor or \
-        #     curr_major == major and curr_minor == minor and curr_build >= build
+    @compute_once
+    def is_uptodate(self):
+        return True  # currently the server part is not active
+        self.eng.client.register_rpc('srv_version')
+        try: ver = self.eng.client.srv_version()
+        except AttributeError:
+            print("can't retrieve the version")
+            return True
+        major, minor, build = ver.split('.')
+        major, minor, build = int(major), int(minor), int(build)
+        curr_ver = self.eng.version
+        if curr_ver == 'deploy-ng': return True
+        info('versions: %s %s' % (curr_ver, ver))
+        return curr_ver >= ver
+        # curr_major, curr_minor, curr_build = curr_ver.split('-')[0].split('.')
+        # curr_major = int(curr_major)
+        # curr_minor = int(curr_minor)
+        # curr_build = int(curr_build)
+        # return curr_major > major or \
+        #     curr_major == major and curr_minor > minor or \
+        #     curr_major == major and curr_minor == minor and curr_build >= build
 
-    def destroy(self):
-        GameObject.destroy(self)
-        # ComputerProxy.destroy(self)  # raises an exception
+    def destroy(self):
+        GameObject.destroy(self)
+        # ComputerProxy.destroy(self)  # raises an exception
 
 
-class EngineLogic(LogicColleague):
+class EngineLogic(LogicColleague):
 
-    @staticmethod
-    def cmd_line():
-        return [arg for arg in iter(argv[1:]) if not arg.startswith('-psn_')]
+    @staticmethod
+    def cmd_line():
+        return [arg for arg in iter(argv[1:]) if not arg.startswith('-psn_')]
 
-    def __init__(self, mediator, cfg=None):
-        LogicColleague.__init__(self, mediator)
-        self.cfg = cfg or Cfg()  # use a default conf if not provided
+    def __init__(self, mediator, cfg=None):
+        LogicColleague.__init__(self, mediator)
+        self.cfg = cfg or Cfg()  # use a default conf if not provided
 
-    @property
-    def version(self):
-        #if not self.is_runtime:
-        #    if not exists('assets/version.txt'): return '-'
-        #    with open('assets/version.txt') as fver:
-        #        return fver.read().strip() + '-source'
-        # ^ --version goes here
-        return self.mediator.lib.build_version
+    @property
+    def version(self):
+        #if not self.is_runtime:
+        #    if not exists('assets/version.txt'): return '-'
+        #    with open('assets/version.txt') as fver:
+        #        return fver.read().strip() + '-source'
+        # ^ --version goes here
+        return self.mediator.lib.build_version
 
-    @property
-    def is_runtime(self):
-        return self.mediator.lib.runtime()
+    @property
+    def is_runtime(self):
+        return self.mediator.lib.runtime()
 
-    @property
-    def curr_path(self):
-        return self.mediator.lib.curr_path + '/' \
-            if self.is_runtime else ''
+    @property
+    def curr_path(self):
+        return self.mediator.lib.curr_path + '/' \
+            if self.is_runtime else ''
 
-    @property
-    def is_appimage(self):
-        return self.mediator.lib.is_appimage
+    @property
+    def is_appimage(self):
+        return self.mediator.lib.is_appimage
 
-    def destroy(self):
-        self.cfg = None
-        LogicColleague.destroy(self)
+    def destroy(self):
+        self.cfg = None
+        LogicColleague.destroy(self)
index 50126d4d6d7db9ab96fc74edf4e2f54f4d0aef0b..8234bf5bb2fc7da7c0dc33219b6259d2b03fec3c 100644 (file)
-from struct import Struct, calcsize, unpack
+from struct import Struct, calcsize, unpack
 
 
-class BinaryData:
+class BinaryData:
 
-    @staticmethod
-    def pack(lst):
-        acc_fmt = '!'
-        acc_elems = []
-        acc_header = ''
-        acc_header = BinaryData._header_lst(lst, acc_header)
-        lst = [acc_header] + lst
-        acc_fmt, acc_elems = BinaryData._pack_lst(lst, acc_fmt, acc_elems)
-        msg_struct = Struct(acc_fmt)
-        msg_data = msg_struct.pack(*acc_elems)
-        return msg_struct.size, msg_data
+    @staticmethod
+    def pack(lst):
+        acc_fmt = '!'
+        acc_elems = []
+        acc_header = ''
+        acc_header = BinaryData._header_lst(lst, acc_header)
+        lst = [acc_header] + lst
+        acc_fmt, acc_elems = BinaryData._pack_lst(lst, acc_fmt, acc_elems)
+        msg_struct = Struct(acc_fmt)
+        msg_data = msg_struct.pack(*acc_elems)
+        return msg_struct.size, msg_data
 
-    @staticmethod
-    def _header_elm(elm, acc_header):
-        if elm is None: add = 'n'
-        elif isinstance(elm, bool): add = 'b'
-        elif isinstance(elm, int): add = 'i'
-        elif isinstance(elm, float): add = 'f'
-        elif isinstance(elm, str): add = 's'
-        elif isinstance(elm, dict): add = '{}'
-        elif isinstance(elm, tuple) or isinstance(elm, list):
-            add = BinaryData._header_lst(elm, acc_header)
-        return acc_header + add
+    @staticmethod
+    def _header_elm(elm, acc_header):
+        if elm is None: add = 'n'
+        elif isinstance(elm, bool): add = 'b'
+        elif isinstance(elm, int): add = 'i'
+        elif isinstance(elm, float): add = 'f'
+        elif isinstance(elm, str): add = 's'
+        elif isinstance(elm, dict): add = '{}'
+        elif isinstance(elm, tuple) or isinstance(elm, list):
+            add = BinaryData._header_lst(elm, acc_header)
+        return acc_header + add
 
-    @staticmethod
-    def _header_lst(elm, acc_header):
-        add = '('
-        for sub_elm in elm:
-            add += BinaryData._header_elm(sub_elm, acc_header)
-        add += ')'
-        return acc_header + add
+    @staticmethod
+    def _header_lst(elm, acc_header):
+        add = '('
+        for sub_elm in elm:
+            add += BinaryData._header_elm(sub_elm, acc_header)
+        add += ')'
+        return acc_header + add
 
-    @staticmethod
-    def _pack_lst(lst, acc_fmt, acc_elems):
-        add_fmt, add_elems = '', []
-        for sub_elm in lst:
-            elm_fmt, elm_elems = BinaryData._pack_elm(sub_elm, '', [])
-            add_fmt += elm_fmt
-            add_elems += elm_elems
-        return acc_fmt + add_fmt, acc_elems + add_elems
+    @staticmethod
+    def _pack_lst(lst, acc_fmt, acc_elems):
+        add_fmt, add_elems = '', []
+        for sub_elm in lst:
+            elm_fmt, elm_elems = BinaryData._pack_elm(sub_elm, '', [])
+            add_fmt += elm_fmt
+            add_elems += elm_elems
+        return acc_fmt + add_fmt, acc_elems + add_elems
 
-    @staticmethod
-    def _pack_elm(elm, acc_fmt, acc_elems):
-        if elm is None:
-            add_fmt = ''
-            add_elems = []
-        elif isinstance(elm, bool):
-            add_fmt = '?'
-            add_elems = [elm]
-        elif isinstance(elm, int):
-            add_fmt = 'i'
-            add_elems = [elm]
-        elif isinstance(elm, float):
-            add_fmt = 'f'
-            add_elems = [elm]
-        elif isinstance(elm, str):
-            b_str = bytes(elm, 'utf-8')
-            add_fmt = 'i%ds' % len(b_str)
-            add_elems = [len(b_str), b_str]
-        elif isinstance(elm, tuple) or isinstance(elm, list):
-            add_fmt, add_elems = BinaryData._pack_lst(elm, '', [])
-        elif isinstance(elm, dict): add_fmt, add_elems = '', []
-        return acc_fmt + add_fmt, acc_elems + add_elems
+    @staticmethod
+    def _pack_elm(elm, acc_fmt, acc_elems):
+        if elm is None:
+            add_fmt = ''
+            add_elems = []
+        elif isinstance(elm, bool):
+            add_fmt = '?'
+            add_elems = [elm]
+        elif isinstance(elm, int):
+            add_fmt = 'i'
+            add_elems = [elm]
+        elif isinstance(elm, float):
+            add_fmt = 'f'
+            add_elems = [elm]
+        elif isinstance(elm, str):
+            b_str = bytes(elm, 'utf-8')
+            add_fmt = 'i%ds' % len(b_str)
+            add_elems = [len(b_str), b_str]
+        elif isinstance(elm, tuple) or isinstance(elm, list):
+            add_fmt, add_elems = BinaryData._pack_lst(elm, '', [])
+        elif isinstance(elm, dict): add_fmt, add_elems = '', []
+        return acc_fmt + add_fmt, acc_elems + add_elems
 
-    @staticmethod
-    def unpack(data):
-        header_length, data = BinaryData.unpack_helper('!i', data)
-        header_length = header_length[0]
-        header, data = BinaryData.unpack_helper('!%ds' % header_length, data)
-        header = header[0].decode('utf-8')
-        vals = []
-        curr_lst = vals
+    @staticmethod
+    def unpack(data):
+        header_length, data = BinaryData.unpack_helper('!i', data)
+        header_length = header_length[0]
+        header, data = BinaryData.unpack_helper('!%ds' % header_length, data)
+        header = header[0].decode('utf-8')
+        vals = []
+        curr_lst = vals
 
-        def parent(sublist, lst):
-            if sublist in lst: return lst
-            for _subl in [elm for elm in lst if isinstance(elm, list)]:
-                if parent(sublist, _subl): return parent(sublist, _subl)
-        for elm in header:
-            if elm == '(':
-                curr_lst += [[]]
-                curr_lst = curr_lst[-1]
-            elif elm == ')':
-                curr_lst = parent(curr_lst, vals)
-            elif elm == '{': pass
-            elif elm == '}': curr_lst += [{}]
-            else:
-                val, data = BinaryData._unpack_elm(elm, data)
-                curr_lst += [val]
-        return vals[0]
+        def parent(sublist, lst):
+            if sublist in lst: return lst
+            for _subl in [elm for elm in lst if isinstance(elm, list)]:
+                if parent(sublist, _subl): return parent(sublist, _subl)
+        for elm in header:
+            if elm == '(':
+                curr_lst += [[]]
+                curr_lst = curr_lst[-1]
+            elif elm == ')':
+                curr_lst = parent(curr_lst, vals)
+            elif elm == '{': pass
+            elif elm == '}': curr_lst += [{}]
+            else:
+                val, data = BinaryData._unpack_elm(elm, data)
+                curr_lst += [val]
+        return vals[0]
 
-    @staticmethod
-    def _unpack_elm(elm, data):
-        if elm == 'n':
-            val, data = [None], data
-            val = val[0]
-        elif elm == 'b':
-            val, data = BinaryData.unpack_helper('!?', data)
-            val = val[0]
-        elif elm == 'i':
-            val, data = BinaryData.unpack_helper('!i', data)
-            val = val[0]
-        elif elm == 'f':
-            val, data = BinaryData.unpack_helper('!f', data)
-            val = val[0]
-        elif elm == 's':
-            s_len, data = BinaryData.unpack_helper('!i', data)
-            val, data = BinaryData.unpack_helper('!%ds' % s_len, data)
-            val = val[0].decode('utf-8')
-        return val, data
+    @staticmethod
+    def _unpack_elm(elm, data):
+        if elm == 'n':
+            val, data = [None], data
+            val = val[0]
+        elif elm == 'b':
+            val, data = BinaryData.unpack_helper('!?', data)
+            val = val[0]
+        elif elm == 'i':
+            val, data = BinaryData.unpack_helper('!i', data)
+            val = val[0]
+        elif elm == 'f':
+            val, data = BinaryData.unpack_helper('!f', data)
+            val = val[0]
+        elif elm == 's':
+            s_len, data = BinaryData.unpack_helper('!i', data)
+            val, data = BinaryData.unpack_helper('!%ds' % s_len, data)
+            val = val[0].decode('utf-8')
+        return val, data
 
-    @staticmethod
-    def unpack_helper(fmt, data):
-        size = calcsize(fmt)
-        return unpack(fmt, data[:size]), data[size:]
+    @staticmethod
+    def unpack_helper(fmt, data):
+        size = calcsize(fmt)
+        return unpack(fmt, data[:size]), data[size:]
index 1bc971ff4f04826c5bbaefe49791099b6345bd05..be39dc21389452065a1ecc5dbe05beb7d2076466 100644 (file)
@@ -1,63 +1,63 @@
-from queue import Queue
-from ya2.engine.network.network import AbsNetwork, NetworkThread, msg_rpc_call
-from ya2.engine.network.binary import BinaryData
+from queue import Queue
+from ya2.engine.network.network import AbsNetwork, NetworkThread, msg_rpc_call
+from ya2.engine.network.binary import BinaryData
 
 
-class ClientThread(NetworkThread):
+class ClientThread(NetworkThread):
 
-    def __init__(self, srv_addr, eng, port):
-        self.srv_addr = srv_addr
-        NetworkThread.__init__(self, eng, port)
-        self.msgs = Queue()
-        self.rpc_ret = Queue()
+    def __init__(self, srv_addr, eng, port):
+        self.srv_addr = srv_addr
+        NetworkThread.__init__(self, eng, port)
+        self.msgs = Queue()
+        self.rpc_ret = Queue()
 
-    def _configure_socket(self):
-        self.tcp_sock.connect((self.srv_addr, self.port))
+    def _configure_socket(self):
+        self.tcp_sock.connect((self.srv_addr, self.port))
 
-    def _rpc_cb(self, data, sock):
-        self.rpc_ret.put(data)
+    def _rpc_cb(self, data, sock):
+        self.rpc_ret.put(data)
 
-    def _queue(self, sock):
-        return self.msgs
+    def _queue(self, sock):
+        return self.msgs
 
-    def send_msg(self, msg, receiver=None): self.msgs.put(msg)
+    def send_msg(self, msg, receiver=None): self.msgs.put(msg)
 
-    def do_rpc(self, funcname, *args, **kwargs):
-        args = list(args)
-        msg_size, msg_data = BinaryData.pack(
-            [msg_rpc_call, funcname, args, kwargs])
-        self.msgs.put((msg_size, msg_data))
-        return self.rpc_ret.get()
+    def do_rpc(self, funcname, *args, **kwargs):
+        args = list(args)
+        msg_size, msg_data = BinaryData.pack(
+            [msg_rpc_call, funcname, args, kwargs])
+        self.msgs.put((msg_size, msg_data))
+        return self.rpc_ret.get()
 
 
-class Client(AbsNetwork):
+class Client(AbsNetwork):
 
-    def __init__(self, port, srv_addr):
-        AbsNetwork.__init__(self, port)
-        self.srv_addr = srv_addr
-        self._functions = []
+    def __init__(self, port, srv_addr):
+        AbsNetwork.__init__(self, port)
+        self.srv_addr = srv_addr
+        self._functions = []
 
-    def start(self, read_cb):
-        return AbsNetwork.start(self, read_cb)
+    def start(self, read_cb):
+        return AbsNetwork.start(self, read_cb)
 
-    def _bld_netw_thr(self):
-        srv, port = self.srv_addr.split(':')
-        return ClientThread(srv, self.eng, int(port))
+    def _bld_netw_thr(self):
+        srv, port = self.srv_addr.split(':')
+        return ClientThread(srv, self.eng, int(port))
 
-    def _configure_udp(self): pass
+    def _configure_udp(self): pass
 
-    def send_udp(self, data_lst, sender):
-        host, port = self.srv_addr.split(':')
-        msg_size, msg_data = BinaryData.pack([sender] + data_lst)
-        self.udp_sock.sendto(msg_data, (host, int(port)))
+    def send_udp(self, data_lst, sender):
+        host, port = self.srv_addr.split(':')
+        msg_size, msg_data = BinaryData.pack([sender] + data_lst)
+        self.udp_sock.sendto(msg_data, (host, int(port)))
 
-    def register_rpc(self, funcname): self._functions += [funcname]
+    def register_rpc(self, funcname): self._functions += [funcname]
 
-    def unregister_rpc(self, funcname): self._functions.remove(funcname)
+    def unregister_rpc(self, funcname): self._functions.remove(funcname)
 
-    def __getattr__(self, attr):
-        if attr not in self._functions: raise AttributeError(attr)
+    def __getattr__(self, attr):
+        if attr not in self._functions: raise AttributeError(attr)
 
-        def do_rpc(*args, **kwargs):
-            return self.netw_thr.do_rpc(attr, *args, **kwargs)
-        return do_rpc
+        def do_rpc(*args, **kwargs):
+            return self.netw_thr.do_rpc(attr, *args, **kwargs)
+        return do_rpc
index f1e015c5032ae77b601bb628469a4eafa0726ff9..b9d32e7183d71a1c95fd94c024c8af2c646ca82e 100644 (file)
-from socket import socket, AF_INET, SOCK_DGRAM, error, SOCK_STREAM, \
-    SOL_SOCKET, SO_REUSEADDR
-from traceback import print_exc
-from logging import info
-from select import select
-from time import sleep
-from queue import Empty
-from threading import Thread
-from struct import Struct, error as unpack_error
-from _thread import interrupt_main
-from ya2.gameobject import GameObject
-from ya2.engine.network.binary import BinaryData
-
-
-msg_rpc_call, msg_rpc_answ = range(2)
-
-
-class _ConnectionError(Exception): pass
-
-
-class NetworkThread(Thread):
-
-    def __init__(self, eng, port):
-        Thread.__init__(self)
-        self.port = port
-        self.daemon = True
-        self.eng = eng
-        self.is_running = True
-        self.size_struct = Struct('!I')
-        self.tcp_sock = socket(AF_INET, SOCK_STREAM)
-        self.tcp_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
-        self._configure_socket()
-        self.connections = [self.tcp_sock]
-
-    def run(self):
-        while self.is_running:
-            sleep(.001)
-            try:
-                readable, writable, exceptional = select(
-                    self.connections, self.connections, self.connections, 1)
-                for sock in readable: self._process_read(sock)
-                for sock in writable: self._process_write(sock)
-                for sock in exceptional: print('exception', sock.getpeername())
-            except (error, AttributeError) as exc: print_exc()
-            # AttributeError happens when the server user exits from a race,
-            # then destroy is being called but _process_read is still alive
-            # and self.eng.cb_mux.add_cb is invoked, but self.eng in None
-            except Exception as exc:
-                print_exc()
-                interrupt_main()
-
-    def _process_read(self, sock):
-        try:
-            data = self.recv_one_msg(sock)
-            if data:
-                try:
-                    msg = BinaryData.unpack(data)
-                    if msg[0] == msg_rpc_call:
-                        funcname, args, kwargs = msg[1:]
-                        self._rpc_cb(funcname, args, kwargs, sock)
-                    elif msg[0] == msg_rpc_answ:
-                        self._rpc_cb(msg[1], sock)
-                    else:
-                        args = [msg, sock]
-                        self.eng.cb_mux.add_cb(self.read_cb, args)
-                except unpack_error as exc:
-                    print(exc)
-                    print_exc()
-        except (_ConnectionError, TypeError) as exc:
-            print_exc()
-            self.notify('on_disconnected', sock)
-            self.connections.remove(sock)
-
-    def _process_write(self, sock):
-        try:
-            msg_size, msg_data = self._queue(sock).get_nowait()
-            sock.sendall(self.size_struct.pack(msg_size))
-            sock.sendall(msg_data)
-        except Empty: pass
-
-    def recv_one_msg(self, sock):
-        lengthbuf = self.recvall(sock, self.size_struct.size)
-        try: length = self.size_struct.unpack(lengthbuf)[0]
-        except unpack_error as exc:
-            print(exc)
-            raise _ConnectionError()
-        return self.recvall(sock, length)
-
-    @staticmethod
-    def recvall(sock, cnt):
-        buf = b''
-        while cnt:
-            newbuf = sock.recv(cnt)
-            if not newbuf: return None
-            buf, cnt = buf + newbuf, cnt - len(newbuf)
-        return buf
-
-    def destroy(self):
-        self.is_running = False
-        self.tcp_sock.close()
-        self.eng = self.tcp_sock = self.connections = None
-
-
-class AbsNetwork(GameObject):
-
-    rate = .1
-    _public_addr = None
-    _local_addr = None
-
-    def __init__(self, port):
-        GameObject.__init__(self)
-        self.netw_thr = self.read_cb = self.udp_sock = self.tcp_sock = \
-            self.udp_sock = None
-        self.port = port
-        self.addr2conn = {}
-
-    def start(self, read_cb):
-        self.eng.attach_obs(self.on_frame, 1)
-        self.read_cb = read_cb
-        self.udp_sock = socket(AF_INET, SOCK_DGRAM)
-        self.udp_sock.setblocking(0)
-        self._configure_udp()
-        try:
-            self.netw_thr = self._bld_netw_thr()
-            self.netw_thr.start()
-            self.netw_thr.read_cb = read_cb
-            args = self.__class__.__name__, self.port
-            info('%s is up, port %s' % args)
-            return True
-        except ValueError:  # e.g. empty server
-            info("can't start the network")
-
-    def register_cb(self, callback):
-        self.read_cb = callback
-        self.netw_thr.read_cb = callback
-
-    def send(self, data_lst, receiver=None):
-        dgram = BinaryData.pack(data_lst)
-        self.netw_thr.send_msg(dgram, receiver)
-
-    def on_frame(self): self.process_udp()
-
-    @property
-    def is_active(self):
-        observers = self.eng.event.observers.values()
-        return self.on_frame in [obs.mth for olst in observers for obs in olst]
-
-    def stop(self):
-        if not self.netw_thr:
-            info('%s was already stopped' % self.__class__.__name__)
-            return
-        self.udp_sock.close()
-        self.netw_thr.destroy()
-        self.udp_sock = self.tcp_sock = self.netw_thr = None
-        self.eng.detach_obs(self.on_frame)
-        self.addr2conn = {}
-        info('%s has been stopped' % self.__class__.__name__)
-
-    def process_udp(self):
-        try: dgram, conn = self.udp_sock.recvfrom(8192)
-        except error: return
-        self.on_udp_pck(dgram, conn)
-        dgram = BinaryData.unpack(dgram)
-        sender, payload = dgram[0], dgram[1:]
-        self.read_cb(payload, conn)
-
-    def on_udp_pck(self, dgram, conn): pass
-
-    def destroy(self):
-        self.stop()
-        info('%s has been destroyed' % self.__class__.__name__)
-        GameObject.destroy(self)
+from socket import socket, AF_INET, SOCK_DGRAM, error, SOCK_STREAM, \
+    SOL_SOCKET, SO_REUSEADDR
+from traceback import print_exc
+from logging import info
+from select import select
+from time import sleep
+from queue import Empty
+from threading import Thread
+from struct import Struct, error as unpack_error
+from _thread import interrupt_main
+from ya2.gameobject import GameObject
+from ya2.engine.network.binary import BinaryData
+
+
+msg_rpc_call, msg_rpc_answ = range(2)
+
+
+class _ConnectionError(Exception): pass
+
+
+class NetworkThread(Thread):
+
+    def __init__(self, eng, port):
+        Thread.__init__(self)
+        self.port = port
+        self.daemon = True
+        self.eng = eng
+        self.is_running = True
+        self.size_struct = Struct('!I')
+        self.tcp_sock = socket(AF_INET, SOCK_STREAM)
+        self.tcp_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
+        self._configure_socket()
+        self.connections = [self.tcp_sock]
+
+    def run(self):
+        while self.is_running:
+            sleep(.001)
+            try:
+                readable, writable, exceptional = select(
+                    self.connections, self.connections, self.connections, 1)
+                for sock in readable: self._process_read(sock)
+                for sock in writable: self._process_write(sock)
+                for sock in exceptional: print('exception', sock.getpeername())
+            except (error, AttributeError) as exc: print_exc()
+            # AttributeError happens when the server user exits from a race,
+            # then destroy is being called but _process_read is still alive
+            # and self.eng.cb_mux.add_cb is invoked, but self.eng in None
+            except Exception as exc:
+                print_exc()
+                interrupt_main()
+
+    def _process_read(self, sock):
+        try:
+            data = self.recv_one_msg(sock)
+            if data:
+                try:
+                    msg = BinaryData.unpack(data)
+                    if msg[0] == msg_rpc_call:
+                        funcname, args, kwargs = msg[1:]
+                        self._rpc_cb(funcname, args, kwargs, sock)
+                    elif msg[0] == msg_rpc_answ:
+                        self._rpc_cb(msg[1], sock)
+                    else:
+                        args = [msg, sock]
+                        self.eng.cb_mux.add_cb(self.read_cb, args)
+                except unpack_error as exc:
+                    print(exc)
+                    print_exc()
+        except (_ConnectionError, TypeError) as exc:
+            print_exc()
+            self.notify('on_disconnected', sock)
+            self.connections.remove(sock)
+
+    def _process_write(self, sock):
+        try:
+            msg_size, msg_data = self._queue(sock).get_nowait()
+            sock.sendall(self.size_struct.pack(msg_size))
+            sock.sendall(msg_data)
+        except Empty: pass
+
+    def recv_one_msg(self, sock):
+        lengthbuf = self.recvall(sock, self.size_struct.size)
+        try: length = self.size_struct.unpack(lengthbuf)[0]
+        except unpack_error as exc:
+            print(exc)
+            raise _ConnectionError()
+        return self.recvall(sock, length)
+
+    @staticmethod
+    def recvall(sock, cnt):
+        buf = b''
+        while cnt:
+            newbuf = sock.recv(cnt)
+            if not newbuf: return None
+            buf, cnt = buf + newbuf, cnt - len(newbuf)
+        return buf
+
+    def destroy(self):
+        self.is_running = False
+        self.tcp_sock.close()
+        self.eng = self.tcp_sock = self.connections = None
+
+
+class AbsNetwork(GameObject):
+
+    rate = .1
+    _public_addr = None
+    _local_addr = None
+
+    def __init__(self, port):
+        GameObject.__init__(self)
+        self.netw_thr = self.read_cb = self.udp_sock = self.tcp_sock = \
+            self.udp_sock = None
+        self.port = port
+        self.addr2conn = {}
+
+    def start(self, read_cb):
+        self.eng.attach_obs(self.on_frame, 1)
+        self.read_cb = read_cb
+        self.udp_sock = socket(AF_INET, SOCK_DGRAM)
+        self.udp_sock.setblocking(0)
+        self._configure_udp()
+        try:
+            self.netw_thr = self._bld_netw_thr()
+            self.netw_thr.start()
+            self.netw_thr.read_cb = read_cb
+            args = self.__class__.__name__, self.port
+            info('%s is up, port %s' % args)
+            return True
+        except ValueError:  # e.g. empty server
+            info("can't start the network")
+
+    def register_cb(self, callback):
+        self.read_cb = callback
+        self.netw_thr.read_cb = callback
+
+    def send(self, data_lst, receiver=None):
+        dgram = BinaryData.pack(data_lst)
+        self.netw_thr.send_msg(dgram, receiver)
+
+    def on_frame(self): self.process_udp()
+
+    @property
+    def is_active(self):
+        observers = self.eng.event.observers.values()
+        return self.on_frame in [obs.mth for olst in observers for obs in olst]
+
+    def stop(self):
+        if not self.netw_thr:
+            info('%s was already stopped' % self.__class__.__name__)
+            return
+        self.udp_sock.close()
+        self.netw_thr.destroy()
+        self.udp_sock = self.tcp_sock = self.netw_thr = None
+        self.eng.detach_obs(self.on_frame)
+        self.addr2conn = {}
+        info('%s has been stopped' % self.__class__.__name__)
+
+    def process_udp(self):
+        try: dgram, conn = self.udp_sock.recvfrom(8192)
+        except error: return
+        self.on_udp_pck(dgram, conn)
+        dgram = BinaryData.unpack(dgram)
+        sender, payload = dgram[0], dgram[1:]
+        self.read_cb(payload, conn)
+
+    def on_udp_pck(self, dgram, conn): pass
+
+    def destroy(self):
+        self.stop()
+        info('%s has been destroyed' % self.__class__.__name__)
+        GameObject.destroy(self)
index da7f8b10f811627992558821ff6afc31206ec2aa..d9ae028a22f2f809e474444ba04494f80ca1cf61 100644 (file)
-from socket import error
-from queue import Queue
-from ya2.engine.network.network import AbsNetwork, NetworkThread, \
-    msg_rpc_answ
-from ya2.engine.network.binary import BinaryData
-from ya2.gameobject import GameObject
-
-
-class ServerThread(NetworkThread, GameObject):
-
-    def __init__(self, eng, rpc_cb, port):
-        NetworkThread.__init__(self, eng, port)
-        GameObject.__init__(self)
-        self.rpc_cb = rpc_cb
-        self.conn2msgs = {}
-
-    def _configure_socket(self):
-        self.tcp_sock.setblocking(0)
-        self.tcp_sock.bind(('', self.port))
-        self.tcp_sock.listen(1)
-
-    def _process_read(self, sock):
-        if sock is self.tcp_sock:
-            conn, addr = sock.accept()
-            conn.setblocking(1)  # required on osx
-            self.connections += [conn]
-            self.conn2msgs[conn] = Queue()
-            self.notify('on_connected', conn)
-        else:
-            NetworkThread._process_read(self, sock)
-
-    def _rpc_cb(self, funcname, args, kwargs, sock):
-        self.eng.cb_mux.add_cb(self.rpc_cb, [funcname, args, kwargs, sock])
-
-    def _queue(self, sock):
-        return self.conn2msgs[sock]
-
-    def send_msg(self, conn, msg):
-        self.conn2msgs[conn].put(msg)
-
-
-class Server(AbsNetwork):
-
-    def __init__(self, port):
-        AbsNetwork.__init__(self, port)
-        self.conn_cb = None
-        self.fname2ref = {}
-
-    @property
-    def connections(self): return self.netw_thr.connections[1:]
-
-    def start(self, read_cb, conn_cb):
-        #TODO: parameters differ from overridden start
-        AbsNetwork.start(self, read_cb)
-        self.conn_cb = conn_cb
-        self.netw_thr.attach(self.on_connected)
-        self.netw_thr.attach(self.on_disconnected)
-
-    def on_connected(self, conn):
-        self.notify('on_connected', conn)
-
-    def on_disconnected(self, conn):
-        self.notify('on_disconnected', conn)
-
-    def _bld_netw_thr(self):
-        return ServerThread(self.eng, self.rpc_cb, self.port)
-
-    def _configure_udp(self): self.udp_sock.bind(('', self.port))
-
-    def send(self, data_lst, receiver=None):
-        receivers = [cln for cln in self.connections if cln == receiver]
-        dests = receivers if receiver else self.connections
-        dgram = BinaryData.pack(data_lst)
-        list(map(lambda cln: self.netw_thr.send_msg(cln, dgram), dests))
-
-    def rpc_cb(self, funcname, args, kwargs, conn):
-        kwargs = kwargs or {}
-        kwargs['sender'] = conn
-        ret = self.fname2ref[funcname](*args, **kwargs)
-        msg_size, msg_data = BinaryData.pack([msg_rpc_answ, ret])
-        self.netw_thr.send_msg(conn, (msg_size, msg_data))
-
-    def register_rpc(self, func): self.fname2ref[func.__name__] = func
-
-    def unregister_rpc(self, func): del self.fname2ref[func.__name__]
-
-    def on_udp_pck(self, dgram, conn):
-        sender = BinaryData.unpack(dgram)[0]
-        if sender not in self.addr2conn: self.addr2conn[sender] = conn
-
-    def process_udp(self):
-        try: dgram, conn = self.udp_sock.recvfrom(8192)
-        except error: return
-        try:
-            dgram = BinaryData.unpack(dgram)
-            sender, payload = dgram[0], dgram[1:]
-            self.read_cb(payload, sender)
-        except IndexError as exc: print(exc)
-
-    def send_udp(self, data_lst, receiver):
-        if receiver[0] not in self.addr2conn: return
-        msg_size, msg_data = BinaryData.pack(['server'] + data_lst)
-        self.udp_sock.sendto(msg_data, self.addr2conn[receiver[0]])
+from socket import error
+from queue import Queue
+from ya2.engine.network.network import AbsNetwork, NetworkThread, \
+    msg_rpc_answ
+from ya2.engine.network.binary import BinaryData
+from ya2.gameobject import GameObject
+
+
+class ServerThread(NetworkThread, GameObject):
+
+    def __init__(self, eng, rpc_cb, port):
+        NetworkThread.__init__(self, eng, port)
+        GameObject.__init__(self)
+        self.rpc_cb = rpc_cb
+        self.conn2msgs = {}
+
+    def _configure_socket(self):
+        self.tcp_sock.setblocking(0)
+        self.tcp_sock.bind(('', self.port))
+        self.tcp_sock.listen(1)
+
+    def _process_read(self, sock):
+        if sock is self.tcp_sock:
+            conn, addr = sock.accept()
+            conn.setblocking(1)  # required on osx
+            self.connections += [conn]
+            self.conn2msgs[conn] = Queue()
+            self.notify('on_connected', conn)
+        else:
+            NetworkThread._process_read(self, sock)
+
+    def _rpc_cb(self, funcname, args, kwargs, sock):
+        self.eng.cb_mux.add_cb(self.rpc_cb, [funcname, args, kwargs, sock])
+
+    def _queue(self, sock):
+        return self.conn2msgs[sock]
+
+    def send_msg(self, conn, msg):
+        self.conn2msgs[conn].put(msg)
+
+
+class Server(AbsNetwork):
+
+    def __init__(self, port):
+        AbsNetwork.__init__(self, port)
+        self.conn_cb = None
+        self.fname2ref = {}
+
+    @property
+    def connections(self): return self.netw_thr.connections[1:]
+
+    def start(self, read_cb, conn_cb):
+        #TODO: parameters differ from overridden start
+        AbsNetwork.start(self, read_cb)
+        self.conn_cb = conn_cb
+        self.netw_thr.attach(self.on_connected)
+        self.netw_thr.attach(self.on_disconnected)
+
+    def on_connected(self, conn):
+        self.notify('on_connected', conn)
+
+    def on_disconnected(self, conn):
+        self.notify('on_disconnected', conn)
+
+    def _bld_netw_thr(self):
+        return ServerThread(self.eng, self.rpc_cb, self.port)
+
+    def _configure_udp(self): self.udp_sock.bind(('', self.port))
+
+    def send(self, data_lst, receiver=None):
+        receivers = [cln for cln in self.connections if cln == receiver]
+        dests = receivers if receiver else self.connections
+        dgram = BinaryData.pack(data_lst)
+        list(map(lambda cln: self.netw_thr.send_msg(cln, dgram), dests))
+
+    def rpc_cb(self, funcname, args, kwargs, conn):
+        kwargs = kwargs or {}
+        kwargs['sender'] = conn
+        ret = self.fname2ref[funcname](*args, **kwargs)
+        msg_size, msg_data = BinaryData.pack([msg_rpc_answ, ret])
+        self.netw_thr.send_msg(conn, (msg_size, msg_data))
+
+    def register_rpc(self, func): self.fname2ref[func.__name__] = func
+
+    def unregister_rpc(self, func): del self.fname2ref[func.__name__]
+
+    def on_udp_pck(self, dgram, conn):
+        sender = BinaryData.unpack(dgram)[0]
+        if sender not in self.addr2conn: self.addr2conn[sender] = conn
+
+    def process_udp(self):
+        try: dgram, conn = self.udp_sock.recvfrom(8192)
+        except error: return
+        try:
+            dgram = BinaryData.unpack(dgram)
+            sender, payload = dgram[0], dgram[1:]
+            self.read_cb(payload, sender)
+        except IndexError as exc: print(exc)
+
+    def send_udp(self, data_lst, receiver):
+        if receiver[0] not in self.addr2conn: return
+        msg_size, msg_data = BinaryData.pack(['server'] + data_lst)
+        self.udp_sock.sendto(msg_data, self.addr2conn[receiver[0]])
index 32eb05dc342d270989229870b6ab4a916c45cfdc..b5a040c5a4480b0b7f74f5b583f4dfa4acd26d63 100755 (executable)
@@ -1,16 +1,16 @@
-# from math import pi
-# from ..gameobject import GameObject
-from ya2.lib.p3d.particle import P3dParticle
-Particle = P3dParticle
+# from math import pi
+# from ..gameobject import GameObject
+from ya2.lib.p3d.particle import P3dParticle
+Particle = P3dParticle
 
 
-# class Particle(GameObject):
+# class Particle(GameObject):
 
-#    def __init__(self, emitter, texture, npart, color=(1, 1, 1, 1), ampl=pi/6,
-#                 ray=.5, rate=.0001, gravity=-.85, vel=3.8, part_lifetime=1.0,
-#                 autodestroy=None):
-#        if not self.eng.lib.version.startswith('1.10'): return
-#        GameObject.__init__(self)
-#        LibParticle(
-#            emitter, texture, npart, color, ampl, ray, rate, gravity, vel,
-#            part_lifetime, autodestroy)
+#    def __init__(self, emitter, texture, npart, color=(1, 1, 1, 1), ampl=pi/6,
+#                 ray=.5, rate=.0001, gravity=-.85, vel=3.8, part_lifetime=1.0,
+#                 autodestroy=None):
+#        if not self.eng.lib.version.startswith('1.10'): return
+#        GameObject.__init__(self)
+#        LibParticle(
+#            emitter, texture, npart, color, ampl, ray, rate, gravity, vel,
+#            part_lifetime, autodestroy)
index 097d16fab92b492837f3ecfc8137a23fcb01a3b6..bb21a95f4d945b568a5cf503350b7f6cea8f1c54 100644 (file)
@@ -1,77 +1,77 @@
-from direct.gui.DirectFrame import DirectFrame
-from ya2.gameobject import GuiColleague, LogicColleague, GameObject, \
-    Colleague
-from ya2.lib.p3d.pause import P3dPause
-LibPause = P3dPause
+from direct.gui.DirectFrame import DirectFrame
+from ya2.gameobject import GuiColleague, LogicColleague, GameObject, \
+    Colleague
+from ya2.lib.p3d.pause import P3dPause
+LibPause = P3dPause
 
 
-class PauseGui(GuiColleague):
+class PauseGui(GuiColleague):
 
-    def __init__(self, mediator):
-        GuiColleague.__init__(self, mediator)
-        self.pause_frm = None
+    def __init__(self, mediator):
+        GuiColleague.__init__(self, mediator)
+        self.pause_frm = None
 
-    def toggle(self, show_frm=True):
-        if not self.mediator.logic._pause.paused:
-            #TODO: don't access protected members
-            if show_frm:
-                self.pause_frm = DirectFrame(frameColor=(.3, .3, .3, .7),
-                                             frameSize=(-1.8, 1.8, -1, 1))
-        else:
-            if self.pause_frm: self.pause_frm.destroy()
+    def toggle(self, show_frm=True):
+        if not self.mediator.logic._pause.paused:
+            #TODO: don't access protected members
+            if show_frm:
+                self.pause_frm = DirectFrame(frameColor=(.3, .3, .3, .7),
+                                             frameSize=(-1.8, 1.8, -1, 1))
+        else:
+            if self.pause_frm: self.pause_frm.destroy()
 
-    def destroy(self):
-        if self.pause_frm: self.pause_frm = self.pause_frm.destroy()
-        GuiColleague.destroy(self)
+    def destroy(self):
+        if self.pause_frm: self.pause_frm = self.pause_frm.destroy()
+        GuiColleague.destroy(self)
 
 
-class PauseLogic(LogicColleague):
+class PauseLogic(LogicColleague):
 
-    def __init__(self, mediator):
-        LogicColleague.__init__(self, mediator)
-        self._pause = LibPause()
+    def __init__(self, mediator):
+        LogicColleague.__init__(self, mediator)
+        self._pause = LibPause()
 
-    def remove_task(self, tsk):
-        self._pause.remove_task(tsk)
+    def remove_task(self, tsk):
+        self._pause.remove_task(tsk)
 
-    def pause(self):
-        self.notify('on_pause')
-        return self._pause.pause()
+    def pause(self):
+        self.notify('on_pause')
+        return self._pause.pause()
 
-    def resume(self):
-        self.notify('on_resume')
-        return self._pause.resume()
+    def resume(self):
+        self.notify('on_resume')
+        return self._pause.resume()
 
-    def toggle(self, show_frm=True):
-        self.mediator.gui.toggle(show_frm)
-        (self.resume if self._pause.paused else self.pause)()
+    def toggle(self, show_frm=True):
+        self.mediator.gui.toggle(show_frm)
+        (self.resume if self._pause.paused else self.pause)()
 
-    def destroy(self):
-        self._pause.destroy()
-        LogicColleague.destroy(self)
+    def destroy(self):
+        self._pause.destroy()
+        LogicColleague.destroy(self)
 
 
-class PauseFacade:
+class PauseFacade:
 
-    @property
-    def paused(self):
-        return self.logic._pause.paused
-        #TODO: don't access protected members
+    @property
+    def paused(self):
+        return self.logic._pause.paused
+        #TODO: don't access protected members
 
 
-class PauseMgr(GameObject, Colleague, PauseFacade):
+class PauseMgr(GameObject, Colleague, PauseFacade):
 
-    def __init__(self, mediator):
-        GameObject.__init__(self)
-        Colleague.__init__(self, mediator)
-        self.gui = PauseGui(self)
-        self.logic = PauseLogic(self)
+    def __init__(self, mediator):
+        GameObject.__init__(self)
+        Colleague.__init__(self, mediator)
+        self.gui = PauseGui(self)
+        self.logic = PauseLogic(self)
 
-    def remove_task(self, tsk):
-        return self.logic.remove_task(tsk)
+    def remove_task(self, tsk):
+        return self.logic.remove_task(tsk)
 
-    def destroy(self):
-        self.gui = self.gui.destroy()
-        self.logic = self.logic.destroy()
-        GameObject.destroy(self)
-        Colleague.destroy(self)
+    def destroy(self):
+        self.gui = self.gui.destroy()
+        self.logic = self.logic.destroy()
+        GameObject.destroy(self)
+        Colleague.destroy(self)
index dfc2ac4d7c03646a5c62f3d2016edd0b304d89f3..6a10378698962caca7a4d27352e826ba77811280 100644 (file)
-from logging import info
-from ya2.gameobject import Colleague
-from ya2.lib.bullet.bullet import (
-    BulletPhysWorld, BulletTriangleMesh, BulletTriangleMeshShape,
-    BulletRigidBodyNode, BulletGhostNode)
-
-
-PhysWorld = BulletPhysWorld
-TriangleMesh = BulletTriangleMesh
-TriangleMeshShape = BulletTriangleMeshShape
-RigidBodyNode = BulletRigidBodyNode
-GhostNode = BulletGhostNode
-
-
-class CollInfo:
-
-    def __init__(self, node, time):
-        self.node = node
-        self.time = time
-
-
-class PhysFacade:
-
-    def attach_rigid_body(self, rbnode):
-        return self.root.attach_rigid_body(rbnode)
-
-    def remove_rigid_body(self, rbnode):
-        return self.root.remove_rigid_body(rbnode)
-
-    def attach_ghost(self, gnode): return self.root.attach_ghost(gnode)
-    def remove_ghost(self, gnode): return self.root.remove_ghost(gnode)
-    def attach_vehicle(self, vehicle): return self.root.attach_vehicle(vehicle)
-    def remove_vehicle(self, vehicle): return self.root.remove_vehicle(vehicle)
-
-    def ray_test_all(self, from_pos, to_pos, mask=None):
-        return self.root.ray_test_all(from_pos, to_pos, mask)
-
-    def ray_test_closest(self, from_pos, to_pos, mask=None):
-        return self.root.ray_test_closest(from_pos, to_pos, mask)
-
-
-class PhysMgr(Colleague, PhysFacade):
-
-    def __init__(self, mediator):
-        Colleague.__init__(self, mediator)
-        self.collision_objs = []  # objects to be processed
-        self.__obj2coll = {}  # {obj: [(node, coll_time), ...], ...}
-        self.root = None
-        self.__debug_np = None
-        PhysFacade.__init__(self)
-
-    def reset(self):
-        self.collision_objs = []
-        self.__obj2coll = {}
-        self.root = PhysWorld()
-        self.root.set_gravity((0, 0, -8.5))
-        self.root.init_debug()
-
-    def start(self):
-        self.eng.attach_obs(self.on_frame, 2)
-
-    def on_frame(self):
-        self.root.do_phys(self.eng.lib.last_frame_dt, 10, 1/180.0)
-        self.__do_collisions()
-
-    def ray_test_closest(self, top, bottom):
-        #TODO: differs from PhysFacade's signature
-        return self.root.ray_test_closest(top, bottom)
-
-    def add_collision_obj(self, node): self.collision_objs += [node]
-
-    def remove_collision_obj(self, node):
-        try: self.collision_objs.remove(node)
-        except ValueError:
-            info("can't remove collision object %s" % node)
-            # it may happen with weapons during pause
-
-    def stop(self):
-        self.root.stop()
-        self.root = None
-        self.eng.detach_obs(self.on_frame)
-
-    def __do_collisions(self):
-        to_clear = self.collision_objs[:]
-        # identical collisions are ignored for .25 seconds
-        for obj in self.collision_objs:
-            if obj not in self.__obj2coll: self.__obj2coll[obj] = []
-            # for contact in self.root.get_contacts(obj):
-            # this doesn't work in 1.9, the following works
-            # odd, this doesn't work too
-            # for contact in self.root.wld.contact_test(obj).get_contacts():
-            result = self.root._wld.contact_test(obj)
-            #TODO: access a protected member
-            for contact in result.get_contacts():
-                self.__process_contact(obj, contact.get_node0(), to_clear)
-                self.__process_contact(obj, contact.get_node1(), to_clear)
-        for obj in to_clear:
-            if obj in self.__obj2coll:  # it may be that it isn't here e.g.
-                # when you fire a rocket while you're very close to the prev
-                # car and the rocket is removed suddenly
-                for coll in self.__obj2coll[obj]:
-                    if self.eng.curr_time - coll.time > .25:
-                        self.__obj2coll[obj].remove(coll)
-
-    def __process_contact(self, obj, node, to_clear):
-        if node == obj: return
-        if obj in to_clear: to_clear.remove(obj)
-        if node in [coll.node for coll in self.__obj2coll[obj]]: return
-        self.__obj2coll[obj] += [CollInfo(node, self.eng.curr_time)]
-        self.eng.event.notify('on_collision', obj, node)
-
-    def toggle_dbg(self):
-        if self.root: self.root.toggle_dbg()
+from logging import info
+from ya2.gameobject import Colleague
+from ya2.lib.bullet.bullet import (
+    BulletPhysWorld, BulletTriangleMesh, BulletTriangleMeshShape,
+    BulletRigidBodyNode, BulletGhostNode)
+
+
+PhysWorld = BulletPhysWorld
+TriangleMesh = BulletTriangleMesh
+TriangleMeshShape = BulletTriangleMeshShape
+RigidBodyNode = BulletRigidBodyNode
+GhostNode = BulletGhostNode
+
+
+class CollInfo:
+
+    def __init__(self, node, time):
+        self.node = node
+        self.time = time
+
+
+class PhysFacade:
+
+    def attach_rigid_body(self, rbnode):
+        return self.root.attach_rigid_body(rbnode)
+
+    def remove_rigid_body(self, rbnode):
+        return self.root.remove_rigid_body(rbnode)
+
+    def attach_ghost(self, gnode): return self.root.attach_ghost(gnode)
+    def remove_ghost(self, gnode): return self.root.remove_ghost(gnode)
+    def attach_vehicle(self, vehicle): return self.root.attach_vehicle(vehicle)
+    def remove_vehicle(self, vehicle): return self.root.remove_vehicle(vehicle)
+
+    def ray_test_all(self, from_pos, to_pos, mask=None):
+        return self.root.ray_test_all(from_pos, to_pos, mask)
+
+    def ray_test_closest(self, from_pos, to_pos, mask=None):
+        return self.root.ray_test_closest(from_pos, to_pos, mask)
+
+
+class PhysMgr(Colleague, PhysFacade):
+
+    def __init__(self, mediator):
+        Colleague.__init__(self, mediator)
+        self.collision_objs = []  # objects to be processed
+        self.__obj2coll = {}  # {obj: [(node, coll_time), ...], ...}
+        self.root = None
+        self.__debug_np = None
+        PhysFacade.__init__(self)
+
+    def reset(self):
+        self.collision_objs = []
+        self.__obj2coll = {}
+        self.root = PhysWorld()
+        self.root.set_gravity((0, 0, -8.5))
+        self.root.init_debug()
+
+    def start(self):
+        self.eng.attach_obs(self.on_frame, 2)
+
+    def on_frame(self):
+        self.root.do_phys(self.eng.lib.last_frame_dt, 10, 1/180.0)
+        self.__do_collisions()
+
+    def ray_test_closest(self, top, bottom):
+        #TODO: differs from PhysFacade's signature
+        return self.root.ray_test_closest(top, bottom)
+
+    def add_collision_obj(self, node): self.collision_objs += [node]
+
+    def remove_collision_obj(self, node):
+        try: self.collision_objs.remove(node)
+        except ValueError:
+            info("can't remove collision object %s" % node)
+            # it may happen with weapons during pause
+
+    def stop(self):
+        self.root.stop()
+        self.root = None
+        self.eng.detach_obs(self.on_frame)
+
+    def __do_collisions(self):
+        to_clear = self.collision_objs[:]
+        # identical collisions are ignored for .25 seconds
+        for obj in self.collision_objs:
+            if obj not in self.__obj2coll: self.__obj2coll[obj] = []
+            # for contact in self.root.get_contacts(obj):
+            # this doesn't work in 1.9, the following works
+            # odd, this doesn't work too
+            # for contact in self.root.wld.contact_test(obj).get_contacts():
+            result = self.root._wld.contact_test(obj)
+            #TODO: access a protected member
+            for contact in result.get_contacts():
+                self.__process_contact(obj, contact.get_node0(), to_clear)
+                self.__process_contact(obj, contact.get_node1(), to_clear)
+        for obj in to_clear:
+            if obj in self.__obj2coll:  # it may be that it isn't here e.g.
+                # when you fire a rocket while you're very close to the prev
+                # car and the rocket is removed suddenly
+                for coll in self.__obj2coll[obj]:
+                    if self.eng.curr_time - coll.time > .25:
+                        self.__obj2coll[obj].remove(coll)
+
+    def __process_contact(self, obj, node, to_clear):
+        if node == obj: return
+        if obj in to_clear: to_clear.remove(obj)
+        if node in [coll.node for coll in self.__obj2coll[obj]]: return
+        self.__obj2coll[obj] += [CollInfo(node, self.eng.curr_time)]
+        self.eng.event.notify('on_collision', obj, node)
+
+    def toggle_dbg(self):
+        if self.root: self.root.toggle_dbg()
index 9cdd54c407908b7e76c323cd9a44aa4263486905..248c4bb804288165728df3e8e2c74ace409d49ac 100644 (file)
@@ -1,72 +1,72 @@
-from os.path import exists
+from os.path import exists
 
 
-if not exists('main.pyo'):  # we don't deploy cProfile
-    from cProfile import Profile
-    from pstats import Stats
-    from io import StringIO
+if not exists('main.pyo'):  # we don't deploy cProfile
+    from cProfile import Profile
+    from pstats import Stats
+    from io import StringIO
 
 
-class AbsProfiler:
+class AbsProfiler:
 
-    @staticmethod
-    def build(percall):
-        prof_cls = AbsProfiler
-        if not exists('main.pyo'):
-            prof_cls = PerCallProfiler if percall else Profiler
-        return prof_cls(percall)
+    @staticmethod
+    def build(percall):
+        prof_cls = AbsProfiler
+        if not exists('main.pyo'):
+            prof_cls = PerCallProfiler if percall else Profiler
+        return prof_cls(percall)
 
-    def __init__(self, percall): pass
+    def __init__(self, percall): pass
 
-    def printstats(self): pass
+    def printstats(self): pass
 
-    def toggle(self): pass
+    def toggle(self): pass
 
-    def destroy(self): pass
+    def destroy(self): pass
 
 
-class Profiler(AbsProfiler):
+class Profiler(AbsProfiler):
 
-    def __init__(self, percall):
-        AbsProfiler.__init__(self, percall)
-        self.percall = percall
-        self.is_profiling = False  # we can't infer from cProfile
-        self.prof = Profile()
-        self.stats = None
+    def __init__(self, percall):
+        AbsProfiler.__init__(self, percall)
+        self.percall = percall
+        self.is_profiling = False  # we can't infer from cProfile
+        self.prof = Profile()
+        self.stats = None
 
-    def toggle(self):
-        if not self.is_profiling: self.__enable()
-        else:
-            self.__disable()
-            self.printstats()
+    def toggle(self):
+        if not self.is_profiling: self.__enable()
+        else:
+            self.__disable()
+            self.printstats()
 
-    def __enable(self):
-        self.prof.enable()
-        self.is_profiling = True
+    def __enable(self):
+        self.prof.enable()
+        self.is_profiling = True
 
-    def __disable(self):
-        self.prof.disable()
-        self.is_profiling = False
+    def __disable(self):
+        self.prof.disable()
+        self.is_profiling = False
 
-    def printstats(self):
-        self.prof.disable()
-        sio = StringIO()
-        self.stats = Stats(self.prof, stream=sio).sort_stats('cumulative')
-        self.stats.print_stats()
-        self._print_lines(sio)
+    def printstats(self):
+        self.prof.disable()
+        sio = StringIO()
+        self.stats = Stats(self.prof, stream=sio).sort_stats('cumulative')
+        self.stats.print_stats()
+        self._print_lines(sio)
 
-    @staticmethod
-    def _print_lines(sio): print(sio.getvalue())
+    @staticmethod
+    def _print_lines(sio): print(sio.getvalue())
 
 
-class PerCallProfiler(Profiler):
+class PerCallProfiler(Profiler):
 
-    def _print_lines(self, sio):
-        lines = sio.getvalue().split('\n')
-        header_lines = lines[:5]
-        content_lines = [line.split() for line in lines[5:] if line]
-        sorted_lines = sorted(content_lines, key=lambda line: line[4])
-        sorted_lines = reversed(sorted_lines)
-        # line[4] is the percall value
-        joined_lines = ['\t'.join(line) for line in sorted_lines]
-        print('\n'.join(header_lines + joined_lines))
+    def _print_lines(self, sio):
+        lines = sio.getvalue().split('\n')
+        header_lines = lines[:5]
+        content_lines = [line.split() for line in lines[5:] if line]
+        sorted_lines = sorted(content_lines, key=lambda line: line[4])
+        sorted_lines = reversed(sorted_lines)
+        # line[4] is the percall value
+        joined_lines = ['\t'.join(line) for line in sorted_lines]
+        print('\n'.join(header_lines + joined_lines))
index af4311b8dfd27d859e97d4b4573051116391ac89..b90bb0f20e5166d4ade943e4657ec0e7a04ee37d 100644 (file)
@@ -1,4 +1,4 @@
-from ya2.lib.p3d.shader import P3dShaderMgr
+from ya2.lib.p3d.shader import P3dShaderMgr
 
 
-ShaderMgr = P3dShaderMgr
+ShaderMgr = P3dShaderMgr
index 19fbafb445228c87c52df03403be95ce9d30cc2c..78f64011591ccd01f2c9874f66b712a56a26a9a7 100644 (file)
@@ -1,3 +1,3 @@
-from ya2.lib.p3d.vec import P3dVec2, P3dVec3
-Vec = P3dVec3
-Vec2 = P3dVec2
+from ya2.lib.p3d.vec import P3dVec2, P3dVec3
+Vec = P3dVec3
+Vec2 = P3dVec2
index 4694b4e9e5743a22fb61a035f5eebb5d11542b46..8a74de48478d90b029c2d516a988394d0323503f 100644 (file)
@@ -1,37 +1,37 @@
-from abc import ABCMeta
-from ya2.gameobject import LogicColleague, GameObject
-from ya2.engine.engine import Engine
+from abc import ABCMeta
+from ya2.gameobject import LogicColleague, GameObject
+from ya2.engine.engine import Engine
 
 
-class GameLogic(LogicColleague):
+class GameLogic(LogicColleague):
 
-    def on_start(self): pass
+    def on_start(self): pass
 
 
-class GameFacade:
+class GameFacade:
 
-    def demand(self, tgt_state, *args):
-        return self.fsm.demand(tgt_state, *args)
+    def demand(self, tgt_state, *args):
+        return self.fsm.demand(tgt_state, *args)
 
 
-class GameBase(GameObject, GameFacade):  # it doesn't manage the window
-    __metaclass__ = ABCMeta
+class GameBase(GameObject, GameFacade):  # it doesn't manage the window
+    __metaclass__ = ABCMeta
 
-    def __init__(self, cfg, client_cls=None):
-        self.logic = LogicColleague(self)
-        self.eng = Engine(cfg, self.destroy, client_cls)
-        GameObject.__init__(self)
+    def __init__(self, cfg, client_cls=None):
+        self.logic = LogicColleague(self)
+        self.eng = Engine(cfg, self.destroy, client_cls)
+        GameObject.__init__(self)
 
-    def destroy(self):
-        self.logic.destroy()
-        GameObject.destroy(self)
-        # self.eng = self.eng.destroy()
-        self.eng.server.destroy()
-        self.eng.client.destroy()
+    def destroy(self):
+        self.logic.destroy()
+        GameObject.destroy(self)
+        # self.eng = self.eng.destroy()
+        self.eng.server.destroy()
+        self.eng.client.destroy()
 
 
-class Game(GameBase):  # it adds the window
+class Game(GameBase):  # it adds the window
 
-    def run(self):
-        self.logic.on_start()
-        base.run()
+    def run(self):
+        self.logic.on_start()
+        base.run()
index d86cdaefb6810b2ee82a3fe81a66320b78a868b1..48d982e11da565e626e3298946d5e5071a88cb3e 100644 (file)
@@ -1,13 +1,13 @@
 from ya2.lib.p3d.p3d import LibP3d
 
 
-class LibBuilder:
-    '''This classe builds the implementation of the library abstraction  (for
-    the Dependency Inversion Principle).'''
+class LibBuilder:
+    '''This classe builds the implementation of the library abstraction  (for
+    the Dependency Inversion Principle).'''
 
-    @staticmethod
-    def build():
-        '''This method actually builds the library implementation.
-        Now it builds Panda3D's implementation layer, but it may be used as a
-        dispatcher (e.g. for new Panda3D versions).'''
-        return LibP3d()
+    @staticmethod
+    def build():
+        '''This method actually builds the library implementation.
+        Now it builds Panda3D's implementation layer, but it may be used as a
+        dispatcher (e.g. for new Panda3D versions).'''
+        return LibP3d()
index b2f390df390482f7c857ac5bc59b7c6f82a466fd..f18925a15c417d552e6d6d50b650914d1bce0b99 100644 (file)
@@ -1,79 +1,79 @@
-from panda3d.bullet import \
-    BulletWorld as BWorld, \
-    BulletDebugNode as BDebugNode, \
-    BulletTriangleMesh as BTriangleMesh, \
-    BulletTriangleMeshShape as BTriangleMeshShape, \
-    BulletRigidBodyNode as BRigidBodyNode, \
-    BulletGhostNode as BGhostNode
+from panda3d.bullet import \
+    BulletWorld as BWorld, \
+    BulletDebugNode as BDebugNode, \
+    BulletTriangleMesh as BTriangleMesh, \
+    BulletTriangleMeshShape as BTriangleMeshShape, \
+    BulletRigidBodyNode as BRigidBodyNode, \
+    BulletGhostNode as BGhostNode
 
 
-class BulletPhysWorld:
+class BulletPhysWorld:
 
-    def __init__(self):
-        self._wld = BWorld()
-        self.__debug_np = None
+    def __init__(self):
+        self._wld = BWorld()
+        self.__debug_np = None
 
-    def attach_rigid_body(self, rbnode):
-        return self._wld.attach_rigid_body(rbnode)
+    def attach_rigid_body(self, rbnode):
+        return self._wld.attach_rigid_body(rbnode)
 
-    def remove_rigid_body(self, rbnode):
-        return self._wld.remove_rigid_body(rbnode)
+    def remove_rigid_body(self, rbnode):
+        return self._wld.remove_rigid_body(rbnode)
 
-    def attach_ghost(self, gnode): return self._wld.attach_ghost(gnode)
-    def remove_ghost(self, gnode): return self._wld.remove_ghost(gnode)
-    def attach_vehicle(self, vehicle): return self._wld.attach_vehicle(vehicle)
-    def remove_vehicle(self, vehicle): return self._wld.remove_vehicle(vehicle)
+    def attach_ghost(self, gnode): return self._wld.attach_ghost(gnode)
+    def remove_ghost(self, gnode): return self._wld.remove_ghost(gnode)
+    def attach_vehicle(self, vehicle): return self._wld.attach_vehicle(vehicle)
+    def remove_vehicle(self, vehicle): return self._wld.remove_vehicle(vehicle)
 
-    def ray_test_closest(self, from_pos, to_pos, mask=None):
-        if mask is not None:
-            res = self._wld.ray_test_closest(from_pos, to_pos, mask)
-        else: res = self._wld.ray_test_closest(from_pos, to_pos)
-        return res
+    def ray_test_closest(self, from_pos, to_pos, mask=None):
+        if mask is not None:
+            res = self._wld.ray_test_closest(from_pos, to_pos, mask)
+        else: res = self._wld.ray_test_closest(from_pos, to_pos)
+        return res
 
-    def do_phys(self, dt, max_substeps, stepsize):
-        return self._wld.do_physics(dt, max_substeps, stepsize)
+    def do_phys(self, dt, max_substeps, stepsize):
+        return self._wld.do_physics(dt, max_substeps, stepsize)
 
-    def set_gravity(self, vec): return self._wld.set_gravity(vec)
+    def set_gravity(self, vec): return self._wld.set_gravity(vec)
 
-    def init_debug(self):
-        debug_node = BDebugNode('Debug')
-        debug_node.show_bounding_boxes(True)
-        self.__debug_np = render.attach_new_node(debug_node)
-        self._wld.set_debug_node(self.__debug_np.node())
+    def init_debug(self):
+        debug_node = BDebugNode('Debug')
+        debug_node.show_bounding_boxes(True)
+        self.__debug_np = render.attach_new_node(debug_node)
+        self._wld.set_debug_node(self.__debug_np.node())
 
-    def stop(self): self.__debug_np.remove_node()
+    def stop(self): self.__debug_np.remove_node()
 
-    def ray_test_all(self, pt_a, pt_b, mask=None):
-        args = [pt_a._vec, pt_b._vec, mask] if mask else [pt_a._vec, pt_b._vec]
-        #TODO: access to protected member
-        return self._wld.ray_test_all(*args)
+    def ray_test_all(self, pt_a, pt_b, mask=None):
+        args = [pt_a._vec, pt_b._vec, mask] if mask else [pt_a._vec, pt_b._vec]
+        #TODO: access to protected member
+        return self._wld.ray_test_all(*args)
 
-    def toggle_dbg(self):
-        hidden = self.__debug_np.is_hidden()
-        (self.__debug_np.show if hidden else self.__debug_np.hide)()
+    def toggle_dbg(self):
+        hidden = self.__debug_np.is_hidden()
+        (self.__debug_np.show if hidden else self.__debug_np.hide)()
 
 
-class BulletTriangleMesh:
+class BulletTriangleMesh:
 
-    def __init__(self):
-        self._mesh = BTriangleMesh()
+    def __init__(self):
+        self._mesh = BTriangleMesh()
 
-    def add_geom(self, geom, rm_dupl, xform):
-        return self._mesh.add_geom(geom, rm_dupl, xform)
+    def add_geom(self, geom, rm_dupl, xform):
+        return self._mesh.add_geom(geom, rm_dupl, xform)
 
 
-class BulletTriangleMeshShape:
+class BulletTriangleMeshShape:
 
-    def __init__(self, mesh, dynamic):
-        self._mesh_shape = BTriangleMeshShape(mesh._mesh, dynamic=dynamic)
-        #TODO: access to protected member
+    def __init__(self, mesh, dynamic):
+        self._mesh_shape = BTriangleMeshShape(mesh._mesh, dynamic=dynamic)
+        #TODO: access to protected member
 
 
-class BulletRigidBodyNode:
+class BulletRigidBodyNode:
 
-    def __init__(self, name): self._node = BRigidBodyNode(name)
+    def __init__(self, name): self._node = BRigidBodyNode(name)
 
 
-class BulletGhostNode:
+class BulletGhostNode:
 
-    def __init__(self, name): self._node = BGhostNode(name)
+    def __init__(self, name): self._node = BGhostNode(name)
index 799c425da2e9b5db372d2d3d575ff6c681b10575..51f2fd814332e92c1faaea78b6a3aca55a49f3c1 100644 (file)
@@ -1,16 +1,16 @@
-'''This module binds abstract GUI classes and actual implementation classes
-(for the Dependency Inversion Principle).'''
-from ya2.lib.p3d.gui import P3dImg, P3dBtn, P3dSlider, P3dCheckBtn, \
-    P3dOptionMenu, P3dEntry, P3dLabel, P3dTxt, P3dFrame, P3dScrolledFrame
+'''This module binds abstract GUI classes and actual implementation classes
+(for the Dependency Inversion Principle).'''
+from ya2.lib.p3d.gui import P3dImg  # , P3dBtn, P3dSlider, P3dCheckBtn, \
+    P3dOptionMenu, P3dEntry, P3dLabel, P3dTxt, P3dFrame, P3dScrolledFrame
 
 
 Img = P3dImg
-Btn = P3dBtn
-Slider = P3dSlider
-CheckBtn = P3dCheckBtn
-OptionMenu = P3dOptionMenu
-Entry = P3dEntry
-Label = P3dLabel
-Text = P3dTxt
-Frame = P3dFrame
-ScrolledFrame = P3dScrolledFrame
+Btn = P3dBtn
+Slider = P3dSlider
+CheckBtn = P3dCheckBtn
+OptionMenu = P3dOptionMenu
+Entry = P3dEntry
+Label = P3dLabel
+Text = P3dTxt
+Frame = P3dFrame
+ScrolledFrame = P3dScrolledFrame
index 279a4635cf1475058a214dad3aac45cf3aeb3c93..9b6398f701b5a32311b9128d8c6adadfb48f0afe 100644 (file)
@@ -1,9 +1,9 @@
-'''This module binds abstract interval classes and actual implementation
-classes (for the Dependency Inversion Principle).'''
-from ya2.lib.p3d.ivals import P3dSeq, P3dWait, P3dPosIval, P3dFunc
+'''This module binds abstract interval classes and actual implementation
+classes (for the Dependency Inversion Principle).'''
+from ya2.lib.p3d.ivals import P3dSeq, P3dWait, P3dPosIval, P3dFunc
 
 
-Seq = P3dSeq
-Wait = P3dWait
-PosIval = P3dPosIval
-Func = P3dFunc
+Seq = P3dSeq
+Wait = P3dWait
+PosIval = P3dPosIval
+Func = P3dFunc
index 4d2b2817473f691755474f29d32657336c87c9b8..35f21a453d56b45c7fa2c712852b4909b81062c0 100644 (file)
@@ -1,19 +1,19 @@
-from panda3d.core import AudioSound
+from panda3d.core import AudioSound
 
 
-class P3dSound:
+class P3dSound:
 
-    def __init__(self, filepath):
-        self.snd = loader.loadSfx(filepath)
+    def __init__(self, filepath):
+        self.snd = loader.loadSfx(filepath)
 
-    def stop(self): return self.snd.stop()
-    def set_loop(self, val): return self.snd.set_loop(val)
-    def set_volume(self, vol): return self.snd.set_volume(vol)
-    def set_play_rate(self, rate): return self.snd.set_play_rate(rate)
+    def stop(self): return self.snd.stop()
+    def set_loop(self, val): return self.snd.set_loop(val)
+    def set_volume(self, vol): return self.snd.set_volume(vol)
+    def set_play_rate(self, rate): return self.snd.set_play_rate(rate)
 
-    def play(self):
-        if self.snd.status() != AudioSound.PLAYING: return self.snd.play()
-        return None
+    def play(self):
+        if self.snd.status() != AudioSound.PLAYING: return self.snd.play()
+        return None
 
-    @property
-    def playing(self): return self.snd.status() == AudioSound.PLAYING
+    @property
+    def playing(self): return self.snd.status() == AudioSound.PLAYING
index 5a6a15810b66e1787c1e78d45075798116ff7b34..56f6a8704b15c78eec2292c6a59d998693354daf 100755 (executable)
@@ -8,7 +8,7 @@ from panda3d.core import get_model_path, AntialiasAttrib, PandaNode, \
     Point3, Texture
 from direct.filter.CommonFilters import CommonFilters
 from direct.actor.Actor import Actor
-from ya2.lib.p3d.p3d import LibP3d
+from ya2.lib.p3d.p3d import LibP3d
 
 
 def set_srgb(model):
@@ -19,45 +19,45 @@ def set_srgb(model):
             texture.set_format(Texture.F_srgb)
 
 
-class RenderToTexture:
+class RenderToTexture:
 
-    def __init__(self, size=(256, 256)):
-        self.__set_buffer(size)
-        self.__set_display_region()
-        self.__set_camera()
-        self.__set_root()
-        self.display_region.set_camera(self.camera)
+    def __init__(self, size=(256, 256)):
+        self.__set_buffer(size)
+        self.__set_display_region()
+        self.__set_camera()
+        self.__set_root()
+        self.display_region.set_camera(self.camera)
 
-    def __set_buffer(self, size):
-        self.buffer = base.win.make_texture_buffer('result buffer', size[0],
-                                                   size[1])
-        self.buffer.set_sort(-100)
+    def __set_buffer(self, size):
+        self.buffer = base.win.make_texture_buffer('result buffer', size[0],
+                                                   size[1])
+        self.buffer.set_sort(-100)
 
-    def __set_display_region(self):
-        self.display_region = self.buffer.make_display_region()
-        self.display_region.set_sort(20)
+    def __set_display_region(self):
+        self.display_region = self.buffer.make_display_region()
+        self.display_region.set_sort(20)
 
-    def __set_camera(self):
-        self.camera = NodePath(Camera('camera 2d'))
-        lens = OrthographicLens()
-        lens.set_film_size(1, 1)
-        lens.set_near_far(-1000, 1000)
-        self.camera.node().set_lens(lens)
+    def __set_camera(self):
+        self.camera = NodePath(Camera('camera 2d'))
+        lens = OrthographicLens()
+        lens.set_film_size(1, 1)
+        lens.set_near_far(-1000, 1000)
+        self.camera.node().set_lens(lens)
 
-    def __set_root(self):
-        self.root = NodePath('root')
-        self.root.set_depth_test(False)
-        self.root.set_depth_write(False)
-        self.camera.reparent_to(self.root)
+    def __set_root(self):
+        self.root = NodePath('root')
+        self.root.set_depth_test(False)
+        self.root.set_depth_write(False)
+        self.camera.reparent_to(self.root)
 
-    @property
-    def texture(self): return self.buffer.get_texture()
+    @property
+    def texture(self): return self.buffer.get_texture()
 
-    def destroy(self):
-        base.graphicsEngine.remove_window(self.buffer)
-        if base.win:  # if you close the window during a race
-            base.win.remove_display_region(self.display_region)
-        list(map(lambda node: node.remove_node(), [self.camera, self.root]))
+    def destroy(self):
+        base.graphicsEngine.remove_window(self.buffer)
+        if base.win:  # if you close the window during a race
+            base.win.remove_display_region(self.display_region)
+        list(map(lambda node: node.remove_node(), [self.camera, self.root]))
 
 
 class P3dGfxMgr:
@@ -181,189 +181,189 @@ class P3dGfxMgr:
             elm[1]()
 
 
-class P3dNode:
-
-    def __init__(self, nodepath):
-        self.nodepath = nodepath
-        self.node.set_python_tag('libnode', self)
-
-    def set_collide_mask(self, mask): return self.node.set_collide_mask(mask)
-    def set_x(self, val): return self.node.set_x(val)
-    def set_y(self, val): return self.node.set_y(val)
-    def set_z(self, val): return self.node.set_z(val)
-    def set_hpr(self, val): return self.node.set_hpr(val)
-    def set_h(self, val): return self.node.set_h(val)
-    def set_p(self, val): return self.node.set_p(val)
-    def set_r(self, val): return self.node.set_r(val)
-    def set_scale(self, val): return self.node.set_scale(val)
-    def set_transparency(self, val): return self.node.set_transparency(val)
-    def set_alpha_scale(self, val): return self.node.set_alpha_scale(val)
-    def set_texture(self, texturestage, texture):
-        return self.node.set_texture(texturestage, texture)
-    def has_tag(self, name): return self.node.has_tag(name)
-    def get_tag(self, name): return self.node.get_tag(name)
-    def get_python_tag(self, name): return self.node.get_python_tag(name)
-    def remove_node(self): return self.node.remove_node()
-    def flatten_strong(self): return self.node.flatten_strong()
-    def clear_model_nodes(self): return self.node.clear_model_nodes()
-    def show(self): return self.node.show()
-    def set_depth_offset(self, val): return self.node.set_depth_offset(val)
-    def loop(self, val): return self.node.loop(val)
-    def cleanup(self): return self.node.cleanup()
-    def write_bam_file(self, fname): return self.node.write_bam_file(fname)
-
-    def attach_node(self, name):
-        return P3dNode(self.node.attach_new_node(name))
-
-    def add_shape(self, shape):
-        return self.node.node().add_shape(shape._mesh_shape)
-        #TODO: don't access a protected member
+# class P3dNode:
 
-    @property
-    def name(self): return self.node.get_name()
+#     def __init__(self, nodepath):
+#         self.nodepath = nodepath
+#         self.node.set_python_tag('libnode', self)
 
-    @property
-    def node(self): return self.nodepath
+#     def set_collide_mask(self, mask): return self.node.set_collide_mask(mask)
+#     def set_x(self, val): return self.node.set_x(val)
+#     def set_y(self, val): return self.node.set_y(val)
+#     def set_z(self, val): return self.node.set_z(val)
+#     def set_hpr(self, val): return self.node.set_hpr(val)
+#     def set_h(self, val): return self.node.set_h(val)
+#     def set_p(self, val): return self.node.set_p(val)
+#     def set_r(self, val): return self.node.set_r(val)
+#     def set_scale(self, val): return self.node.set_scale(val)
+#     def set_transparency(self, val): return self.node.set_transparency(val)
+#     def set_alpha_scale(self, val): return self.node.set_alpha_scale(val)
+#     def set_texture(self, texturestage, texture):
+#         return self.node.set_texture(texturestage, texture)
+#     def has_tag(self, name): return self.node.has_tag(name)
+#     def get_tag(self, name): return self.node.get_tag(name)
+#     def get_python_tag(self, name): return self.node.get_python_tag(name)
+#     def remove_node(self): return self.node.remove_node()
+#     def flatten_strong(self): return self.node.flatten_strong()
+#     def clear_model_nodes(self): return self.node.clear_model_nodes()
+#     def show(self): return self.node.show()
+#     def set_depth_offset(self, val): return self.node.set_depth_offset(val)
+#     def loop(self, val): return self.node.loop(val)
+#     def cleanup(self): return self.node.cleanup()
+#     def write_bam_file(self, fname): return self.node.write_bam_file(fname)
 
-    @property
-    def p3dnode(self): return self.node.node()
+#     def attach_node(self, name):
+#         return P3dNode(self.node.attach_new_node(name))
 
-    def set_pos(self, pos): return self.node.set_pos(pos._vec)
-        #TODO: don't access a protected member
+#     def add_shape(self, shape):
+#         return self.node.node().add_shape(shape._mesh_shape)
+#         #TODO: don't access a protected member
 
-    def get_pos(self, other=None):
-        return self.node.get_pos(* [] if other is None else [other.node])
+#     @property
+#     def name(self): return self.node.get_name()
 
-    @property
-    def x(self): return self.node.get_x()
+    @property
+#     def node(self): return self.nodepath
 
-    @property
-    def y(self): return self.node.get_y()
+    @property
+#     def p3dnode(self): return self.node.node()
 
-    @property
-    def z(self): return self.node.get_z()
+#     def set_pos(self, pos): return self.node.set_pos(pos._vec)
+#         #TODO: don't access a protected member
 
-    @property
-    def hpr(self): return self.node.get_hpr()
+#     def get_pos(self, other=None):
+#         return self.node.get_pos(* [] if other is None else [other.node])
 
-    @property
-    def h(self): return self.node.get_h()
+    @property
+#     def x(self): return self.node.get_x()
 
-    @property
-    def p(self): return self.node.get_p()
+    @property
+#     def y(self): return self.node.get_y()
 
-    @property
-    def r(self): return self.node.get_r()
+    @property
+#     def z(self): return self.node.get_z()
 
-    @property
-    def scale(self): return self.node.get_scale()
+    @property
+#     def hpr(self): return self.node.get_hpr()
 
-    @property
-    def is_empty(self): return self.node.is_empty()
+    @property
+#     def h(self): return self.node.get_h()
 
-    def get_relative_vector(self, node, vec):
-        return self.node.get_relative_vector(node.node, vec)
+#     @property
+#     def p(self): return self.node.get_p()
 
-    def set_material(self, mat): return self.node.set_material(mat, 1)
+#     @property
+#     def r(self): return self.node.get_r()
 
-    def set_python_tag(self, name, val):
-        return self.node.set_python_tag(name, val)
+#     @property
+#     def scale(self): return self.node.get_scale()
 
-    def get_distance(self, other_node):
-        return self.node.get_distance(other_node.node)
+#     @property
+#     def is_empty(self): return self.node.is_empty()
 
-    def reparent_to(self, parent): return self.node.reparent_to(parent.node)
+#     def get_relative_vector(self, node, vec):
+#         return self.node.get_relative_vector(node.node, vec)
 
-    def wrt_reparent_to(self, parent):
-        return self.node.wrt_reparent_to(parent.node)
+#     def set_material(self, mat): return self.node.set_material(mat, 1)
 
-    @staticmethod
-    def __get_pandanode(nodepath):
-        if nodepath.has_python_tag('libnode'):
-            return nodepath.get_python_tag('libnode')
-        return P3dNode(nodepath)
+#     def set_python_tag(self, name, val):
+#         return self.node.set_python_tag(name, val)
 
-    def find_all_matches(self, name):
-        nodes = self.node.find_all_matches(name)
-        return [self.__get_pandanode(node) for node in nodes]
+#     def get_distance(self, other_node):
+#         return self.node.get_distance(other_node.node)
 
-    def find(self, name):
-        model = self.node.find(name)
-        if model: return self.__get_pandanode(model)
+#     def reparent_to(self, parent): return self.node.reparent_to(parent.node)
 
-    def optimize(self):
-        self.node.prepare_scene(base.win.get_gsg())  # crash with texture.set_format
-        self.node.premunge_scene(base.win.get_gsg())
+#     def wrt_reparent_to(self, parent):
+#         return self.node.wrt_reparent_to(parent.node)
 
-    def hide(self, mask=None):
-        return self.node.hide(*[] if mask is None else [mask])
+#     @staticmethod
+#     def __get_pandanode(nodepath):
+#         if nodepath.has_python_tag('libnode'):
+#             return nodepath.get_python_tag('libnode')
+#         return P3dNode(nodepath)
 
-    @property
-    def tight_bounds(self): return self.node.get_tight_bounds()
+#     def find_all_matches(self, name):
+#         nodes = self.node.find_all_matches(name)
+#         return [self.__get_pandanode(node) for node in nodes]
 
-    @property
-    def parent(self): return self.node.get_parent()
+#     def find(self, name):
+#         model = self.node.find(name)
+#         if model: return self.__get_pandanode(model)
 
-    @property
-    def children(self): return self.node.get_children()
+#     def optimize(self):
+#         self.node.prepare_scene(base.win.get_gsg())  # crash with texture.set_format
+#         self.node.premunge_scene(base.win.get_gsg())
 
-    def destroy(self): return self.node.remove_node()
+#     def hide(self, mask=None):
+#         return self.node.hide(*[] if mask is None else [mask])
 
+#     @property
+#     def tight_bounds(self): return self.node.get_tight_bounds()
 
-class P3dAnimNode:
+#     @property
+#     def parent(self): return self.node.get_parent()
 
-    def __init__(self, filepath, anim_dct):
-        self.node = Actor(filepath, anim_dct)
+#     @property
+#     def children(self): return self.node.get_children()
 
-    def loop(self, val): return self.node.loop(val)
+#     def destroy(self): return self.node.remove_node()
 
-    def reparent_to(self, node): self.node.reparent_to(node)
 
-    @property
-    def name(self): return self.node.get_name()
+# class P3dAnimNode:
+
+#     def __init__(self, filepath, anim_dct):
+#         self.node = Actor(filepath, anim_dct)
+
+#     def loop(self, val): return self.node.loop(val)
+
+#     def reparent_to(self, node): self.node.reparent_to(node)
+
+#     @property
+#     def name(self): return self.node.get_name()
 
-    def optimize(self):
-        self.node.prepare_scene(base.win.get_gsg())
-        self.node.premunge_scene(base.win.get_gsg())
+    def optimize(self):
+        self.node.prepare_scene(base.win.get_gsg())
+        self.node.premunge_scene(base.win.get_gsg())
 
-    def set_omni(self):
-        self.node.node().set_bounds(OmniBoundingVolume())
-        self.node.node().set_final(True)
+    def set_omni(self):
+        self.node.node().set_bounds(OmniBoundingVolume())
+        self.node.node().set_final(True)
 
-    def destroy(self): self.node.cleanup()
+    def destroy(self): self.node.cleanup()
 
 
-class P3dAmbientLight:
+class P3dAmbientLight:
 
-    def __init__(self, color):
-        ambient_lgt = P3DAmbientLight('ambient light')
-        ambient_lgt.set_color(color)
-        self.ambient_np = render.attach_new_node(ambient_lgt)
-        render.set_light(self.ambient_np)
+    def __init__(self, color):
+        ambient_lgt = P3DAmbientLight('ambient light')
+        ambient_lgt.set_color(color)
+        self.ambient_np = render.attach_new_node(ambient_lgt)
+        render.set_light(self.ambient_np)
 
-    def destroy(self):
-        render.clear_light(self.ambient_np)
-        self.ambient_np.remove_node()
+    def destroy(self):
+        render.clear_light(self.ambient_np)
+        self.ambient_np.remove_node()
 
 
-class P3dSpotlight:
+class P3dSpotlight:
 
-    def __init__(self, mask=None):
-        self.spot_lgt = render.attach_new_node(P3DSpotlight('spot'))
-        snode = self.spot_lgt.node()
-        snode.set_scene(render)
-        snode.set_shadow_caster(True, 1024, 1024)
-        snode.get_lens().set_fov(40)
-        snode.get_lens().set_near_far(20, 200)
-        if mask: snode.set_camera_mask(mask)
-        render.set_light(self.spot_lgt)
+    def __init__(self, mask=None):
+        self.spot_lgt = render.attach_new_node(P3DSpotlight('spot'))
+        snode = self.spot_lgt.node()
+        snode.set_scene(render)
+        snode.set_shadow_caster(True, 1024, 1024)
+        snode.get_lens().set_fov(40)
+        snode.get_lens().set_near_far(20, 200)
+        if mask: snode.set_camera_mask(mask)
+        render.set_light(self.spot_lgt)
 
-    def set_pos(self, pos): return self.spot_lgt.set_pos(*pos)
+    def set_pos(self, pos): return self.spot_lgt.set_pos(*pos)
 
-    def look_at(self, pos): return self.spot_lgt.look_at(*pos)
+    def look_at(self, pos): return self.spot_lgt.look_at(*pos)
 
-    def set_color(self, color): return self.spot_lgt.set_color(*color)
+    def set_color(self, color): return self.spot_lgt.set_color(*color)
 
-    def destroy(self):
-        render.clear_light(self.spot_lgt)
-        self.spot_lgt.remove_node()
+    def destroy(self):
+        render.clear_light(self.spot_lgt)
+        self.spot_lgt.remove_node()
index 80ef54d9952f90e1988b8fcdef3662873b3e5fd5..5e6a214dbdb27e60e7f604309accc066ee389ccf 100755 (executable)
@@ -14,7 +14,7 @@ from direct.gui.DirectFrame import DirectFrame
 from direct.gui.OnscreenText import OnscreenText
 from direct.gui.DirectScrolledFrame import DirectScrolledFrame
 from ya2.observer import Subject
-from ya2.lib.ivals import Seq, Wait, PosIval, Func
+from ya2.lib.ivals import Seq, Wait, PosIval, Func
 
 
 class CommonBase:
@@ -114,292 +114,292 @@ class P3dImg(CommonBase):
     def destroy(self): self.img = self.img.destroy()
 
 
-class P3dBase(CommonBase):
+class P3dBase(CommonBase):
 
-    def __init__(self, tra_src=None, tra_tra=None):
-        # self.text_src_tra = None  # it breaks the gui
-        if tra_src and tra_tra: self.bind_tra(tra_src, tra_tra)
+    def __init__(self, tra_src=None, tra_tra=None):
+        # self.text_src_tra = None  # it breaks the gui
+        if tra_src and tra_tra: self.bind_tra(tra_src, tra_tra)
 
-    def set_pos(self, pos): return self.wdg.set_pos(pos)
-    def show(self): return self.wdg.show()
-    def hide(self): return self.wdg.hide()
+    def set_pos(self, pos): return self.wdg.set_pos(pos)
+    def show(self): return self.wdg.show()
+    def hide(self): return self.wdg.hide()
 
-    def bind_tra(self, text_src, text_transl):
-        # text_transl is not used, anyway we need it since we have this kind of
-        # use: self.bind_transl('example str', _('example str'))
-        # this allows to change translations on the fly keeping the source
-        # text for remapping it later
-        # TODO: try reverse mapping? i.e. retrieve the src string from the
-        # translated one
-        self.text_src_tra = text_src
-        self.text_tra_tra = text_transl
-        tra = lambda self: _(self.text_tra_tra)
-        self.__class__.bind_transl = property(tra)
-        self['text'] = self.bind_transl
+    def bind_tra(self, text_src, text_transl):
+        # text_transl is not used, anyway we need it since we have this kind of
+        # use: self.bind_transl('example str', _('example str'))
+        # this allows to change translations on the fly keeping the source
+        # text for remapping it later
+        # TODO: try reverse mapping? i.e. retrieve the src string from the
+        # translated one
+        self.text_src_tra = text_src
+        self.text_tra_tra = text_transl
+        tra = lambda self: _(self.text_tra_tra)
+        self.__class__.bind_transl = property(tra)
+        self['text'] = self.bind_transl
 
-    def get_pos(self, pos=None):
-        return self.wdg.get_pos(*[pos] if pos else [])
+    def get_pos(self, pos=None):
+        return self.wdg.get_pos(*[pos] if pos else [])
 
-    def __setitem__(self, key, value): self.wdg[key] = value
+    def __setitem__(self, key, value): self.wdg[key] = value
 
-    def __getitem__(self, key): return self.wdg[key]
+#     def __getitem__(self, key): return self.wdg[key]
+
+#     def get_np(self): return self.wdg
+
+#     @property
+#     def hidden(self): return self.wdg.is_hidden()
+
+#     def destroy(self): self.wdg.destroy()
+
+
+# class P3dAbs(P3dBase):
+
+#     def get_value(self): return self.wdg.getValue()
+#     def initialiseoptions(self): return self.wdg.initialiseoptions()
+#     def set_z(self, val): return self.wdg.set_z(val)
+#     def set_shader(self, shader): return self.wdg.set_shader(shader)
+#     def set_shader_input(self, name, val):
+#         return self.wdg.set_shader_input(name, val)
+#     def set_transparency(self, val): return self.wdg.set_transparency(val)
+#     def bind(self, evt, mth): return self.wdg.bind(evt, mth)
+
+#     def attachNewNode(self, gui_itm, sort_order):
+#         # it won't work if we name it attach_node. hopefully this will be
+#         # possible when we'll use decorators in place of mixins
+#         return self.wdg.attachNewNode(gui_itm, sort_order)
+
+#     @property
+#     def is_enabled(self): return self.wdg['state'] != DISABLED
+
+
+# class P3dBtn(P3dAbs):
+
+#     def __init__(
+#             self, text='', parent=None, pos=(0, 0), scale=(1, 1),
+#             cmd=None, frame_size=(-1, 1, -1, 1), click_snd=None,
+#             text_fg=(1, 1, 1, 1), frame_col=(1, 1, 1, 1), text_font=None,
+#             over_snd=None, extra_args=None, frame_texture=None, img=None,
+#             tra_src=None, tra_tra=None, text_scale=1.0):
+#         str2par = {'bottomcenter': base.a2dBottomCenter}
+#         parent = str2par.get(parent, parent)
+#         extra_args = extra_args or []
+#         self.wdg = DirectButton(
+#             text=text, parent=parent, pos=(pos[0], 1, pos[1]),
+#             scale=(scale[0], 1, scale[1]), command=cmd,
+#             frameSize=frame_size, clickSound=click_snd, text_fg=text_fg,
+#             frameColor=frame_col, text_font=text_font, rolloverSound=over_snd,
+#             extraArgs=extra_args, frameTexture=frame_texture, image=img,
+#             text_scale=text_scale)
+#         P3dAbs.__init__(self, tra_src, tra_tra)
+#         self['relief'] = FLAT
+#         args = [(ENTER, self._on_enter), (EXIT, self._on_exit)]
+#         list(map(lambda args: self.bind(*args), args))
+
+#     def _on_enter(self, pos): pass  # pos comes from mouse
+
+#     def _on_exit(self, pos): pass  # pos comes from mouse
+
+#     # we add these with the mixins
+#     # def enable(self): self['state'] = NORMAL
+
+#     # def disable(self): self['state'] = DISABLED
+
+
+# class P3dSlider(P3dAbs):
+
+#     def __init__(
+#             self, parent=None, pos=(0, 0), scale=1, val=0,
+#             frame_col=(1, 1, 1, 1), thumb_frame_col=(1, 1, 1, 1),
+#             cmd=None, range_=(0, 1), tra_src=None, tra_tra=None):
+#         self.wdg = DirectSlider(
+#             parent=parent, pos=(pos[0], 1, pos[1]), scale=scale, value=val,
+#             frameColor=frame_col, thumb_frameColor=thumb_frame_col,
+#             command=cmd, range=range_)
+#         P3dAbs.__init__(self, tra_src, tra_tra)
+
+
+# class P3dCheckBtn(P3dAbs):
+
+#     def __init__(
+#             self, pos=(0, 0), text='', indicator_val=False,
+#             indicator_frame_col=(1, 1, 1, 1), frame_col=(1, 1, 1, 1),
+#             scale=(1, 1, 1), click_snd=None, over_snd=None,
+#             text_fg=(1, 1, 1, 1), text_font=None, cmd=None, tra_src=None,
+#             tra_tra=None):
+#         self.wdg = DirectCheckButton(
+#             pos=(pos[0], 1, pos[1]), text=text, indicatorValue=indicator_val,
+#             indicator_frameColor=indicator_frame_col,
+#             frameColor=frame_col, scale=scale, clickSound=click_snd,
+#             rolloverSound=over_snd, text_fg=text_fg, text_font=text_font,
+#             command=cmd)
+#         P3dAbs.__init__(self, tra_src, tra_tra)
+
+
+# class P3dOptionMenu(P3dAbs):
+
+#     def __init__(
+#             self, text='', items=None, pos=(0, 0), scale=(1, 1, 1),
+#             initialitem='', cmd=None, frame_size=(-1, 1, -1, 1),
+#             click_snd=None, over_snd=None, text_may_change=False,
+#             text_fg=(1, 1, 1, 1), item_frame_col=(1, 1, 1, 1),
+#             frame_col=(1, 1, 1, 1), highlight_col=(1, 1, 1, 1),
+#             text_scale=.05, popup_marker_col=(1, 1, 1, 1),
+#             item_relief=None, item_text_font=None, text_font=None,
+#             tra_src=None, tra_tra=None):
+#         items = items or []
+#         self.wdg = DirectOptionMenu(
+#             text=text, items=items, pos=(pos[0], 1, pos[1]), scale=scale,
+#             initialitem=initialitem, command=cmd, frameSize=frame_size,
+#             clickSound=click_snd, rolloverSound=over_snd,
+#             textMayChange=text_may_change, text_fg=text_fg,
+#             item_frameColor=item_frame_col, frameColor=frame_col,
+#             highlightColor=highlight_col, text_scale=text_scale,
+#             popupMarker_frameColor=popup_marker_col,
+#             item_relief=item_relief, item_text_font=item_text_font,
+#             text_font=text_font)
+#         P3dAbs.__init__(self, tra_src, tra_tra)
+
+#     def set(self, idx, f_cmd=1): return self.wdg.set(idx, f_cmd)
+
+#     @property
+#     def curr_val(self): return self.wdg.get()
+
+#     @property
+#     def curr_idx(self): return self.wdg.selectedIndex
+
+
+# class P3dEntry(P3dAbs, DirectObject, Subject):
+
+#     def __init__(
+#             self, scale=.05, pos=(0, 0), entry_font=None, width=12,
+#             frame_col=(1, 1, 1, 1), initial_text='', obscured=False,
+#             cmd=None, focus_in_cmd=None, focus_in_args=None,
+#             focus_out_cmd=None, focus_out_args=None, parent=None,
+#             tra_src=None, tra_tra=None, text_fg=(1, 1, 1, 1), on_tab=None,
+#             on_click=None):
+#         self.__focused = False
+#         self.__focus_in_cmd = focus_in_cmd
+#         self.__focus_out_cmd = focus_out_cmd
+#         DirectObject.__init__(self)
+#         Subject.__init__(self)
+#         focus_in_args = focus_in_args or []
+#         focus_out_args = focus_out_args or []
+#         self.wdg = DirectEntry(
+#             scale=scale, pos=(pos[0], 1, pos[1]), entryFont=entry_font,
+#             width=width, frameColor=frame_col, initialText=initial_text,
+#             obscured=obscured, command=cmd, focusInCommand=self._focus_in_cmd,
+#             focusInExtraArgs=focus_in_args,
+#             focusOutCommand=self._focus_out_cmd,
+#             focusOutExtraArgs=focus_out_args, parent=parent,
+#             text_fg=text_fg)
+#         P3dAbs.__init__(self, tra_src, tra_tra)
+#         if on_tab:
+#             self.on_tab_cb = on_tab
+#             self.accept('tab-up', self.on_tab)
+#         if on_click: self.wdg.bind(B1PRESS, on_click)
+
+#     def set(self, txt): return self.wdg.set(txt)
+
+#     def _focus_in_cmd(self, *args):
+#         self.__focused = True
+#         if self.__focus_in_cmd: self.__focus_in_cmd(*args)
+#         self.notify('on_entry_enter')
+
+#     def _focus_out_cmd(self, *args):
+#         self.__focused = False
+#         if self.__focus_out_cmd: self.__focus_out_cmd(*args)
+#         self.notify('on_entry_exit')
+
+#     def on_tab(self):
+#         if self.wdg['focus'] == ENTRY_FOCUS_STATE: self.on_tab_cb()
+
+#     @property
+#     def focused(self): return self.__focused
+
+#     @property
+#     def text(self): return self.wdg.get()
+
+#     def enter_text(self, txt):
+#         return self.wdg.enterText(txt)
+
+#     def enable(self): self['state'] = NORMAL
+
+#     def disable(self): self['state'] = DISABLED
+
+#     def destroy(self):
+#         self.ignore('tab-up')
+#         self.on_tab_cb = None
+#         Subject.destroy(self)
+#         P3dAbs.destroy(self)
+
+
+# class P3dLabel(P3dAbs):
+
+#     def __init__(
+#             self, text='', pos=(0, 0), parent=None, text_wordwrap=12,
+#             text_align=None, text_fg=(1, 1, 1, 1), text_font=None, scale=.05,
+#             frame_col=(1, 1, 1, 1), tra_src=None, tra_tra=None, hpr=(0, 0, 0)):
+#         self.wdg = DirectLabel(
+#             text=text, pos=(pos[0], 1, pos[1]), parent=parent,
+#             text_wordwrap=text_wordwrap, text_align=text_align,
+#             text_fg=text_fg, text_font=text_font, scale=scale,
+#             frameColor=frame_col, hpr=hpr)
+#         P3dAbs.__init__(self, tra_src, tra_tra)
+
+#     def set_bin(self, bin_name, priority): return self.wdg.set_bin(bin_name, priority)
+
+#     def set_x(self, x): return self.wdg.set_x(x)
+
+#     def set_alpha_scale(self, alpha): return self.wdg.set_alpha_scale(alpha)
+
+
+# class P3dTxt(P3dBase):
+
+#     def __init__(
+#             self, txt='', pos=(0, 0), scale=.05, wordwrap=12, parent=None,
+#             fg=(1, 1, 1, 1), font=None, align=None, tra_src=None,
+#             tra_tra=None):
+#         str2par = {'bottomleft': base.a2dBottomLeft,
+#                    'bottomright': base.a2dBottomRight,
+#                    'leftcenter': base.a2dLeftCenter}
+#         str2al = {'left': TextNode.A_left, 'right': TextNode.A_right,
+#                   'center': TextNode.A_center}
+#         if parent and parent in str2par: parent = str2par[parent]
+#         if align: align = str2al[align]
+#         self.wdg = OnscreenText(
+#             text=txt, pos=pos, scale=scale, wordwrap=wordwrap,
+#             parent=parent, fg=fg, font=font, align=align)
+#         P3dBase.__init__(self, tra_src, tra_tra)
+
+#     def set_r(self, r): return self.wdg.set_r(r)
+
+
+# class P3dFrame(P3dAbs):
+
+#     def __init__(self, frame_size=(-1, 1, -1, 1), frame_col=(1, 1, 1, 1),
+#                  pos=(0, 0), parent=None, texture_coord=False):
+#         P3dAbs.__init__(self)
+#         self.wdg = DirectFrame(frameSize=frame_size, frameColor=frame_col,
+#                                pos=(pos[0], 1, pos[1]), parent=parent)
+#         if texture_coord: self.wdg['frameTexture'] = Texture()
+
+
+# class P3dScrolledFrame(P3dAbs):
+
+#     def __init__(
+#             self, frame_sz=(-1, 1, -1, 1), canvas_sz=(0, 1, 0, 1),
+#             scrollbar_width=.05, frame_col=(1, 1, 1, 1),
+#             pos=(0, 0), parent='topleft'):
+#         P3dAbs.__init__(self)
+#         par2p3d = {'topleft': base.a2dTopLeft}
+#         if parent and parent in par2p3d: parent = par2p3d[parent]
+#         self.wdg = DirectScrolledFrame(
+#             frameSize=frame_sz,
+#             canvasSize=canvas_sz,
+#             scrollBarWidth=scrollbar_width,
+#             frameColor=frame_col,
+#             pos=(pos[0], 1, pos[1]),
+#             parent=parent)
 
-    def get_np(self): return self.wdg
-
-    @property
-    def hidden(self): return self.wdg.is_hidden()
-
-    def destroy(self): self.wdg.destroy()
-
-
-class P3dAbs(P3dBase):
-
-    def get_value(self): return self.wdg.getValue()
-    def initialiseoptions(self): return self.wdg.initialiseoptions()
-    def set_z(self, val): return self.wdg.set_z(val)
-    def set_shader(self, shader): return self.wdg.set_shader(shader)
-    def set_shader_input(self, name, val):
-        return self.wdg.set_shader_input(name, val)
-    def set_transparency(self, val): return self.wdg.set_transparency(val)
-    def bind(self, evt, mth): return self.wdg.bind(evt, mth)
-
-    def attachNewNode(self, gui_itm, sort_order):
-        # it won't work if we name it attach_node. hopefully this will be
-        # possible when we'll use decorators in place of mixins
-        return self.wdg.attachNewNode(gui_itm, sort_order)
-
-    @property
-    def is_enabled(self): return self.wdg['state'] != DISABLED
-
-
-class P3dBtn(P3dAbs):
-
-    def __init__(
-            self, text='', parent=None, pos=(0, 0), scale=(1, 1),
-            cmd=None, frame_size=(-1, 1, -1, 1), click_snd=None,
-            text_fg=(1, 1, 1, 1), frame_col=(1, 1, 1, 1), text_font=None,
-            over_snd=None, extra_args=None, frame_texture=None, img=None,
-            tra_src=None, tra_tra=None, text_scale=1.0):
-        str2par = {'bottomcenter': base.a2dBottomCenter}
-        parent = str2par.get(parent, parent)
-        extra_args = extra_args or []
-        self.wdg = DirectButton(
-            text=text, parent=parent, pos=(pos[0], 1, pos[1]),
-            scale=(scale[0], 1, scale[1]), command=cmd,
-            frameSize=frame_size, clickSound=click_snd, text_fg=text_fg,
-            frameColor=frame_col, text_font=text_font, rolloverSound=over_snd,
-            extraArgs=extra_args, frameTexture=frame_texture, image=img,
-            text_scale=text_scale)
-        P3dAbs.__init__(self, tra_src, tra_tra)
-        self['relief'] = FLAT
-        args = [(ENTER, self._on_enter), (EXIT, self._on_exit)]
-        list(map(lambda args: self.bind(*args), args))
-
-    def _on_enter(self, pos): pass  # pos comes from mouse
-
-    def _on_exit(self, pos): pass  # pos comes from mouse
-
-    # we add these with the mixins
-    # def enable(self): self['state'] = NORMAL
-
-    # def disable(self): self['state'] = DISABLED
-
-
-class P3dSlider(P3dAbs):
-
-    def __init__(
-            self, parent=None, pos=(0, 0), scale=1, val=0,
-            frame_col=(1, 1, 1, 1), thumb_frame_col=(1, 1, 1, 1),
-            cmd=None, range_=(0, 1), tra_src=None, tra_tra=None):
-        self.wdg = DirectSlider(
-            parent=parent, pos=(pos[0], 1, pos[1]), scale=scale, value=val,
-            frameColor=frame_col, thumb_frameColor=thumb_frame_col,
-            command=cmd, range=range_)
-        P3dAbs.__init__(self, tra_src, tra_tra)
-
-
-class P3dCheckBtn(P3dAbs):
-
-    def __init__(
-            self, pos=(0, 0), text='', indicator_val=False,
-            indicator_frame_col=(1, 1, 1, 1), frame_col=(1, 1, 1, 1),
-            scale=(1, 1, 1), click_snd=None, over_snd=None,
-            text_fg=(1, 1, 1, 1), text_font=None, cmd=None, tra_src=None,
-            tra_tra=None):
-        self.wdg = DirectCheckButton(
-            pos=(pos[0], 1, pos[1]), text=text, indicatorValue=indicator_val,
-            indicator_frameColor=indicator_frame_col,
-            frameColor=frame_col, scale=scale, clickSound=click_snd,
-            rolloverSound=over_snd, text_fg=text_fg, text_font=text_font,
-            command=cmd)
-        P3dAbs.__init__(self, tra_src, tra_tra)
-
-
-class P3dOptionMenu(P3dAbs):
-
-    def __init__(
-            self, text='', items=None, pos=(0, 0), scale=(1, 1, 1),
-            initialitem='', cmd=None, frame_size=(-1, 1, -1, 1),
-            click_snd=None, over_snd=None, text_may_change=False,
-            text_fg=(1, 1, 1, 1), item_frame_col=(1, 1, 1, 1),
-            frame_col=(1, 1, 1, 1), highlight_col=(1, 1, 1, 1),
-            text_scale=.05, popup_marker_col=(1, 1, 1, 1),
-            item_relief=None, item_text_font=None, text_font=None,
-            tra_src=None, tra_tra=None):
-        items = items or []
-        self.wdg = DirectOptionMenu(
-            text=text, items=items, pos=(pos[0], 1, pos[1]), scale=scale,
-            initialitem=initialitem, command=cmd, frameSize=frame_size,
-            clickSound=click_snd, rolloverSound=over_snd,
-            textMayChange=text_may_change, text_fg=text_fg,
-            item_frameColor=item_frame_col, frameColor=frame_col,
-            highlightColor=highlight_col, text_scale=text_scale,
-            popupMarker_frameColor=popup_marker_col,
-            item_relief=item_relief, item_text_font=item_text_font,
-            text_font=text_font)
-        P3dAbs.__init__(self, tra_src, tra_tra)
-
-    def set(self, idx, f_cmd=1): return self.wdg.set(idx, f_cmd)
-
-    @property
-    def curr_val(self): return self.wdg.get()
-
-    @property
-    def curr_idx(self): return self.wdg.selectedIndex
-
-
-class P3dEntry(P3dAbs, DirectObject, Subject):
-
-    def __init__(
-            self, scale=.05, pos=(0, 0), entry_font=None, width=12,
-            frame_col=(1, 1, 1, 1), initial_text='', obscured=False,
-            cmd=None, focus_in_cmd=None, focus_in_args=None,
-            focus_out_cmd=None, focus_out_args=None, parent=None,
-            tra_src=None, tra_tra=None, text_fg=(1, 1, 1, 1), on_tab=None,
-            on_click=None):
-        self.__focused = False
-        self.__focus_in_cmd = focus_in_cmd
-        self.__focus_out_cmd = focus_out_cmd
-        DirectObject.__init__(self)
-        Subject.__init__(self)
-        focus_in_args = focus_in_args or []
-        focus_out_args = focus_out_args or []
-        self.wdg = DirectEntry(
-            scale=scale, pos=(pos[0], 1, pos[1]), entryFont=entry_font,
-            width=width, frameColor=frame_col, initialText=initial_text,
-            obscured=obscured, command=cmd, focusInCommand=self._focus_in_cmd,
-            focusInExtraArgs=focus_in_args,
-            focusOutCommand=self._focus_out_cmd,
-            focusOutExtraArgs=focus_out_args, parent=parent,
-            text_fg=text_fg)
-        P3dAbs.__init__(self, tra_src, tra_tra)
-        if on_tab:
-            self.on_tab_cb = on_tab
-            self.accept('tab-up', self.on_tab)
-        if on_click: self.wdg.bind(B1PRESS, on_click)
-
-    def set(self, txt): return self.wdg.set(txt)
-
-    def _focus_in_cmd(self, *args):
-        self.__focused = True
-        if self.__focus_in_cmd: self.__focus_in_cmd(*args)
-        self.notify('on_entry_enter')
-
-    def _focus_out_cmd(self, *args):
-        self.__focused = False
-        if self.__focus_out_cmd: self.__focus_out_cmd(*args)
-        self.notify('on_entry_exit')
-
-    def on_tab(self):
-        if self.wdg['focus'] == ENTRY_FOCUS_STATE: self.on_tab_cb()
-
-    @property
-    def focused(self): return self.__focused
-
-    @property
-    def text(self): return self.wdg.get()
-
-    def enter_text(self, txt):
-        return self.wdg.enterText(txt)
-
-    def enable(self): self['state'] = NORMAL
-
-    def disable(self): self['state'] = DISABLED
-
-    def destroy(self):
-        self.ignore('tab-up')
-        self.on_tab_cb = None
-        Subject.destroy(self)
-        P3dAbs.destroy(self)
-
-
-class P3dLabel(P3dAbs):
-
-    def __init__(
-            self, text='', pos=(0, 0), parent=None, text_wordwrap=12,
-            text_align=None, text_fg=(1, 1, 1, 1), text_font=None, scale=.05,
-            frame_col=(1, 1, 1, 1), tra_src=None, tra_tra=None, hpr=(0, 0, 0)):
-        self.wdg = DirectLabel(
-            text=text, pos=(pos[0], 1, pos[1]), parent=parent,
-            text_wordwrap=text_wordwrap, text_align=text_align,
-            text_fg=text_fg, text_font=text_font, scale=scale,
-            frameColor=frame_col, hpr=hpr)
-        P3dAbs.__init__(self, tra_src, tra_tra)
-
-    def set_bin(self, bin_name, priority): return self.wdg.set_bin(bin_name, priority)
-
-    def set_x(self, x): return self.wdg.set_x(x)
-
-    def set_alpha_scale(self, alpha): return self.wdg.set_alpha_scale(alpha)
-
-
-class P3dTxt(P3dBase):
-
-    def __init__(
-            self, txt='', pos=(0, 0), scale=.05, wordwrap=12, parent=None,
-            fg=(1, 1, 1, 1), font=None, align=None, tra_src=None,
-            tra_tra=None):
-        str2par = {'bottomleft': base.a2dBottomLeft,
-                   'bottomright': base.a2dBottomRight,
-                   'leftcenter': base.a2dLeftCenter}
-        str2al = {'left': TextNode.A_left, 'right': TextNode.A_right,
-                  'center': TextNode.A_center}
-        if parent and parent in str2par: parent = str2par[parent]
-        if align: align = str2al[align]
-        self.wdg = OnscreenText(
-            text=txt, pos=pos, scale=scale, wordwrap=wordwrap,
-            parent=parent, fg=fg, font=font, align=align)
-        P3dBase.__init__(self, tra_src, tra_tra)
-
-    def set_r(self, r): return self.wdg.set_r(r)
-
-
-class P3dFrame(P3dAbs):
-
-    def __init__(self, frame_size=(-1, 1, -1, 1), frame_col=(1, 1, 1, 1),
-                 pos=(0, 0), parent=None, texture_coord=False):
-        P3dAbs.__init__(self)
-        self.wdg = DirectFrame(frameSize=frame_size, frameColor=frame_col,
-                               pos=(pos[0], 1, pos[1]), parent=parent)
-        if texture_coord: self.wdg['frameTexture'] = Texture()
-
-
-class P3dScrolledFrame(P3dAbs):
-
-    def __init__(
-            self, frame_sz=(-1, 1, -1, 1), canvas_sz=(0, 1, 0, 1),
-            scrollbar_width=.05, frame_col=(1, 1, 1, 1),
-            pos=(0, 0), parent='topleft'):
-        P3dAbs.__init__(self)
-        par2p3d = {'topleft': base.a2dTopLeft}
-        if parent and parent in par2p3d: parent = par2p3d[parent]
-        self.wdg = DirectScrolledFrame(
-            frameSize=frame_sz,
-            canvasSize=canvas_sz,
-            scrollBarWidth=scrollbar_width,
-            frameColor=frame_col,
-            pos=(pos[0], 1, pos[1]),
-            parent=parent)
-
-    @property
-    def canvas(self): return self.wdg.getCanvas()
+#     @property
+#     def canvas(self): return self.wdg.getCanvas()
index 182c6e3899a05813461c9c1a793872147ea75a6d..898d6de1872d7583b8dc2d31aa81c0b45a7039fd 100644 (file)
@@ -1,33 +1,33 @@
-from direct.interval.MetaInterval import Sequence
-from direct.interval.FunctionInterval import Func, Wait
-from direct.interval.LerpInterval import LerpPosInterval
+from direct.interval.MetaInterval import Sequence
+from direct.interval.FunctionInterval import Func, Wait
+from direct.interval.LerpInterval import LerpPosInterval
 
 
-class P3dSeq:
+class P3dSeq:
 
-    def __init__(self, *ivals):
-        self.seq = Sequence(*[ival._ival for ival in ivals])
-        #TODO: don't access a protected member
+    def __init__(self, *ivals):
+        self.seq = Sequence(*[ival._ival for ival in ivals])
+        #TODO: don't access a protected member
 
-    def start(self): return self.seq.start()
+    def start(self): return self.seq.start()
 
-    def __add__(self, ival):
-        self.seq.append(ival._ival)  #TODO: don't access a protected member
-        return self.seq
+    def __add__(self, ival):
+        self.seq.append(ival._ival)  #TODO: don't access a protected member
+        return self.seq
 
 
-class P3dWait:
+class P3dWait:
 
-    def __init__(self, time): self._ival = Wait(time)
+    def __init__(self, time): self._ival = Wait(time)
 
 
-class P3dPosIval:
+class P3dPosIval:
 
-    def __init__(self, node, time=1.0, pos=(0, 0, 0), blend_type='ease'):
-        btype = {'ease': 'easeInOut'}[blend_type]
-        self._ival = LerpPosInterval(node, time, pos=pos, blendType=btype)
+    def __init__(self, node, time=1.0, pos=(0, 0, 0), blend_type='ease'):
+        btype = {'ease': 'easeInOut'}[blend_type]
+        self._ival = LerpPosInterval(node, time, pos=pos, blendType=btype)
 
 
-class P3dFunc:
+class P3dFunc:
 
-    def __init__(self, fun, *args): self._ival = Func(fun, *args)
+    def __init__(self, fun, *args): self._ival = Func(fun, *args)
index 37ab8ddee6f532db426b3185e2929dbff58a165a..676f018e7804f051317f9608e57d4732d405debb 100644 (file)
-from panda3d.core import InputDevice
+from panda3d.core import InputDevice
 
 
-class P3dJoystickMgr:
+class P3dJoystickMgr:
 
-    def __init__(self):
-        self.joysticks = []
-        self.curr_vibration = {}
-        self.__is_vibrating = [False, False, False, False]
+    def __init__(self):
+        self.joysticks = []
+        self.curr_vibration = {}
+        self.__is_vibrating = [False, False, False, False]
 
-    def init_joystick(self):
-        for i, dev in enumerate(base.devices.getDevices(InputDevice.DeviceClass.gamepad)):
-            base.attachInputDevice(dev, prefix='joypad%s' % i)
-        taskMgr.add(self._update, 'update joysticks')
-        # pygame.init()
-        # joystick.init()
-        # self.joysticks = [
-        #     joystick.Joystick(idx) for idx in range(joystick.get_count())]
-        # list(map(lambda joystick: joystick.init(), self.joysticks))
+    def init_joystick(self):
+        for i, dev in enumerate(base.devices.getDevices(InputDevice.DeviceClass.gamepad)):
+            base.attachInputDevice(dev, prefix='joypad%s' % i)
+        taskMgr.add(self._update, 'update joysticks')
+        # pygame.init()
+        # joystick.init()
+        # self.joysticks = [
+        #     joystick.Joystick(idx) for idx in range(joystick.get_count())]
+        # list(map(lambda joystick: joystick.init(), self.joysticks))
 
-    @property
-    def num_joysticks(self):
-        return len(base.devices.getDevices(InputDevice.DeviceClass.gamepad))
+    @property
+    def num_joysticks(self):
+        return len(base.devices.getDevices(InputDevice.DeviceClass.gamepad))
 
-    @staticmethod
-    def get_joystick(player_idx):
-        devices = base.devices.getDevices(InputDevice.DeviceClass.gamepad)
-        if player_idx > len(devices) - 1:
-            return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-        gamepad = devices[player_idx]
-        face_a = gamepad.findButton('face_a')
-        face_b = gamepad.findButton('face_b')
-        face_x = gamepad.findButton('face_x')
-        face_y = gamepad.findButton('face_y')
-        dpad_l = gamepad.findButton('dpad_left')
-        dpad_r = gamepad.findButton('dpad_right')
-        dpad_u = gamepad.findButton('dpad_up')
-        dpad_d = gamepad.findButton('dpad_down')
-        trigger_l = gamepad.findButton('ltrigger')
-        trigger_r = gamepad.findButton('rtrigger')
-        shoulder_l = gamepad.findButton('lshoulder')
-        shoulder_r = gamepad.findButton('rshoulder')
-        stick_l = gamepad.findButton('lstick')
-        stick_r = gamepad.findButton('rstick')
-        left_x = gamepad.findAxis(InputDevice.Axis.left_x)
-        left_y = gamepad.findAxis(InputDevice.Axis.left_y)
-        trigger_l_axis = gamepad.findAxis(InputDevice.Axis.left_trigger)
-        trigger_r_axis = gamepad.findAxis(InputDevice.Axis.right_trigger)
-        trigger_l_known = trigger_l.known
-        trigger_r_known = trigger_r.known
-        return (left_x.value, -left_y.value, face_a.pressed, face_b.pressed,
-                face_x.pressed, face_y.pressed,
-                dpad_l.pressed, dpad_r.pressed, dpad_u.pressed, dpad_d.pressed,
-                trigger_l.pressed or trigger_l_axis.value > .5,
-                trigger_r.pressed or trigger_r_axis.value > .5,
-                shoulder_l.pressed, shoulder_r.pressed, stick_l.pressed,
-                stick_r.pressed, trigger_l_known, trigger_r_known)
-        # for _ in pygame.event.get(): pass
-        # if not self.joysticks: return 0, 0, 0, 0
-        # jstick = self.joysticks[0]
-        # axis, btn = jstick.get_axis, jstick.get_button
-        # return axis(0), axis(1), btn(0), btn(1)
+    @staticmethod
+    def get_joystick(player_idx):
+        devices = base.devices.getDevices(InputDevice.DeviceClass.gamepad)
+        if player_idx > len(devices) - 1:
+            return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+        gamepad = devices[player_idx]
+        face_a = gamepad.findButton('face_a')
+        face_b = gamepad.findButton('face_b')
+        face_x = gamepad.findButton('face_x')
+        face_y = gamepad.findButton('face_y')
+        dpad_l = gamepad.findButton('dpad_left')
+        dpad_r = gamepad.findButton('dpad_right')
+        dpad_u = gamepad.findButton('dpad_up')
+        dpad_d = gamepad.findButton('dpad_down')
+        trigger_l = gamepad.findButton('ltrigger')
+        trigger_r = gamepad.findButton('rtrigger')
+        shoulder_l = gamepad.findButton('lshoulder')
+        shoulder_r = gamepad.findButton('rshoulder')
+        stick_l = gamepad.findButton('lstick')
+        stick_r = gamepad.findButton('rstick')
+        left_x = gamepad.findAxis(InputDevice.Axis.left_x)
+        left_y = gamepad.findAxis(InputDevice.Axis.left_y)
+        trigger_l_axis = gamepad.findAxis(InputDevice.Axis.left_trigger)
+        trigger_r_axis = gamepad.findAxis(InputDevice.Axis.right_trigger)
+        trigger_l_known = trigger_l.known
+        trigger_r_known = trigger_r.known
+        return (left_x.value, -left_y.value, face_a.pressed, face_b.pressed,
+                face_x.pressed, face_y.pressed,
+                dpad_l.pressed, dpad_r.pressed, dpad_u.pressed, dpad_d.pressed,
+                trigger_l.pressed or trigger_l_axis.value > .5,
+                trigger_r.pressed or trigger_r_axis.value > .5,
+                shoulder_l.pressed, shoulder_r.pressed, stick_l.pressed,
+                stick_r.pressed, trigger_l_known, trigger_r_known)
+        # for _ in pygame.event.get(): pass
+        # if not self.joysticks: return 0, 0, 0, 0
+        # jstick = self.joysticks[0]
+        # axis, btn = jstick.get_axis, jstick.get_button
+        # return axis(0), axis(1), btn(0), btn(1)
 
-    def set_vibration(self, player_idx, code, time=-1):
-        devices = base.devices.getDevices(InputDevice.DeviceClass.gamepad)
-        if player_idx < 0 or player_idx > len(devices) - 1: return
-        if player_idx in self.curr_vibration and \
-               code in self.curr_vibration[player_idx]: return
-        if player_idx not in self.curr_vibration:
-            self.curr_vibration[player_idx] = {}
-        self.curr_vibration[player_idx][code] = time
+    def set_vibration(self, player_idx, code, time=-1):
+        devices = base.devices.getDevices(InputDevice.DeviceClass.gamepad)
+        if player_idx < 0 or player_idx > len(devices) - 1: return
+        if player_idx in self.curr_vibration and \
+               code in self.curr_vibration[player_idx]: return
+        if player_idx not in self.curr_vibration:
+            self.curr_vibration[player_idx] = {}
+        self.curr_vibration[player_idx][code] = time
 
-    def clear_vibration(self, player_idx, code=None):
-        devices = base.devices.getDevices(InputDevice.DeviceClass.gamepad)
-        if player_idx < 0 or player_idx > len(devices) - 1: return
-        if player_idx not in self.curr_vibration or \
-           code not in self.curr_vibration[player_idx]: return
-        if code is None: del self.curr_vibration[player_idx]
-        else: del self.curr_vibration[player_idx][code]
+    def clear_vibration(self, player_idx, code=None):
+        devices = base.devices.getDevices(InputDevice.DeviceClass.gamepad)
+        if player_idx < 0 or player_idx > len(devices) - 1: return
+        if player_idx not in self.curr_vibration or \
+           code not in self.curr_vibration[player_idx]: return
+        if code is None: del self.curr_vibration[player_idx]
+        else: del self.curr_vibration[player_idx][code]
 
-    def _update(self, task):
-        devices = base.devices.getDevices(InputDevice.DeviceClass.gamepad)
-        for player_idx in self.curr_vibration:
-            for code in self.curr_vibration[player_idx]:
-                if self.curr_vibration[player_idx][code] != -1:
-                    dt = globalClock.getDt()
-                    self.curr_vibration[player_idx][code] -= dt
-        for player_idx in self.curr_vibration:
-            for code in list(self.curr_vibration[player_idx])[:]:
-                if self.curr_vibration[player_idx][code] != -1:
-                    if self.curr_vibration[player_idx][code] < 0:
-                        del self.curr_vibration[player_idx][code]
-        for player_idx in list(self.curr_vibration)[:]:
-            if not self.curr_vibration[player_idx]:
-                del self.curr_vibration[player_idx]
-        for player_idx, dev in enumerate(devices):
-            gamepad = devices[player_idx]
-            if player_idx in self.curr_vibration and \
-                    not self.__is_vibrating[player_idx]:
-                gamepad.set_vibration(.2, .4)
-                self.__is_vibrating[player_idx] = True
-            elif player_idx not in self.curr_vibration:
-                gamepad.set_vibration(0, 0)
-                self.__is_vibrating[player_idx] = False
-        return task.cont
+    def _update(self, task):
+        devices = base.devices.getDevices(InputDevice.DeviceClass.gamepad)
+        for player_idx in self.curr_vibration:
+            for code in self.curr_vibration[player_idx]:
+                if self.curr_vibration[player_idx][code] != -1:
+                    dt = globalClock.getDt()
+                    self.curr_vibration[player_idx][code] -= dt
+        for player_idx in self.curr_vibration:
+            for code in list(self.curr_vibration[player_idx])[:]:
+                if self.curr_vibration[player_idx][code] != -1:
+                    if self.curr_vibration[player_idx][code] < 0:
+                        del self.curr_vibration[player_idx][code]
+        for player_idx in list(self.curr_vibration)[:]:
+            if not self.curr_vibration[player_idx]:
+                del self.curr_vibration[player_idx]
+        for player_idx, dev in enumerate(devices):
+            gamepad = devices[player_idx]
+            if player_idx in self.curr_vibration and \
+                    not self.__is_vibrating[player_idx]:
+                gamepad.set_vibration(.2, .4)
+                self.__is_vibrating[player_idx] = True
+            elif player_idx not in self.curr_vibration:
+                gamepad.set_vibration(0, 0)
+                self.__is_vibrating[player_idx] = False
+        return task.cont
 
-    def destroy(self):
-        pass
-        # joystick.quit()
-        # pygame.quit()
-        # self.joysticks = []
+    def destroy(self):
+        pass
+        # joystick.quit()
+        # pygame.quit()
+        # self.joysticks = []
index 0721813fca2fd667f843c143fd108f3d7773a20e..f4115e99b81b4d1be5a872d220f57c0bceee64fa 100755 (executable)
@@ -13,7 +13,7 @@ from direct.task.Task import Task
 #from gltf import patch_loader
 
 
-class LibShowBase(ShowBase): pass
+class LibShowBase(ShowBase): pass
 
 
 class LibP3d(DirectObject):
index 6884ef6d986b388a36d2f47b39c8e2729f8811a7..9cc92088da8f06ed147c6bde472bbd10b8e3493c 100755 (executable)
-from math import pi, sin, cos
-from array import array
-from random import uniform
-from itertools import chain
-from logging import info
-from panda3d.core import Geom, GeomVertexFormat, GeomVertexData, GeomPoints, \
-    OmniBoundingVolume, GeomNode, Vec3, ShaderAttrib, TexGenAttrib, \
-    TextureStage, Texture, GeomEnums, NodePath
-from ya2.lib.p3d.shader import load_shader
-from ya2.lib.p3d.gfx import P3dNode
-from ya2.gameobject import GameObject
-
-
-class P3dParticle(GameObject):
-
-    _vdata = {}  # don't regenerate input structures
-
-    def __init__(
-            self, emitter, texture, color=(1, 1, 1, 1), ampl=pi/6,
-            ray=.5, rate=.001, gravity=-9.81, vel=1.0, part_duration=1.0,
-            autodestroy=None, size=10):
-        GameObject.__init__(self)
-        self.__tex_pos = self.__tex_curr_pos = self.__tex_times = \
-            self.__tex_start_vel = self.__tex_curr_vel = self.__emitternode = \
-            None
-        self.__texture = texture
-        self.__color = color
-        self.__ampl = ampl
-        self.__ray = ray
-        self.__rate = rate
-        self.__gravity = gravity
-        self.__vel = vel
-        self.__part_duration = part_duration
-        self.__size = size
-        self.__npart = int(round(part_duration * 1 / rate))
-        if emitter.__class__ != P3dNode:  # emitter is a position
-            self.__emitternode = P3dNode(NodePath('tmp'))
-            self.__emitternode.set_pos(emitter)
-            self.__emitternode.reparent_to(self.eng.gfx.root)
-            emitter = self.__emitternode
-        self.__emitter = emitter
-        self.__old_pos = (0, 0, 0)
-        self._nodepath = render.attach_new_node(self.__node())
-        self._nodepath.set_transparency(True)
-        self._nodepath.set_bin('fixed', 0)
-        self.__set_shader()
-        self._nodepath.set_render_mode_thickness(10)
-        self._nodepath.set_tex_gen(TextureStage.getDefault(),
-                                   TexGenAttrib.MPointSprite)
-        self._nodepath.set_depth_write(False)
-        self.upd_tsk = taskMgr.add(self._update, 'update')
-        if autodestroy: self.eng.do_later(autodestroy, self.destroy)
-
-    def __node(self):
-        points = GeomPoints(GeomEnums.UH_static)
-        points.add_next_vertices(self.__npart)
-        geom = Geom(self.__vdata())
-        geom.add_primitive(points)
-        geom.set_bounds(OmniBoundingVolume())
-        node = GeomNode('node')
-        node.add_geom(geom)
-        return node
-
-    def __vdata(self):
-        entry = (self.__texture, self.__npart, self.__color, self.__ampl,
-                 self.__ray, self.__rate, self.__gravity)
-        if entry in P3dParticle._vdata:
-            vdata, pos, times, vels = P3dParticle._vdata[entry]
-            self.__set_textures(pos, times, vels)
-            return vdata
-        pos, times, vels = self.__init_textures()
-        self.__set_textures(pos, times, vels)
-        format_ = GeomVertexFormat.get_empty()
-        vdata = GeomVertexData('abc', format_, GeomEnums.UH_static)
-        P3dParticle._vdata[self.__texture, self.__npart, self.__color,
-                           self.__ampl, self.__ray, self.__rate,
-                           self.__gravity] = \
-            vdata, pos, times, vels
-        return P3dParticle._vdata[self.__texture, self.__npart, self.__color,
-                                  self.__ampl, self.__ray, self.__rate,
-                                  self.__gravity][0]
-
-    def __init_textures(self):
-        positions = [self.__rnd_pos() for i in range(self.__npart)]
-        pos_lst = [[pos.x, pos.y, pos.z, 1] for pos in positions]
-        pos_lst = list(chain.from_iterable(pos_lst))
-        emission_times = [
-            (self.__rate * i, 0, 0, 0) for i in range(self.__npart)]
-        times_lst = list(chain.from_iterable(emission_times))
-        velocities = self.__init_velocities()
-        vel_lst = [[v_vel[0], v_vel[1], v_vel[2], 1] for v_vel in velocities]
-        vel_lst = list(chain.from_iterable(vel_lst))
-        return pos_lst, times_lst, vel_lst
-
-    def __set_textures(self, pos_lst, times_lst, vel_lst):
-        self.__tex_pos = self.__buff_tex(pos_lst)
-        self.__tex_curr_pos = self.__buff_tex(pos_lst)
-        self.__tex_times = self.__buff_tex(times_lst)
-        self.__tex_start_vel = self.__buff_tex(vel_lst)
-        self.__tex_curr_vel = self.__buff_tex(vel_lst)
-
-    def __buff_tex(self, vals):
-        data = array('f', vals)
-        tex = Texture('tex')
-        tex.setup_buffer_texture(
-            self.__npart, Texture.T_float, Texture.F_rgba32,
-            GeomEnums.UH_static)
-        tex.set_ram_image(data)
-        return tex
-
-    def __rnd_pos(self):
-        ro = uniform(0, self.__ray)
-        alpha = uniform(0, 2 * pi)
-        return Vec3(ro * cos(alpha), ro * sin(alpha), 0)
-
-    def __init_velocities(self):
-        vels = []
-        for _ in range(self.__npart):
-            vec = self.__rnd_vel()
-            vels += [(vec.x, vec.y, vec.z)]
-        return vels
-
-    def __rnd_vel(self):
-        theta = uniform(0, self.__ampl)
-        phi = uniform(0, 2 * pi)
-        vec = Vec3(
-            sin(theta) * cos(phi),
-            sin(theta) * sin(phi),
-            cos(theta))
-        return vec * uniform(self.__vel * .8, self.__vel * 1.2)
-
-    def __set_shader(self):
-        path = 'assets/shaders/'
-        shader = load_shader(path + 'particle.vert', path + 'particle.frag')
-        if not shader: return
-        self._nodepath.set_shader(shader)
-        sha_attr = ShaderAttrib.make(shader)
-        sha_attr = sha_attr.set_flag(ShaderAttrib.F_shader_point_size, True)
-        self._nodepath.set_attrib(sha_attr)
-        img = loader.loadTexture('assets/images/game/%s.dds' % self.__texture)
-        self._nodepath.set_shader_inputs(
-            start_pos=self.__tex_pos,
-            positions=self.__tex_curr_pos,
-            emitter_old_pos=self.__old_pos,
-            emitter_pos=self.__emitter.get_pos(P3dNode(render)),
-            start_vel=self.__tex_start_vel,
-            velocities=self.__tex_curr_vel,
-            accel=(0, 0, self.__gravity),
-            start_time=globalClock.get_frame_time(),
-            emission_times=self.__tex_times,
-            part_duration=self.__part_duration,
-            emitting=1,
-            col=self.__color,
-            image=img,
-            size=self.__size)
-
-    def _update(self, task):
-        if self.__emitter and not self.__emitter.is_empty:
-            pos = self.__emitter.get_pos(P3dNode(render))
-        else: pos = (0, 0, 0)
-        try:
-            self._nodepath.set_shader_inputs(
-                emitter_old_pos=self.__old_pos,
-                emitter_pos=pos)
-            self.__old_pos = pos
-            return task.again
-        except AttributeError:
-            # _nodepath may be None on menu/pause
-            info('_nodepath: %s' % self._nodepath)
-
-    def destroy(self, now=False):
-        #TODO: the signature differs from the parent's one
-        try:
-            self._nodepath.set_shader_input('emitting', 0)
-        except AttributeError:
-            # _nodepath may be None on menu/pause
-            info('_nodepath: %s' % self._nodepath)
-        self.eng.do_later(0 if now else 1.2 * self.__part_duration,
-                          self.__destroy)
-
-    def __destroy(self):
-        try:
-            self.upd_tsk = taskMgr.remove(self.upd_tsk)
-        except TypeError:
-            info("can't remove %s" % self.upd_tsk)
-            # it may happen on pause/menu
-        try:
-            self._nodepath = self._nodepath.remove_node()
-        except AttributeError:
-            info("_nodepath %s" % self._nodepath)
-            # it may happen on pause/menu
-        if self.__emitternode:
-            self.__emitternode = self.__emitternode.destroy()
-        GameObject.destroy(self)
+from math import pi, sin, cos
+from array import array
+from random import uniform
+from itertools import chain
+from logging import info
+from panda3d.core import Geom, GeomVertexFormat, GeomVertexData, GeomPoints, \
+    OmniBoundingVolume, GeomNode, Vec3, ShaderAttrib, TexGenAttrib, \
+    TextureStage, Texture, GeomEnums, NodePath
+from ya2.lib.p3d.shader import load_shader
+from ya2.lib.p3d.gfx import P3dNode
+from ya2.gameobject import GameObject
+
+
+class P3dParticle(GameObject):
+
+    _vdata = {}  # don't regenerate input structures
+
+    def __init__(
+            self, emitter, texture, color=(1, 1, 1, 1), ampl=pi/6,
+            ray=.5, rate=.001, gravity=-9.81, vel=1.0, part_duration=1.0,
+            autodestroy=None, size=10):
+        GameObject.__init__(self)
+        self.__tex_pos = self.__tex_curr_pos = self.__tex_times = \
+            self.__tex_start_vel = self.__tex_curr_vel = self.__emitternode = \
+            None
+        self.__texture = texture
+        self.__color = color
+        self.__ampl = ampl
+        self.__ray = ray
+        self.__rate = rate
+        self.__gravity = gravity
+        self.__vel = vel
+        self.__part_duration = part_duration
+        self.__size = size
+        self.__npart = int(round(part_duration * 1 / rate))
+        if emitter.__class__ != P3dNode:  # emitter is a position
+            self.__emitternode = P3dNode(NodePath('tmp'))
+            self.__emitternode.set_pos(emitter)
+            self.__emitternode.reparent_to(self.eng.gfx.root)
+            emitter = self.__emitternode
+        self.__emitter = emitter
+        self.__old_pos = (0, 0, 0)
+        self._nodepath = render.attach_new_node(self.__node())
+        self._nodepath.set_transparency(True)
+        self._nodepath.set_bin('fixed', 0)
+        self.__set_shader()
+        self._nodepath.set_render_mode_thickness(10)
+        self._nodepath.set_tex_gen(TextureStage.getDefault(),
+                                   TexGenAttrib.MPointSprite)
+        self._nodepath.set_depth_write(False)
+        self.upd_tsk = taskMgr.add(self._update, 'update')
+        if autodestroy: self.eng.do_later(autodestroy, self.destroy)
+
+    def __node(self):
+        points = GeomPoints(GeomEnums.UH_static)
+        points.add_next_vertices(self.__npart)
+        geom = Geom(self.__vdata())
+        geom.add_primitive(points)
+        geom.set_bounds(OmniBoundingVolume())
+        node = GeomNode('node')
+        node.add_geom(geom)
+        return node
+
+    def __vdata(self):
+        entry = (self.__texture, self.__npart, self.__color, self.__ampl,
+                 self.__ray, self.__rate, self.__gravity)
+        if entry in P3dParticle._vdata:
+            vdata, pos, times, vels = P3dParticle._vdata[entry]
+            self.__set_textures(pos, times, vels)
+            return vdata
+        pos, times, vels = self.__init_textures()
+        self.__set_textures(pos, times, vels)
+        format_ = GeomVertexFormat.get_empty()
+        vdata = GeomVertexData('abc', format_, GeomEnums.UH_static)
+        P3dParticle._vdata[self.__texture, self.__npart, self.__color,
+                           self.__ampl, self.__ray, self.__rate,
+                           self.__gravity] = \
+            vdata, pos, times, vels
+        return P3dParticle._vdata[self.__texture, self.__npart, self.__color,
+                                  self.__ampl, self.__ray, self.__rate,
+                                  self.__gravity][0]
+
+    def __init_textures(self):
+        positions = [self.__rnd_pos() for i in range(self.__npart)]
+        pos_lst = [[pos.x, pos.y, pos.z, 1] for pos in positions]
+        pos_lst = list(chain.from_iterable(pos_lst))
+        emission_times = [
+            (self.__rate * i, 0, 0, 0) for i in range(self.__npart)]
+        times_lst = list(chain.from_iterable(emission_times))
+        velocities = self.__init_velocities()
+        vel_lst = [[v_vel[0], v_vel[1], v_vel[2], 1] for v_vel in velocities]
+        vel_lst = list(chain.from_iterable(vel_lst))
+        return pos_lst, times_lst, vel_lst
+
+    def __set_textures(self, pos_lst, times_lst, vel_lst):
+        self.__tex_pos = self.__buff_tex(pos_lst)
+        self.__tex_curr_pos = self.__buff_tex(pos_lst)
+        self.__tex_times = self.__buff_tex(times_lst)
+        self.__tex_start_vel = self.__buff_tex(vel_lst)
+        self.__tex_curr_vel = self.__buff_tex(vel_lst)
+
+    def __buff_tex(self, vals):
+        data = array('f', vals)
+        tex = Texture('tex')
+        tex.setup_buffer_texture(
+            self.__npart, Texture.T_float, Texture.F_rgba32,
+            GeomEnums.UH_static)
+        tex.set_ram_image(data)
+        return tex
+
+    def __rnd_pos(self):
+        ro = uniform(0, self.__ray)
+        alpha = uniform(0, 2 * pi)
+        return Vec3(ro * cos(alpha), ro * sin(alpha), 0)
+
+    def __init_velocities(self):
+        vels = []
+        for _ in range(self.__npart):
+            vec = self.__rnd_vel()
+            vels += [(vec.x, vec.y, vec.z)]
+        return vels
+
+    def __rnd_vel(self):
+        theta = uniform(0, self.__ampl)
+        phi = uniform(0, 2 * pi)
+        vec = Vec3(
+            sin(theta) * cos(phi),
+            sin(theta) * sin(phi),
+            cos(theta))
+        return vec * uniform(self.__vel * .8, self.__vel * 1.2)
+
+    def __set_shader(self):
+        path = 'assets/shaders/'
+        shader = load_shader(path + 'particle.vert', path + 'particle.frag')
+        if not shader: return
+        self._nodepath.set_shader(shader)
+        sha_attr = ShaderAttrib.make(shader)
+        sha_attr = sha_attr.set_flag(ShaderAttrib.F_shader_point_size, True)
+        self._nodepath.set_attrib(sha_attr)
+        img = loader.loadTexture('assets/images/game/%s.dds' % self.__texture)
+        self._nodepath.set_shader_inputs(
+            start_pos=self.__tex_pos,
+            positions=self.__tex_curr_pos,
+            emitter_old_pos=self.__old_pos,
+            emitter_pos=self.__emitter.get_pos(P3dNode(render)),
+            start_vel=self.__tex_start_vel,
+            velocities=self.__tex_curr_vel,
+            accel=(0, 0, self.__gravity),
+            start_time=globalClock.get_frame_time(),
+            emission_times=self.__tex_times,
+            part_duration=self.__part_duration,
+            emitting=1,
+            col=self.__color,
+            image=img,
+            size=self.__size)
+
+    def _update(self, task):
+        if self.__emitter and not self.__emitter.is_empty:
+            pos = self.__emitter.get_pos(P3dNode(render))
+        else: pos = (0, 0, 0)
+        try:
+            self._nodepath.set_shader_inputs(
+                emitter_old_pos=self.__old_pos,
+                emitter_pos=pos)
+            self.__old_pos = pos
+            return task.again
+        except AttributeError:
+            # _nodepath may be None on menu/pause
+            info('_nodepath: %s' % self._nodepath)
+
+    def destroy(self, now=False):
+        #TODO: the signature differs from the parent's one
+        try:
+            self._nodepath.set_shader_input('emitting', 0)
+        except AttributeError:
+            # _nodepath may be None on menu/pause
+            info('_nodepath: %s' % self._nodepath)
+        self.eng.do_later(0 if now else 1.2 * self.__part_duration,
+                          self.__destroy)
+
+    def __destroy(self):
+        try:
+            self.upd_tsk = taskMgr.remove(self.upd_tsk)
+        except TypeError:
+            info("can't remove %s" % self.upd_tsk)
+            # it may happen on pause/menu
+        try:
+            self._nodepath = self._nodepath.remove_node()
+        except AttributeError:
+            info("_nodepath %s" % self._nodepath)
+            # it may happen on pause/menu
+        if self.__emitternode:
+            self.__emitternode = self.__emitternode.destroy()
+        GameObject.destroy(self)
index 3cbe4c62aa9f0b572d0ccf0c22065e077a14b49f..7d00212d1fdf63f2cc5b69ce79d0b77713524c18 100644 (file)
-from os import pardir  # pardir is .. (parent directory)
-from os.path import dirname, abspath, join
-from sys import modules
-from direct.task import Task
-from direct.interval.IntervalGlobal import ivalMgr
-from ya2.gameobject import GameObject
-
-
-class TaskDec:
-
-    paused_taskchain = 'paused tasks'
-
-    def __init__(self, tsk):
-        self.tsk = tsk
-        path = dirname(modules[Task.__name__].__file__)
-        self.__direct_dir = abspath(join(path, pardir))  # path of direct.*
-
-    def process(self):
-        func = self.tsk.get_function()  # ordinary tasks
-        mod = func.__module__
-        modfile = ''
-        if "from '" in str(modules[mod]):
-            modfile = str(modules[mod]).split("from '")[1][:-2]
-        sys_mod = modfile.find(self.__direct_dir) < 0
-        actor_ival = False
-        if hasattr(func, 'im_class'):
-            actor_ival = func.im_class.__name__ == 'ActorInterval'
-        if mod.find('direct.interval') == 0 and not actor_ival:
-            self.tsk.interval.pause()  # python-based intervals
-            return self.tsk
-        if mod not in modules or sys_mod: return self.tsk
-        return None
-
-    def pause(self):
-        tsk = self.tsk
-        has_args = hasattr(tsk, 'getArgs')
-        tsk.stored_extraArgs = tsk.get_args() if has_args else None
-        if hasattr(tsk, 'getFunction'): tsk.stored_call = tsk.get_function()
-        has_p = hasattr(tsk, '_priority')
-        tsk.stored_priority = tsk._priority if has_p else tsk.get_sort()
-        if hasattr(tsk, 'remainingTime'): tsk.remove()  # do_later tasks
-        else:  # ordinary tasks
-            tsk.lastactivetime = -tsk.time if hasattr(tsk, 'time') else 0
-            tsk.setTaskChain(TaskDec.paused_taskchain)
-
-    def __resume_do_later(self):
-        tsk = self.tsk
-        d_t = globalClock.get_real_time() - globalClock.get_frame_time()
-        tmp_delay = tsk.remainingTime - d_t
-        upon_death = tsk.uponDeath if hasattr(tsk, 'uponDeath') else None
-        new_task = taskMgr.doMethodLater(
-            tmp_delay, tsk.stored_call, tsk.name, uponDeath=upon_death,
-            priority=tsk.stored_priority, extraArgs=tsk.stored_extraArgs)
-        if hasattr(tsk, 'remainingTime'): new_task.delayTime = tsk.delayTime
-
-    def resume(self):
-        tsk = self.tsk
-        if hasattr(tsk, 'interval'):
-            tsk.interval.resume()
-            if hasattr(tsk, 'stored_call'): tsk.set_function(tsk.stored_call)
-            return
-        if hasattr(tsk, 'remainingTime'):
-            self.__resume_do_later()
-            return
-        tsk.set_delay(tsk.lastactivetime)  # ordinary tasks
-        tsk.set_task_chain('default')
-        tsk.clear_delay()  # to avoid assertion error on resume
-
-
-class P3dPause(GameObject):
-
-    def __init__(self):
-        GameObject.__init__(self)
-        taskMgr.setupTaskChain(TaskDec.paused_taskchain, frameBudget=0)
-        self.__paused_ivals = []
-        self.__paused_tasks = []
-
-    @property
-    def paused(self):
-        tsk = taskMgr.getTasksNamed('__on_frame')[0]
-        return tsk.getTaskChain() == TaskDec.paused_taskchain
-
-    def pause_tasks(self):
-        is_tsk = lambda tsk: tsk and hasattr(tsk, 'getFunction')
-        tasks = [TaskDec(tsk) for tsk in taskMgr.getTasks() if is_tsk(tsk)]
-        tasks = [tsk for tsk in tasks
-                 if tsk.tsk.get_task_chain() != 'unpausable']
-        namefilter = ['igLoop', 'dataLoop', 'ivalLoop', 'collisionLoop',
-                      'garbageCollectStates', 'audioLoop',
-                      'resetPrevTransform', 'eventManager']
-        tasks = [tsk for tsk in tasks
-                 if tsk.tsk.get_name_prefix() not in namefilter]
-        not_none = lambda tsk: tsk is not None
-        paused_tasks = list(filter(not_none, [tsk.process() for tsk in tasks]))
-        self.__paused_tasks = list(map(TaskDec, paused_tasks))
-        for tsk in list(filter(is_tsk, taskMgr.getDoLaters())):
-            self.__paused_tasks += [TaskDec(tsk)]
-            tsk.remainingTime = tsk.wakeTime - globalClock.get_frame_time()
-        list(map(lambda tsk: tsk.pause(), self.__paused_tasks))
-
-    def remove_task(self, tsk):
-        list(map(self.__paused_tasks.remove, [ptsk for ptsk in self.__paused_tasks if ptsk.tsk == tsk]))
-
-    def pause(self):
-        self.__paused_ivals = ivalMgr.getIntervalsMatching('*')
-        self.pause_tasks()
-        return self.paused
-
-    def resume(self):
-        list(map(lambda ival: ival.resume(), self.__paused_ivals))
-        list(map(lambda tsk: tsk.resume(), self.__paused_tasks))
-        return self.paused
-
-    def destroy(self): GameObject.destroy(self)
+from os import pardir  # pardir is .. (parent directory)
+from os.path import dirname, abspath, join
+from sys import modules
+from direct.task import Task
+from direct.interval.IntervalGlobal import ivalMgr
+from ya2.gameobject import GameObject
+
+
+class TaskDec:
+
+    paused_taskchain = 'paused tasks'
+
+    def __init__(self, tsk):
+        self.tsk = tsk
+        path = dirname(modules[Task.__name__].__file__)
+        self.__direct_dir = abspath(join(path, pardir))  # path of direct.*
+
+    def process(self):
+        func = self.tsk.get_function()  # ordinary tasks
+        mod = func.__module__
+        modfile = ''
+        if "from '" in str(modules[mod]):
+            modfile = str(modules[mod]).split("from '")[1][:-2]
+        sys_mod = modfile.find(self.__direct_dir) < 0
+        actor_ival = False
+        if hasattr(func, 'im_class'):
+            actor_ival = func.im_class.__name__ == 'ActorInterval'
+        if mod.find('direct.interval') == 0 and not actor_ival:
+            self.tsk.interval.pause()  # python-based intervals
+            return self.tsk
+        if mod not in modules or sys_mod: return self.tsk
+        return None
+
+    def pause(self):
+        tsk = self.tsk
+        has_args = hasattr(tsk, 'getArgs')
+        tsk.stored_extraArgs = tsk.get_args() if has_args else None
+        if hasattr(tsk, 'getFunction'): tsk.stored_call = tsk.get_function()
+        has_p = hasattr(tsk, '_priority')
+        tsk.stored_priority = tsk._priority if has_p else tsk.get_sort()
+        if hasattr(tsk, 'remainingTime'): tsk.remove()  # do_later tasks
+        else:  # ordinary tasks
+            tsk.lastactivetime = -tsk.time if hasattr(tsk, 'time') else 0
+            tsk.setTaskChain(TaskDec.paused_taskchain)
+
+    def __resume_do_later(self):
+        tsk = self.tsk
+        d_t = globalClock.get_real_time() - globalClock.get_frame_time()
+        tmp_delay = tsk.remainingTime - d_t
+        upon_death = tsk.uponDeath if hasattr(tsk, 'uponDeath') else None
+        new_task = taskMgr.doMethodLater(
+            tmp_delay, tsk.stored_call, tsk.name, uponDeath=upon_death,
+            priority=tsk.stored_priority, extraArgs=tsk.stored_extraArgs)
+        if hasattr(tsk, 'remainingTime'): new_task.delayTime = tsk.delayTime
+
+    def resume(self):
+        tsk = self.tsk
+        if hasattr(tsk, 'interval'):
+            tsk.interval.resume()
+            if hasattr(tsk, 'stored_call'): tsk.set_function(tsk.stored_call)
+            return
+        if hasattr(tsk, 'remainingTime'):
+            self.__resume_do_later()
+            return
+        tsk.set_delay(tsk.lastactivetime)  # ordinary tasks
+        tsk.set_task_chain('default')
+        tsk.clear_delay()  # to avoid assertion error on resume
+
+
+class P3dPause(GameObject):
+
+    def __init__(self):
+        GameObject.__init__(self)
+        taskMgr.setupTaskChain(TaskDec.paused_taskchain, frameBudget=0)
+        self.__paused_ivals = []
+        self.__paused_tasks = []
+
+    @property
+    def paused(self):
+        tsk = taskMgr.getTasksNamed('__on_frame')[0]
+        return tsk.getTaskChain() == TaskDec.paused_taskchain
+
+    def pause_tasks(self):
+        is_tsk = lambda tsk: tsk and hasattr(tsk, 'getFunction')
+        tasks = [TaskDec(tsk) for tsk in taskMgr.getTasks() if is_tsk(tsk)]
+        tasks = [tsk for tsk in tasks
+                 if tsk.tsk.get_task_chain() != 'unpausable']
+        namefilter = ['igLoop', 'dataLoop', 'ivalLoop', 'collisionLoop',
+                      'garbageCollectStates', 'audioLoop',
+                      'resetPrevTransform', 'eventManager']
+        tasks = [tsk for tsk in tasks
+                 if tsk.tsk.get_name_prefix() not in namefilter]
+        not_none = lambda tsk: tsk is not None
+        paused_tasks = list(filter(not_none, [tsk.process() for tsk in tasks]))
+        self.__paused_tasks = list(map(TaskDec, paused_tasks))
+        for tsk in list(filter(is_tsk, taskMgr.getDoLaters())):
+            self.__paused_tasks += [TaskDec(tsk)]
+            tsk.remainingTime = tsk.wakeTime - globalClock.get_frame_time()
+        list(map(lambda tsk: tsk.pause(), self.__paused_tasks))
+
+    def remove_task(self, tsk):
+        list(map(self.__paused_tasks.remove, [ptsk for ptsk in self.__paused_tasks if ptsk.tsk == tsk]))
+
+    def pause(self):
+        self.__paused_ivals = ivalMgr.getIntervalsMatching('*')
+        self.pause_tasks()
+        return self.paused
+
+    def resume(self):
+        list(map(lambda ival: ival.resume(), self.__paused_ivals))
+        list(map(lambda tsk: tsk.resume(), self.__paused_tasks))
+        return self.paused
+
+    def destroy(self): GameObject.destroy(self)
index f19b224106dd25d6a877bc7bb55402ab09542ac3..3eae60fe4c58a1465263fde3cd027dbb14873bc3 100644 (file)
-from os.path import isfile, dirname
-from panda3d.core import AmbientLight, DirectionalLight, PointLight, \
-    Spotlight, LVector4f, LVector3f, Vec3, Shader, TextureStage, \
-    TexMatrixAttrib
-from direct.filter.FilterManager import FilterManager
-from ya2.lib.builder import LibP3d
-
-
-def load_shader(vert, frag):
-
-    def is_file(path):
-        joinchar = '/' if LibP3d.runtime() and not path.startswith('/') else ''
-        dpath = LibP3d.runtime() and dirname(__file__)
-        return isfile((dpath or '') + joinchar + path)
-    if is_file(vert) and is_file(frag):
-        shader = Shader.load(Shader.SLGLSL, vert, frag)
-    else: shader = Shader.make(Shader.SLGLSL, vert, frag)
-    return shader
-
-
-class P3dShaderMgr:
-
-    def __init__(self, shaders, gamma):
-        self.filter_mgr = None
-        self.gamma, self.buffer, self.lcam, self.lights = gamma, None, None, []
-        if shaders: self.setup_post_fx()
-
-    def __set_lgt(self, lgt, col):
-        if type(col) in [int, float]: lgt.set_color_temperature(col)
-        else: lgt.set_color(col)
-        self.lights += [render.attach_new_node(lgt)]
-        render.set_light(self.lights[-1])
-
-    def set_amb_lgt(self, col):
-        self.__set_lgt(AmbientLight('ambient light'), col)
-
-    def set_dir_lgt(self, col, direction):
-        self.__set_lgt(DirectionalLight('directional light'), col)
-        self.lights[-1].set_hpr(*direction)
-
-    def set_shadow_lgt(self, direction):
-        self.__set_lgt(DirectionalLight('directional light'), (1, 1, 1, 1))
-        self.lights[-1].node().set_shadow_caster(True, 8192, 8192)
-        self.lights[-1].node().get_lens().set_film_size(2048, 2048)
-        self.lights[-1].node().get_lens().set_near_far(1, 2048)
-        #self.lights[-1].node().show_frustum()
-        self.lights[-1].set_hpr(*direction)
-        return self.lights[-1]
-
-    def set_pnt_lgt(self, col, pos):
-        self.__set_lgt(PointLight('point light'), col)
-        self.lights[-1].set_pos(*pos)
-
-    def set_spotlight(self, col, exp, cutoff, pos, look_at):
-        self.__set_lgt(Spotlight('spotlight'), col)
-        self.lights[-1].set_exponent(exp)
-        self.lights[-1].get_lens().set_fov(cutoff, cutoff)
-        self.lights[-1].set_pos(*pos)
-        self.lights[-1].look_at(*look_at)
-
-    @staticmethod
-    def set_default_args(idx):
-        pref = 'lights[%s].' % idx
-        args = [(pref + 'pos', LVector4f(0, 0, 0, 1)),
-                (pref + 'amb', LVector3f(0, 0, 0)),
-                (pref + 'diff', LVector3f(0, 0, 0)),
-                (pref + 'spec', LVector3f(0, 0, 0)),
-                (pref + 'dir', LVector3f(0, 0, 0)),
-                (pref + 'exp', .0),
-                (pref + 'cutoff', .0)]
-        list(map(lambda _args: render.set_shader_input(*_args), args))
-
-    def set_lgt_args(self, idx, lgt):
-        self.set_default_args(idx)
-        ShaderSetter.build(lgt).set('lights[%s].' % idx, lgt)
-
-    def clear_lights(self):
-        for lgt in self.lights:
-            base.render.clear_light(lgt)
-            lgt.removeNode()
-        self.lights = []
-
-    def setup_post_fx(self):
-        self.filter_mgr = FilterManager(base.win, base.cam)
-        # rendered_scene = Texture()
-        # aa_scene = Texture()
-        # filtered_scene = Texture()
-        # filter_quad = self.filter_mgr.renderQuadInto(colortex=filtered_scene)
-        # aa_quad = self.filter_mgr.renderQuadInto(colortex=aa_scene)
-        # final_quad = self.filter_mgr.renderSceneInto(colortex=rendered_scene)
-        # filter_quad.set_shader(self.__load_shader('filter', 'sobel_filter'))
-        # filter_quad.set_shader_input('in_tex', rendered_scene)
-        # aa_quad.set_shader(self.__load_shader('fxaa', 'fxaa'))
-        # aa_quad.set_shader_input('in_tex', filtered_scene)
-        # final_quad.set_shader(self.__load_shader('filter', 'pass'))
-        # final_quad.set_shader_input('gamma', self.gamma)
-        # final_quad.set_shader_input('in_tex', aa_scene)
-
-    @staticmethod
-    def __load_shader(vshad, fshad):
-        with open('assets/shaders/%s.vert' % vshad) as vfile:
-            fvert = vfile.read()
-        with open('assets/shaders/%s.frag' % fshad) as ffile:
-            ffrag = ffile.read()
-        return load_shader(fvert, ffrag)
-
-    def apply(self):
-        # winprops = WindowProperties.size(2048, 2048)
-        # props = FrameBufferProperties()
-        # props.set_rgb_color(1)
-        # props.set_alpha_bits(1)
-        # props.set_depth_bits(1)
-        # lbuffer = base.graphicsEngine.make_output(
-        #     base.pipe, 'offscreen buffer', -2, props, winprops,
-        #     GraphicsPipe.BFRefuseWindow, base.win.getGsg(), base.win)
-        # self.buffer = lbuffer
-        # ldepthmap = Texture()
-        # lbuffer.addRenderTexture(ldepthmap, GraphicsOutput.RTMBindOrCopy,
-        #                          GraphicsOutput.RTPDepthStencil)
-        # ldepthmap.set_minfilter(Texture.FTShadow)
-        # ldepthmap.set_magfilter(Texture.FTShadow)
-
-        # base.camLens.set_near_far(1.0, 10000)
-        # base.camLens.set_fov(75)
-
-        # self.lcam = base.makeCamera(lbuffer)
-        # self.lcam.node().set_scene(render)
-        # self.lcam.node().get_lens().set_fov(45)
-        # self.lcam.node().get_lens().set_near_far(1, 100)
-
-        # render.set_shader_input('light', self.lcam)
-        # render.set_shader_input('depthmap', ldepthmap)
-        # render.set_shader_input('ambient', .15, .15, .15, 1.0)
-
-        # lci = NodePath(PandaNode('light camera initializer'))
-        # lci.set_shader(self.__load_shader('caster', 'caster'))
-        # self.lcam.node().set_initial_state(lci.get_state())
-
-        # mci = NodePath(PandaNode('main camera initializer'))
-        # # use PTALVecBaseX instead
-        # # setShaderInput('vec3argname', PTALVecBase3(((0, 0, 0), (1, 1, 1))))
-        render.set_shader(self.__main_shader())
-        # render.set_shader_input('num_lights', len(self.lights))
-        # self.set_shader_pars(render)
-        # list(map(
-        #     lambda lgt: self.set_lgt_args(*lgt), enumerate(self.lights)))
-        # mci.setShader(self.__main_shader())
-        # base.cam.node().set_initial_state(mci.getState())
-
-        # self.lcam.set_pos(15, 30, 45)
-        # self.lcam.look_at(0, 15, 0)
-        # self.lcam.node().get_lens().set_near_far(1, 100)
-
-    def __main_shader(self):
-        with open('assets/shaders/main.vert') as fvert:
-            vert = fvert.read()
-        with open('assets/shaders/main.frag') as ffrag:
-            frag = ffrag.read()
-        frag = frag.replace('<LIGHTS>', str(len(self.lights)))
-        return load_shader(vert, frag)
-
-    def toggle_shader(self):
-        if render.get_shader():
-            render.set_shader_off()
-            render.set_shader_auto()
-            return
-        self.apply()
-
-    def set_shader_pars(self, model):
-        texture_stages = model.find_all_texture_stages()
-        model.set_shader_input('gloss_slot', 0)
-        model.set_shader_input('detail_slot', 0)
-        model.set_shader_input('detail_scale', (1, 1))
-        for tstage in texture_stages:
-            if tstage.getSort() == 0: continue
-            self.__set_slots(tstage, model, 1 if tstage.getSort() == 10 else 2)
-
-    @staticmethod
-    def __set_slots(tstage, model, slot):
-        if tstage.getMode() == TextureStage.MGloss:
-            model.set_shader_input('gloss_slot', slot)
-        else:
-            model.set_shader_input('detail_slot', slot)
-            attrib_type = TexMatrixAttrib.get_class_type()
-            for geom_np in model.find_all_matches('**/+GeomNode'):
-                geom_node = geom_np.node()
-                for i in range(geom_node.get_num_geoms()):
-                    state = geom_node.get_geom_state(i)
-                    if state.has_attrib(attrib_type):
-                        attrib = state.get_attrib(attrib_type)
-                        for j in range(attrib.get_num_stages()):
-                            stage = attrib.get_stage(j)
-                            scale = attrib.get_transform(stage).get_scale()
-                            model.set_shader_input('detail_scale', scale)
-
-    def destroy(self): self.clear_lights()
-
-
-class ShaderSetter:
-
-    @staticmethod
-    def build(lgt):
-        cls2sett = {
-            AmbientLight: ShaderSetterAmbient,
-            PointLight: ShaderSetterPointLight,
-            DirectionalLight: ShaderSetterDirectionalLight,
-            Spotlight: ShaderSetterSpotlight}
-        return cls2sett[lgt.node().__class__]()
-
-    @staticmethod
-    def _set_pars(pref, lgt_pos, lgt):
-        render.set_shader_input(pref + 'pos', lgt_pos)
-        render.set_shader_input(pref + 'diff', lgt.node().get_color())
-        render.set_shader_input(pref + 'spec', lgt.node().get_color())
-
-
-class ShaderSetterAmbient(ShaderSetter):
-
-    @staticmethod
-    def set(pref, lgt):
-        render.set_shader_input(pref + 'amb', lgt.node().get_color())
-
-
-class ShaderSetterPointLight(ShaderSetter):
-
-    @staticmethod
-    def set(pref, lgt):
-        lgt_pos = lgt.get_mat(base.cam).xform(LVector4f(0, 0, 0, 1))
-        ShaderSetter._set_pars(pref, lgt_pos, lgt)
-
-
-class ShaderSetterDirectionalLight(ShaderSetter):
-
-    @staticmethod
-    def set(pref, lgt):
-        lgt_vec = -render.get_relative_vector(lgt, Vec3(0, 1, 0))
-        lgt_pos = LVector4f(lgt_vec[0], lgt_vec[1], lgt_vec[2], 0)
-        ShaderSetter._set_pars(pref, lgt_pos, lgt)
-
-
-class ShaderSetterSpotlight(ShaderSetter):
-
-    @staticmethod
-    def set(pref, lgt):
-        lgt_vec = base.cam.get_relative_vector(lgt, Vec3(0, 1, 0))
-        lgt_pos = lgt.get_mat(base.cam).xform(LVector4f(0, 0, 0, 1))
-        ShaderSetter._set_pars(pref, lgt_pos, lgt)
-        render.set_shader_input(pref + 'dir', lgt_vec)
-        render.set_shader_input(pref + 'exp', lgt.node().get_exponent())
-        cutoff = lgt.node().get_lens().get_fov()[0]
-        render.set_shader_input(pref + 'cutoff', cutoff)
+from os.path import isfile, dirname
+from panda3d.core import AmbientLight, DirectionalLight, PointLight, \
+    Spotlight, LVector4f, LVector3f, Vec3, Shader, TextureStage, \
+    TexMatrixAttrib
+from direct.filter.FilterManager import FilterManager
+from ya2.lib.builder import LibP3d
+
+
+def load_shader(vert, frag):
+
+    def is_file(path):
+        joinchar = '/' if LibP3d.runtime() and not path.startswith('/') else ''
+        dpath = LibP3d.runtime() and dirname(__file__)
+        return isfile((dpath or '') + joinchar + path)
+    if is_file(vert) and is_file(frag):
+        shader = Shader.load(Shader.SLGLSL, vert, frag)
+    else: shader = Shader.make(Shader.SLGLSL, vert, frag)
+    return shader
+
+
+class P3dShaderMgr:
+
+    def __init__(self, shaders, gamma):
+        self.filter_mgr = None
+        self.gamma, self.buffer, self.lcam, self.lights = gamma, None, None, []
+        if shaders: self.setup_post_fx()
+
+    def __set_lgt(self, lgt, col):
+        if type(col) in [int, float]: lgt.set_color_temperature(col)
+        else: lgt.set_color(col)
+        self.lights += [render.attach_new_node(lgt)]
+        render.set_light(self.lights[-1])
+
+    def set_amb_lgt(self, col):
+        self.__set_lgt(AmbientLight('ambient light'), col)
+
+    def set_dir_lgt(self, col, direction):
+        self.__set_lgt(DirectionalLight('directional light'), col)
+        self.lights[-1].set_hpr(*direction)
+
+    def set_shadow_lgt(self, direction):
+        self.__set_lgt(DirectionalLight('directional light'), (1, 1, 1, 1))
+        self.lights[-1].node().set_shadow_caster(True, 8192, 8192)
+        self.lights[-1].node().get_lens().set_film_size(2048, 2048)
+        self.lights[-1].node().get_lens().set_near_far(1, 2048)
+        #self.lights[-1].node().show_frustum()
+        self.lights[-1].set_hpr(*direction)
+        return self.lights[-1]
+
+    def set_pnt_lgt(self, col, pos):
+        self.__set_lgt(PointLight('point light'), col)
+        self.lights[-1].set_pos(*pos)
+
+    def set_spotlight(self, col, exp, cutoff, pos, look_at):
+        self.__set_lgt(Spotlight('spotlight'), col)
+        self.lights[-1].set_exponent(exp)
+        self.lights[-1].get_lens().set_fov(cutoff, cutoff)
+        self.lights[-1].set_pos(*pos)
+        self.lights[-1].look_at(*look_at)
+
+    @staticmethod
+    def set_default_args(idx):
+        pref = 'lights[%s].' % idx
+        args = [(pref + 'pos', LVector4f(0, 0, 0, 1)),
+                (pref + 'amb', LVector3f(0, 0, 0)),
+                (pref + 'diff', LVector3f(0, 0, 0)),
+                (pref + 'spec', LVector3f(0, 0, 0)),
+                (pref + 'dir', LVector3f(0, 0, 0)),
+                (pref + 'exp', .0),
+                (pref + 'cutoff', .0)]
+        list(map(lambda _args: render.set_shader_input(*_args), args))
+
+    def set_lgt_args(self, idx, lgt):
+        self.set_default_args(idx)
+        ShaderSetter.build(lgt).set('lights[%s].' % idx, lgt)
+
+    def clear_lights(self):
+        for lgt in self.lights:
+            base.render.clear_light(lgt)
+            lgt.removeNode()
+        self.lights = []
+
+    def setup_post_fx(self):
+        self.filter_mgr = FilterManager(base.win, base.cam)
+        # rendered_scene = Texture()
+        # aa_scene = Texture()
+        # filtered_scene = Texture()
+        # filter_quad = self.filter_mgr.renderQuadInto(colortex=filtered_scene)
+        # aa_quad = self.filter_mgr.renderQuadInto(colortex=aa_scene)
+        # final_quad = self.filter_mgr.renderSceneInto(colortex=rendered_scene)
+        # filter_quad.set_shader(self.__load_shader('filter', 'sobel_filter'))
+        # filter_quad.set_shader_input('in_tex', rendered_scene)
+        # aa_quad.set_shader(self.__load_shader('fxaa', 'fxaa'))
+        # aa_quad.set_shader_input('in_tex', filtered_scene)
+        # final_quad.set_shader(self.__load_shader('filter', 'pass'))
+        # final_quad.set_shader_input('gamma', self.gamma)
+        # final_quad.set_shader_input('in_tex', aa_scene)
+
+    @staticmethod
+    def __load_shader(vshad, fshad):
+        with open('assets/shaders/%s.vert' % vshad) as vfile:
+            fvert = vfile.read()
+        with open('assets/shaders/%s.frag' % fshad) as ffile:
+            ffrag = ffile.read()
+        return load_shader(fvert, ffrag)
+
+    def apply(self):
+        # winprops = WindowProperties.size(2048, 2048)
+        # props = FrameBufferProperties()
+        # props.set_rgb_color(1)
+        # props.set_alpha_bits(1)
+        # props.set_depth_bits(1)
+        # lbuffer = base.graphicsEngine.make_output(
+        #     base.pipe, 'offscreen buffer', -2, props, winprops,
+        #     GraphicsPipe.BFRefuseWindow, base.win.getGsg(), base.win)
+        # self.buffer = lbuffer
+        # ldepthmap = Texture()
+        # lbuffer.addRenderTexture(ldepthmap, GraphicsOutput.RTMBindOrCopy,
+        #                          GraphicsOutput.RTPDepthStencil)
+        # ldepthmap.set_minfilter(Texture.FTShadow)
+        # ldepthmap.set_magfilter(Texture.FTShadow)
+
+        # base.camLens.set_near_far(1.0, 10000)
+        # base.camLens.set_fov(75)
+
+        # self.lcam = base.makeCamera(lbuffer)
+        # self.lcam.node().set_scene(render)
+        # self.lcam.node().get_lens().set_fov(45)
+        # self.lcam.node().get_lens().set_near_far(1, 100)
+
+        # render.set_shader_input('light', self.lcam)
+        # render.set_shader_input('depthmap', ldepthmap)
+        # render.set_shader_input('ambient', .15, .15, .15, 1.0)
+
+        # lci = NodePath(PandaNode('light camera initializer'))
+        # lci.set_shader(self.__load_shader('caster', 'caster'))
+        # self.lcam.node().set_initial_state(lci.get_state())
+
+        # mci = NodePath(PandaNode('main camera initializer'))
+        # # use PTALVecBaseX instead
+        # # setShaderInput('vec3argname', PTALVecBase3(((0, 0, 0), (1, 1, 1))))
+        render.set_shader(self.__main_shader())
+        # render.set_shader_input('num_lights', len(self.lights))
+        # self.set_shader_pars(render)
+        # list(map(
+        #     lambda lgt: self.set_lgt_args(*lgt), enumerate(self.lights)))
+        # mci.setShader(self.__main_shader())
+        # base.cam.node().set_initial_state(mci.getState())
+
+        # self.lcam.set_pos(15, 30, 45)
+        # self.lcam.look_at(0, 15, 0)
+        # self.lcam.node().get_lens().set_near_far(1, 100)
+
+    def __main_shader(self):
+        with open('assets/shaders/main.vert') as fvert:
+            vert = fvert.read()
+        with open('assets/shaders/main.frag') as ffrag:
+            frag = ffrag.read()
+        frag = frag.replace('<LIGHTS>', str(len(self.lights)))
+        return load_shader(vert, frag)
+
+    def toggle_shader(self):
+        if render.get_shader():
+            render.set_shader_off()
+            render.set_shader_auto()
+            return
+        self.apply()
+
+    def set_shader_pars(self, model):
+        texture_stages = model.find_all_texture_stages()
+        model.set_shader_input('gloss_slot', 0)
+        model.set_shader_input('detail_slot', 0)
+        model.set_shader_input('detail_scale', (1, 1))
+        for tstage in texture_stages:
+            if tstage.getSort() == 0: continue
+            self.__set_slots(tstage, model, 1 if tstage.getSort() == 10 else 2)
+
+    @staticmethod
+    def __set_slots(tstage, model, slot):
+        if tstage.getMode() == TextureStage.MGloss:
+            model.set_shader_input('gloss_slot', slot)
+        else:
+            model.set_shader_input('detail_slot', slot)
+            attrib_type = TexMatrixAttrib.get_class_type()
+            for geom_np in model.find_all_matches('**/+GeomNode'):
+                geom_node = geom_np.node()
+                for i in range(geom_node.get_num_geoms()):
+                    state = geom_node.get_geom_state(i)
+                    if state.has_attrib(attrib_type):
+                        attrib = state.get_attrib(attr