Jump to content

  • Log In with Google      Sign In   
  • Create Account


Moonkis

Member Since 10 Apr 2011
Offline Last Active Feb 20 2014 02:35 AM
-----

Topics I've Started

Problem defining a new 'new' macro

31 January 2014 - 04:31 AM

I'm trying to implement a crude memory tracking, following this source:

http://www.chrisculy.com/writings/Programmatic_Memory_Leak_Detection_in_C++.pdf

 

However, most things works fine (apart from delete crashing) except that I can't macro the new keyword. I'v been searching far and wide for any answers on how to do it. But I haven't found anything.

I'm using Visual Studio 2012, here is the source:

Rememrall.h
 

#ifdef _DEBUG
void* operator new(size_t size, const char* file, unsigned int line);
void operator delete(void* memory);

#undef new
#define new new(__FILE__, __LINE__)

#endif

void reportMemoryStatus();

Remembrall.cpp
 

#ifdef _DEBUG
#include "Remembrall.h"
#include "Logger.h"
#include <cstring>
#include <cstdlib>
#include <list>

#include <iostream>


static std::string stripped_path( const char* str ) 
{
	std::string path = str;
	return path.substr(path.find_last_of('\\')+1, path.size()-1);
}

struct MemoryRecord
{
	const char* file;
	unsigned int line;
	unsigned int size;
	unsigned long address;
};

static std::list< MemoryRecord > memoryArchive;


void* operator new(size_t size, const char* file, unsigned int line)
{
	void* memory = malloc(size);

	MemoryRecord record;
	record.file = file;
	record.line = line;
	record.size = size;
	record.address = (unsigned long) memory;

	memoryArchive.push_back(record);

	return memory;
}

void operator delete(void* memory)
{
	/*
	auto it = memoryArchive.begin();
	auto end = memoryArchive.end();


	while(it != end)
	{
	if( (*it).address == ( unsigned long ) memory )
	{
	memoryArchive.erase(it);
	break;
	}
	it++;
	}
	*/

	free(memory);
}




void reportMemoryStatus()
{
	auto it = memoryArchive.begin();
	std::string info = "";
	while( !memoryArchive.empty() )
	{
		info = "[MEMLEAK]\tFile: ";
		info += stripped_path((*it).file);
		info += "\tLine: ";
		info += std::to_string((*it).line);
		info += "\tAddress: ";
		info += std::to_string((*it).address);
		info += "\tSize: ";
		info += std::to_string((*it).size);
		std::cout << info << std::endl;
		db::logger.write( info, db::outs::error, true );
		memoryArchive.erase(it);
		it = memoryArchive.begin();
	}
	db::logger.panic();
}
#else
void reportMemoryStatus() {}
#endif

EDIT

I found a solution, making a new header, include the Remembrall-header then AFTER that add the new macro. It feels kind of hackish, is this really the only way?


[C++/SFML] ECS - How to deal with the entities?

02 October 2013 - 01:45 AM

I'm currently trying to wrap my head around Entity, Component and Systems and I'm having a few problems with my design so far.
Basically Entities is a class that contains an index-value and an unique id associated with said index. I feel the way I create, store, recycle and iterate through the entities in the manger is quite unefficient and the code is filled with cluttery. I'm currently using a number of vectors that is somewhat hard to keep synced ( index-wise ) with each other.

 

#ifndef ENTITYMANAGER_HPP
#define ENTITYMANAGER_HPP

#include <vector>
#include "Entity.hpp"
#include "Component.hpp"
#include "System.hpp"

class EntityManager {
private:
	unsigned int indexCount;

	std::vector< Entity* > activeEntities; 
	std::vector< Entity* > deadEntities;
	std::vector< std::vector<Component*> > components;
	std::vector< System* > systems;
public:
	EntityManager();
	~EntityManager();

	Entity createEntity();

	void killEntity(Entity entity);
	void registerComponent(Entity entity, Component* component);
	void removeComponent(Entity entity, CID cid);
	
	Component* getComponent(Entity entity, CID cid);
	
	bool isAlive(Entity entity);

	void invokeSystems();
};

#endif
#include "EntityManager.hpp"
#include "DummySystem.hpp"

EntityManager::EntityManager():indexCount(0) {
	 deadEntities.reserve(100);
	 activeEntities.reserve(100);
	 // This will initialize 100, like reserve but for 2D vectors.
	 components.reserve(100);
	 components.resize(100, std::vector<Component*>(CID::UNIQUE_COUNT, nullptr) );
	 systems.push_back(new DummySystem(this));
}

EntityManager::~EntityManager() {
	for(Entity* e : activeEntities) delete e;
	for(Entity* e : deadEntities) delete e;
	for(System* s : systems) delete s;
	for(auto& v : components)
		for(Component* c : v) delete c;
}

Entity EntityManager::createEntity() {
	// Try to recycle a dead entity
	if ( !deadEntities.empty() ) {
		Entity* entity = deadEntities.back();
		deadEntities.pop_back();
		// Give it a new unique id to make sure it is treated as a new entity
		entity->setUID(entity->getUID()+1);
		activeEntities[entity->getIndex()] = entity;
		return (*entity); 
	}
	
	Entity* entity = new Entity(indexCount++,0);
	activeEntities.push_back(entity);
	components.push_back( std::vector<Component*>(CID::UNIQUE_COUNT) );
	return (*entity);
}

void EntityManager::killEntity(Entity entity) {
	if (!isAlive(entity)) return;
	for(int i = 0; i < CID::UNIQUE_COUNT; i++) {
		delete components[entity.getIndex()][i];
		components[entity.getIndex()][i] = nullptr;
	}
	deadEntities.push_back(activeEntities[entity.getIndex()]);
	activeEntities[entity.getIndex()] = nullptr;
}

Component* EntityManager::getComponent(Entity entity, CID cid) {
	if (!isAlive(entity)) return nullptr;
	return components[entity.getIndex()][cid];
}

bool EntityManager::isAlive(Entity entity) {
	if ( activeEntities.empty() ) return false;
	if ( activeEntities[entity.getIndex()] == nullptr ) return false;
	if ( activeEntities[entity.getIndex()]->getUID() != entity.getUID()) return false;
	return true;
}

void EntityManager::registerComponent(Entity entity, Component* component) {
	if (!isAlive(entity)) return;
	if ( component == nullptr ) return;

	if ( components[entity.getIndex()][component->getCID()] != nullptr )
		delete components[entity.getIndex()][component->getCID()];
	components[entity.getIndex()][component->getCID()] = component;
}

void EntityManager::removeComponent(Entity entity, CID cid) {
	if (!isAlive(entity)) return;
	if ( components[entity.getIndex()][cid] != nullptr )
		delete components[entity.getIndex()][cid];
	components[entity.getIndex()][cid] = nullptr;
}

void EntityManager::invokeSystems() {
	for(Entity* e : activeEntities)
		if (e != nullptr)
			for(System* sys : systems) sys->process(e);
}

Should I rather use another container? Like std::set or std::map and just use a unsigned int id as a key?
Should the EntitySystem handle both entities, components and systems? 


Problem with my Quadtree - converting from std::vector to std::set

29 June 2013 - 12:46 PM

I recently made a dynamic quadtree for moving objects for a game I'm creating. Initially i used the std::vector to contain all objects present in the current rectangle and after some optimization and fixing stack overflow it's now working perfectly with 1000+ moving objects.
 

 

However, a friend of mine told me ( or rather a chat ) that I should be using std::set rather than std::vector because it uses less alloc/moving/resizing-calls and has improved access time.

My naive approach was simply just change all std::vector operations to be std::set, change a few loops to use iterators instead of an integer and so forth. The code in it self is exactly "the same" as the one with vectors but for some reason it's crashing inside the "Quadtree::update()" method which simply updates the quadtree which contains moving objects.

The function looks like this:
 

void Quadtree::update() {
	if ( status == QuadStatus::BRANCH && hasLeafChildren() )
		merge();
	
	if(status == QuadStatus::LEAF) {
		for( auto it = objects.begin(); it != objects.end(); ++it) {
			if(!inBounds((*it)->getX(), (*it)->getY()) ) {
				GameObject* o = (*it);
				it = objects.erase(it); // THIS IS WHAT IS CAUSING THE CRASH!!!
				parent->addObject(o);
			}
		}
		return;
	}
	else
		for(int i = 0; i < 4; i++) {
			if(nodes[i] != nullptr)
				nodes[i]->update();
		}
}

Apparently it's the line "it = objects.erase(it)" that is making the program crash - here is the call stack:
 

 

0  0x00449a26  std::_Rb_tree_increment(std::_Rb_tree_node_base const*)    

1  0x004ceed6  std::_Rb_tree_const_iterator<GameObject*>::operator++  c:\\mingw-4.7.1\\lib\\gcc\\mingw32\\4.7.1\\include\\c++\\bits\\stl_tree.h  269
2  0x00403cca  Quadtree::update  C:\\Users\\Victor\\Documents\\CodeLite\\OneGameAMonth\\TinyQuest\\Quadtree.cpp  213
3  0x00403d58  Quadtree::update  C:\\Users\\Victor\\Documents\\CodeLite\\OneGameAMonth\\TinyQuest\\Quadtree.cpp  231
4  0x00403d58  Quadtree::update  C:\\Users\\Victor\\Documents\\CodeLite\\OneGameAMonth\\TinyQuest\\Quadtree.cpp  231
5  0x00401ad1  main  C:\\Users\\Victor\\Documents\\CodeLite\\OneGameAMonth\\TinyQuest\\main.cpp  79

I'm not entirely sure why ( I think it's an overflow ) but isn't std::set suppose to use LESS operations than an vector?


Kind regards, Moonkis


Handling interaction/collision response between multiple "GameObjects" nicely.

17 June 2013 - 07:51 PM

This is one of the hardest part of game-development according to my brain apparently, I have a hard time figuring out how to handle interaction between multiple objects that are derived from the same base-class.

Let me try to explain it. Lets say I have a few objects that all derives from the parent-class "GameObject":

  • Bullet
  • Player
  • Enemies
  • Power-Ups
  • Sword Slash Bounding-box
  • Tiles - such as platforms ect.

 

Here we have a lot of game objects, that shares the common attributes and functions which are stored inside an vector<GameObject*> which contains all the objects present on the map.

So far so good! But here is when my brain just implodes, trying to determine what interacts with what without looping EVERY object and dynamic-casting everything!

Lets assume I have some magical query function that can fetch an array of nearby objects from any arbitrary object!

What I do at the moment is something along the lines:

GameObject has two virtual methods called getType() and getSubType() which returns a string.
When queering close by objects, I iterate through the vector checking if anyone is colliding ( or whatever triggers the interaction ) and if they are I check what type they are, to determine if they should react to the colliding object.

I often put the interaction code inside of the object - i,e Bullets interacts with either Player or Enemy ( depending on the subtype ), Power-Ups interact with the Player and so on:

Example:
 

// Inside of Player-class
void update( float dt ) {
    /* Code */
    vector<GameObject*> v = mWorld.fetchObjects(this->x,this-y,50);
    for( GameObjects* o : v ) {
        if(o->collide(this)) {
            o->interactWith(this); // Object "o" will check "this"->getType() and determine what it will do.
        }
    }
}

Though I am a bit afraid I might do some unecessary already done collision checks+interactions - but shouldn't be a problem as long as I define what object interacts with what! I.E Bullet checks for Enemy-collisions but Enemies don't check for Bullets ( a bit weird isn't it? ).

The problems I feel with this approach is that:
1) It's not clear of what object should check for what collision - Enemy vs Bullets or Bullets vs Enemies?
2) Not flexible when more and more object-types are introduced.


I have tried searching for clean, simple ( low on complexity and code-base ) 2D projects to see how they handle all the objects interaction - especially when they are "anonymous" as in they are stored in a vector<GameObject*>.

There must be a better way ( without resorting to Component systems or a shit ton of dynamic-casts ) to deal with interacting with different types of objects!

Hopefully someone will spread some light on this topic because my searches have failed me.

Kind regards,
Moonkis


Weird encounter with exposing C++ objects to LUA

12 June 2013 - 01:18 PM

I have tried to get into Lua programming for a while but haven't really gotten around to it until now, I studied the stack and how it worked before continued ( it confused me at first ).

I followed an excellent guide: https://gist.github.com/kizzx2/1594905 on how to bind objects and expose them to Lua, so far everything is great and it works perfectly! ( Almost )

There are two things that I'm not entirely sure of and how to approach:

My full C++ code

Spoiler

 

Calling Foo.new(parameter)

This is my main concern, why is that the only function that can ( and must ) be called as Foo.new instead of Foo:new as the normal standard? How do I actually manage to chaing it so it can be used as Foo:new() instead? Because I really really want to!


Calling self made functions

function Foo:Speak(a)
    print("[LUA] "..a:printInt())
end

The above line is a self made ( extended ) function from withing the Lua file that an object can call, however I must pass what object is going to retrieve it's value from the C++ side which makes it kinda redundant and weird looking:
 

foo:Speak(foo)

instead I want:

foo:Speak()
bar:Speak()
boo:Speak()

But I'm not sure how to do that seeing as it must call <lua object>:getInt() inside the call - how can I know what lua object is calling the speak without passing the object itself?

My guess on this matter is that I need to incorporate some kind of Lua class system? Is this the right track?

Hopefully someone can explain this to me!

Kind regards, Moonkis


PARTNERS