source: branches/active/character_customization/game/parpg/application.py @ 810

Revision 810, 9.3 KB checked in by aspidites, 8 years ago (diff)

Patch by Aspidites

  • Removed SystemDataDirectory? and UserDataDirectory?
    • it is the the settings module's job to keep track of this sort of thing, not fife or PARPG's
    • consequently, setting.py's command line interface became simple
    • this will also prevent those "I generated a settings file but PARPG doesnt run" complaints
    • I think I'm going to have some helper methods to generate platform-specific paths at run-time
  • User data directory is now properly created
  • added platform_paths(system) which returns the platform-specific paths for the given system
  • if no system is given, it gives the paths for the system that the script was run on
  • changed logic of settings.py so that it is not required to pass a path.
  • not passing a path invokes paltform_paths
  • Property svn:eol-style set to native
Line 
1#   This program is free software: you can redistribute it and/or modify
2#   it under the terms of the GNU General Public License as published by
3#   the Free Software Foundation, either version 3 of the License, or
4#   (at your option) any later version.
5
6#   This program is distributed in the hope that it will be useful,
7#   but WITHOUT ANY WARRANTY; without even the implied warranty of
8#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9#   GNU General Public License for more details.
10
11#   You should have received a copy of the GNU General Public License
12#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
13"""This module contains the main Application class
14and the basic Listener for PARPG """
15
16import os
17
18from fife import fife
19from fife.extensions import pychan
20from fife.extensions.serializers.xmlanimation import XMLAnimationLoader
21from fife.extensions.basicapplication import ApplicationBase
22
23from parpg import console
24from parpg.gamemodel import GameModel
25from parpg.mainmenuview import MainMenuView
26from parpg.mainmenucontroller import MainMenuController
27from parpg.common.listeners.event_listener import EventListener
28from parpg.common.listeners.key_listener import KeyListener
29from parpg.common.listeners.mouse_listener import MouseListener
30from parpg.common.listeners.command_listener import CommandListener
31from parpg.common.listeners.console_executor import ConsoleExecuter
32from parpg.common.listeners.widget_listener import WidgetListener
33
34class KeyFilter(fife.IKeyFilter):
35    """
36    This is the implementation of the fife.IKeyFilter class.
37   
38    Prevents any filtered keys from being consumed by guichan.
39    """
40    def __init__(self, keys):
41        fife.IKeyFilter.__init__(self)
42        self._keys = keys
43
44    def isFiltered(self, event):
45        """Checks if an key is filtered"""
46        return event.getKey().getValue() in self._keys
47
48class ApplicationListener(KeyListener,
49                        MouseListener,
50                        ConsoleExecuter,
51                        CommandListener,
52                        WidgetListener):   
53    """Basic listener for PARPG"""
54       
55    def __init__(self, event_listener, engine, view, model):
56        """Initialize the instance.
57           @type engine: fife.engine
58           @param engine: ???
59           @type view: viewbase.ViewBase
60           @param view: View that draws the current state
61           @type model: GameModel
62           @param model: The game model"""
63
64        KeyListener.__init__(self, event_listener)
65        MouseListener.__init__(self, event_listener)
66        ConsoleExecuter.__init__(self, event_listener)
67        CommandListener.__init__(self, event_listener)
68        WidgetListener.__init__(self, event_listener)       
69        self.engine = engine
70        self.view = view
71        self.model = model
72        keyfilter = KeyFilter([fife.Key.ESCAPE])
73        keyfilter.__disown__()       
74       
75        engine.getEventManager().setKeyFilter(keyfilter)
76        self.quit = False
77        self.about_window = None
78        self.console = console.Console(self)
79
80    def quitGame(self):
81        """Forces a quit game on next cycle.
82           @return: None"""
83        self.quit = True
84
85    def onConsoleCommand(self, command):
86        """
87        Called on every console comand, delegates calls  to the a console
88        object, implementing the callbacks
89        @type command: string
90        @param command: the command to run
91        @return: result
92        """
93        return self.console.handleConsoleCommand(command)
94
95    def onCommand(self, command):
96        """Enables the game to be closed via the 'X' button on the window frame
97           @type command: fife.Command
98           @param command: The command to read.
99           @return: None"""
100        if(command.getCommandType() == fife.CMD_QUIT_GAME):
101            self.quit = True
102            command.consume()
103
104class PARPGApplication(ApplicationBase):
105    """Main Application class
106       We use an MVC model model
107       self.gamesceneview is our view,self.model is our model
108       self.controller is the controller"""
109       
110    def __init__(self, setting):
111        """Initialise the instance.
112           @return: None"""
113        self._setting = setting
114        self.engine = fife.Engine()
115        fonts_dir = os.path.join(self._setting.paths['system'],
116                                 self._setting.fife.FontsDirectory)
117        self.fonts_directory = fonts_dir
118        self.loadSettings()
119        self.engine.init()
120        self._animationloader = XMLAnimationLoader(self.engine.getImagePool(),
121                                                   self.engine.getVFS())
122        self.engine.getAnimationPool().addResourceLoader(self._animationloader)
123
124        pychan.init(self.engine, debug = True)
125        pychan.setupModalExecution(self.mainLoop,self.breakFromMainLoop)
126
127        self.quitRequested = False
128        self.breakRequested = False
129        self.returnValues = []
130        #self.engine.getModel(self)
131        self.model = GameModel(self.engine, setting)
132        self.model.readMapFiles()
133        self.model.readObjectDB()
134        self.model.getAgentImportFiles()
135        self.model.readAllAgents()
136        self.model.getDialogues()
137        self.view = MainMenuView(self.engine, self.model)
138        self.loadFonts(self.fonts_directory)
139        self.event_listener = EventListener(self.engine)
140        self.controllers = []
141        controller = MainMenuController(self.engine, self.view, self.model, 
142                                        self)
143        #controller.initHud()
144        self.controllers.append(controller)
145        self.listener = ApplicationListener(self.event_listener,
146                                            self.engine, 
147                                            self.view, 
148                                            self.model)
149        #start_map = self._setting.fife.get("PARPG", "Map")
150        #self.model.changeMap(start_map)
151
152    def loadFonts(self, fonts_directory):
153        file_names = os.listdir(fonts_directory)
154        for file_name in file_names:
155            base_name, extension = os.path.splitext(file_name)
156            if extension == '.fontdef':
157                file_path = os.path.join(fonts_directory, file_name)
158                pychan.loadFonts(file_path)
159
160    def loadSettings(self):
161        """
162        Load the settings from a python file and load them into the engine.
163        Called in the ApplicationBase constructor.
164        """
165
166        engineSetting = self.engine.getSettings()
167        engineSetting.setDefaultFontGlyphs(self._setting.fife.FontGlyphs)
168        engineSetting.setDefaultFontPath(os.path.join(self.fonts_directory,
169                                                       self._setting.fife.Font))
170        engineSetting.setDefaultFontSize(self._setting.fife.DefaultFontSize)
171        engineSetting.setBitsPerPixel(self._setting.fife.BitsPerPixel)
172        engineSetting.setInitialVolume(self._setting.fife.InitialVolume)
173        engineSetting.setSDLRemoveFakeAlpha(self._setting.fife.SDLRemoveFakeAlpha)
174        engineSetting.setScreenWidth(self._setting.fife.ScreenWidth)
175        engineSetting.setScreenHeight(self._setting.fife.ScreenHeight)
176        engineSetting.setRenderBackend(self._setting.fife.RenderBackend)
177        engineSetting.setFullScreen(self._setting.fife.FullScreen)
178        engineSetting.setVideoDriver(self._setting.fife.VideoDriver)
179        engineSetting.setLightingModel(self._setting.fife.Lighting)
180        engineSetting.setColorKeyEnabled(self._setting.fife.ColorKeyEnabled)
181
182        engineSetting.setColorKey(*[int(digit) 
183                                    for digit in self._setting.fife.ColorKey])
184
185        engineSetting.setWindowTitle(self._setting.fife.WindowTitle)
186        engineSetting.setWindowIcon(os.path.join(self._setting.paths['system'], 
187                                                 self._setting.fife.IconsDirectory,
188                                                 self._setting.fife.WindowIcon))
189
190    def createListener(self):
191        """ __init__ takes care of creating an event listener, so
192            basicapplication's createListener is harmful. Without
193            overriding it, the program quit's on esc press, rather than
194            invoking the main menu
195        """
196        pass
197
198    def pushController(self, controller):
199        """Adds a controller to the list to be the current active one."""
200        self.controllers[-1].pause(True)
201        self.controllers.append(controller)
202   
203    def popController(self):
204        """Removes and returns the current active controller, unless its the last one"""
205        ret_controller = None
206        if self.controllers.count > 1:
207            ret_controller = self.controllers.pop()
208            self.controllers[-1].pause(False)
209        ret_controller.onStop()
210        return ret_controller
211   
212    def switchController(self, controller):
213        """Clears the controller list and adds a controller to be the current active one"""
214        for old_controller in self.controllers:
215            old_controller.onStop()
216        self.controllers = []
217        self.controllers.append(controller)
218   
219    def _pump(self):
220        """Main game loop.
221           There are in fact 2 main loops, this one and the one in GameSceneView.
222           @return: None"""
223        if self.listener.quit:
224            self.breakRequested = True #pylint: disable-msg=C0103
225        else:
226            for controller in self.controllers:
227                controller.pump()
Note: See TracBrowser for help on using the repository browser.