/*
** Command & Conquer Generals(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see .
*/
////////////////////////////////////////////////////////////////////////////////
// //
// (c) 2001-2003 Electronic Arts Inc. //
// //
////////////////////////////////////////////////////////////////////////////////
// FILE: ModuleFactory.h //////////////////////////////////////////////////////////////////////////
// Author: Colin Day, September 2001
// Desc: TheModuleFactory is where we actually instance modules for objects
// and drawbles. Those modules are things such as an UpdateModule
// or DamageModule or DrawModule etc.
//
// TheModuleFactory will contain a list of ModuleTemplates, when we
// request a new module, we will look for that template in our
// list and create it
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __MODULEFACTORY_H_
#define __MODULEFACTORY_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include
#include "Common/GameMemory.h"
#include "Common/SubsystemInterface.h"
#include "Common/AsciiString.h"
#include "Common/NameKeyGenerator.h"
#include "Common/Module.h"
#include "Common/STLTypedefs.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Thing;
class Object;
class Drawable;
class INI;
// TYPE DEFINITIONS ///////////////////////////////////////////////////////////////////////////////
typedef Module *(*NewModuleProc)(Thing *thing, const ModuleData* moduleData);
typedef ModuleData* (*NewModuleDataProc)(INI* ini);
//-------------------------------------------------------------------------------------------------
/** We use TheModulyFactory to register classes that will be attached
* to objects and drawables which will be executed or "called back" in the
* correct situations ... such as Die, Damage, Update etc or just as
* a place to store data specific to that type of thing */
//-------------------------------------------------------------------------------------------------
class ModuleFactory : public SubsystemInterface, public Snapshot
{
public:
ModuleFactory( void );
virtual ~ModuleFactory( void );
virtual void init( void );
virtual void reset( void ) { } ///< We don't reset during the lifetime of the app
virtual void update( void ) { } ///< As of now, we don't have a need for an update
Module *newModule( Thing *thing, const AsciiString& name, const ModuleData* data, ModuleType type ); ///< allocate a new module
// module-data
ModuleData* newModuleDataFromINI(INI* ini, const AsciiString& name, ModuleType type, const AsciiString& moduleTag);
Int findModuleInterfaceMask(const AsciiString& name, ModuleType type);
virtual void crc( Xfer *xfer );
virtual void xfer( Xfer *xfer );
virtual void loadPostProcess( void );
protected:
class ModuleTemplate
{
public:
ModuleTemplate() : m_createProc(NULL), m_createDataProc(NULL), m_whichInterfaces(0)
{
}
NewModuleProc m_createProc; ///< creation method
NewModuleDataProc m_createDataProc; ///< creation method
Int m_whichInterfaces;
};
const ModuleTemplate* findModuleTemplate(const AsciiString& name, ModuleType type);
/// adding a new module template to the factory, and assisting macro to make it easier
void addModuleInternal( NewModuleProc proc, NewModuleDataProc dataproc, ModuleType type, const AsciiString& name, Int whichIntf );
#define addModule( classname ) \
addModuleInternal( classname::friend_newModuleInstance, \
classname::friend_newModuleData, \
classname::getModuleType(), \
AsciiString( #classname ), \
classname::getInterfaceMask())
static NameKeyType makeDecoratedNameKey(const AsciiString& name, ModuleType type);
typedef std::map< NameKeyType, ModuleTemplate, std::less > ModuleTemplateMap;
typedef std::vector ModuleDataList;
ModuleTemplateMap m_moduleTemplateMap;
ModuleDataList m_moduleDataList;
}; // end class ModuleFactory
// EXTERN /////////////////////////////////////////////////////////////////////////////////////////
extern ModuleFactory *TheModuleFactory; ///< singleton definition
#endif // __MODULEFACTORY_H_