Closed shierei closed 5 years ago
Do you have an example of this failing please? The unit tests seem to work: https://github.com/billyquith/ponder/blob/master/test/ponder/class.cpp
Attached please see a modified test/exampels/simple.cpp. The key is to give the name of metaclass that is not the same as the metaclass's C++ type name. For example, in this example I gave the name of the Person metaclass "People". After you re-make simple.cpp and run it, you should see the following exception raised.
test/examples/simple.cpp:112: FAILED: due to unexpected exception with message: the metaclass Person couldn't be found
simple.cpp.txt:
#include "test.hpp"
//! [eg_simple]
#include <ponder/classbuilder.hpp>
#include <ponder/uses/runtime.hpp>
#include <iostream>
//! [eg_simple_class]
class Person
{
public:
// constructor
Person(const std::string& name)
: m_name(name)
{}
// accessors for private members
std::string name() const { return m_name; }
void setName(const std::string& name) { m_name = name; }
// public members
float height;
unsigned int shoeSize;
// member function
bool hasBigFeet() const { return shoeSize > 10; } // U.K.!
private:
std::string m_name;
};
//! [eg_simple_class]
//! [eg_simple_declare]
PONDER_TYPE(Person) // declare the type to Ponder
static void declare() // declare the class members to Ponder
{
ponder::Class::declare<Person>("People")
.constructor<std::string>()
.property("name", &Person::name, &Person::setName)
.property("height", &Person::height)
.property("shoeSize", &Person::shoeSize)
.function("hasBigFeet", &Person::hasBigFeet)
;
}
//! [eg_simple_declare]
//! [eg_simple_use]
// An example of how you might use Ponder:
static void use()
{
//! [eg_simple_metaclass]
// retrieve the metaclass (containing the member data)
const ponder::Class& metaclass = ponder::classByName("People");
//! [eg_simple_metaclass]
//! [eg_simple_create]
// construct a new person
ponder::UserObject person = ponder::runtime::create(metaclass, "Bozo");
//! [eg_simple_create]
// set attributes
person.set("height", 1.62f);
person.set("shoeSize", 28);
// retrieve a function we would like to call
const auto& func = metaclass.function("hasBigFeet");
// call the function and get the result
const bool bigFeet = ponder::runtime::call(func, person).to<bool>();
// nasty
//! [eg_simple_destroy]
ponder::runtime::destroy(person);
//! [eg_simple_destroy]
}
//! [eg_simple_use]
//! [eg_simple]
Ok, yes this needs some work.
return UserObject(&classByObject(object), new Holder(RefTraits::getPointer(object)));
from UserObject UserObject::makeRef(T& object)
is the problem. classByName()
isn't the problem, it is makeRef() trying to get the metaclass details via the object type, which is different. Probably best to look up everything by type (id) and map the names instead. This could mean substantial changes to the registration/declaration.
When you declare a metaclass, you can give it a name. This name however cannot be used to retrieve the metaclass back using ponder::classByName(). The name given has to be either an empty string or the same as the C++ class type name. I think this is a major usage problem for reflection purposes.