• Content count

  • Joined

  • Last visited

Community Reputation

275 Neutral

About PureSnowX

  • Rank
  1. I know there are tons of better, more well established methods. In this case I wanted to learn something. I'm not to found of getting tons of suggestions telling me I can avoid learning anything by just using a library. Don't get me wrong, I appreciate the effort of others, but when everyone says; "Just use <insert lib> instead", It get on my nerves. However, I got my code to work under circumstances the only problem was I didn't know exactly why it worked or why it didn't work. I actually got the code to work as intended with a single .h and .cpp file. I put the "#define new new(__FILE__,__LINE__) at the end of the header and right after all the includes in my .cpp file I added #undef new I haven't ran into any problems with this yet and I'm quite happy with the result. In the future I guess I should make it clear from the very beginning if I'm interested in alternative solutions or not, in this case I wanted to understand the raw code of it all.    Most articles had something similar:   #define DEBUG_NEW new(__FILE__,__LINE__) #define new DEBUG_NEW This didn't even remotely work for some reason.
  2. I'm sure there is tons of better ways, and I do appreciate the effort in showing me another way. However I'm not looking for an alternative way right now, this is for a small project  on a deadline. Also I'd love to actually know why this isn't working! So far I have gotten it to work in two ways:   Write all the code inside the header and add #define new new(__FILE__,__LINE__), this however dosen't work if two headerfiles includes the memoryleak header even if it's inside a header-guard. The compiler compains of already used function symbols. Sepperate the leak code into a .h and .cpp, wrap it around another header and add the macro last.   I'm trying to figure out WHY my first attempt isn't working, and how to "properly" do it.
  3. That is a great resource, but it doesn't explain my problem unfortunatly :/
  4. 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?
  5. [C++/SFML] ECS - How to deal with the entities?

    So I'm currently necroing this thread because I'm back again, desperately trying to wrap my head around ECS! I did read all the way until the last post, so I'm aware of what have been said, although some is a bit fuzzy. The root of my problems with ECS is basically the entities themselves! How to store them, how to "kill" them and how to make sure that old entity id's are validated as "alive" if they have been reused. I'm stuck here and I'v been reading source like crazy and googling like there is no tomorrow. Most of the code i find are either very cluttered or quite "heavy", making it hard to get a good overview of the system, they aren't simple so to speak. I have gained some more insight on templates since last time, and "typeid(T).name()" have served me well in various tasks. However the root of my problem with the ECS problem still exists. The entities. My current naive implementation is basically that each entity is an "unsigned long long" and that the "World" has a std::map< unsigned long long, std::map< std::string, Component* > > componentBag; that keeps components associated with objects. I can imagine it's rather ineffective and as one might guess I'm not recycling any old entity id's I turn to you guys, In hope of getting a throughout and careful explanation on how to deal with entities and how to invalidate and recycle. Preferably some mentions of the association of components.  I know it's a lot to ask, but hopefully someone might be able to answer my request :)
  6. [C++/SFML] ECS - How to deal with the entities?

    The reason I ask is because: What if you have a homing missile targeting an entity. The homing missile would need to know whether or not the target is still valid. Running a isValid(Entity e) every frame might be quite expensive considering there is a lot of entities. But I guess the object could subscribe to an "onDeletion" event for that or something similar. Thanks a lot! I will try to implement this ASAP. I feel that ECS plays so nicely along with OOP.
  7. [C++/SFML] ECS - How to deal with the entities?

    Well I guess that makes sense ... somewhat. When we want to check if an entity is alive or if an entity has X-component wouldn't we need to iterate the ( possibly ) WHOLE vector to find a match? The same when "deleting" an object and it's associated components. We basically need to iterate through all vectors the entity was relevant in?
  8. [C++/SFML] ECS - How to deal with the entities?

      If I remove the entity index and just keep the id how would I recycle old entities? As well as making sure that an old entity that should be dead is validated as alive seeing as it exists in the same index? I'm a tad confused. What do you mean just generate an entity at a free id? How do I keep track of which id's are free? Also regarding the templated helper functions, how would that look like? Could you give me an example?  
  9. 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? 
  10. What library to choose to write games in C + +

    Seconded. I have used a tiny bit of SFML, and it is quite easy to get started with, stick some sprites on the screen and so on. Follow some tutorial to get over the initial hurdle of getting some app to compile, and you are set. I'm planning to use SDL2 for a learning project precisely because it has less structure and hand-holding than SFML, and I would like to build my stuff from the ground up for once.   Thirded (....). I use SFML in almost all of my project and it's great! Easy to follow, easy to understand and very well designed with OOP in mind. I feel like enough people have voiced their opinion about using C++ as beginners ( Even though you didn't ask...4+ answers basically says the same thing ).
  11. This did the trick, here is the altered code:   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); parent->addObject(o); if ( it == objects.end() ) break; } } return; } Problem is, I don't understand why "if ( it == objects.end() ) break;" is needed! If the objects.erase() returns "end()" the for-loop should catch it before increasing the iterator, why doesn't it?
  12. 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:   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
  13. I'm disappointed - I'm not interested in a Physic-lib ( I want to be able to do it and understand it myself ) nor is the actual collision detection the problem. It's about interaction! I want to know how too handle interaction between a lot of different object-TYPES - seeing as they are stored as GameObject*  A bullet will for example interact with an Enemy and Player but not a Power-Up Krohm Could you please elaborate?
  14. 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
  15. Weird encounter with exposing C++ objects to LUA

    They are not. When calling a function, the former form just calls it while the latter form calls it with "Foo" as the first argument, i.e. Foo:new(12) is syntactic sugar for Foo.new(Foo, 12).   If you really must, you could change the C++ implementation to support such a mechanism, for example by ignoring the first argument or asserting that the first argument is what you expect, and then handling the subsequent arguments.     You must have a reason for it, no?   I believe however that many Lua programmers would find that quite idiosyncratic. The colon function invocation operator is intended for the Lua equivalent of member functions, and it doesn't make a huge amount of sense to use this where there is no obvious object to use.   Just like the following non-idiomatic C++ code would strike most C++ programmers as unnecessarily unusual: class Foo { public:     Foo(int x) : x(x)     {     }       static void frobnicate(Foo &self)     {         self.x *= -2;     }   private:     int x; };   int main() {      Foo instance;      // Huh?      Foo::frobnicate(instance); } If you were looking at such code, you'd immediately be wondering why the programmer didn't just use a regular member function.   Thank you! Your explanations are easy to follow and spot on! I guess I still have a long way to go. It makes sense after reading this, and also I think I didn't quite grasp that the first thing pushed into the stack was the object itself when calling with Object:Function() - even though I use it inside my C++ code... Well I guess that was all, thank you again!