Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualKhatharr

Posted 27 November 2012 - 10:35 PM

Sometimes a light-weight ID token is a reasonable solution, but it kinda just sounds like you're afraid of the RTTI boogeyman. Perhaps if you explain more about what this ID is used for we can suggest a better solution to your problem.


Thank you.

Here's the current imp. I haven't yet applied Alvaro's ident as vfunc idea.

[source lang="cpp"]#pragma once//"vcl_Scene.h"#include "ns_scenemgr.h"//When adding a new 'Scene' inheritor be sure//to add its enumeration value to SceneID,//add a case in the SceneMgr::update() switch//and include the Scene's header in ns_SceneMgr.cpp.//These locations are marked and can be found by//searching for the *~* comment token.//Also remember to set the 'ident' base member in//the class' constructor.class Scene {public: virtual ~Scene() {}; virtual int initialize() = 0; virtual int update() = 0; SceneID ident;};[/source]

[source lang="cpp"]#pragma once//"ns_SceneMgr.h"enum SceneID : int { NO_SCENE = 0, // *~*Begin scene ident enumerations SCENE_TEST, // End scene ident enumerations};namespace SceneMgr { extern SceneID sceneID; int initialize(SceneID startingScene); int update();};[/source]
[source lang="cpp"]//"ns_SceneMgr.cpp"#include "ns_scenemgr.h"#include "vcl_Scene.h"#include <memory>// *~*Begin scene header inclusions#include "Scene_Test.h"// End scene header inclusionsusing namespace std;//This public variable can be changed to cause the//SceneMgr to switch to a different scene.SceneID SceneMgr::sceneID;static auto_ptr<Scene> g_sceneObject(NULL);//This private class is used to create a 'dummy'//object for bootstrapping the scene manager.class Scene_Null : public Scene {public: Scene_Null() {ident = (SceneID)-1;} virtual ~Scene_Null() {} virtual int initialize() {return 0;} virtual int update() { MessageBoxA(0, "Attempted to update the null Scene.", 0, 0); return -1; }};int SceneMgr::initialize(SceneID startingScene) { sceneID = startingScene; try{g_sceneObject.reset(new Scene_Null);} catch(bad_alloc) {return -1;} return 0;}int SceneMgr::update() { if(sceneID != g_sceneObject->ident) { try { switch(sceneID) { // *~*Begin Scene construction cases case SCENE_TEST: g_sceneObject.reset(new Scene_Test); break; // End Scene construction cases case NO_SCENE: PostQuitMessage(0); return 0; default: MessageBoxA(0, "Invalid SceneID.", 0, 0); return -1; }; } catch(bad_alloc) { MessageBoxA(0, "Failed allocation for new Scene object.", 0, 0); return -1; } if(g_sceneObject->initialize()) {return -1;} } return g_sceneObject->update();}[/source]

To apply C++ RTTI here would require that all Scene derivatives include one another's headers in order to signal the type of the new derivative to switch to. The overwhelming problem with C++ RTTI is that while it's certainly aware of the type at runtime it's not aware of the types available at code-writing time. If the RTTI functionality provided a token that could be mapped to an enum value or something then that would be fine. (A predictable value that I could actually work with instead of an object that I have no use for.)

#1Khatharr

Posted 27 November 2012 - 10:31 PM

Sometimes a light-weight ID token is a reasonable solution, but it kinda just sounds like you're afraid of the RTTI boogeyman. Perhaps if you explain more about what this ID is used for we can suggest a better solution to your problem.


Thank you.

Here's the current imp. I haven't yet applied Alvaro's ident as vfunc idea.

[source lang="cpp"]#pragma once//"vcl_Scene.h"#include "ns_scenemgr.h"//When adding a new 'Scene' inheritor be sure//to add its enumeration value to SceneID,//add a case in the SceneMgr::update() switch//and include the Scene's header in ns_SceneMgr.cpp.//These locations are marked and can be found by//searching for the *~* comment token.//Also remember to set the 'ident' base member in//the class' constructor.class Scene {public: virtual ~Scene() {}; virtual int initialize() = 0; virtual int update() = 0; SceneID ident;};[/source]

[source lang="cpp"]#pragma once//"ns_SceneMgr.h"enum SceneID : int { NO_SCENE = 0, // *~*Begin scene ident enumerations SCENE_TEST, // End scene ident enumerations};namespace SceneMgr { extern SceneID sceneID; int initialize(SceneID startingScene); int update();};[/source]
[source lang="cpp"]//"ns_SceneMgr.cpp"#include "ns_scenemgr.h"#include "vcl_Scene.h"#include <memory>// *~*Begin scene header inclusions#include "Scene_Test.h"// End scene header inclusionsusing namespace std;//This public variable can be changed to cause the//SceneMgr to switch to a different scene.SceneID SceneMgr::sceneID;static auto_ptr<Scene> g_sceneObject(NULL);//This private class is used to create a 'dummy'//object for bootstrapping the scene manager.class Scene_Null : public Scene {public: Scene_Null() {ident = (SceneID)-1;} virtual ~Scene_Null() {} virtual int initialize() {return 0;} virtual int update() { MessageBoxA(0, "Attempted to update the null Scene.", 0, 0); return -1; }};int SceneMgr::initialize(SceneID startingScene) { sceneID = startingScene; try{g_sceneObject.reset(new Scene_Null);} catch(bad_alloc) {return -1;} return 0;}int SceneMgr::update() { if(sceneID != g_sceneObject->ident) { try { switch(sceneID) { // *~*Begin Scene construction cases case SCENE_TEST: g_sceneObject.reset(new Scene_Test); break; // End Scene construction cases case NO_SCENE: PostQuitMessage(0); return 0; default: MessageBoxA(0, "Invalid SceneID.", 0, 0); return -1; }; } catch(bad_alloc) { MessageBoxA(0, "Failed allocation for new Scene object.", 0, 0); return -1; } if(g_sceneObject->initialize()) {return -1;} } return g_sceneObject->update();}[/source]

PARTNERS