Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 24 May 2012
Offline Last Active Today, 04:29 AM

Topics I've Started

C++ class destroyed twice?

Yesterday, 12:07 PM


I'm trying to bind a non-template value type based on iraxef's reflection proposal, but I'm facing a weird runtime crash...
It appears that when ~CScriptType is called for the first time, it has already been destroyed Oo
(when I debug ~CScriptType, members are fucked up, addresses are 0xcdcdcdcd or unreadable, and the first call to m_ot->Release() creates the crash)

What I have in AS:

    SomeClass c;
    Type t(c); // Just instantiate a Type

Here is how I register the class:

    r = e.RegisterObjectType("Type", sizeof(CScriptType), asOBJ_VALUE | asOBJ_APP_CLASS_DA); assert(r >= 0);

    r = e.RegisterObjectBehaviour("Type", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(CScriptType_DefaultConstruct), asCALL_CDECL_OBJLAST); assert(r >= 0);

    r = e.RegisterObjectBehaviour("Type", asBEHAVE_CONSTRUCT, "void f(const ?&in)", asFUNCTION(CScriptType_InstanceConstruct), asCALL_GENERIC); assert(r >= 0);
    r = e.RegisterObjectBehaviour("Type", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(CScriptType_Destruct), asCALL_CDECL_OBJLAST); assert(r >= 0);
static void CScriptType_DefaultConstruct(void * mem)                               { new(mem)CScriptType(NULL); }
static void CScriptType_Destruct(CScriptType *obj)                                 { obj->~CScriptType(); }

// Note: generic calling convention was used to have access to the engine,
// so we can get the asIObjectType from the type ID
static void CScriptType_InstanceConstruct(asIScriptGeneric * g)
    int typeID = g->GetArgTypeId(0);
    void * mem = g->GetArgAddress(0);

    asIObjectType * ot = g->GetEngine()->GetObjectTypeById(typeID);

    if (strcmp(ot->GetNamespace(), "") == 0 && strcmp(ot->GetName(), "type") == 0)
        // The argument is a type<T> instance, get the T instead
        ot = ot->GetSubType();


Am I missing something?

Note: my implementation of reflection also has a "type<T>" which is bound the exact same way, and uses the same C++ object.
However, when I instantiate it, I get no crash at all.

AS version: 2.30.0 WIP, Windows 7

Value type with no default constructor?

19 December 2014 - 08:37 PM

I'm trying to register a value type that doesn't have a default constructor,

but the script engine complains:


E: : (0, 0): Type 'Type' is missing behaviours
I: : (0, 0): A non-pod value type must have the default constructor and destructor behaviours


The problem is that I don't want to enable users to create instances of my class without parameters, because it doesn't make any sense, and would need many unneeded checks in C++...



Serializing C++ objects with references

16 December 2014 - 05:08 PM

Hello, I'm thinking about all problems I'll have to face when implemening hot-reloading of scripts.
Currently, I assume that I'll use the Serializer add-on.

I have difficulty to find a good solution against the following problem:

// In C++ (simplified)

class ScriptObject
    int addRef();
    int release();
    // etc...

class Foo : public ScriptObject
    string name;

class Bar : public ScriptObject
    Foo * foo; // A function is used to bind this field to AS
// In AS

// Script before hot reload:
Foo@ foo; // Globals
Foo@ foo2; // Global too etc
Bar@ bar;
Bar@ bar2;

// Somewhere:
foo.name = "Yay";
bar.foo = foo;
bar2.foo = foo;
// Script after hot reload:
// The user removed foo and foo2
Bar@ bar;
Bar@ bar2;

// Somewhere else:
// Expected: printing "Yay" twice, coming from the same Foo instance.

First, how can we serialize Bar?


- Save foo as a full instance?
Despite "Yay" will be printed twice,
we'll end up with two Foo instances instead of a shared one...


- Just save the address of foo in it, not its value?
Foo is deleted in the process of recompiling, so the print will badly crash in C++.


- Call addRef on each C++ objects before recompiling, so they stay in memory when recompiling?

Then, how would we prevent objects from leaking?


I'm new to hot-reloading with AngelScript, so does someone has an idea how to handle this case?

Template methods in scripts?

03 December 2014 - 04:35 PM



Is it possible (or planned) to declare template functions, classes or methods in AngelScript?
I know it is possible to use a template system when registering the application interface,
however my script classes will not always be bound to C++ code.

Just like C++/C#/Java, I want to factorise code like this:

void sayHello<T>(obj)
    obj.hello(); // Compiler error if T doesn't have a hello method

class Entity
    Component@[] _components;

    Cmp_T@ addComponent<Cmp_T>()
        // Compiler error if T doesn't derives from Component
        Cmp_T@ cmp = Cmp_T();
        return cmp;

    Cmp_T@ getComponent<Cmp_T>()

class Spawner<T>
    T spawn()
        return T();

I'm asking this because I find that templates are a good feature in strong typed languages, for many reasons:

- Type-safe statements

- Less code repetitions

- Reduces overuse of explicit casts

- Makes code reusable more quickly

- Allows defining new containers directly in AS

Just like C++, the compiler could generate the corresponding implementations at compile-time,
or check the types at run-time (but it sounds less efficient to me).

I'm not dreaming on something as hard as C++ templates, C# template system is fine already, and hasn't the drawbacks of debugging C++ ones.

I know that interfaces exist to handle some of these situations,
but personnally I find these a bit old-fashioned and too heavy to be used in scripting, where quick iteration should be an advantage.


Is this feature possible to implement/is planned?

Problem implementing a BMFont renderer

20 December 2012 - 08:03 PM

I'm implementing a custom BMFont renderer in C++, but I get weird results with xoffset and yoffset :
Posted Image
The green-red lines are the origin axes,
yellow rects are not offset char rects,
cyan rects are offset char rects.

Characters are not displayed the right way, but I can't find what I'm doing wronng :(
I believe it's not a bug of BMFont, as I used the same font in a Java game with Slick2D and it worked fine.

Here is my drawing code :
[source lang="cpp"]void Font::draw(const std::string text){ unsigned int originX = 0, originY = 0; // Cursor position unsigned int x, y; // Shifted position float tx, ty, tw, th; // Texture sub-rect coordinates char c; // Current read character glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for(unsigned int i = 0; i < text.size(); i++) { c = text[i]; // Line endings if(c == '\n') { originY += m_settings.lineHeight; originX = 0; continue; } else if(c == '\r') { continue; } // Get character descriptor const CharDescriptor * cd = m_settings.getChar©; if(cd == nullptr) { //std::cout << "E" << (int)c; break; } // Use the glyph atlas texture const sf::Texture &amp; tex = m_textures[cd->page]; tex.bind(); // Get glyph texture sub-rect const sf::Vector2u ts = tex.getSize(); tx = static_cast<float>(cd->x) / static_cast<float>(ts.x); ty = static_cast<float>(cd->y) / static_cast<float>(ts.y); tw = static_cast<float>(cd->width) / static_cast<float>(ts.x); th = static_cast<float>(cd->height) / static_cast<float>(ts.y); // Get drawing coordinates x = originX + cd->xoffset; y = originY + cd->yoffset; // Draw glyph glBegin(GL_QUADS); glTexCoord2f(tx, ty + th); glVertex2i(x, y); glTexCoord2f(tx + tw, ty + th); glVertex2i(x + cd->width, y); glTexCoord2f(tx + tw, ty); glVertex2i(x + cd->width, y + cd->height); glTexCoord2f(tx, ty); glVertex2i(x, y + cd->height); glEnd(); // Advance cursor originX += cd->xadvance; // DEBUG // Some code to draw the rects }}[/source]

The full implementation source code is available here : https://dl.dropbox.com/u/60408088/INFO/bmfont_impl_src_part.zip
But it is not really useable alone because it has a few dependencies to other parts of a bigger project (will be on github in the future).