EOSERV Forum > Game Development > How to create a class that can hold an unspecified class
Page: << 1 >>
How to create a class that can hold an unspecified class
Author Message
Post #201028 How to create a class that can hold an unspecified class

Its kind of hard to explain but what I am trying to do is create an empty class that can be filled with an unspecified class. Maybe thats a shitty way to go about so what I am actualy trying to do is create a windows event engine so far it looks like this

struct Event
{
    unsigned int event;
    EventType *type;
    Event(unsigned int msg_,EventType *type_) : event(msg_),type(type_) {}
};

Now this is the class I want to be able to fill with different EventTypes

struct EventType
{
    EventType();
};
extern std::vector<WML_Event*> events;

I thought I could use a template but I'm not to good with them maybe its possible maybe not
template <class T,class T1> void mf(T* t,T1* t1) {t = t1;}

I am trying to initiate like this

WML::WindowEvent *e = new WML::WindowEvent();
EventType *ty = 0;

mf(ty,e);

WML::events.push_back(new WML_Event(WM_LBUTTONDOWN,ty));//Window Event

I get these warnings and errors

C:\Users\insom_000\Desktop\programming\WML\src\wml.hpp: In instantiation of 'void WML::mf(T*, T1*) [with T = WML::EventType; T1 = WML::WindowEvent]':
C:\Users\insom_000\Desktop\programming\WML\src\window.cpp:18:20:   required from here
C:\Users\insom_000\Desktop\programming\WML\src\wml.hpp:222:53: error: cannot convert 'WML::WindowEvent*' to 'WML::EventType*' in assignment

the event types that need to be handled
struct SystemEvent
{
    enum event
    {
        System = 0
    };
};
struct WindowEvent
{
    enum event
    {
        Window = 0
    };
};
struct KeyBoardEvent
{
    enum event
    {
        KeyDown = 0,
        KeyUp = 1
    };
};
struct MouseEvent
{
    enum event
    {
        MouseMotion = 0,
        MouseButtonDown = 1,
        MouseButtonUp = 2,
        MouseWheel = 3
    };
};
struct JoyStickEvent
{
    enum even
    {
        JoyStick = 0
    };
};
struct ControllEvent
{
    enum event
    {
        Controll = 0
    };
};
struct TouchEvent
{
    enum event
    {
        Touch = 0
    };
};
struct AppEvent
{
    enum event
    {
        App = 0
    };
};

I'm prolly over thinking this any help or input would be appreciated thankyou!


7 years, 30 weeks ago
Post #201030 Re: How to create a class that can hold an unspecified class

http://pastebin.com/PtnfcUBp ... This is how you do what you rather want with templates.

Honestly i don't think this gonna work.
If you put *type as a system event , it won't compile if you try to access any member of other structs

Even if you conditioned inside the struct event for which type is it, it's not gonna work because the compiler gonna try every condition even if not right.

You got to change your orientation plan unless u are doing something else.


Edit : honestly i don't know what are you triyng to do after "I am trying to initiate like this"

Edit 2 : try this to handle events http://pastebin.com/52aWKNPd

7 years, 30 weeks ago
Post #201035 Re: How to create a class that can hold an unspecified class

I would almost say you need something like Allegro for what it appears you are doing. Basically any input runs thru as an Allegro Event which you can from there set these events to do the functions you require. The biggest difference is everything is already declared in Allegro as long as you include the necessary libraries and you don't have to spend all kinds of extra time creating all of the extra things you need to do simple tasks.

7 years, 30 weeks ago
Post #201036 Re: How to create a class that can hold an unspecified class
Apollo posted: (29th Sep 2016, 01:12 am)

I would almost say you need something like Allegro for what it appears you are doing. Basically any input runs thru as an Allegro Event which you can from there set these events to do the functions you require. The biggest difference is everything is already declared in Allegro as long as you include the necessary libraries and you don't have to spend all kinds of extra time creating all of the extra things you need to do simple tasks.

I am creating a win 32 library similar to Allegro - SDL - SFML. So far the project is comming along pretty good what I am attempting to do here is capture messages in the window procedure
static LRESULT Procedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case:
        case:
        case:
       events.push_back(msg,event_type);
    }
}

So you can process the events your self at some point
//struct to fill in the next loop
WML_Event event;
//loop to check events vector
WML_CheckEvents(event)
{
    if(event->type == WML_WindowEvent)
    {

    }
}

Any suggestions? I looked over some doc's I guess SDL uses a union to do this.. I'm going to look over Allegro's docs here in a bit thanks for reminding me about about that lib :D!

@ freezingsoul thankyou that is very close to what i need to do I'm going to toy arround with it a bit more and see what happens!!

Edit: looking over my files I migh be able to create some macros
#define WML_WINDOWEVENT 0
#define WML_SYSTEMEVENT 1
#define WML_KEYBOARDEVENT 2
#define WML_MOUSEEVENT 3

and change my event struct to

struct Event
{
    unsigned int event;
    unsigned int type;
    Event(unsigned int msg_,unsigned int type_) : event(msg_),type(type_) {}
};

then I can assign a number value to the type

static LRESULT Procedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
       case WM_LBUTTONDOWN:
       case: WM_RBUTTONDOWN:
       events.push_back(msg,WML_MOUSEEVENT);
       case: WM_KEYDOWN:
       case: WM_KEYUP:
       events.push_back(msg,WML_KEYBOARDEVENT);
    }
}

then this loop would make since

WML_CheckEvents(event)
{
    if(event.type == WML_WINDOWEVENT)
    {
        //check window events
    }
    else if(event.type == WML_MOUSEEVENT)
    {
        //check mouse events
       
    }

    or
    switch(event.type)
    {
        case WML_MOUSEEVENT:
        {
       
        }
   
    }
7 years, 30 weeks ago
Post #201042 Re: How to create a class that can hold an unspecified class

I am going to go out on a limb here and say you will be much better off using an existing library than trying to create one from scratch. Allegro is pretty good for essentially any 2d graphic programming you will do. It has a fairly large community, well documented, and hundreds of YouTube tutorials exist. You could use a different library as there are certainly arguments to be made for this, but I have found it will pretty much cover your needs. Give it a look, watch a tutorial or two so you can see it in action, then make that call. Either way, you don't need to be trying to recreate the wheel, it already exists.

7 years, 30 weeks ago
Post #201043 Re: How to create a class that can hold an unspecified class

If you are going to use allegro don't use allegro 4 , it's discontinued and lack many features which going to leave you with a dead end eventually then you will have to convert your whole project to 5 or quit.

7 years, 30 weeks ago
Post #201046 Re: How to create a class that can hold an unspecified class
Apollo posted: (30th Sep 2016, 05:48 pm)

I am going to go out on a limb here and say you will be much better off using an existing library than trying to create one from scratch. Allegro is pretty good for essentially any 2d graphic programming you will do. It has a fairly large community, well documented, and hundreds of YouTube tutorials exist. You could use a different library as there are certainly arguments to be made for this, but I have found it will pretty much cover your needs. Give it a look, watch a tutorial or two so you can see it in action, then make that call. Either way, you don't need to be trying to recreate the wheel, it already exists.


Thanks! Where I am at with  C++ programming these days is I don't want to be dependent on a library for my games I want to create my own. I'm not sure why I do this to my self and yes its a pain in the ass and even if I fail my knowlege for the win api will be pretty extensive so it will be worth it.

As far as selecting a library I've used Allegro - SFML - SDL. I still use SDL 1.2 for most of my gameing projects and mess arround with Allegro when adding stuff to the EO Map editor agh SFML is allright I just didnt like alot of the code structures and limitations... same with SDL it is very limited "SimpleDirectLayer" simple says it.

@Freezingsoul Yeah Allegro 4 is pretty decent I dont see why they restructured Allegro 5 so much. In my opinion they should have fixed bugs from 4 and released the same structures for 5.

I think after this project is done or I put a decent chunk of time into it I am going to jump into winsock ) : or possibly add in networking to this library time will tell.Networking is another beast I have been putting off for ever.

I wasnt able to answer the question but I resolved it like this

the event struct

class Event
{
    public:
    unsigned int msg;
    unsigned int type;

    WML_SystemEvent *sys_event;
    WML_WindowEvent *win_event;
    WML_KeyBoardEvent *key_event;
    WML_MouseEvent *mouse_event;
    WML_JoyStickEvent *joy_event;
    WML_ControllEvent *ctrl_event;
    WML_TouchEvent *touch_event;
    WML_AppEvent *app_event;

    Event(unsigned int msg_,unsigned int type_) : msg(msg_),type(type_)
    {
        sys_event = (type != 0 ? 0 : new WML_SystemEvent());
        win_event = (type != 1 ? 0 : new WML_WindowEvent());
        key_event = (type != 2 ? 0 : new WML_KeyBoardEvent());
        mouse_event = (type != 3 ? 0 : new WML_MouseEvent());
        joy_event = (type != 4 ? 0 : new WML_JoyStickEvent());
        ctrl_event = (type != 5 ? 0 : new WML_ControllEvent());
        touch_event = (type != 6 ? 0 : new WML_TouchEvent());
    }
};

the event loop

WML_Event *event = 0;
 while((event = WML_CheckEvents()) != 0)
 {
    WML_Console::Out(" %i, %i",event->msg,event->type);
    WML_Console::Out("hi" + WML_Util::to_string((signed)WML::events.size()));

     if(event->type == WML_MOUSEEVENT)
     {
           WML::Console::Out("x %i, y %i",event->mouse_event->x,event->mouse_event->y);
     }
}

WML_Event *CheckEvents()
{
    WML_Event *event = 0;

    if(!events.empty())
    {
        event = events[events.size()-1];
        HandleEvent(event);
        events.erase(events.end()-1);
    }

    return event;
}

handles events

void HandleEvent(WML_Event *event)
{
    unsigned int type = event->type;

    switch(type)
    {
        case 0:
        case 1:
        break;

        default: break;
    }
}

It would still be nice to know if there is a way to create a class or struct that can hold any unspecified class?
7 years, 30 weeks ago
Post #201056 Re: How to create a class that can hold an unspecified class
insomniac posted: (30th Sep 2016, 07:27 pm)

Apollo posted: (30th Sep 2016, 05:48 pm)

I am going to go out on a limb here and say you will be much better off using an existing library than trying to create one from scratch. Allegro is pretty good for essentially any 2d graphic programming you will do. It has a fairly large community, well documented, and hundreds of YouTube tutorials exist. You could use a different library as there are certainly arguments to be made for this, but I have found it will pretty much cover your needs. Give it a look, watch a tutorial or two so you can see it in action, then make that call. Either way, you don't need to be trying to recreate the wheel, it already exists.


Thanks! Where I am at with  C++ programming these days is I don't want to be dependent on a library for my games I want to create my own. I'm not sure why I do this to my self and yes its a pain in the ass and even if I fail my knowlege for the win api will be pretty extensive so it will be worth it.

As far as selecting a library I've used Allegro - SFML - SDL. I still use SDL 1.2 for most of my gameing projects and mess arround with Allegro when adding stuff to the EO Map editor agh SFML is allright I just didnt like alot of the code structures and limitations... same with SDL it is very limited "SimpleDirectLayer" simple says it.

@Freezingsoul Yeah Allegro 4 is pretty decent I dont see why they restructured Allegro 5 so much. In my opinion they should have fixed bugs from 4 and released the same structures for 5.

I think after this project is done or I put a decent chunk of time into it I am going to jump into winsock ) : or possibly add in networking to this library time will tell.Networking is another beast I have been putting off for ever.

I wasnt able to answer the question but I resolved it like this

the event struct

class Event
{
    public:
    unsigned int msg;
    unsigned int type;

    WML_SystemEvent *sys_event;
    WML_WindowEvent *win_event;
    WML_KeyBoardEvent *key_event;
    WML_MouseEvent *mouse_event;
    WML_JoyStickEvent *joy_event;
    WML_ControllEvent *ctrl_event;
    WML_TouchEvent *touch_event;
    WML_AppEvent *app_event;

    Event(unsigned int msg_,unsigned int type_) : msg(msg_),type(type_)
    {
        sys_event = (type != 0 ? 0 : new WML_SystemEvent());
        win_event = (type != 1 ? 0 : new WML_WindowEvent());
        key_event = (type != 2 ? 0 : new WML_KeyBoardEvent());
        mouse_event = (type != 3 ? 0 : new WML_MouseEvent());
        joy_event = (type != 4 ? 0 : new WML_JoyStickEvent());
        ctrl_event = (type != 5 ? 0 : new WML_ControllEvent());
        touch_event = (type != 6 ? 0 : new WML_TouchEvent());
    }
};

the event loop

WML_Event *event = 0;
 while((event = WML_CheckEvents()) != 0)
 {
    WML_Console::Out(" %i, %i",event->msg,event->type);
    WML_Console::Out("hi" + WML_Util::to_string((signed)WML::events.size()));

     if(event->type == WML_MOUSEEVENT)
     {
           WML::Console::Out("x %i, y %i",event->mouse_event->x,event->mouse_event->y);
     }
}

WML_Event *CheckEvents()
{
    WML_Event *event = 0;

    if(!events.empty())
    {
        event = events[events.size()-1];
        HandleEvent(event);
        events.erase(events.end()-1);
    }

    return event;
}

handles events

void HandleEvent(WML_Event *event)
{
    unsigned int type = event->type;

    switch(type)
    {
        case 0:
        case 1:
        break;

        default: break;
    }
}

It would still be nice to know if there is a way to create a class or struct that can hold any unspecified class?

I'm still not sure I understand what you're trying to do, but it looks like you're thinking of templates. My C++ is pretty rusty but I'll try some samples.

template<class T>
class Event
{
public:
  int msg, type;
  T * EventObj

  Event(int _msg, int _type, T * eventObj) : msg(_msg), type(_type)
  { EventObj = eventObj }
}

However, I think a better implementation would have an abstract base class with a Handle() method that is implemented by derived class objects.

class EventBase
{
public:
  virtual void Handle() = 0;
}
class MouseEvent : public EventBase
{
public:
  MouseEvent(/* parameters for click position, button, etc. */) { }
  virtual void Handle() override
  {
    //handle mouse event here
  }
}

Then you can have some sort of event queue elsewhere:

std::queue<std::unique_ptr<EventBase>> eventQueue;
//get mouse event from device and put it in the queue...
eventQueue.push_back(std::unique_ptr(new MouseEvent(/* parameters from device */)));


Then in your processing loop, you can just pop off the event on the front of the queue and call handle:
auto nextEvent = eventQueue.front();
nextEvent.Pop();
nextEvent->Handle();

Obviously a pretty simple example but it should be enough to demonstrate the general idea. You'll probably need to adjust the sample to provide something to the Handle() method so that it can actually do a thing. I highly recommend against using global variables or singletons since they make maintaining a project a nightmare and are extremely bug-prone.

Generally, if you want a type to be able to "hold an unspecified class", it should truly be generic, like with the STL collections (list, vector, queue, etc). Since you obviously wouldn't want every single type to be held within an event, templates should not be used here (since it isn't truly a generic object).

A couple other things about your code: 1, you really shouldn't be using raw pointers, as they're super prone to memory leaks. Assuming you pasted your code above directly from your IDE you're forgetting delete operations on each of the pointers you allocate. Smart points solve this problem by keeping a reference count and automatically deleting themselves when they no longer have any references. 2, you should use nullptr instead of NULL or 0. Not as big a deal as smart pointers, but C++11 has been out for a while now...

---
class EOSERV {
Programmer | Oldbie
Open source EO Client: https://github.com/ethanmoffat/EndlessClient
};
7 years, 30 weeks ago
Post #201057 Re: How to create a class that can hold an unspecified class
ethanmoffat posted: (1st Oct 2016, 05:59 am)

insomniac posted: (30th Sep 2016, 07:27 pm)

Apollo posted: (30th Sep 2016, 05:48 pm)

I am going to go out on a limb here and say you will be much better off using an existing library than trying to create one from scratch. Allegro is pretty good for essentially any 2d graphic programming you will do. It has a fairly large community, well documented, and hundreds of YouTube tutorials exist. You could use a different library as there are certainly arguments to be made for this, but I have found it will pretty much cover your needs. Give it a look, watch a tutorial or two so you can see it in action, then make that call. Either way, you don't need to be trying to recreate the wheel, it already exists.


Thanks! Where I am at with  C++ programming these days is I don't want to be dependent on a library for my games I want to create my own. I'm not sure why I do this to my self and yes its a pain in the ass and even if I fail my knowlege for the win api will be pretty extensive so it will be worth it.

As far as selecting a library I've used Allegro - SFML - SDL. I still use SDL 1.2 for most of my gameing projects and mess arround with Allegro when adding stuff to the EO Map editor agh SFML is allright I just didnt like alot of the code structures and limitations... same with SDL it is very limited "SimpleDirectLayer" simple says it.

@Freezingsoul Yeah Allegro 4 is pretty decent I dont see why they restructured Allegro 5 so much. In my opinion they should have fixed bugs from 4 and released the same structures for 5.

I think after this project is done or I put a decent chunk of time into it I am going to jump into winsock ) : or possibly add in networking to this library time will tell.Networking is another beast I have been putting off for ever.

I wasnt able to answer the question but I resolved it like this

the event struct

class Event
{
    public:
    unsigned int msg;
    unsigned int type;

    WML_SystemEvent *sys_event;
    WML_WindowEvent *win_event;
    WML_KeyBoardEvent *key_event;
    WML_MouseEvent *mouse_event;
    WML_JoyStickEvent *joy_event;
    WML_ControllEvent *ctrl_event;
    WML_TouchEvent *touch_event;
    WML_AppEvent *app_event;

    Event(unsigned int msg_,unsigned int type_) : msg(msg_),type(type_)
    {
        sys_event = (type != 0 ? 0 : new WML_SystemEvent());
        win_event = (type != 1 ? 0 : new WML_WindowEvent());
        key_event = (type != 2 ? 0 : new WML_KeyBoardEvent());
        mouse_event = (type != 3 ? 0 : new WML_MouseEvent());
        joy_event = (type != 4 ? 0 : new WML_JoyStickEvent());
        ctrl_event = (type != 5 ? 0 : new WML_ControllEvent());
        touch_event = (type != 6 ? 0 : new WML_TouchEvent());
    }
};

the event loop

WML_Event *event = 0;
 while((event = WML_CheckEvents()) != 0)
 {
    WML_Console::Out(" %i, %i",event->msg,event->type);
    WML_Console::Out("hi" + WML_Util::to_string((signed)WML::events.size()));

     if(event->type == WML_MOUSEEVENT)
     {
           WML::Console::Out("x %i, y %i",event->mouse_event->x,event->mouse_event->y);
     }
}

WML_Event *CheckEvents()
{
    WML_Event *event = 0;

    if(!events.empty())
    {
        event = events[events.size()-1];
        HandleEvent(event);
        events.erase(events.end()-1);
    }

    return event;
}

handles events

void HandleEvent(WML_Event *event)
{
    unsigned int type = event->type;

    switch(type)
    {
        case 0:
        case 1:
        break;

        default: break;
    }
}

It would still be nice to know if there is a way to create a class or struct that can hold any unspecified class?

I'm still not sure I understand what you're trying to do, but it looks like you're thinking of templates. My C++ is pretty rusty but I'll try some samples.

template<class T>
class Event
{
public:
  int msg, type;
  T * EventObj

  Event(int _msg, int _type, T * eventObj) : msg(_msg), type(_type)
  { EventObj = eventObj }
}

However, I think a better implementation would have an abstract base class with a Handle() method that is implemented by derived class objects.

class EventBase
{
public:
  virtual void Handle() = 0;
}
class MouseEvent : public EventBase
{
public:
  MouseEvent(/* parameters for click position, button, etc. */) { }
  virtual void Handle() override
  {
    //handle mouse event here
  }
}

Then you can have some sort of event queue elsewhere:

std::queue<std::unique_ptr<EventBase>> eventQueue;
//get mouse event from device and put it in the queue...
eventQueue.push_back(std::unique_ptr(new MouseEvent(/* parameters from device */)));


Then in your processing loop, you can just pop off the event on the front of the queue and call handle:
auto nextEvent = eventQueue.front();
nextEvent.Pop();
nextEvent->Handle();

Obviously a pretty simple example but it should be enough to demonstrate the general idea. You'll probably need to adjust the sample to provide something to the Handle() method so that it can actually do a thing. I highly recommend against using global variables or singletons since they make maintaining a project a nightmare and are extremely bug-prone.

Generally, if you want a type to be able to "hold an unspecified class", it should truly be generic, like with the STL collections (list, vector, queue, etc). Since you obviously wouldn't want every single type to be held within an event, templates should not be used here (since it isn't truly a generic object).

A couple other things about your code: 1, you really shouldn't be using raw pointers, as they're super prone to memory leaks. Assuming you pasted your code above directly from your IDE you're forgetting delete operations on each of the pointers you allocate. Smart points solve this problem by keeping a reference count and automatically deleting themselves when they no longer have any references. 2, you should use nullptr instead of NULL or 0. Not as big a deal as smart pointers, but C++11 has been out for a while now...



I thought it would be cool to be able to call Event and fill it with unspecified paramters maybe just declare the struct Event; and fill it with whatever eventype struct that just occurred.

 I'm useing a vector to store events but after quite a few hours of working with the event struct I realize its only processing 1 event per repitition so I could just use std::unique_ptr instead of a container holding raw pointers.All the raw pointers in the event class will be inited to either to a new event type or 0 "null_ptr" when the struct is created so its pretty controlled.Maybe at some point the events container will be usefull but for now its only processing key presses and tracking mouse movement. Thankyou for your take on this and pointing out the fact I havnt been releasing the memory from the events and for poining out class inheritance thats what I was trying to do all retarted lol and answers my original question.. I completely spaced it..

Solved-

7 years, 29 weeks ago
Post #201086 Re: How to create a class that can hold an unspecified class

http://en.cppreference.com/w/cpp/utility/any exists as the C++ alternative to dynamically allocated objects pointed to by void* in C, which are typically used so a caller can give you "anything" to get given back later.

Usually you want to avoid both like the plague. For an event-/callback-based library in C++, lambda captures allow the caller to capture whatever they need which is far less error-prone (no chance to convert to the wrong object) and more useful (multiple objects can be captured in a lambda) than using std::any.

Example:

#include <functional>
#include <iostream>
#include <memory>

std::function<void(int)> registered_callback;

void register_callback(std::function<void(int)> callback)
{
registered_callback = callback;
}

void do_stuff()
{
registered_callback(1);
registered_callback(2);
registered_callback(3);
}

int main()
{
std::shared_ptr<int> my_data(new int(123));

register_callback([my_data](int event_number)
{
std::cout << "Event number " << event_number << " and my data is " << ((*my_data)++) << std::endl;
});

do_stuff();

std::cout << "Final value of my_data is " << *my_data << std::endl;
}

Should output:
Event number 1 and my data is 123
Event number 2 and my data is 124
Event number 3 and my data is 125
Final value of my_data is 126
7 years, 29 weeks ago
Post #201096 Re: How to create a class that can hold an unspecified class
Sausage posted: (6th Oct 2016, 02:12 pm)

http://en.cppreference.com/w/cpp/utility/any exists as the C++ alternative to dynamically allocated objects pointed to by void* in C, which are typically used so a caller can give you "anything" to get given back later.

Usually you want to avoid both like the plague. For an event-/callback-based library in C++, lambda captures allow the caller to capture whatever they need which is far less error-prone (no chance to convert to the wrong object) and more useful (multiple objects can be captured in a lambda) than using std::any.

Example:

#include <functional>
#include <iostream>
#include <memory>

std::function<void(int)> registered_callback;

void register_callback(std::function<void(int)> callback)
{
registered_callback = callback;
}

void do_stuff()
{
registered_callback(1);
registered_callback(2);
registered_callback(3);
}

int main()
{
std::shared_ptr<int> my_data(new int(123));

register_callback([my_data](int event_number)
{
std::cout << "Event number " << event_number << " and my data is " << ((*my_data)++) << std::endl;
});

do_stuff();

std::cout << "Final value of my_data is " << *my_data << std::endl;
}

Should output:
Event number 1 and my data is 123
Event number 2 and my data is 124
Event number 3 and my data is 125
Final value of my_data is 126

Thank you I  was hoping you would reply.. "any" thats awesome and yes seems pretty dangerous. The callback method seems very legit I'm going to mess with it a bit and see if I can replace any current functions.
7 years, 28 weeks ago
Page: << 1 >>

EOSERV Forum > Game Development > How to create a class that can hold an unspecified class