From 0ba75354289e8ab8b2a9477b59946a835852ac2b Mon Sep 17 00:00:00 2001 From: James Turk Date: Tue, 15 Mar 2005 19:21:51 +0000 Subject: [PATCH] post-Kernel --- SConstruct | 10 +- include/AppCore.hpp | 118 ++++++++++++------------ include/Application.hpp | 33 +++---- include/Kernel.hpp | 105 +++++++++++++++++++++ include/Task.hpp | 152 +++++++++++++++++++++++++++++++ include/entrypoint.hpp | 19 ++-- include/photon.hpp | 1 - src/AppCore.cpp | 197 +++++++++++++++++++--------------------- src/Application.cpp | 44 +++++++-- src/Kernel.cpp | 155 +++++++++++++++++++++++++++++++ src/Task.cpp | 62 +++++++++++++ todo.txt | 6 +- 12 files changed, 691 insertions(+), 211 deletions(-) create mode 100644 include/Kernel.hpp create mode 100644 include/Task.hpp create mode 100644 src/Kernel.cpp create mode 100644 src/Task.cpp diff --git a/SConstruct b/SConstruct index 51c0674..1965edb 100644 --- a/SConstruct +++ b/SConstruct @@ -5,7 +5,7 @@ # James Turk (jpt2433@rit.edu) # # Version: -# $Id: SConstruct,v 1.4 2005/03/04 13:06:49 cozman Exp $ +# $Id: SConstruct,v 1.5 2005/03/15 19:21:51 cozman Exp $ import os,os.path import glob @@ -87,12 +87,14 @@ class Builder: self.checkDepends() self.namedBuild('photon', os.path.join('lib',libName), 'Library', - default=True, - source = self.srcFiles, CPPPATH = self.incDirs) + default=True, + source = self.srcFiles, CPPPATH = 'include', + CPPFLAGS = '-Wall -pedantic -pg') self.namedBuild('test00', 'test00', 'Program', default=False, source = 'test00.cpp', CPPPATH = self.incDirs, LIBPATH='./lib', - LIBS=['photon','openal32','glfw','opengl32','glu32','physfs']) + LIBS=['photon','openal32','glfw','opengl32','glu32','physfs'], + CPPFLAGS = '-Wall -pedantic -pg', LINKFLAGS='-pg') self.buildSuperHeader(libName) ndoc = self.env.Command('docs/index.html', './include', """NaturalDocs -nag -i $SOURCES -o HTML ./docs -p ./ndoc""", diff --git a/include/AppCore.hpp b/include/AppCore.hpp index 09c349a..bcc385c 100644 --- a/include/AppCore.hpp +++ b/include/AppCore.hpp @@ -5,33 +5,37 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: AppCore.hpp,v 1.4 2005/03/04 13:06:49 cozman Exp $ +// $Id: AppCore.hpp,v 1.5 2005/03/15 19:22:07 cozman Exp $ #ifndef PHOTON_APPCORE_HPP #define PHOTON_APPCORE_HPP #include "types.hpp" -#include "glfw/types_glfw.hpp" #include "util/VersionInfo.hpp" #include "util/Singleton.hpp" +#include "Task.hpp" namespace photon { // Class: AppCore -// Photon's core for application behavior. Defines the interface +// Photon's core for application behavior. Defines the interface // through which all "application" related functions are performed. // -// AppCore is the Core that essentially represents the window management, +// AppCore is the Core that essentially represents the window management, // input, and timing systems. // // Parent: // class AppCore : public util::Singleton { - + +public: + AppCore(); + ~AppCore(); + // Group: Video -public: +public: // Function: createDisplay // This function attempts to create a display with the given parameters. @@ -46,11 +50,11 @@ public: // depthBits - desired bitdepth of depth buffer // stencilBits - desired bitdepth of stencil buffer // fullscreen - true: fullscreen, false: windowed - // title - title of application - void createDisplay(uint width, uint height, - uint redBits, uint greenBits, uint blueBits, + // [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); + bool fullscreen, const std::string& title="Photon App"); // Function: createDisplay // This function attempts to create a display with the given parameters. @@ -62,24 +66,24 @@ public: // depthBits - desired bitdepth of depth buffer // stencilBits - desired bitdepth of stencil buffer // fullscreen - true: fullscreen, false: windowed - // title - title of application - void createDisplay(uint width, uint height, uint bpp, + // [title - title of application, optional] + void createDisplay(uint width, uint height, uint bpp, uint depthBits, uint stencilBits, bool fullscreen, - const std::string& title); + 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: mouseButtonPressed // Check if a given mouse button is currently pressed. // @@ -105,7 +109,7 @@ public: int getMouseY(); // Function: getMouseWheelPos - // Gets current location of mouse wheel, treated as if wheel describes a + // Gets current location of mouse wheel, treated as if wheel describes a // third axis of movement for the mouse. // // Returns: @@ -122,56 +126,41 @@ public: // Time, represented as a floating-point number in seconds, application has // been running. scalar getTime(); - -// Group: General + +// Group: General public: - // Function: update - // Updates the internals of the application, including the display. - void update(); // 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: requestQuit - // Sets the internal quit flag to true. - void requestQuit(); - - // Function: quitRequested - // Checks the internal quit flag, if a quit has been requested, - // the application should comply. - // - // Returns: - // State of internal quit flag, if true application should quit ASAP. - bool quitRequested(); - // Function: isActive - // Checks if application is active, which on most systems simply means it + // Checks if application is active, which on most systems simply means it // has focus. - // - // Returns: + // + // Returns: // True if application is active, false otherwise. bool isActive(); // Function: getElapsedTime - // Finds the amount of time passed between frames, useful for time-based + // Finds the amount of time passed between frames, useful for time-based // movement. - // - // Returns: + // + // Returns: // Time between current frame and last frame. (1/()) double getElapsedTime(); - + // Function: getFramerate // Gets number of frames per second the application is currently being run at. - // - // Returns: + // + // Returns: // Current frames per second. double getFramerate(); -// Group: Accessors +// Group: Accessors public: // Function: getDisplayWidth // Get the width of the display. @@ -179,7 +168,7 @@ public: // Returns: // Width of display in pixels. uint getDisplayWidth(); - + // Function: getDisplayHeight // Get the height of the display. // @@ -187,30 +176,37 @@ public: // Height of display in pixels. uint getDisplayHeight(); + class UpdateTask : public Task + { + + friend class AppCore; + + public: + UpdateTask(); + + void update(); + + private: + uint mouseX_; + uint mouseY_; + bool active_; + bool timerPaused_; + bool unpauseOnActive_; + scalar lastPause_; + scalar pausedTime_; + scalar secPerFrame_; + scalar lastUpdate_; + }; + // data members private: uint dispWidth_; uint dispHeight_; - bool quitRequested_; - bool active_; - bool timerPaused_; - bool unpauseOnActive_; - scalar lastPause_; - scalar pausedTime_; - scalar secPerFrame_; - scalar lastUpdate_; + shared_ptr task_; // API initialization private: util::VersionInfo initGLFW(); - -// Singleton-required code -private: - AppCore(); - ~AppCore(); - - friend class util::Singleton; - friend class std::auto_ptr; }; } diff --git a/include/Application.hpp b/include/Application.hpp index ced9c9f..f3afce0 100644 --- a/include/Application.hpp +++ b/include/Application.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Application.hpp,v 1.6 2005/03/02 08:40:51 cozman Exp $ +// $Id: Application.hpp,v 1.7 2005/03/15 19:22:07 cozman Exp $ #ifndef PHOTON_APPLICATION_HPP #define PHOTON_APPLICATION_HPP @@ -17,6 +17,7 @@ #include "types.hpp" #include "util/VersionInfo.hpp" +#include "Task.hpp" namespace photon { @@ -26,10 +27,10 @@ namespace photon // implementations of Application. // // Derived classes are made entrypoint via . -class Application : public boost::noncopyable +class Application { -// Group: (Con/De)structors +// Group: (Con/De)structors public: // Function: Application // Default constructor, initializes the internal state & dependencies. @@ -39,10 +40,12 @@ public: // Default destructor, shuts down dependencies. virtual ~Application(); +// Group: Main +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 Amph application. + // this becomes the entry point for a Amph application. // // Parameters: // args - containing arguments passed to program. @@ -52,34 +55,20 @@ public: // // See Also: // - virtual int main(StrVec args)=0; + virtual int main(const StrVec& args)=0; -// Behind the scenes +// behind the scenes public: - // Function: setInitOptions(const char* arg0) - // Internal use function, used to set initialization options. - // (params not documented since function signature is subject to change and - // should not be relied on by user-level code) - static void setInitOptions(const char* appPath); - + static void setInitOptions(const char* arg0); + // Group: API Initialization private: - // Function: initPhysFS - // Initialize PhysFS for use. - // - // Parameters: - // arg0 - Path to application (argv[0]) - // - // Returns: - // with PhysFS version. util::VersionInfo initPhysFS(const char* arg0); -// Data Members private: // version number for photon util::VersionInfo photonVer_; - // arg0 from command line static std::string arg0_; }; diff --git a/include/Kernel.hpp b/include/Kernel.hpp new file mode 100644 index 0000000..771cdcb --- /dev/null +++ b/include/Kernel.hpp @@ -0,0 +1,105 @@ +//This file is part of Photon (http://photon.sourceforge.net) +//Copyright (C) 2004-2005 James Turk +// +// Author: +// James Turk (jpt2433@rit.edu) +// +// Version: +// $Id: Kernel.hpp,v 1.1 2005/03/15 19:22:07 cozman Exp $ + +#ifndef PHOTON_KERNEL_HPP +#define PHOTON_KERNEL_HPP + +#include +#include + +#include "util/Singleton.hpp" +#include "Task.hpp" + +namespace photon +{ + +// Class: Kernel +// Singleton Kernel class, maintains a list of and manages their +// status, including adding, deleting, pausing, and unpausing tasks. +// +// To use Kernel: +// - (1) Add any tasks (should be derived from ) +// - (2) call +// - (3) in order to avoid running forever, all tasks should eventually die +class Kernel : public util::Singleton +{ + +// Group: (Con/De)structors +public: + // Function: Kernel + // Kernel constructor, initializes kernel singleton. + Kernel(); + + // Function: ~Kernel + // Kernel destructor, destroys kernel singleton. + ~Kernel(); + +// Group: Running +public: + // 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. + void run(); + +// Group: Task Management +public: + // Function: addTask + // Add a new to the Kernel's list. All tasks MUST have unique + // names. + // + // Parameters: + // task - representing instance of subclass to add. + void addTask(TaskPtr task); + + // Function: killTask + // Kill a task in the Kernel task list. + // Dead tasks are removed in next loop through tasks. + // + // Parameters: + // taskName - Name of task to kill. + void killTask(const std::string& taskName); + + // Function: pauseTask + // Pause a task in the Kernel task list. + // + // Parameters: + // taskName - Name of task to pause. + void pauseTask(const std::string& taskName); + + // Function: unpauseTask + // Unpause a task in the Kernel task list. + // + // Parameters: + // taskName - Name of task to unpause. + void unpauseTask(const std::string& taskName); + + // Function: killAllTasks + // Kills all tasks. + // Dead tasks are removed in next loop through tasks. + void killAllTasks(); + +// data members +private: + + //stored list of tasks (stored in order of priority highest to lowest) + std::list tasks_; + + //predicate for search + class TaskNameEq : public std::binary_function + { + public: + bool operator()(const TaskPtr& lhs, const std::string& rhs) const; + }; +}; + +} + +#endif //PHOTON_KERNEL_HPP diff --git a/include/Task.hpp b/include/Task.hpp new file mode 100644 index 0000000..2d28129 --- /dev/null +++ b/include/Task.hpp @@ -0,0 +1,152 @@ +//This file is part of Photon (http://photon.sourceforge.net) +//Copyright (C) 2004-2005 James Turk +// +// Author: +// James Turk (jpt2433@rit.edu) +// +// Version: +// $Id: Task.hpp,v 1.1 2005/03/15 19:22:07 cozman Exp $ + +#ifndef PHOTON_TASK_HPP +#define PHOTON_TASK_HPP + +#include + +#include "types.hpp" + +namespace photon +{ + +// Title: Task + +// 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; + +// Enum: PriorityLevel +// Enumeration defining priority of a Task. +// +// Values: +// PRI_LOWEST - Lowest priority available. +// PRI_LOW - Lower-than-usual priority. +// PRI_NORMAL - Normal priority, suitable for most tasks. +// PRI_HIGH - Lower-than-usual priority. +// PRI_CORE - Priority used by the various cores, between high and highest. +// PRI_HIGHEST - Highest priority available. +enum PriorityLevel +{ + PRI_LOWEST, + PRI_LOW, + PRI_NORMAL, + PRI_HIGH, + PRI_CORE, + PRI_HIGHEST +}; + +// Class: Task +// Abstract class for tasks, which are runnable classes for use with . +// +// When writing a task, only update() needs to be overloaded. +class Task +{ +// Group: (Con/De)structors +public: + // Function: Task + // Constructor, every task needs a name and priority. + // + // Parameters: + // name - Name for task, must be unique! + // priority - Optional argument for desired for the Task, + // controls order in which tasks are run by the . + // [default = PRI_NORMAL] + Task(const std::string& name, PriorityLevel priority=PRI_NORMAL); + + // Function: ~Task + // Virtual destructor, exists simply to make inheritance safe. + virtual ~Task(); + +// Group: Control +public: + // Function: update + // Pure virtual, every child task must overload it's own update(), when a + // task is active this is called every 'frame.' + virtual void update()=0; + + // Function: onStart + // Virtual function, overload to define behavior when the task is started. + virtual void onStart(); + + // Function: onKill + // Virtual function, overload to define behavior when the task is killed. + virtual void onKill(); + + // Function: onPause + // Virtual function, overload to define behavior every time that the + // task is paused. + // + // Note: + // Children of onPause should call Task::onPause to let the task know it's + // been paused. + virtual void onPause(); + + // Function: onUnpause + // Virtual function, overload to define behavior every time that the + // task is unpaused. + // + // Note: + // Children of onUnpause should call Task::onUnpause to let the task know + // it's been paused. + virtual void onUnpause(); + + // Function: kill + // Sets state of application to dead, dead tasks remove themselves from + // the Kernel's task pool. + void kill(); + +// Group: Accessors +public: + // Function: getName + // Get the name of the task. + // + // Return: + // Name of task. + std::string getName() const; + + // Function: getPriority + // Get the priority of the task. + // + // Return: + // of task. + PriorityLevel getPriority() const; + + // Function: isAlive + // Check if task is alive or not. + // + // Return: + // true if task is alive, false if task has been killed + bool isAlive() const; + + // Function: isPaused + // Check if task is paused or not. + // + // Return: + // true iff task is paused + bool isPaused() const; + +// data members +private: + std::string name_; + PriorityLevel priority_; + bool alive_; + bool paused_; +}; + +} + +#endif //PHOTON_TASK_HPP diff --git a/include/entrypoint.hpp b/include/entrypoint.hpp index b92a4b3..90e5586 100644 --- a/include/entrypoint.hpp +++ b/include/entrypoint.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: entrypoint.hpp,v 1.3 2005/03/04 13:06:49 cozman Exp $ +// $Id: entrypoint.hpp,v 1.4 2005/03/15 19:22:07 cozman Exp $ #ifndef PHOTON_ENTRYPOINT_HPP @@ -22,7 +22,7 @@ which implements main, in the file defining PongGame it is important to include ENTRYPOINT(PongGame) so that the entry point becomes PongGame::main. */ -#define ENTRYPOINT(className) int main(int argc, char *argv[]) \ +#define ENTRYPOINT(className) int main(int argc, const char** argv) \ { return photon::mainclass(argc,argv); } namespace photon @@ -30,25 +30,28 @@ namespace photon // function which does all the work of MAINCLASS template -int mainclass(int argc, char *argv[]) +int mainclass(int argc, const char** argv) { try { + App app; StrVec args; for(int i=0; i < argc; ++i) + { args.push_back(argv[i]); + } App::setInitOptions(argv[0]); - App app; + return app.main(args); } - catch(photon::Exception &e) + catch(Exception &e) { - photon::Log::getInstance().error() << e; + Log::getInstance().error() << e; return 0; } - catch(photon::Error &e) + catch(Error &e) { - photon::Log::getInstance().critical() << e; + Log::getInstance().critical() << e; return 1; } } diff --git a/include/photon.hpp b/include/photon.hpp index b3f7ca9..1def34d 100644 --- a/include/photon.hpp +++ b/include/photon.hpp @@ -14,7 +14,6 @@ #include "Task.hpp" #include "types.hpp" #include "audio/AudioCore.hpp" -#include "glfw/types_glfw.hpp" #include "math/Circle.hpp" #include "math/math.hpp" #include "math/Rect.hpp" diff --git a/src/AppCore.cpp b/src/AppCore.cpp index 9202015..406c77b 100644 --- a/src/AppCore.cpp +++ b/src/AppCore.cpp @@ -5,41 +5,56 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: AppCore.cpp,v 1.4 2005/03/04 13:06:49 cozman Exp $ +// $Id: AppCore.cpp,v 1.5 2005/03/15 19:22:07 cozman Exp $ #include "AppCore.hpp" #include #include "glfw.h" //This file depends on glfw +#include "Kernel.hpp" #include "exceptions.hpp" namespace photon { -void AppCore::createDisplay(uint width, uint height, - uint redBits, uint greenBits, uint blueBits, +AppCore::AppCore() : + dispWidth_(0), dispHeight_(0), + task_(new UpdateTask()) +{ + util::VersionInfo glfwReq(2,4,2); // requires GLFW 2.4.2 + util::ensureVersion("GLFW", initGLFW(), glfwReq); + + Kernel::getInstance().addTask(task_); +} + +AppCore::~AppCore() +{ + 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) + 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."); } - + dispWidth_ = width; dispHeight_ = height; - + glfwSetWindowTitle(title.c_str()); // title is set separately - - quitRequested_ = false; //now that a window is open, no quit requested } -void AppCore::createDisplay(uint width, uint height, uint bpp, +void AppCore::createDisplay(uint width, uint height, uint bpp, uint depthBits, uint stencilBits, bool fullscreen, const std::string &title) { @@ -47,24 +62,24 @@ void AppCore::createDisplay(uint width, uint height, uint bpp, switch(bpp) { case 8: - createDisplay(width, height, 3, 3, 2, 0, depthBits, stencilBits, + createDisplay(width, height, 3, 3, 2, 0, depthBits, stencilBits, fullscreen, title); break; case 16: - createDisplay(width, height, 5, 6, 5, 0, depthBits, stencilBits, + createDisplay(width, height, 5, 6, 5, 0, depthBits, stencilBits, fullscreen, title); break; case 24: - createDisplay(width, height, 8, 8, 8, 0, depthBits, stencilBits, + createDisplay(width, height, 8, 8, 8, 0, depthBits, stencilBits, fullscreen, title); break; case 32: - createDisplay(width, height, 8, 8, 8, 8, depthBits, stencilBits, + 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 " + + throw ArgumentException("bpp argument of createDisplay must be " + "8,16,24, or 32, passed " + boost::lexical_cast(bpp) ); } } @@ -81,16 +96,12 @@ bool AppCore::mouseButtonPressed(MouseButton button) int AppCore::getMouseX() { - int x; - glfwGetMousePos(&x,0); //only get x - return x; + return task_->mouseX_; } int AppCore::getMouseY() { - int y; - glfwGetMousePos(0,&y); //only get y - return y; + return task_->mouseY_; } int AppCore::getMouseWheelPos() @@ -100,26 +111,76 @@ int AppCore::getMouseWheelPos() scalar AppCore::getTime() { - return glfwGetTime() - pausedTime_; + return glfwGetTime() - task_->pausedTime_; } -void AppCore::update() +void AppCore::setTitle(const std::string& title) { - scalar curTime = getTime(); - + 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", PRI_CORE), + 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(); - + glfwSwapBuffers(); + // 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)) && + if(!glfwGetWindowParam(GLFW_OPENED) || + ( (glfwGetKey(GLFW_KEY_LALT) || glfwGetKey(GLFW_KEY_RALT)) && (glfwGetKey(GLFW_KEY_F4) || glfwGetKey('X')) ) ) { - quitRequested_ = true; + Kernel::getInstance().killAllTasks(); } // hold active-state @@ -140,72 +201,4 @@ void AppCore::update() } } -void AppCore::setTitle(const std::string& title) -{ - glfwSetWindowTitle(title.c_str()); -} - -void AppCore::requestQuit() -{ - quitRequested_ = true; -} - -bool AppCore::quitRequested() -{ - return quitRequested_; -} - -bool AppCore::isActive() -{ - return active_; -} - -double AppCore::getElapsedTime() -{ - return secPerFrame_; -} - -double AppCore::getFramerate() -{ - return 1/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::AppCore() : - dispWidth_(0), dispHeight_(0), - quitRequested_(true), active_(false), timerPaused_(false), - unpauseOnActive_(false), lastPause_(0), pausedTime_(0), - secPerFrame_(0), lastUpdate_(0) -{ - util::VersionInfo glfwReq(2,4,2); // requires GLFW 2.4.2 - - util::ensureVersion("GLFW", initGLFW(), glfwReq); -} - -AppCore::~AppCore() -{ - glfwCloseWindow(); //close GLFW window - glfwTerminate(); //shutdown GLFW -} - } diff --git a/src/Application.cpp b/src/Application.cpp index 97d1167..16fdf50 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -5,15 +5,20 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Application.cpp,v 1.5 2005/02/27 07:43:37 cozman Exp $ - +// $Id: Application.cpp,v 1.6 2005/03/15 19:22:07 cozman Exp $ #include "Application.hpp" -#include "exceptions.hpp" #include "physfs.h" +#include "gl/gl.h" -#include +#include + +#include "exceptions.hpp" +#include "Log.hpp" +#include "Kernel.hpp" +#include "AppCore.hpp" +#include "video/VideoCore.hpp" namespace photon { @@ -22,13 +27,37 @@ Application::Application() : photonVer_(0,0,1) // this is the current version { util::VersionInfo physfsReq(1,0,0); // requires PhysFS 1.0.0 + + // create the singletons + new Log; + new Kernel; + new AppCore; + new video::VideoCore; + // StrVec args; + // + // for(int i=0; i < argc; ++i) + // { + // args.push_back(argv[i]); + // } + util::ensureVersion("PhysFS", initPhysFS(arg0_.c_str()), physfsReq); } Application::~Application() { PHYSFS_deinit(); //shutdown PhysFS + + // destroy the singletons + AppCore::destroy(); + video::VideoCore::destroy(); + Kernel::destroy(); + Log::destroy(); +} + +void Application::setInitOptions(const char* arg0) +{ + arg0_ = arg0; } util::VersionInfo Application::initPhysFS(const char* arg0) @@ -40,11 +69,6 @@ util::VersionInfo Application::initPhysFS(const char* arg0) return util::VersionInfo(ver.major, ver.minor, ver.patch); } -void Application::setInitOptions(const char* appPath) -{ - arg0_ = appPath; -} - -std::string Application::arg0_; //static initializer +std::string Application::arg0_; } diff --git a/src/Kernel.cpp b/src/Kernel.cpp new file mode 100644 index 0000000..f796399 --- /dev/null +++ b/src/Kernel.cpp @@ -0,0 +1,155 @@ +//This file is part of Photon (http://photon.sourceforge.net) +//Copyright (C) 2004-2005 James Turk +// +// Author: +// James Turk (jpt2433@rit.edu) +// +// Version: +// $Id: Kernel.cpp,v 1.1 2005/03/15 19:22:07 cozman Exp $ + +#include "Kernel.hpp" + +#include "exceptions.hpp" + +#include "Log.hpp" + +namespace photon +{ + +Kernel::Kernel() +{ +} + +Kernel::~Kernel() +{ +} + +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()) + { + // Log::getInstance().note() << "updating task : " << task->getName(); + 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(); + it = tasks_.erase(it); + } + else + { + ++it; //advance iterator, if not deleting + } + } + } +} + +void Kernel::addTask(TaskPtr task) +{ + std::list::iterator it = tasks_.begin(); + std::list::iterator found = std::find_if(tasks_.begin(), + tasks_.end(), + std::bind2nd(TaskNameEq(), task->getName()) ); + + // if found task (meaning task w/ same name exists) throw exception + if(found != tasks_.end()) + { + throw PreconditionException("Attempted to add duplicate task \"" + + task->getName() + "\"."); + } + + task->onStart(); + + // find the first task in the list with a lower priority + while(it != tasks_.end() && task->getPriority() <= (*it)->getPriority()) + { + ++it; + } + tasks_.insert(it, task); // insert task after iterator +} + +void Kernel::killTask(const std::string& taskName) +{ + std::list::iterator task = std::find_if(tasks_.begin(), + tasks_.end(), + std::bind2nd(TaskNameEq(), taskName) ); + if(task != tasks_.end()) + { + (*task)->kill(); + } + else + { + throw PreconditionException("Attempted to kill nonexistant task \"" + + taskName + "\"."); + } +} + +void Kernel::pauseTask(const std::string& taskName) +{ + std::list::iterator task = std::find_if(tasks_.begin(), + tasks_.end(), + std::bind2nd(TaskNameEq(), taskName) ); + if(task != tasks_.end()) + { + (*task)->onPause(); + } + else + { + throw PreconditionException("Attempted to pause nonexistant task \"" + + taskName + "\"."); + } +} + +void Kernel::unpauseTask(const std::string& taskName) +{ + std::list::iterator task = std::find_if(tasks_.begin(), + tasks_.end(), + std::bind2nd(TaskNameEq(), taskName) ); + if(task != tasks_.end()) + { + (*task)->onUnpause(); + } + else + { + throw PreconditionException("Attempted to unpause nonexistant task \"" + + taskName + "\"."); + } +} + +void Kernel::killAllTasks() +{ + // set all tasks to dead + for(std::list::iterator it = tasks_.begin(); + it != tasks_.end(); + ++it) + { + (*it)->kill(); + } +} + +bool Kernel::TaskNameEq::operator()(const TaskPtr& lhs, + const std::string& rhs) const +{ + return lhs->getName() == rhs; +} + +} diff --git a/src/Task.cpp b/src/Task.cpp new file mode 100644 index 0000000..c0c1664 --- /dev/null +++ b/src/Task.cpp @@ -0,0 +1,62 @@ +//This file is part of Photon (http://photon.sourceforge.net) +//Copyright (C) 2004-2005 James Turk +// +// Author: +// James Turk (jpt2433@rit.edu) +// +// Version: +// $Id: Task.cpp,v 1.1 2005/03/15 19:22:07 cozman Exp $ + +#include "Task.hpp" + +namespace photon +{ + +Task::Task(const std::string& name, PriorityLevel priority) : + name_(name), priority_(priority), alive_(true), paused_(false) +{ +} + +// do nothing (how I wish destructors were virtual by default) +Task::~Task() { } + +// do nothings (non-pure since some tasks may not need special behavior) +void Task::onStart() { } +void Task::onKill() { } + +void Task::onPause() +{ + paused_ = true; +} + +void Task::onUnpause() +{ + paused_ = false; +} + +void Task::kill() +{ + alive_ = false; +} + +std::string Task::getName() const +{ + return name_; +} + +PriorityLevel Task::getPriority() const +{ + return priority_; +} + +bool Task::isAlive() const +{ + return alive_; +} + +bool Task::isPaused() const +{ + return paused_; +} + +} diff --git a/todo.txt b/todo.txt index 0d6a3da..1a76ae4 100644 --- a/todo.txt +++ b/todo.txt @@ -1,10 +1,10 @@ -$Id: todo.txt,v 1.3 2005/02/27 09:05:54 cozman Exp $ +$Id: todo.txt,v 1.4 2005/03/15 19:22:07 cozman Exp $ next: be nova-photon-complete -week: - -be ZEngine-feature complete month: + -be ZEngine-feature complete +quarter: -experimental python bindings -documentation