Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 22 Jul 2007
Offline Last Active Oct 18 2013 02:40 PM

Topics I've Started

Finite-State-Machine library

24 December 2009 - 09:56 PM

With today being a holiday and everything I took Finite State Machine (FSM) code out from my project and made it into a small library. It contains doxygen documentation, examples for usage, sourcecode and a BSD license. If anything is wrong with it or something is unclear, drop me a message. Grab it from my project page: FSM from secret project or from a link directly to the zipped library: FSM library Merry Christmas!

Problem with registering global behaviour

10 October 2007 - 08:47 PM

I am trying to register automatic conversion (assignment) from abstract Value class to integer, but it doesn't seem to work. Non-abstract class does just fine and I can register other functions easily for Value, just not the global behaviour. The global behaviour registration works fine with DoubleValue, a non-abstract class derived from Value. The only difference between these two that I have been able to find is that Value is abstract. But the function that does the assignment is static, so the fact that Value is abstract should definitely not break anything or probably should do so in compilation time, not later. I don't seem to get any error messages from AngelScript callback either, although it is registered and works in other cases. I extracted some of the code:
// Abstract baseclass
class Value {
  virtual double getIntValue() = 0;

int assignValueToInt(Value* value) {
  return value->getIntValue();

// Subclass of value
class DoubleValue : public Value {
  double getDoubleValue() { return 0.0; }

int assignDoubleValueToInt(DoubleValue* value) {
  return value->getIntValue();

// Regist
r = engine->RegisterObjectType("Value", sizeof(Value), asOBJ_CLASS_CA); assert( r >= 0 );

// Register dummy constructor that gives an error etc...

// This works fine
r = engine->RegisterObjectBehaviour("String", asBEHAVE_ASSIGNMENT,
                                      "String& f(const Value &in)",
                                      asCALL_CDECL_OBJFIRST); assert( r >= 0 );

// Doesn't work, assert aborts, return code is -5 (invalid argument)
	r = engine->RegisterGlobalBehaviour(asBEHAVE_ASSIGNMENT,
                                      "int f(const Value &in)",
                                      asCALL_CDECL); assert( r >= 0 );

r = engine->RegisterObjectType("DoubleValue", sizeof(DoubleValue), asOBJ_CLASS_CA); assert( r >= 0 );

// Works just fine
r = engine->RegisterGlobalBehaviour(asBEHAVE_ASSIGNMENT,
                                      "int f(const DoubleValue &in)",
                                      asCALL_CDECL); assert( r >= 0 );
I don't even have any more ideas where the problem might be... I am probably overlooking something, but I have tried to find the problem for two days by now, so any help is appreciated. Mr Jones

Avoid referencing stack objects?

25 July 2007 - 11:17 PM

I have registered both referencing and releasing for String class. The memory manager that handles references is keeps the references separately such that the actual objects are not aware of the reference and release mechanism. There are no memory leaks for constructed and factory made strings, but addition of strings causes memory leak. My + operator returns a string from stack, but AngelScript attempts to release its reference, but since it is from stack, it should be ignored completely. Is it somehow possible to avoid AngelScript trying to manage external pointers or should I handle it in my own memory manager by wrapping operators in separate functions and completely ignoring the pointers they return by setting the reference value to at least 2? I wouldn't want to use the same method as in the example, where reference counter is included inside the object, because I have quite many classes and it is difficult to manage them this way. The code is below, perhaps it makes more sense than my fuzzy explanation:
AngelMemoryManager<DATA::String*> AngelString::memoryManager; // Strings memory manager

String* AngelString::reference(DATA::String* str) {
  return memoryManager.reference(str); // registers the pointer and increments the value (if pointer is new, the reference is 1)

void AngelString::release(DATA::String* str) {
  memoryManager.release(str); // releases the pointer and decrements the value (if value is 0, the pointer is deleted)

// This is the string factory that creates new strings for the script
String* AngelString::factory(asUINT length, const char *s) {
  return reference(NEW(String(s, length)));

// This is a wrapper for the default AngelString constructor, since
// it is not possible to take the address of the constructor directly
void AngelString::construct(String* thisPointer) {
  reference(PLACEMENT_NEW(thisPointer, String()));

String operator + (const String& string1, const String& string2); // the declaration of addition operator 

// Current operator registration
	r = engine->RegisterObjectBehaviour("String", asBEHAVE_ADDREF,
                                      "void f()", asFUNCTION(AngelString::reference),
                                      asCALL_CDECL_OBJLAST); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("String", asBEHAVE_RELEASE,
                                      "void f()", asFUNCTION(AngelString::release),
                                      asCALL_CDECL_OBJLAST); assert( r >= 0 );

	r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "String f(const String &in, const String &in)",
                                      asFUNCTIONPR(operator +,
                                                  (const String &, const String &),
                                      asCALL_CDECL); assert( r >= 0 );
Thanks a lot to anybody who has a good idea for solving this problem.