I was wondering if there was some way (probably obvious) to make my approach to the following problem more elegant:
Problem:
I need to be able to call a method and or function in an abstract, interchangeable (for lack of a better word) way.
Meaning, either call an overloaded method, or use some sort of function pointer or delegate, or use inheritance (preferably not).
The main use of this will be to cast an object of any arbitrary type (derived from a common base class) at any time in the correct method and
perform an operation on it.
Current (ugly) Solution:
WARNING: LOTS OF CODE!
Say we have the following code (Pseudo C++):
View on pastebin.com too: http://pastebin.com/vsN0aatE
Code: Select all
//These are all classes I plan to have in my application.//
//Application name = White - Storm: Lightning.//
struct WSLObject {
//Stuff...//
};
//Part of the "solution".//
struct BaseCastOperation {
virtual void DoCastOperation( WSLObject* operationRecipiant ) = 0;
//For arbitrary and possibly nessisary information.//
std::string info;
};
struct ScriptingLanguage
{
std::string fileType;
static std::string GetExtension( std::string scriptFileName ) = 0;
virtual void RunScript( std::string scriptFile ) = 0;
//Stuff...//
};
class BaseEntity : public WSLObject
{
protected:
/*Yes, yes I know this is suppose to be
implementation level.*/
std::vector<ScriptingLangauge*> scriptingLanguages;
std::vector<BaseCastOperation*> scriptTranslators; /*The purpose of these objects
will be to take an Entity, cast it into its derived type, then "send it" (set it
as a global) to the script, why so many? So any scripting language that can fit
this functionality in-to one method can be used in the engine. Other scripting
classes will exist. This functionality will also allow for more extensibility
in the engine as in terms of what you can do with the core-framework, and have
all "senders" you need be applicable to all objects anywhere in the hierarchy.*/
//All the scripts that will be run (file names/directories).//
std::string, init, ref, oth, des;
//Stuff...//
public:
virtual void Initialize() = 0;
virtual void Refresh() = 0;
virtual void Other() = 0;
virtual void Destroy() = 0;
//More stuff...//
};
//Make sure it is consistent through the engine.//
static const std::string globalObjectName = "object";
template< typename T >
struct LuaSender : public BaseCastOperation
{
LuaSender() {
info = ".lua";
}
void DoCastOperation( WSLObject* operationRecipiant )
{
/*Luabind stuff included luabind::global sets a global
in Lua, it is picky about type though (I cant send a pointer of type BaseEntity that
points to an entity, it will be sent as a BaseEntity.*/
//This is kinda yucky, but necessary... so bare with me...//
luabind::globals[ globalObjectName ] = dynamic_cast<T>( operationRecipiant );
}
};
//Others may include, Python, C#, or even Java-script.//
struct Lua : public ScriptingLanguage
{
Lua() {
fileType = ".lua";
}
void RunScript( std::string scriptFile ) {
//<IMPLEMENTATION NOT SHOWN>//
}
//Stuff...//
};
class Entity : public BaseEntity
{
//Stuff...//
public:
Entity()
{
//Stuff...//
//More "senders" can be added later.//
scriptTranslators.push_back( new LuaSender<Entity> );
//More "scripting languages" can be added later.//
scriptingLangauges.push_back( new Lua );
}
//Stuff...//
void Refresh()
{
//Stuff...//
//Sorry, I just have to put this optimization in there.//
unsigned int tsize = scriptTranslators.size();
unsigned int lSize = scriptingLangauages.size();
bool break_ = true;
for( unsigned int i = 0; i < tSize && break_; ++i )
{
for( unsigned int j = 0; j < lSize; ++j )
{
if( ScriptingLanguage::GetExtension( ref ) ==
scriptTranslators[i]->info &&
ScriptingLanguage::GetExtension( ref ) ==
scriptingLangauages[j]->fileType )
{
//=================================//
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
//!!!!!!!!!The main point.!!!!!!!!!//
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
//=================================//
scriptTranslators[i]->DoCastOperation( this );
scriptingLangauages[j]->RunScript( ref );
break_ = false;
break;
}
}
}
}
};
while now to come up with a better way, but I do not see any MAJOR break-through's in the future, does anyone else have a better idea than I?
P.s If any further clarification is needed please do not hesitate to let me know
-----EDIT-----:
I just realized I derp'd and put this topic in "Game Development" by accident, so yes I am aware XD.