Jump to content

  • Log In with Google      Sign In   
  • Create Account

Six222

Member Since 26 Mar 2010
Offline Last Active May 19 2014 04:45 AM

Topics I've Started

Events with lambdas

04 January 2014 - 03:12 PM

I've been playing around and trying to get to grips with some of the new C++ features and decided to do a little project using them, I really like lambdas I think they are a really great addition. However I'm having a few issues on coming up with a way to use them in an event system.

 

Ideally I'm trying to design a system where components can register themselves to listen for certain events and when an event is triggered these registered components are notified. My first implementation of it worked well, here's what I had:

class EventManager
{
public:
	void AddListener(std::string name, std::function<void(void)> func)
	{
		events[name].push_back(func);
	}

	void TriggerEvent(std::string name)
	{
		//Error checking here
		for (auto it = events[name].begin(); it != events[name].end(); it++)
		{
			(*it)();
		}
	}
	
private:
	std::map<std::string, std::vector<std::function<void(void)>>> events;

};

int main()
{
	EventManager ev;

	auto func = []() {std::cout << "Hello world!" << std::endl; };
	ev.AddListener("hello", func);
	ev.AddListener("hello", func);

	ev.TriggerEvent("hello");
	system("PAUSE");
	return 0;
}

As I said this works quite well but it's fairly basic.. Now my problem that I'm trying to solve is I'd like to be able to pass around variables. For example on a "WindowResize" event I'd like to be able to pass the new width and height to each function but still be able to maintain them in one class.

 

My second attempt used polymorphism to remove the limit of only being able to store std::function<void(void)>'s which looks like this:

class IEvent
{
public:
	virtual void dummy() = 0;
};

template<class T>
class Event : public IEvent
{
public:
	Event(T t) : func(t) { }

	virtual void dummy()
	{

	}

	T func;
};

class EventManager
{
public:
	void AddListener(std::string name, IEvent* func)
	{
		events[name].push_back(func);
	}

        //This is incorrect.
	template<class... Args>
	void TriggerEvent(std::string name, Args... args)
	{
		//Error checking here

		for (auto it = events[name].begin(); it != events[name].end(); it++)
		{
			//Call function here
		}
	}
	
private:
	std::map<std::string, std::vector<IEvent*>> events;

};

int main()
{
	EventManager ev;

	Event<std::function<void(int, int)>> something([](int x, int y) {std::cout << "X: " << x << "Y:" << y << std::endl; });

	ev.AddListener("hello", &something);
	ev.AddListener("hello", &something);

	ev.TriggerEvent("hello");
	system("PAUSE");
	return 0;
}

But I'm unable to figure out how to actually trigger the event and pass in the correct parameters. When I got to this point I realized that I can't use the variadic template in that way and that also events with different function types could be stored in the same vector which causes horrible run time errors when called... If anyone could point me in the right direction on how to "properly" do this that'd be great smile.png

 

Thanks.


Matrix Multiplication Order

23 October 2013 - 08:51 AM

I have a question about matrix multiplication order in HLSL. For example in C++ I do the following:

XMMATRIX matFinal = matWorld * matView * matProj;

This works correctly and I just upload the final matrix to the GPU and do 

position = mul(matWorld, position)

But when I transfer each matrix individually and try and to the multiplication in the shader I doesn't work... Example:

float4x4 matFinal = mul(mul(matWorld, matView), matProj);
position = mul(matFinal, position);

If anyone could explain or point me in the right direction that would be great smile.png

 

Thanks.


Windows message loop questions

13 October 2013 - 11:16 AM

I have a few questions regarding the Windows procedure and how to properly manage messages.

 

1) What's the difference between handling messages in the example:

while(!exitGame)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);

			switch(msg.message)
			{
			case WM_KEYDOWN:
				keyboard.UpdateKey(msg.wParam, true);
				break;
			}
        }

Compared to handling it in the WindowProc method

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_KEYDOWN:
             keyboard.UpdateKey(msg.wParam, true);
	     break;

    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}

My first guess is that in the WindowProc is that it handles it per-window? 

 

2) For an application that's only dealing with 1 window is it okay to just ignore the WindowProc method? My main problem with this is I would like to update my Keyboard input class from within the function, is the only way to get around this to make it a global?

 

Thanks smile.png


Calling template functions

20 September 2013 - 12:58 PM

I'm having an issue with syntax and I was wondering if anyone could explain why the following code counts as a redefinition and doesn't work as expected?

int z;

template<class T>
void add(T x, T y) {
	z = x + y;
}

add<int>(100, 50); // Error C2365

int main() {

	cout << z << endl;

	return 0;
}

Thanks smile.png


File Read Errors

30 August 2013 - 09:41 AM

I'm having some problems with reading a binary file, I keep getting an unhandled exception in XUtility.h. It reads the first sections of the file fine, but when it goes out of scope it crashes?

 

Here's my code:

void ViewEnts() {
	system("CLS");
	cout << "Entity List" << endl;
	
	ifstream file("entities.entl", ios::in | ios::binary);
	if(file.is_open()) {
		EntityHeader head;
		file.read((char*)&head, sizeof(EntityHeader));
		
		for(int x = 0; x != head.num; x++) {
			EntityStructure ent;
			file.read((char*)&ent, sizeof(EntityStructure));

			cout << "Entity " << x << ") " << ent.className << endl;
			cout << "Renderable: " << ent.isRenderable << endl;
			cout << "Script Location: " << ent.scriptLocation << endl;
			system("PAUSE");
			
		} //CRASHES HERE 
	} else {
		cout << "FATAL ERROR OCCURED: COULD NOT OPEN FILE" << endl;
		system("PAUSE");
	}

	file.close();
	system("PAUSE");
}

Also if I make "EntityStructure ent;" a global variable it will read the whole file fine until I exit the program which it then will crash?


PARTNERS