Skip to content

Instantly share code, notes, and snippets.

@johnb003
Last active October 9, 2019 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnb003/e4553a7a7d1444c9455a9f2c4716d9da to your computer and use it in GitHub Desktop.
Save johnb003/e4553a7a7d1444c9455a9f2c4716d9da to your computer and use it in GitHub Desktop.
Adaptable Components in C++
#include <vector>
#include <typeinfo>
#include <typeindex>
#include <unordered_map>
#include <iostream>
class Adaptable;
class AdaptableComponent {
Adaptable *container;
friend Adaptable;
public:
virtual ~AdaptableComponent() {}
template <typename T> T *As() { return container->As<T>(); }
};
class Adaptable {
std::vector<AdaptableComponent *> comps;
public:
Adaptable(std::vector<AdaptableComponent *> comps)
: comps(comps)
{
for (AdaptableComponent *c : comps)
c->container = this; // that's what friends are for.
}
virtual ~Adaptable() {
for (auto p : comps)
delete p;
}
template <typename T>
T *As() {
for (auto c : comps) {
T *t = dynamic_cast<T *>(c);
if (t) return t;
}
return NULL;
}
};
class IDerp
{
public:
virtual int GetInt() const = 0;
};
class Acomp : public AdaptableComponent, public IDerp
{
public:
int a_stuff;
virtual int GetInt() const override { return a_stuff; }
};
class Bcomp : public AdaptableComponent
{
public:
int b_stuff;
void SoftDependencyExample() {
b_stuff = 5;
IDerp *softDepAcomp = As<IDerp>();
if (softDepAcomp) {
std::cout << "Combined Total " << softDepAcomp->GetInt() + b_stuff << std::endl;
}
else {
std::cout << "My Lonesome Total " << b_stuff << std::endl;
}
}
};
void TestAdaptable() {
Adaptable i({ new Acomp(), new Bcomp() });
i.As<Acomp>()->a_stuff = 1;
i.As<Bcomp>()->SoftDependencyExample();
}
int main(int argc, char *argv[]) {
TestAdaptable();
return 0;
}
@johnb003
Copy link
Author

johnb003 commented Oct 9, 2019

The first revision seemed promising to avoid iterating over all objects using dynamic_cast, but alas, the key is only based on the most derived type, so it fails to find interfaces. The linear search really sucks though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment