diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 92ac0f2..b00c065 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,37 +1,38 @@ Changelog for Photon -$Id: CHANGELOG.txt,v 1.2 2005/07/19 18:35:20 cozman Exp $ +$Id: CHANGELOG.txt,v 1.3 2005/08/07 07:12:46 cozman Exp $ -0.1.0 (Massachusetts) - Initial Release - * Kernel/Task design that allows easy creation of graphical - games/applications without sacrificing control - * Extensive Log system that allows full control over logging including +0.0.1 + + State-based design that allows easy creation of applications by simply + deriving from a basic 'State' class. + + Kernel/Task system allowing full control over game loop. + + Extensive Log system that allows full control over logging including various log levels and three built in forms of output, with the ability to add custom output formats. - * A wide variety of helper utilities for tasks such as filesystem + + A wide variety of helper utilities for tasks such as filesystem navigation, FileBuffer capable of reading from archives, random number generation, versioning, and timing - * Powerful input system allowing for direct access to keyboard/mouse status + + Powerful input system allowing for direct access to keyboard/mouse status or passive listeners which are notified of events when they occur. - * Resource Management system including the ability to load resources from + + Resource Management system including the ability to load resources from specified directories or archives. - * Variety of math classes including Circle, Rectangle, and Vector classes + + Variety of math classes including Circle, Rectangle, and Vector classes convinient for game use - * ConfigFile class for reading/writing INI-style files for game settings - * OpenGL management including ability to set video mode, and easy management + + ConfigFile class for reading/writing INI-style files for game settings + + OpenGL management including ability to set video mode, and easy management of multiple viewports - * Resource-managed Texture class allowing for loading of textures for use in + + Resource-managed Texture class allowing for loading of textures for use in OpenGL - * Image class that extends Texture class, allowing for hardware accellerated + + Image class that extends Texture class, allowing for hardware accellerated drawing, rotation, scaling, and blending of images for use in 2D environments - * Resource-managed Font class allowing for the rendering of text using + + Resource-managed Font class allowing for the rendering of text using TrueType fonts - * Primitive-drawing ‘Pen’ class allowing for drawing of various geometric + + Primitive-drawing ‘Pen’ class allowing for drawing of various geometric shapes, lines, and vectors. - * OpenAL based sound system* - * Entire library is built in a highly-modular fashion with extensibility in + + OpenAL based sound system* + + Entire library is built in a highly-modular fashion with extensibility in mind. Use of modern programming techniques like templates and exceptions contributes to ease of use and ease of development. - * 13 demo programs showing features and ease of use of various components. + + 12 demo programs showing features and ease of use of various components. diff --git a/IFAQ.txt b/IFAQ.txt index 1ddc960..4806641 100644 --- a/IFAQ.txt +++ b/IFAQ.txt @@ -1,5 +1,5 @@ IfAQ (Infrequently Asked Questions) -$Id: IFAQ.txt,v 1.1 2005/07/17 22:41:03 cozman Exp $ +$Id: IFAQ.txt,v 1.2 2005/08/07 07:12:46 cozman Exp $ --basic questions-- @@ -70,6 +70,12 @@ Q. Does Photon use proprietary libraries like DirectX? A. Photon only uses free open source libraries, so that by using Photon you are not subjected to any proprietary licensing terms. +Q. When will features X, Y, and Z be completed? +A. When I get to them, I can only work on Photon in my spare time, if you have a + specific request let me know and I can give you an estimate of when I plan + on getting to it. There's always the option that you help out and then the + feature will be added sooner rather than later. + Q. What if I have something to add? A. Feel free to contribute to Photon, bugfixes are greatly appreciated. Not all submitted features can be accepted, but I'll usually at least add a diff --git a/include/AppCore.hpp b/include/AppCore.hpp index 6d496b4..8b13789 100644 --- a/include/AppCore.hpp +++ b/include/AppCore.hpp @@ -1,256 +1 @@ -//This file is part of Photon (http://photon.sourceforge.net) -//Copyright (C) 2004-2005 James Turk -// -// Author: -// James Turk (jpt2433@rit.edu) -// -// Version: -// $Id: AppCore.hpp,v 1.9 2005/08/02 23:07:51 cozman Exp $ -#ifndef PHOTON_APPCORE_HPP -#define PHOTON_APPCORE_HPP - -#include "types.hpp" -#include "util/VersionInfo.hpp" -#include "Task.hpp" -#include "InputListener.hpp" - -#include - -namespace photon -{ - -// Class: AppCore -// Photon's core for application behavior. Defines the interface through which -// all "application" related functions are performed. This means input, -// display creation, etc. -// -// AppCore is the Core that essentially represents the window management, -// input, and timing systems. -class AppCore -{ - -public: - AppCore(); - ~AppCore(); - - void init(); - void shutdown(); - -// Group: Video -public: - - // Function: createDisplay - // This function attempts to create a display with the given parameters. - // - // Parameters: - // width - desired width of display - // height - desired height of display - // redBits - desired bits per pixel for red value - // greenBits - desired bits per pixel for green value - // blueBits - desired bits per pixel for blue value - // alphaBits - desired bits per pixel for alpha value - // depthBits - desired bitdepth of depth buffer - // stencilBits - desired bitdepth of stencil buffer - // fullscreen - true: fullscreen, false: windowed - // [title - title of application, optional] - void createDisplay(uint width, uint height, - uint redBits, uint greenBits, uint blueBits, - uint alphaBits, uint depthBits, uint stencilBits, - bool fullscreen, const std::string& title="Photon App"); - - // Function: createDisplay - // This function attempts to create a display with the given parameters. - // - // Parameters: - // width - desired width of display - // height - desired height of display - // bpp - desired bits per pixel (aka bitdepth) of display - // depthBits - desired bitdepth of depth buffer - // stencilBits - desired bitdepth of stencil buffer - // fullscreen - true: fullscreen, false: windowed - // [title - title of application, optional] - void createDisplay(uint width, uint height, uint bpp, - uint depthBits, uint stencilBits, bool fullscreen, - const std::string& title="Photon App"); - -// Group: Input -public: - - // Function: keyPressed - // Check if a given key is currently pressed. - // - // Parameters: - // key - of key to determine status of. - // - // Returns: - // true: key is pressed, false: key isn't pressed - bool keyPressed(KeyCode key); - - // Function: getPressedKeys - // Obtain a list of all keys which are currently pressed. - // - // Returns: - // std::vector of of any pressed keys. - std::vector getPressedKeys(); - - // Function: mouseButtonPressed - // Check if a given mouse button is currently pressed. - // - // Parameters: - // button - to determine status of. - // - // Returns: - // true: button is pressed, false: button isn't pressed - bool mouseButtonPressed(MouseButton button); - - // Function: getMouseX - // Gets current x location of mouse with respect to screen coordinates. - // - // Returns: - // Mouse x-coordinate, with respect to screen coordinates. - int getMouseX(); - - // Function: getMouseY - // Gets current y location of mouse with respect to screen coordinates. - // - // Returns: - // Mouse y-coordinate, with respect to screen coordinates. - int getMouseY(); - - // Function: getMouseWheelPos - // Gets current location of mouse wheel, treated as if wheel describes a - // third axis of movement for the mouse. - // - // Returns: - // Mouse wheel position, zero assumed to be starting position. - int getMouseWheelPos(); - -// Group: Input Listeners -public: - - // Function: addInputListener - // Registers an to listen for any input events so that it - // is notified when they occur. - // - // Parameters: - // listener - Pointer to to add. - static void addInputListener(InputListener *listener); - - // Function: removeInputListener - // Removes an from the list of active listeners. - // - // Parameters: - // listener - Pointer to to remove. - static void removeInputListener(InputListener *listener); - - static void GLFWCALL keyCallback(int key, int action); - //static void GLFWCALL charCallback(int character, int action); - static void GLFWCALL mouseButtonCallback(int button, int action); - static void GLFWCALL mouseMoveCallback(int x, int y); - //static void GLFWCALL mouseWheelCallback(int pos); - -// Group: Timing -public: - - // Function: getTime - // Get time, in seconds, that application has been running. - // - // Returns: - // Time, represented as a floating-point number in seconds, application has - // been running. - scalar getTime(); - -// Group: General -public: - - // Function: setTitle - // Sets title of application that shows up in title bar. - // - // Parameters: - // title - New title of application. - void setTitle(const std::string& title); - - // Function: isActive - // Checks if application is active, which on most systems simply means it - // has focus. - // - // Returns: - // True if application is active, false otherwise. - bool isActive(); - - // Function: getElapsedTime - // Finds the amount of time passed between frames, useful for time-based - // movement. - // - // Returns: - // Time between current frame and last frame. (1/()) - double getElapsedTime(); - - // Function: getFramerate - // Gets number of frames per second the application is currently processing - // - // Returns: - // Current frames per second. - double getFramerate(); - -// Group: Accessors -public: - // Function: getDisplayWidth - // Get the width of the display. - // - // Returns: - // Width of display in pixels. - uint getDisplayWidth(); - - // Function: getDisplayHeight - // Get the height of the display. - // - // Returns: - // Height of display in pixels. - uint getDisplayHeight(); - - - // UpdateTask, does the updating work of AppCore, registered as a Task - // so that user need not call something akin to AppCore::update() every - // frame - class UpdateTask : public Task - { - - friend class AppCore; - - public: - UpdateTask(); - - void update(); - - private: - int mouseX_; - int mouseY_; - bool active_; - bool timerPaused_; - bool unpauseOnActive_; - scalar lastPause_; - scalar pausedTime_; - scalar secPerFrame_; - scalar lastUpdate_; - }; - -// data members -private: - uint dispWidth_; - uint dispHeight_; - shared_ptr task_; - - // input monitoring variables - static std::vector listeners_; - static std::vector pressedKeys_; - -// API initialization -private: - util::VersionInfo initGLFW(); -}; - -} - -#endif //PHOTON_APPCORE_HPP diff --git a/include/Application.hpp b/include/Application.hpp index 38082e0..3cf900e 100644 --- a/include/Application.hpp +++ b/include/Application.hpp @@ -5,12 +5,13 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Application.hpp,v 1.10 2005/08/02 23:07:51 cozman Exp $ +// $Id: Application.hpp,v 1.11 2005/08/07 07:12:46 cozman Exp $ #ifndef PHOTON_APPLICATION_HPP #define PHOTON_APPLICATION_HPP #include +#include #include #include @@ -19,77 +20,368 @@ #include "util/VersionInfo.hpp" #include "Task.hpp" #include "Kernel.hpp" -#include "AppCore.hpp" +#include "InputListener.hpp" #include "video/VideoCore.hpp" #include "audio/AudioCore.hpp" +#include "util/Singleton.hpp" + +#include namespace photon { + +class State +{ +public: + State() { }; + virtual ~State() { }; + +public: + virtual void enterState() { }; + virtual void exitState() { }; + +public: + virtual void update()=0; + virtual void render()=0; +}; + + // Class: Application // Abstract main class, all photon applications should derive from Application. // // Derived classes are made entrypoint via . -class Application +class Application : public util::Singleton { // Group: (Con/De)structors public: // Function: Application // Default constructor, initializes the internal state & dependencies. - Application(); + Application(const std::string& arg0); // Function: ~Application // Default destructor, shuts down dependencies. virtual ~Application(); -// Group: Main +// Group: Video public: - // Function: main - // Pure virtual, must be defined by derived class, using some preprocessor - // magic () on the derived class - // this becomes the entry point for a Photon application. + + // Function: createDisplay + // This function attempts to create a display with the given parameters. // // Parameters: - // args - containing arguments passed to program. + // width - desired width of display + // height - desired height of display + // redBits - desired bits per pixel for red value + // greenBits - desired bits per pixel for green value + // blueBits - desired bits per pixel for blue value + // alphaBits - desired bits per pixel for alpha value + // depthBits - desired bitdepth of depth buffer + // stencilBits - desired bitdepth of stencil buffer + // fullscreen - true: fullscreen, false: windowed + // [title - title of application, optional] + void createDisplay(uint width, uint height, + uint redBits, uint greenBits, uint blueBits, + uint alphaBits, uint depthBits, uint stencilBits, + bool fullscreen, const std::string& title="Photon App"); + + // Function: createDisplay + // This function attempts to create a display with the given parameters. // - // Returns: 0 upon success, other upon failure. - // (Same as main in Standard C/C++). + // Parameters: + // width - desired width of display + // height - desired height of display + // bpp - desired bits per pixel (aka bitdepth) of display + // depthBits - desired bitdepth of depth buffer + // stencilBits - desired bitdepth of stencil buffer + // fullscreen - true: fullscreen, false: windowed + // [title - title of application, optional] + void createDisplay(uint width, uint height, uint bpp, + uint depthBits, uint stencilBits, bool fullscreen, + const std::string& title="Photon App"); + +// Group: Input +public: + + // Function: keyPressed + // Check if a given key is currently pressed. // - // See Also: - // - virtual int main(const StrVec& args)=0; + // Parameters: + // key - of key to determine status of. + // + // Returns: + // true: key is pressed, false: key isn't pressed + bool keyPressed(KeyCode key); + // Function: getPressedKeys + // Obtain a list of all keys which are currently pressed. + // + // Returns: + // std::vector of of any pressed keys. + std::vector getPressedKeys(); + + // Function: mouseButtonPressed + // Check if a given mouse button is currently pressed. + // + // Parameters: + // button - to determine status of. + // + // Returns: + // true: button is pressed, false: button isn't pressed + bool mouseButtonPressed(MouseButton button); + + // Function: getMouseX + // Gets current x location of mouse with respect to screen coordinates. + // + // Returns: + // Mouse x-coordinate, with respect to screen coordinates. + int getMouseX(); + + // Function: getMouseY + // Gets current y location of mouse with respect to screen coordinates. + // + // Returns: + // Mouse y-coordinate, with respect to screen coordinates. + int getMouseY(); + + // Function: getMouseWheelPos + // Gets current location of mouse wheel, treated as if wheel describes a + // third axis of movement for the mouse. + // + // Returns: + // Mouse wheel position, zero assumed to be starting position. + int getMouseWheelPos(); + +// Group: Input Listeners +public: + + // Function: addInputListener + // Registers an to listen for any input events so that it + // is notified when they occur. + // + // Parameters: + // listener - Pointer to to add. + static void addInputListener(InputListener *listener); + + // Function: removeInputListener + // Removes an from the list of active listeners. + // + // Parameters: + // listener - Pointer to to remove. + static void removeInputListener(InputListener *listener); + + static void GLFWCALL keyCallback(int key, int action); + //static void GLFWCALL charCallback(int character, int action); + static void GLFWCALL mouseButtonCallback(int button, int action); + static void GLFWCALL mouseMoveCallback(int x, int y); + //static void GLFWCALL mouseWheelCallback(int pos); + +// Group: Timing +public: + + // Function: getTime + // Get time, in seconds, that application has been running. + // + // Returns: + // Time, represented as a floating-point number in seconds, application has + // been running. + scalar getTime(); + +// Group: General +public: + + // Function: setTitle + // Sets title of application that shows up in title bar. + // + // Parameters: + // title - New title of application. + void setTitle(const std::string& title); + + // Function: isActive + // Checks if application is active, which on most systems simply means it + // has focus. + // + // Returns: + // True if application is active, false otherwise. + bool isActive(); + + // Function: isRunning + // Checks if application is running, which means that no quit has been + // requested. + // + // Returns: + // True if application is running, false otherwise. + bool isRunning(); + + // Function: getElapsedTime + // Finds the amount of time passed between frames, useful for time-based + // movement. + // + // Returns: + // Time between current frame and last frame. (1/()) + double getElapsedTime(); + + // Function: getFramerate + // Gets number of frames per second the application is currently processing + // + // Returns: + // Current frames per second. + double getFramerate(); + +// Group: State Management +public: + // Function: registerState + // Register a new type. + // + // Arguments: + // stateName - Name of new . + // + // Template Parameters: + // StateT - Class derived from to register. + template + void registerState(const std::string& stateName); + + // TODO: why would someone want to unregister a state? + + // Function: unregisterState + // Unregister a registered type. + // + // Arguments: + // stateName - Name of to unregister. + void unregisterState(const std::string& stateName); + + // Function: setCurrentState + // Set the current Application . + // + // Arguments: + // stateName - Name of to make active + void setCurrentState(const std::string& stateName); + // Group: Core Access public: - static Kernel& getKernel(); - static AppCore& getAppCore(); - static video::VideoCore& getVideoCore(); - static audio::AudioCore& getAudioCore(); - static void initVideoCore(uint width, uint height); - static void initAudioCore(const std::string& deviceName); - -// behind the scenes + video::VideoCore& getVideoCore(); + audio::AudioCore& getAudioCore(); + void initVideoCore(uint width, uint height); + void initAudioCore(const std::string& deviceName); + +// Group: Accessors public: - static void setInitOptions(const char* arg0); + // Function: getDisplayWidth + // Get the width of the display. + // + // Returns: + // Width of display in pixels. + uint getDisplayWidth(); + + // Function: getDisplayHeight + // Get the height of the display. + // + // Returns: + // Height of display in pixels. + uint getDisplayHeight(); + + // Group: API Initialization private: - util::VersionInfo initPhysFS(); + util::VersionInfo initPhysFS(const std::string& arg0); + util::VersionInfo initGLFW(); + + // UpdateTask, does the updating work of AppCore, registered as a Task + // so that user need not call something akin to AppCore::update() every + // frame + class UpdateTask : public Task + { + + friend class Application; + + public: + UpdateTask(); + + void update(); + + private: + int mouseX_; + int mouseY_; + bool active_; + bool timerPaused_; + bool unpauseOnActive_; + scalar lastPause_; + scalar pausedTime_; + scalar secPerFrame_; + scalar lastUpdate_; + bool quitRequested_; + }; + + // State system + typedef shared_ptr StatePtr; + typedef std::map StateMap; + + // StateUpdate + class StateUpdate : public Task + { + + friend class Application; + + public: + StateUpdate(); + void update(); + + private: + StatePtr state_; + }; + + // StateRender + class StateRender : public Task + { + + friend class Application; + + public: + StateRender(); + void update(); + + private: + StatePtr state_; + }; private: // version number for photon util::VersionInfo photonVer_; + + uint dispWidth_; + uint dispHeight_; + shared_ptr updateTask_; + shared_ptr stateUpdate_; + shared_ptr stateRender_; + + // State system + StateMap stateMap_; + + // input monitoring variables + static std::vector listeners_; + static std::vector pressedKeys_; // Cores and Kernel - static Kernel kernel_; - static AppCore appCore_; - static std::auto_ptr videoCore_; - static std::auto_ptr audioCore_; - - static std::string arg0_; + std::auto_ptr videoCore_; + std::auto_ptr audioCore_; }; +template +void Application::registerState(const std::string& stateName) +{ + StateMap::iterator it( stateMap_.find(stateName) ); + + if(it != stateMap_.end()) + { + throw PreconditionException("Application::registerState called twice " + "with same name: \"" + stateName + "\""); + } + + stateMap_[stateName] = StatePtr(new StateT); +} + } #endif //PHOTON_APPLICATION_HPP diff --git a/include/Kernel.hpp b/include/Kernel.hpp index cf77314..a64a29e 100644 --- a/include/Kernel.hpp +++ b/include/Kernel.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Kernel.hpp,v 1.2 2005/08/02 23:07:52 cozman Exp $ +// $Id: Kernel.hpp,v 1.3 2005/08/07 07:12:46 cozman Exp $ #ifndef PHOTON_KERNEL_HPP #define PHOTON_KERNEL_HPP @@ -13,6 +13,7 @@ #include #include +#include "util/Singleton.hpp" #include "Task.hpp" namespace photon @@ -26,7 +27,7 @@ namespace photon // - (1) Add any tasks (should be derived from ) // - (2) call // - (3) in order to avoid running forever, all tasks should eventually die -class Kernel +class Kernel : public util::Singleton { // Group: (Con/De)structors @@ -41,11 +42,18 @@ public: // Group: Running public: + // Function: step + // Steps the kernel, calling each active task once. + // + // Each 'step' all tasks are run in order of their priorities, if two + // tasks have the same priority, they are run in the order they were added. + void step(); + // Function: run // Runs tasks until all tasks are asleep or dead. // - // Each 'frame' all tasks are run in order of their priorities, if two - // tasks have the same priority, they are run in the order they were added. + // See Also: + // void run(); // Group: Task Management diff --git a/include/Task.hpp b/include/Task.hpp index 94a2acf..c6e1d65 100644 --- a/include/Task.hpp +++ b/include/Task.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Task.hpp,v 1.3 2005/07/20 06:12:54 cozman Exp $ +// $Id: Task.hpp,v 1.4 2005/08/07 07:12:46 cozman Exp $ #ifndef PHOTON_TASK_HPP #define PHOTON_TASK_HPP @@ -17,17 +17,29 @@ namespace photon { -// Title: Task +// Type: TaskPriority +enum PriorityLevel +{ + PRI_APP_UPDATE, // special priority for Application updating (first) -// Group: Helper Types - -class Task; -class Kernel; - -// Type: TaskPtr -// Pointer to a task, used since Task is abstract and will always be accessed -// via a pointer. -typedef shared_ptr TaskPtr; + // user-level priorities all lie in logic area + PRI_HIGHEST, + PRI_HIGH, + PRI_NORMAL, + PRI_LOW, + PRI_LOWEST, + + PRI_VIDEO_UPDATE, // special priority for clearing screen/video buffers + PRI_RENDER // special priority for rendering (right after clear) + + // It is also important that no priorities fall between render/app update + // so that flow of applications is: + // 1) Update & SwapBuffers + // 2) Logic & User Level tasks + // 3) Clear screen/buffers + // 4) Render + // 5) SwapBuffers again (see step 1) +}; // Class: Task // Abstract class for tasks, which are runnable classes for use with . @@ -44,10 +56,8 @@ public: // name - Name for task, must be unique! // priority - Optional argument for desired priority for the Task, // controls order in which tasks are run by the . - // Tasks are executed starting with the lowest number for - // priority, meaning a task with priority=0 will execute first. - // Default priority is 5000. - Task(const std::string& name, uint priority=5000); + // Default Priority is PRI_NORMAL + Task(const std::string& name, PriorityLevel priority=PRI_NORMAL); // Function: ~Task // Virtual destructor, exists simply to make inheritance safe. @@ -124,11 +134,16 @@ public: // data members private: std::string name_; // all tasks need a unique name - uint priority_; // priority determines ordering of tasks + PriorityLevel priority_; // priority determines ordering of tasks bool alive_; // if false, task will be pruned bool paused_; // if false task won't be executed }; +// Type: TaskPtr +// Pointer to a task, used since Task is abstract and will always be accessed +// via a pointer. +typedef shared_ptr TaskPtr; + } #endif //PHOTON_TASK_HPP diff --git a/include/audio/AudioCore.hpp b/include/audio/AudioCore.hpp index 5aaf329..166e36e 100644 --- a/include/audio/AudioCore.hpp +++ b/include/audio/AudioCore.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: AudioCore.hpp,v 1.10 2005/08/02 23:07:52 cozman Exp $ +// $Id: AudioCore.hpp,v 1.11 2005/08/07 07:12:47 cozman Exp $ #ifdef PHOTON_USE_OPENAL @@ -15,7 +15,6 @@ #include "AL/al.h" #include "AL/alc.h" -#include "util/Singleton.hpp" #include "util/VersionInfo.hpp" namespace photon diff --git a/include/entrypoint.hpp b/include/entrypoint.hpp index 5b28544..954e4ba 100644 --- a/include/entrypoint.hpp +++ b/include/entrypoint.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: entrypoint.hpp,v 1.6 2005/07/19 01:31:37 cozman Exp $ +// $Id: entrypoint.hpp,v 1.7 2005/08/07 07:12:46 cozman Exp $ #ifndef PHOTON_ENTRYPOINT_HPP @@ -15,54 +15,41 @@ // Title: Entrypoint -// Macro: ENTRYPOINT -// A macro which is used to specify the class containing the entrypoint. -// For example, if the class PongGame is the class derived from -// which implements main, in the file defining PongGame it is important to -// include ENTRYPOINT(PongGame) so that the entry point becomes PongGame::main. +int PhotonMain(const photon::StrVec& args); -#define ENTRYPOINT(className) int main(int argc, const char** argv) \ - { return photon::mainclass(argc,argv); } - -namespace photon -{ - -// function which does all the work of ENTRYPOINT -template -int mainclass(int argc, const char** argv) +int main(int argc, const char** argv) { // logging of uncaught exceptions to console - Log log; - log.addSink(LogSinkPtr(new photon::ConsoleSink("out"))); - + photon::Log log; + log.addSink(photon::LogSinkPtr(new photon::ConsoleSink("out"))); + try { - App::setInitOptions(argv[0]); - - App app; - + new photon::Application(argv[0]); + // push arguments into StrVec - StrVec args; + photon::StrVec args; for(int i=0; i < argc; ++i) { args.push_back(argv[i]); } + + int retVal = PhotonMain(args); + + photon::Application::destroy(); - // hand arguments to Application::main and return what main returns - return app.main(args); + return retVal; } - catch(Exception &e) // log exceptions as errors (wow that's confusing) + catch(photon::Exception &e) // log exceptions as errors (confusing?) { log.error() << e; - return 1; + return 1; } - catch(Error &e) // log errors as critical errors + catch(photon::Error &e) // log errors as critical errors { log.critical() << e; return 1; } } -} - #endif //PHOTON_ENTRYPOINT_HPP diff --git a/include/util/Timer.hpp b/include/util/Timer.hpp index 97e1932..9c65ce2 100644 --- a/include/util/Timer.hpp +++ b/include/util/Timer.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Timer.hpp,v 1.2 2005/07/18 06:18:51 cozman Exp $ +// $Id: Timer.hpp,v 1.3 2005/08/07 07:12:47 cozman Exp $ #ifndef PHOTON_UTIL_TIMER_HPP #define PHOTON_UTIL_TIMER_HPP @@ -76,7 +76,6 @@ private: // data members private: - AppCore& appCore_; bool appTimeLinked_; bool paused_; double pausedTime_; diff --git a/photon.mm b/photon.mm index 10f7c93..8bade82 100644 --- a/photon.mm +++ b/photon.mm @@ -3,9 +3,40 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -15,104 +46,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -133,7 +102,7 @@ - + @@ -144,25 +113,41 @@ - + + + + + + + + + + + + + + + - + + + - - - - - - - + + + + + + + diff --git a/src/AppCore.cpp b/src/AppCore.cpp index 7cbe47f..8b13789 100644 --- a/src/AppCore.cpp +++ b/src/AppCore.cpp @@ -1,343 +1 @@ -//This file is part of Photon (http://photon.sourceforge.net) -//Copyright (C) 2004-2005 James Turk -// -// Author: -// James Turk (jpt2433@rit.edu) -// -// Version: -// $Id: AppCore.cpp,v 1.14 2005/08/02 23:07:52 cozman Exp $ -#include "AppCore.hpp" - -#include -#include "GL/glfw.h" //This file depends on glfw - -#include "Application.hpp" -#include "Kernel.hpp" -#include "exceptions.hpp" -#include "video/VideoCore.hpp" - -namespace photon -{ - -// static initializer -std::vector AppCore::listeners_; -std::vector AppCore::pressedKeys_; - -AppCore::AppCore() : - dispWidth_(0), dispHeight_(0), - task_(new UpdateTask()) -{ } - -AppCore::~AppCore() -{ -} - -void AppCore::init() -{ - util::VersionInfo glfwReq(2,4,2); // requires GLFW 2.4.2 - util::ensureVersion("GLFW", initGLFW(), glfwReq); - - Application::getKernel().addTask(task_); // add updater task -} - -void AppCore::shutdown() -{ - if(dispWidth_ && dispHeight_) - { - glfwCloseWindow(); //close GLFW window - } - - glfwTerminate(); //shutdown GLFW -} - -void AppCore::createDisplay(uint width, uint height, - uint redBits, uint greenBits, uint blueBits, - uint alphaBits, uint depthBits, uint stencilBits, - bool fullscreen, const std::string &title) -{ - GLboolean status; - status = glfwOpenWindow(width, height, redBits, greenBits, - blueBits, alphaBits, depthBits, stencilBits, - fullscreen ? GLFW_FULLSCREEN : GLFW_WINDOW); - if(status == GL_FALSE) - { - throw APIError("Failed to create display."); - } - - // register the callbacks (after a window is open) - glfwSetKeyCallback(AppCore::keyCallback); - //glfwSetCharCallback(AppCore::charCallback); - glfwSetMouseButtonCallback(AppCore::mouseButtonCallback); - glfwSetMousePosCallback(AppCore::mouseMoveCallback); - //glfwSetMouseWheelCallback(AppCore::mouseWheelCallback); - - Application::initVideoCore(width, height); - dispWidth_ = width; - dispHeight_ = height; - - glfwSetWindowTitle(title.c_str()); // title is set separately -} - -void AppCore::createDisplay(uint width, uint height, uint bpp, - uint depthBits, uint stencilBits, bool fullscreen, - const std::string &title) -{ - // call main version of createDisplay with individual values for rgba bits - switch(bpp) - { - case 8: - createDisplay(width, height, 3, 3, 2, 0, depthBits, stencilBits, - fullscreen, title); - break; - case 16: - createDisplay(width, height, 5, 6, 5, 0, depthBits, stencilBits, - fullscreen, title); - break; - case 24: - createDisplay(width, height, 8, 8, 8, 0, depthBits, stencilBits, - fullscreen, title); - break; - case 32: - createDisplay(width, height, 8, 8, 8, 8, depthBits, stencilBits, - fullscreen, title); - break; - default: - throw ArgumentException("bpp argument of createDisplay must be " - "8,16,24, or 32, passed " + - boost::lexical_cast(bpp) ); - } -} - -bool AppCore::keyPressed(KeyCode key) -{ - return glfwGetKey(key) == GLFW_PRESS; -} - -std::vector AppCore::getPressedKeys() -{ - return pressedKeys_; -} - -bool AppCore::mouseButtonPressed(MouseButton button) -{ - return glfwGetMouseButton(button) == GLFW_PRESS; -} - -int AppCore::getMouseX() -{ - return task_->mouseX_; -} - -int AppCore::getMouseY() -{ - return task_->mouseY_; -} - -int AppCore::getMouseWheelPos() -{ - return glfwGetMouseWheel(); -} - -void AppCore::addInputListener(InputListener *listener) -{ - // should never happen since listeners add themselves with a this pointer - if(!listener) - { - throw ArgumentException("Null pointer in AppCore::addInputListener"); - } - - // add the listener - listeners_.push_back(listener); -} - -void AppCore::removeInputListener(InputListener *listener) -{ - // should never happen since listeners remove themselves with a this pointer - if(!listener) - { - throw ArgumentException("Null pointer in AppCore::removeInputListener"); - } - - // find and erase the listener - std::vector::iterator it; - it = std::find(listeners_.begin(), listeners_.end(), listener); - - if(it != listeners_.end()) - { - listeners_.erase(it); - } -} - -void GLFWCALL AppCore::keyCallback(int key, int action) -{ - // notify all listeners - for(std::vector::iterator listener = listeners_.begin(); - listener != listeners_.end(); - ++listener) - { - // only active listeners get messages - if((*listener)->isActive()) - { - if(action == GLFW_PRESS) - { - (*listener)->onKeyPress(key); - } - else - { - (*listener)->onKeyRelease(key); - } - } - } - - // maintain a list of pressed keys - if(action == GLFW_PRESS) - { - pressedKeys_.push_back(static_cast(key)); - } - else - { - // delete a key from the vector - std::vector::iterator it; - it = std::find(pressedKeys_.begin(), pressedKeys_.end(), key); - - if(it != pressedKeys_.end()) - { - pressedKeys_.erase(it); - } - } -} - -void GLFWCALL AppCore::mouseButtonCallback(int button, int action) -{ - // notify all listeners - for(std::vector::iterator listener = listeners_.begin(); - listener != listeners_.end(); - ++listener) - { - // only active listeners get messages - if((*listener)->isActive()) - { - if(action == GLFW_PRESS) - { - (*listener)->onMouseButtonPress(button); - } - else - { - (*listener)->onMouseButtonRelease(button); - } - } - } -} - -void GLFWCALL AppCore::mouseMoveCallback(int x, int y) -{ - // notify all listeners - for(std::vector::iterator listener = listeners_.begin(); - listener != listeners_.end(); - ++listener) - { - // only active listeners get messages - if((*listener)->isActive()) - { - (*listener)->onMouseMove(math::Vector2(static_cast(x), - static_cast(y))); - } - } -} - -scalar AppCore::getTime() -{ - return glfwGetTime() - task_->pausedTime_; -} - -void AppCore::setTitle(const std::string& title) -{ - glfwSetWindowTitle(title.c_str()); -} - -bool AppCore::isActive() -{ - return task_->active_; -} - -double AppCore::getElapsedTime() -{ - return task_->secPerFrame_; -} - -double AppCore::getFramerate() -{ - return 1/task_->secPerFrame_; -} - -uint AppCore::getDisplayWidth() -{ - return dispWidth_; -} - -uint AppCore::getDisplayHeight() -{ - return dispHeight_; -} - -util::VersionInfo AppCore::initGLFW() -{ - int maj,min,patch; - if(glfwInit() == GL_FALSE) - { - throw APIError("Initialization of GLFW failed!"); - } - glfwGetVersion(&maj,&min,&patch); - return util::VersionInfo(maj,min,patch); -} - -AppCore::UpdateTask::UpdateTask() : - Task("AppCore::UpdateTask", 10), - mouseX_(0), mouseY_(0), - active_(false), timerPaused_(false), - unpauseOnActive_(false), lastPause_(0), pausedTime_(0), - secPerFrame_(0), lastUpdate_(0) -{ -} - -void AppCore::UpdateTask::update() -{ - scalar curTime = glfwGetTime() - pausedTime_; - - // update the display here instead of VideoCore (since it belongs to glfw) - glfwSwapBuffers(); - - glfwGetMousePos(&mouseX_, &mouseY_); - - // keep track of time between frames - secPerFrame_ = curTime-lastUpdate_; - lastUpdate_ = curTime; - - // quit on window closing or Alt-F4/Alt-X - if(!glfwGetWindowParam(GLFW_OPENED) || - ( (glfwGetKey(GLFW_KEY_LALT) || glfwGetKey(GLFW_KEY_RALT)) && - (glfwGetKey(GLFW_KEY_F4) || glfwGetKey('X')) ) ) - { - Application::getKernel().killAllTasks(); - } - - // hold active-state - active_ = (glfwGetWindowParam(GLFW_ACTIVE) == GL_TRUE); - - // automatically pause/unpause app timer on focus - if(!active_ && !timerPaused_) - { - timerPaused_ = true; - lastPause_ = curTime; - unpauseOnActive_ = true; - } - else if(active_ && unpauseOnActive_) - { - timerPaused_ = true; - pausedTime_ += curTime - lastPause_; - unpauseOnActive_ = false; - } -} - -} diff --git a/src/Application.cpp b/src/Application.cpp index a6e662f..06d9787 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -5,18 +5,19 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Application.cpp,v 1.14 2005/08/02 23:07:52 cozman Exp $ +// $Id: Application.cpp,v 1.15 2005/08/07 07:12:47 cozman Exp $ #include "Application.hpp" #include "physfs.h" #include "GL/gl.h" +#include "GL/glfw.h" //This file depends on glfw #include #include "exceptions.hpp" #include "Log.hpp" #include "Kernel.hpp" -#include "AppCore.hpp" +#include "Application.hpp" #include "video/VideoCore.hpp" #include "audio/AudioCore.hpp" #include "util/filesys/filesys.hpp" @@ -25,36 +26,248 @@ namespace photon { -Kernel Application::kernel_; -AppCore Application::appCore_; -std::auto_ptr Application::videoCore_; -std::auto_ptr Application::audioCore_; -std::string Application::arg0_; +std::vector Application::listeners_; +std::vector Application::pressedKeys_; -Application::Application() : - photonVer_(0,0,1) // this is the current version +Application::Application(const std::string& arg0) : + photonVer_(0,0,1), // this is the current version + dispWidth_(0), dispHeight_(0), + updateTask_(new UpdateTask()), + stateUpdate_(new StateUpdate()), + stateRender_(new StateRender()) { util::VersionInfo physfsReq(1,0,0); // requires PhysFS 1.0.0 - util::ensureVersion("PhysFS", initPhysFS(), physfsReq); + util::ensureVersion("PhysFS", initPhysFS(arg0), physfsReq); - appCore_.init(); // init appcore + util::VersionInfo glfwReq(2,4,2); // requires GLFW 2.4.2 + util::ensureVersion("GLFW", initGLFW(), glfwReq); + + new Kernel; // create Kernel before it is used + + Kernel::getInstance().addTask(updateTask_); // add updater task + Kernel::getInstance().addTask(stateUpdate_); // add state updater task + Kernel::getInstance().addTask(stateRender_); // add state renderer task } Application::~Application() { - appCore_.shutdown(); // shutdown appcore + if(dispWidth_ && dispHeight_) + { + glfwCloseWindow(); //close GLFW window + } - PHYSFS_deinit(); // shutdown PhysFS + glfwTerminate(); //shutdown GLFW + + PHYSFS_deinit(); // shutdown PhysFS + + Kernel::destroy(); } -Kernel& Application::getKernel() +void Application::createDisplay(uint width, uint height, + uint redBits, uint greenBits, uint blueBits, + uint alphaBits, uint depthBits, uint stencilBits, + bool fullscreen, const std::string &title) { - return kernel_; + GLboolean status; + status = glfwOpenWindow(width, height, redBits, greenBits, + blueBits, alphaBits, depthBits, stencilBits, + fullscreen ? GLFW_FULLSCREEN : GLFW_WINDOW); + if(status == GL_FALSE) + { + throw APIError("Failed to create display."); + } + + // register the callbacks (after a window is open) + glfwSetKeyCallback(Application::keyCallback); + //glfwSetCharCallback(Application::charCallback); + glfwSetMouseButtonCallback(Application::mouseButtonCallback); + glfwSetMousePosCallback(Application::mouseMoveCallback); + //glfwSetMouseWheelCallback(Application::mouseWheelCallback); + + Application::initVideoCore(width, height); + dispWidth_ = width; + dispHeight_ = height; + + glfwSetWindowTitle(title.c_str()); // title is set separately } -AppCore& Application::getAppCore() +void Application::createDisplay(uint width, uint height, uint bpp, + uint depthBits, uint stencilBits, bool fullscreen, + const std::string &title) { - return appCore_; + // call main version of createDisplay with individual values for rgba bits + switch(bpp) + { + case 8: + createDisplay(width, height, 3, 3, 2, 0, depthBits, stencilBits, + fullscreen, title); + break; + case 16: + createDisplay(width, height, 5, 6, 5, 0, depthBits, stencilBits, + fullscreen, title); + break; + case 24: + createDisplay(width, height, 8, 8, 8, 0, depthBits, stencilBits, + fullscreen, title); + break; + case 32: + createDisplay(width, height, 8, 8, 8, 8, depthBits, stencilBits, + fullscreen, title); + break; + default: + throw ArgumentException("bpp argument of createDisplay must be " + "8,16,24, or 32, passed " + + boost::lexical_cast(bpp) ); + } +} + +bool Application::keyPressed(KeyCode key) +{ + return glfwGetKey(key) == GLFW_PRESS; +} + +std::vector Application::getPressedKeys() +{ + return pressedKeys_; +} + +bool Application::mouseButtonPressed(MouseButton button) +{ + return glfwGetMouseButton(button) == GLFW_PRESS; +} + +int Application::getMouseX() +{ + return updateTask_->mouseX_; +} + +int Application::getMouseY() +{ + return updateTask_->mouseY_; +} + +int Application::getMouseWheelPos() +{ + return glfwGetMouseWheel(); +} + +void Application::addInputListener(InputListener *listener) +{ + // should never happen since listeners add themselves with a this pointer + if(!listener) + { + throw ArgumentException("Null pointer in " + "Application::addInputListener"); + } + + // add the listener + listeners_.push_back(listener); +} + +void Application::removeInputListener(InputListener *listener) +{ + // should never happen since listeners remove themselves with a this pointer + if(!listener) + { + throw ArgumentException("Null pointer in " + "Application::removeInputListener"); + } + + // find and erase the listener + std::vector::iterator it; + it = std::find(listeners_.begin(), listeners_.end(), listener); + + if(it != listeners_.end()) + { + listeners_.erase(it); + } +} + +void GLFWCALL Application::keyCallback(int key, int action) +{ + // notify all listeners + for(std::vector::iterator listener = listeners_.begin(); + listener != listeners_.end(); + ++listener) + { + // only active listeners get messages + if((*listener)->isActive()) + { + if(action == GLFW_PRESS) + { + (*listener)->onKeyPress(key); + } + else + { + (*listener)->onKeyRelease(key); + } + } + } + + // maintain a list of pressed keys + if(action == GLFW_PRESS) + { + pressedKeys_.push_back(static_cast(key)); + } + else + { + // delete a key from the vector + std::vector::iterator it; + it = std::find(pressedKeys_.begin(), pressedKeys_.end(), key); + + if(it != pressedKeys_.end()) + { + pressedKeys_.erase(it); + } + } +} + +void GLFWCALL Application::mouseButtonCallback(int button, int action) +{ + // notify all listeners + for(std::vector::iterator listener = listeners_.begin(); + listener != listeners_.end(); + ++listener) + { + // only active listeners get messages + if((*listener)->isActive()) + { + if(action == GLFW_PRESS) + { + (*listener)->onMouseButtonPress(button); + } + else + { + (*listener)->onMouseButtonRelease(button); + } + } + } +} + +void GLFWCALL Application::mouseMoveCallback(int x, int y) +{ + // notify all listeners + for(std::vector::iterator listener = listeners_.begin(); + listener != listeners_.end(); + ++listener) + { + // only active listeners get messages + if((*listener)->isActive()) + { + (*listener)->onMouseMove(math::Vector2(static_cast(x), + static_cast(y))); + } + } +} + +scalar Application::getTime() +{ + return glfwGetTime() - updateTask_->pausedTime_; +} + +void Application::setTitle(const std::string& title) +{ + glfwSetWindowTitle(title.c_str()); } video::VideoCore& Application::getVideoCore() @@ -105,18 +318,155 @@ void Application::initAudioCore(const std::string& deviceName) } } -void Application::setInitOptions(const char* arg0) +bool Application::isActive() { - arg0_ = arg0; + return updateTask_->active_; } -util::VersionInfo Application::initPhysFS() +bool Application::isRunning() +{ + return !updateTask_->quitRequested_; +} + +double Application::getElapsedTime() +{ + return updateTask_->secPerFrame_; +} + +double Application::getFramerate() +{ + return 1/updateTask_->secPerFrame_; +} + +void Application::unregisterState(const std::string& stateName) +{ + StateMap::iterator it( stateMap_.find(stateName) ); + + if(it == stateMap_.end()) + { + throw PreconditionException("Application::unregisterState called with " + "non-existant state name: \"" + stateName + "\""); + } + + stateMap_.erase(stateName); +} + +void Application::setCurrentState(const std::string& stateName) +{ + StateMap::iterator it( stateMap_.find(stateName) ); + + if(it == stateMap_.end()) + { + throw PreconditionException("Application::setCurrentState called with " + "non-existant state name: \"" + stateName + "\""); + } + + if(stateUpdate_->state_.get() != 0) + { + stateUpdate_->state_->exitState(); + } + + stateRender_->state_ = stateUpdate_->state_ = stateMap_[stateName]; + stateUpdate_->state_->enterState(); +} + +uint Application::getDisplayWidth() +{ + return dispWidth_; +} + +uint Application::getDisplayHeight() +{ + return dispHeight_; +} + +util::VersionInfo Application::initPhysFS(const std::string& arg0) { PHYSFS_Version ver; - PHYSFS_init(arg0_.c_str()); + PHYSFS_init(arg0.c_str()); PHYSFS_addToSearchPath(PHYSFS_getBaseDir(),0); PHYSFS_getLinkedVersion(&ver); return util::VersionInfo(ver.major, ver.minor, ver.patch); } +util::VersionInfo Application::initGLFW() +{ + int maj,min,patch; + if(glfwInit() == GL_FALSE) + { + throw APIError("Initialization of GLFW failed!"); + } + glfwGetVersion(&maj,&min,&patch); + return util::VersionInfo(maj,min,patch); +} + +Application::UpdateTask::UpdateTask() : + Task("Application::UpdateTask", PRI_APP_UPDATE), + mouseX_(0), mouseY_(0), + active_(false), timerPaused_(false), + unpauseOnActive_(false), lastPause_(0), pausedTime_(0), + secPerFrame_(0), lastUpdate_(0), + quitRequested_(false) +{ +} + +void Application::UpdateTask::update() +{ + scalar curTime = glfwGetTime() - pausedTime_; + + // update the display here instead of VideoCore (since it belongs to glfw) + glfwSwapBuffers(); + + glfwGetMousePos(&mouseX_, &mouseY_); + + // keep track of time between frames + secPerFrame_ = curTime-lastUpdate_; + lastUpdate_ = curTime; + + // quit on window closing or Alt-F4/Alt-X + if(!glfwGetWindowParam(GLFW_OPENED) || + ( (glfwGetKey(GLFW_KEY_LALT) || glfwGetKey(GLFW_KEY_RALT)) && + (glfwGetKey(GLFW_KEY_F4) || glfwGetKey('X')) ) ) + { + Kernel::getInstance().killAllTasks(); + } + + // hold active-state + active_ = (glfwGetWindowParam(GLFW_ACTIVE) == GL_TRUE); + + // automatically pause/unpause app timer on focus + if(!active_ && !timerPaused_) + { + timerPaused_ = true; + lastPause_ = curTime; + unpauseOnActive_ = true; + } + else if(active_ && unpauseOnActive_) + { + timerPaused_ = true; + pausedTime_ += curTime - lastPause_; + unpauseOnActive_ = false; + } +} + +Application::StateUpdate::StateUpdate() : + Task("StateUpdate", PRI_NORMAL) +{ +} + +void Application::StateUpdate::update() +{ + state_->update(); +} + +Application::StateRender::StateRender() : + Task("StateRender", PRI_RENDER) +{ +} + +void Application::StateRender::update() +{ + state_->render(); +} + } diff --git a/src/InputListener.cpp b/src/InputListener.cpp index 168ca99..954eb97 100644 --- a/src/InputListener.cpp +++ b/src/InputListener.cpp @@ -5,11 +5,11 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: InputListener.cpp,v 1.1 2005/07/19 05:45:24 cozman Exp $ +// $Id: InputListener.cpp,v 1.2 2005/08/07 07:12:47 cozman Exp $ #include "InputListener.hpp" -#include "AppCore.hpp" +#include "Application.hpp" namespace photon { @@ -17,12 +17,12 @@ namespace photon InputListener::InputListener() : active_(true) { - AppCore::addInputListener(this); + Application::addInputListener(this); } InputListener::~InputListener() { - AppCore::removeInputListener(this); + Application::removeInputListener(this); } void InputListener::setActive(bool active) diff --git a/src/Kernel.cpp b/src/Kernel.cpp index 4e8e961..e8a00b7 100644 --- a/src/Kernel.cpp +++ b/src/Kernel.cpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Kernel.cpp,v 1.3 2005/07/20 06:12:54 cozman Exp $ +// $Id: Kernel.cpp,v 1.4 2005/08/07 07:12:47 cozman Exp $ #include "Kernel.hpp" @@ -22,6 +22,41 @@ Kernel::Kernel() Kernel::~Kernel() { + killAllTasks(); +} + +void Kernel::step() +{ + std::list::iterator it; + + // loop through active tasks, updating each one + for(it = tasks_.begin(); it != tasks_.end(); ++it) + { + TaskPtr& task(*it); + + // only update alive, non-paused tasks + if(task->isAlive() && !task->isPaused()) + { + task->update(); + } + } + + // loop through tasks, removing any dead tasks + for(it = tasks_.begin(); it != tasks_.end(); ) + { + TaskPtr& task(*it); + + // remove dead tasks + if(!task->isAlive()) + { + task->onKill(); // symmetry with onStart, clean up act + it = tasks_.erase(it); + } + else + { + ++it; //advance iterator, if not deleting + } + } } void Kernel::run() @@ -29,36 +64,7 @@ void Kernel::run() // loop on activeTasks while(!tasks_.empty()) { - std::list::iterator it; - - // loop through active tasks, updating each one - for(it = tasks_.begin(); it != tasks_.end(); ++it) - { - TaskPtr& task(*it); - - // only update alive, non-paused tasks - if(task->isAlive() && !task->isPaused()) - { - task->update(); - } - } - - // loop through tasks, removing any dead tasks - for(it = tasks_.begin(); it != tasks_.end(); ) - { - TaskPtr& task(*it); - - // remove dead tasks - if(!task->isAlive()) - { - task->onKill(); // symmetry with onStart, clean up act - it = tasks_.erase(it); - } - else - { - ++it; //advance iterator, if not deleting - } - } + step(); } } diff --git a/src/Task.cpp b/src/Task.cpp index 823a1a6..ccf58af 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -5,14 +5,14 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Task.cpp,v 1.3 2005/07/20 06:12:54 cozman Exp $ +// $Id: Task.cpp,v 1.4 2005/08/07 07:12:47 cozman Exp $ #include "Task.hpp" namespace photon { -Task::Task(const std::string& name, uint priority) : +Task::Task(const std::string& name, PriorityLevel priority) : name_(name), priority_(priority), alive_(true), paused_(false) { } diff --git a/src/util/Timer.cpp b/src/util/Timer.cpp index 5bc640f..ca24f3c 100644 --- a/src/util/Timer.cpp +++ b/src/util/Timer.cpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Timer.cpp,v 1.4 2005/08/02 23:07:52 cozman Exp $ +// $Id: Timer.cpp,v 1.5 2005/08/07 07:12:48 cozman Exp $ #include "util/Timer.hpp" #include "Application.hpp" @@ -16,7 +16,6 @@ namespace util { Timer::Timer(bool appTimeLinked) : - appCore_(Application::getAppCore()), appTimeLinked_(appTimeLinked) { reset(); //initializes other members @@ -74,7 +73,8 @@ double Timer::getTimeInternal() const { if(appTimeLinked_) { - return appCore_.getTime(); // get from AppCore timer if linked + // get from Application timer if linked + return Application::getInstance().getTime(); } else { diff --git a/src/video/VideoCore.cpp b/src/video/VideoCore.cpp index c189945..13e2f83 100644 --- a/src/video/VideoCore.cpp +++ b/src/video/VideoCore.cpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: VideoCore.cpp,v 1.9 2005/08/02 23:07:53 cozman Exp $ +// $Id: VideoCore.cpp,v 1.10 2005/08/07 07:12:48 cozman Exp $ #include "video/VideoCore.hpp" @@ -27,9 +27,9 @@ VideoCore::VideoCore(uint width, uint height) : { initOpenGL(); setOrthoView(); - + //add updater task - Application::getKernel().addTask(shared_ptr(new UpdateTask())); + Kernel::getInstance().addTask(shared_ptr(new UpdateTask())); } VideoCore::~VideoCore() @@ -114,8 +114,8 @@ void VideoCore::initOpenGL() glShadeModel(GL_SMOOTH); // Setup depth checking. - glDepthFunc(GL_LEQUAL); - glEnable(GL_DEPTH_TEST); + //glDepthFunc(GL_LEQUAL); + //glEnable(GL_DEPTH_TEST); //setup hints glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); @@ -148,7 +148,7 @@ uint VideoCore::getDisplayHeight() } VideoCore::UpdateTask::UpdateTask() : - Task("VideoCore::UpdateTask", 20) + Task("VideoCore::UpdateTask", PRI_VIDEO_UPDATE) { } diff --git a/test/Audio_test.cpp b/test/Audio_test.cpp index 8ea3107..8aa050f 100644 --- a/test/Audio_test.cpp +++ b/test/Audio_test.cpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Audio_test.cpp,v 1.8 2005/08/02 23:07:53 cozman Exp $ +// $Id: Audio_test.cpp,v 1.9 2005/08/07 07:12:48 cozman Exp $ #include "photon.hpp" using namespace photon; @@ -200,14 +200,14 @@ public: Application::getAppCore().createDisplay(800,600,32,0,0,false); // create sound device Application::initAudioCore("OSS"); - + // be sure to add FPSDisplayTask Application::getKernel().addTask(TaskPtr(new FPSDisplayTask())); // add the main task to the Kernel Application::getKernel().addTask(TaskPtr(new MainTask())); // run Kernel until task finishes - Application::getKernel().run(); - + Application::getKernel().run(); + return 0; } }; diff --git a/test/FPSDisplayTask.hpp b/test/FPSDisplayTask.hpp index b582161..efbc35a 100644 --- a/test/FPSDisplayTask.hpp +++ b/test/FPSDisplayTask.hpp @@ -11,8 +11,8 @@ class FPSDisplayTask : public photon::Task { public: FPSDisplayTask() : - Task("FPSDisplayTask", 1000000), // extremely low priority - app(photon::Application::getAppCore()), + Task("FPSDisplayTask"), + app(Application::getInstance()), lastUpdate(0) { } @@ -28,7 +28,7 @@ public: } private: - photon::AppCore& app; + Application& app; double lastUpdate; }; diff --git a/test/Image_test.cpp b/test/Image_test.cpp index bb5df81..84ded50 100644 --- a/test/Image_test.cpp +++ b/test/Image_test.cpp @@ -5,23 +5,24 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Image_test.cpp,v 1.8 2005/08/02 23:07:53 cozman Exp $ +// $Id: Image_test.cpp,v 1.9 2005/08/07 07:12:48 cozman Exp $ #include "photon.hpp" using namespace photon; #include "FPSDisplayTask.hpp" // used to display FPS in title bar -class MainTask : public Task + + +class MainState : public State { public: - MainTask() : - Task("MainTask"), - app(Application::getAppCore()), - video(Application::getVideoCore()) + MainState() : + app(Application::getInstance()) + { } + + void enterState() { - video.setOrthoView(800,600); - // load the images video::Image::addResource("data/icon.png"); video::Texture::addResource("robo","data/robo.png"); @@ -30,20 +31,24 @@ public: img[0].open("robo"); img[0].setAlpha(128); img[0].resize(100,200); - + // load img[1] img[1].open("data/icon.png"); - + // copy img[0] into img[2] and flip it img[2] = img[0]; img[2].flip(true,true); } void update() + { + } + + void render() { // draw in top left corner img[0].draw(0,0); - + // rotate according to timer img[1].drawRotated(200,200,app.getTime()*5); @@ -56,28 +61,22 @@ public: private: video::Image img[3]; - - AppCore& app; - video::VideoCore& video; + + Application& app; }; -// standard application, creates window, registers task and runs -class ImageTest : public Application +int PhotonMain(const StrVec& args) { -public: + Application::getInstance().createDisplay(800,600,32,0,0,true); - int main(const StrVec& args) - { - Application::getAppCore().createDisplay(800,600,32,0,0,false); + // be sure to add FPSDisplayTask + Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask())); - // be sure to add FPSDisplayTask - Application::getKernel().addTask(TaskPtr(new FPSDisplayTask())); - Application::getKernel().addTask(TaskPtr(new MainTask())); - - Application::getKernel().run(); + Application::getInstance().registerState("main"); + Application::getInstance().setCurrentState("main"); - return 0; - } -}; + Kernel::getInstance().run(); + + return 0; +} -ENTRYPOINT(ImageTest)