i have been trying to debug this program for about 2 days(not the whole days, just when ive been coding) and i still cant find the source of this bug. i have been trying to create a class factory system for a game that i want to make. first, let me explain some things about how i use it:

you make an entity class that has the base class of CBase.
after the class definition(after the closing }) you put this code: LINK_ENTITY_TO_CLASS( className, entityName ) this generates a separate class definition that is the class's factory which holds the entityName and has a method called Create to make new instances of the class.
this(LINK_ENTITY_TO_CLASS) is a define and className is the name of the class(eg. CTest) and entityName is a string for finding that class's factory(eg. "test_entity"). when the class factory is instanced, it adds itself(in it's constructor) to a list that is searched when trying to find class factories. my problem is that the factories aren't getting put into the list(it's a std::vector, btw) when they're instanced.

i have used all sorts of debugging techniques(break points, putting watches on variables) and i still can't find the source of this problem.

hopefully this explanation is understandable and clear so it can help you to solve my problem.

here is my code:

util.h:

#ifndef UTIL_H
#define UTIL_H
#ifdef _WIN32
#pragma once
#endif
#include <vector>
#include "baseclass.h"

template< typename T >
T *CreateEntityTemplate( )
{
	return new T;
}

class CEntityFactory {
public:
	CEntityFactory( char *pFactoryName );
	char *m_pFactoryName;
	virtual CBase *Create( );
};

class CEntityFactoryDictionary {
public:
	void InstallFactory( CEntityFactory *factory, char *pFactoryName );
	void UninstallFactory( char *pFactoryName );
	CEntityFactory *FindFactory( char *pFactoryName );
	std::vector< CEntityFactory* > m_Factories;
};

CEntityFactoryDictionary EntityFactoryDictionary( );

#define LINK_ENTITY_TO_CLASS( className, entityName ) \
	class CEntityFactory_##className : public CEntityFactory{ \
	public: \
		CEntityFactory_##className ( char *pFactoryName ):CEntityFactory( pFactoryName ){ } \
		CBase *Create( ){ return CreateEntityTemplate< className >( ); } \
	}; \
	CEntityFactory_##className factory2( entityName ); \
	CEntityFactory_##className *factory = &factory2

#endif //UTIL_H

util.cpp:

#include "util.h"

CBase *CEntityFactory::Create( )
{
	return CreateEntityTemplate< CBase >( );
}

CEntityFactory::CEntityFactory( char *pFactoryName )
	:m_pFactoryName( pFactoryName )
{
	EntityFactoryDictionary( ).InstallFactory( this, pFactoryName );
}

void CEntityFactoryDictionary::InstallFactory( CEntityFactory *factory, char *pFactoryName )
{
	factory->m_pFactoryName = pFactoryName;
	m_Factories.push_back( factory );
}

void CEntityFactoryDictionary::UninstallFactory( char *pFactoryName )
{
	std::vector< CEntityFactory* >::const_iterator it;
	for( it = m_Factories.begin( ); it != m_Factories.end( ); ++it )
	{
		if( 0 == strcmp( (*it)->m_pFactoryName, pFactoryName ) )
		{
			m_Factories.erase( it );
		}
	}
}

CEntityFactory *CEntityFactoryDictionary::FindFactory( char *pFactoryName )
{
	for( unsigned int i = 0; i < m_Factories.size( ); i++ )
	{
		if( 0 == strcmp( m_Factories[i]->m_pFactoryName, pFactoryName ) )
		{
			return m_Factories[i];
		}
	}
	return NULL;
}

CEntityFactoryDictionary EntityFactoryDictionary( )
{
	static CEntityFactoryDictionary s_EntityFactoryDictionary;
	return s_EntityFactoryDictionary;
}

baseclass.h(which holds CBase):

#ifndef BASECLASS_H
#define BASECLASS_H
#ifdef _WIN32
#pragma once
#endif

class CBase {
	int m_nID;
	float m_fNextThinkTime;
public:
	CBase( );

	float GetNextThink( );
	void  SetNextThink( float fNextThinkTime );

	virtual void Spawn( ){ }
	virtual void Activate( ){ }
	virtual void Think( ){ }
	virtual void Update( ){ }
	virtual void Delete( ){ }
};

#endif //BASECLASS_H

baseclass.cpp:

#include "baseclass.h"
#include "id_manager.h"

CBase::CBase( )
	:m_nID( GetNextUsableID( ) ), m_fNextThinkTime( 0.0f )
{
}

float CBase::GetNextThink( )
{
	return m_fNextThinkTime;
}

void CBase::SetNextThink( float fNextThinkTime )
{
	m_fNextThinkTime = fNextThinkTime;
}

main.cpp:

#include "util.h"
#include <iostream>

class CTest : public CBase {
};

LINK_ENTITY_TO_CLASS( CTest, "test_entity" );

int main( )
{
	CBase *lol = NULL;

	if( !EntityFactoryDictionary( ).FindFactory( "test_entity" ) )
	{
		std::cout << "lol == NULL D:";
		std::cin.get( );
	}
	else
	{
		lol = EntityFactoryDictionary( ).FindFactory( "test_entity" )->Create( );
		std::cout << lol->GetNextThink( ) << " KI!K\n";
	}

	return 0;
}

thank you for your time

Recommended Answers

All 2 Replies

In this function

CEntityFactoryDictionary EntityFactoryDictionary( )
{
  static CEntityFactoryDictionary s_EntityFactoryDictionary;
  return s_EntityFactoryDictionary;
}

You are returning (by value) an anonymous temporary object which is a copy of the static s_EntityFactoryDictionary; you call InstallFactory on this anonymous temporary object which is immediately destroyed after that.

Modify the function as:

CEntityFactoryDictionary[B]&[/B] EntityFactoryDictionary( )
{
  static CEntityFactoryDictionary s_EntityFactoryDictionary;
  return s_EntityFactoryDictionary;
}

and you should be ok.

Caveat: I haven't looked at the rest of your code.

Thankyou sir! This made it work.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.