Source

tutagx / ttgx / demo.py

The branch 'nsgui' does not exist.
Full commit
import logging
import os
import sys
import datetime
import argparse
import importlib

import pyglet

parser = argparse.ArgumentParser(description="Tutagx Demo")
parser.add_argument('-g', help='Name of gameset to load', metavar='GAMESET',
                    dest='gameset', default='default')
parser.add_argument('-d', '--debug', help="Add DEBUG output",
                    action='store_true', dest='debug', default=False)
parser.add_argument('--home', help="Override game home directory",
                    default=None)

# needs to happen before other edits in case import-time metaprogramming
# (e.g. model definitions) need to log something
args = parser.parse_args()
loglvl = logging.INFO
if args.debug:
    loglvl = logging.DEBUG

logging.basicConfig(
    style='{',
    format="{name}:{levelname}: {message}",
    level=loglvl
)

import ttgx.nsgui.driver as gui_driver
import ttgx.nsgui.window as gui_window
import ttgx.nsgui.model as gui_model

import ttgx.util.path as ttgx_path
import ttgx.config
import ttgx.assets
from ttgx.model import gamestate
from ttgx.meta import from_yaml

log = logging.getLogger('ttg-demo')
draw_count = 0


def init():
    if args.home is None:
        ttgx_path.init_from_module(__name__)
    else:
        ttgx_path.init_from_directory(args.home)
    ttgx.config.load()
    core_assets_path = ttgx_path.core_assets_dir()
    log.debug('Core assets expected in %r', core_assets_path)
    assets = ttgx.assets.AssetCollection(core_assets_path)
    gsc = gamestate.GameStateController(args.gameset, assets)
    return gsc


def init_display(gsc):
    # enable alpha blending -- see image_display example
    pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
    pyglet.gl.glBlendFunc(
        pyglet.gl.GL_SRC_ALPHA,
        pyglet.gl.GL_ONE_MINUS_SRC_ALPHA
    )
    
    window = gui_window.Window(width=1024, height=700)
    window.setup()
    driver = gui_driver.GUIDriver(window)

    pages = gui_model.Page.load_from_path(gsc.gameset_gui_path(),
                                          from_yaml.YAMLReader())
    for page in pages:
        driver.add_screen(page.name, page.create_widget())
    driver.switch(gsc.gameset.start_page)


#XXX FPS and CPU time is incredibly high (>90% CPU, usually thousands of FPS,
# sometimes tens of thousands).
# Somehow, pyglet sucks at sleep()ing or doesn't even try.
# Despite the docs praising the built-in event loop as less CPU-hungry,
# it does as many updates as it can, so the end result is just as CPU-hungry.
# (Though to be fair, it may avoid busy waits in some places and just use the
#  free time for other drawing.)
#TODO: dive into pyglet.event.EventLoop and come up with a better idle() that
# respects FPS limits


def run():
    start_time = datetime.datetime.now()
    pyglet.app.run()
    end_time = datetime.datetime.now()
    dt = end_time - start_time
    pseudo_fps = draw_count / dt.total_seconds()
    log.info(
        "%d draw() calls in %.2f seconds => %.2f FPS",
        draw_count, dt.total_seconds(), pseudo_fps
    )


def exit(gsc):
    if gsc.game_active:
        try:
            gsc.save('autosave')
        except Exception:
            log.error('error during saving:', exc_info=True)


def main():
    try:
        gsc = init()
    except Exception:
        log.error('Initialization failed:', exc_info=True)
        sys.exit(3)
    init_display(gsc)
    run()
    exit(gsc)

if __name__ == '__main__':
    main()