GPWiki.org
GPWiki.org
It is currently Thu Jun 20, 2013 12:52 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Wed Feb 13, 2013 5:06 pm 
Rookie

Joined: Wed Feb 13, 2013 4:42 pm
Posts: 1
Hello,

First of all, my question is linked to this page : http://content.gpwiki.org/index.php/SDL ... _a_cApp.3F

I've been torturing my mind for the two last hours trying to understand how to deal with this non-type pointer named CallerPtr and, in general, the cStateManager class.

I think i understood the mechanics of it, but i can't create any code line working like i want to.

cStateManager Class Header:
Code:
#ifndef STATE_MAN
#define STATE_MAN

#include "globals.h"
#include "ePurpose.h"

struct sState
{
   sState* Prev;
   void (*Function)(void* CallerPtr, Purpose Purp);
   
   sState()
   {
      Prev = NULL;
      Function = NULL;
   }
   
   ~sState()
   {
      delete Prev;
   }
};


class cStateManager
{
   public:
      cStateManager();
      ~cStateManager();
      bool Push( void (*Function)(void* CallerPtr, Purpose Purp),  void* CallerPtr = NULL);
      bool Pop( void* CallerPtr = NULL);
      bool PopAll( void* CallerPtr = NULL);
      bool Process( void* CallerPtr = NULL);
   
   private:
         sState* m_CurrentState;
};


cStateManager Class :
Code:
/*
 *  cStateManager.cpp
 *  Kore-Engine
 *
 *  Created by Sean Chapel on 11/15/05.
 *  Copyright 2005 Seoushi Games. All rights reserved.
 *
 */

#include "cStateManager.h"

cStateManager::cStateManager()
{
   m_CurrentState = NULL;
}

cStateManager::~cStateManager()
{
   PopAll(NULL);
}

bool cStateManager::Push( void (*Function)(void* CallerPtr, Purpose Purp), void* CallerPtr )
{
   //only add if the function is valid
   if(Function != NULL)
   {
      //create the new state
      sState* newState = new sState();
      newState->Prev = m_CurrentState;
      newState->Function = Function;

      //set the current state to the new one
      m_CurrentState = newState;

      //do init function on state
      newState->Function(CallerPtr, INIT_PURPOSE);

      return true; // indicate success
   }

   return false; // indicate failer
}

bool cStateManager::cStateManager::Pop( void* CallerPtr)
{
   //only pop if there is a state
   if(m_CurrentState != NULL)
   {
      //tell the state we all killing it
      m_CurrentState->Function(CallerPtr, STOP_PURPOSE);

      //create a temporary pointer to the state
      sState* delState = m_CurrentState;

      //make the current state the previous one
      m_CurrentState = m_CurrentState->Prev;

      //set the Prev to NULL so we only delete this state
      delState->Prev = NULL;
      delete delState;

      return true; //indicate success
   }

   return false; //indicate failure
}

bool cStateManager::PopAll( void* CallerPtr )
{
   //check to see if there are states to delete
   if(m_CurrentState != NULL)
   {
      while( m_CurrentState != NULL )
      {
         Pop( CallerPtr );
      }

      return true; //indicate success
   }

   return false; //indicate failer
}

bool cStateManager::Process( void* CallerPtr)
{
   //if there is a state then do it
   if(m_CurrentState != NULL)
   {
      m_CurrentState->Function( CallerPtr, FRAME_PURPOSE );

      return true; //indicate success
   }

   return false; //indicate success
}


So, i create a cStateManager object and then i try to Push a state (such as it has been designed to) it doesn't do anything.

In the wiki, i found "If you haven't figured it out it is just a pointer to what called the function." about CallerPtr.
When i read that, keeping in mind that i call the cStateManager object function from the main, I can't find wath it is.

Here is my code :
Code:
#include "globals.h"
#include "SystemCore.h"

using namespace std;

void mainInitialisation(void* CallerPtr, Purpose Purp);

int main(int argc, char *argv[])
{
    cApp Window(1024, 768, 0, "Electron", false);
    cStateManager StateMan;
    StateMan.Push(mainInitialisation(Window, INIT_PURPOSE), NULL);
    StateMan.Process(NULL);
    StateMan.Pop();
    // Cleanup

    return 0;
}

void mainInitialisation(void* CallerPtr, Purpose Purp) {
    switch(Purp)
   {
      case STOP_PURPOSE:
         cout << "Core initialisation ended with success." << endl;
         break;
      case INIT_PURPOSE:
         cout << "Core initialisation begin." << endl;
         break;
      case FRAME_PURPOSE:
         cout << "Core initialisation processing." << endl;
         break;
      default:
         cout << "Strange event in the core." << endl;
         break;
   }
}


If anyone could help, it would be great. This is the first application of the game designing tutorial, 'getting a little bit frustrated :\

And 'ya, I hope my english is good enough, i don't use it often :D


Top
 Profile  
 
PostPosted: Wed Feb 13, 2013 11:29 pm 
Octogenarian
User avatar

Joined: Sun Aug 05, 2012 9:32 pm
Posts: 98
The way i understand is that you have to call

Code:
StateMan.Push(mainInitialisation, Window);


- Function name is without brackets, so its not trying to execute it without parameters, but rather point at the location of the function

because the function pointer only points to a function with the specified kind of parameters but no the parameters it self. and after closely looking at the Push function, you can see that the CallerPtr pointer is used as a CallerPtr in the Function you pointed at + the value of INIT_PURPOSE by default. So when you call Push, the first parameter is a Pointer to a function without parameters, and the second is the parameter you want to use in the function. and INIT_PURPOSE is then used automatically.
This should work if "Window" is a valid type of CallerPtr, but you should know if it is or not, I have no idea :D


Edit 1:
Also could you please state what exactly do you expect to happen and it's not happening? Cause I assumed you have problem using the Function Pointing mechanism, but I might be mistaken, so sorry if I didn't help at all :D

_________________
Did you ever wonder, how time works?


Top
 Profile  
 
PostPosted: Fri Feb 15, 2013 3:21 am 
Lord of Cheesecakes

Joined: Sun Jun 24, 2012 12:49 am
Posts: 358
Correction:

Code:
PieMan.Push(mainInitialisation, Window);

_________________
What most people don't understand is what I like to explain as a thing that I understand.


Top
 Profile  
 
PostPosted: Mon Feb 18, 2013 8:26 pm 
Dexterous Droid
User avatar

Joined: Wed Aug 18, 2004 7:40 pm
Posts: 3746
Location: South Africa
Hmmm, this code is dealing with some fairly advanced concepts and in my opinion it's not doing an amazing job. I say this because, if you're starting out, I would suggest following a different set of tutorials that will get pixels drawn to the screen in a more simple way. It's ok to write spaghetti code in the beginning - it's part of learning the value of using classes and other higher level coding concepts.

I think Hazarth is right about the usage, pass a function pointer as the first parameter. It looks like you can just pass NULL for the last parameter if you don't need to use the CallerPtr.

But really, this solution is not the cleanest. All these naked function pointers give me the segfault shivers. A much cleaner implementation would use a stack of an abstract class AScreen or somesuch. Then one could implement AScreens to do the various things and push and pop them to your hearts content. If you're starting out: do yourself a favour and start blitting pixels ASAP.

_________________
Whatever the mind can conceive and believe, it can achieve


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group