Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


_orm_

Member Since 16 May 2010
Offline Last Active Jun 12 2013 12:48 PM

Topics I've Started

Segmentation Fault Originating From ExecuteNext

13 October 2011 - 10:01 AM

I'll let the stacktrace speak for itself, but this is a pretty odd bug. I am using an outdated version of Angelscript, so I will see if using the latest SVN ffixes it, but here:

Program received signal SIGSEGV, Segmentation fault.
0x6523ecc3 in asCContext::ExecuteNext (this=0xbbd0fd8) at C:\mengin\src\deps\angelscript\as_context.cpp:1292
1292            switch( *(asBYTE*)l_bc )
(gdb) bt fuull
No symbol "fuull" in current context.
(gdb) bt full
#0  0x6523ecc3 in asCContext::ExecuteNext (this=0xbbd0fd8) at C:\mengin\src\deps\angelscript\as_context.cpp:1292
        l_bc = 0x0
        l_sp = 0xbb2ba54
        l_fp = 0xbb2ba54
#1  0x6523e424 in asCContext::Execute (this=0xbbd0fd8) at C:\mengin\src\deps\angelscript\as_context.cpp:985
No locals.
#2  0x651289b7 in _fu121___ZSt4cout (this=0xbbbc6e8, act=0xba73608, collider=0xbbbc6e8) at C:\mengin\src\core\CollisionObject.cpp:346
        r = 0
        info = 0xc14d440
#3  0x651283e9 in Irre::CollisionObject::RunCollisionDetection (this=0xbbbc6e8) at C:\mengin\src\core\CollisionObject.cpp:308
        pt = @0xb580d90
        p = 0
        manifold = 0xb580d8c
        objA = 0xbb29050
        cooA = 0xbb28ab8
        other_object = 0xbb28ab8
        objB = 0xbbbc8c0
        cooB = 0xbbbc6e8
        directionSign = 1
        j = 0
        pair = @0x8b6e270
        collisionPair = 0xbbf3b60
        i = 0
        manifoldArray = {m_allocator = {<No data fields>}, m_size = 1, m_capacity = 1, m_data = 0x8b7fc40, m_ownsMemory = true}
        pairArray = @0xbba58f4
        numPairs = 4
#4  0x651136a8 in Irre::ObjectManager::PropagateOnCollide (this=0xbb23f48, a1=0x0, co1=0x0, a2=0x0, co2=0x0) at C:\mengin\src\core\ObjectManager.cpp:446
        obj = 0xbbbc6e8
        i = {<boost::iterator<std::forward_iterator_tag, std::pair<int const, Irre::Object*>, int, std::pair<int const, Irre::Object*>*, std::pair<int const, Irre::Object*>&>> = {<boost::detail::iterator_base<std::forward_iterator_tag, std::pair<int const, Irre::Object*>, int, std::pair<int const, Irre::Object*>*, std::pair<int const, Irre::Object*>&>> = {<std::iterator<std::forward_iterator_tag, std::pair<int const, Irre::Object*>, int, std::pair<int const, Irre::Object*>*, std::pair<int const,
Irre::Object*>&>> = {<No data fields>}, <No data fields>}, <No data fields>}, base_ = {bucket_ = 0xba83b3c, node_ = 0xbbd5008}}
#5  0x65123fcf in Irre::WorldTickCallback (world=0x8b5aed0, timestep=0.00416666688) at C:\mengin\src\physics\World.cpp:478
No locals.
#6  0x651fcb9f in btDiscreteDynamicsWorld::internalSingleStepSimulation (this=0x8b5aed0, timeStep=0.00416666688)
    at C:\mengin\src\deps\bullet\BulletDynamics\Dynamics\btDiscreteDynamicsWorld.cpp:355
        __profile = {<No data fields>}
        dispatchInfo = @0x8b5aeec
#7  0x651fc9b1 in btDiscreteDynamicsWorld::stepSimulation (this=0x8b5aed0, timeStep=62, maxSubSteps=15, fixedTimeStep=0.00416666688)
    at C:\mengin\src\deps\bullet\BulletDynamics\Dynamics\btDiscreteDynamicsWorld.cpp:290
        i = 0
        clampedSimulationSteps = 15
        __profile = {<No data fields>}
        numSimulationSubSteps = 14880
#8  0x651252ab in Irre::World::Update (this=0x8b4f478, delta=46) at C:\mengin\src\physics\World.cpp:566
        elapsed = 62
        substeps = 15
        timestep = 0.0620000027
#9  0x651320a2 in Irre::Stage::Update (this=0x8aeacd0, time_delta=46) at C:\mengin\src\core\stage\StageAngel.cpp:409
No locals.
#10 0x6510eb3b in Irre::LogicThread::SingleThreadRun (this=0x8aefd50) at C:\mengin\src\core\LogicThread.cpp:86
        time_delta = 46
#11 0x651067cc in Irre::Engine::Run (this=0x4d9808) at C:\mengin\src\core\Engine.cpp:105
        tid = 0
#12 0x65106980 in Irre::Run () at C:\mengin\src\core\Engine.cpp:165
No locals.
#13 0x004013e5 in main (ac=1, av=0x4d44f0) at C:\mengin\src\runner\main.cpp:11
No locals.

More on this as I find out.


Using the CScriptHandle between C++ and Angelscript

09 October 2011 - 12:03 PM

Are the there any examples of this? I wanted to use it as a vehicle for user data for my messaging system, but the problem is that after it's gone between Angelscript to the C++ side, casting it back to toe required type in Angelscript results in a null pointer.

Here is a basic overview of the system.




#pragma once
#ifndef IR_MESSAGE_DISPATCHER_H
#define IR_MESSAGE_DISPATCHER_H

#include <set>

#include "Object.h"
#include "../script/angel/scripthandle.h"


#undef DispatchMessage

namespace Irre {


struct Telegram
{
    Telegram( double delay,
              asIScriptObject* sender,
              asIScriptObject* receiver,
              int message,
              CScriptHandle& data )
        : Sender( sender ),
          Receiver( receiver ),
          Message( message ),
          DispatchTime( delay ),
          Data( data ) 
    { 
        Sender->AddRef();
        Receiver->AddRef();
    }

    ~Telegram()
    {
        Sender->Release();
        Receiver->Release();
    }

    asIScriptObject* Sender;
    asIScriptObject* Receiver;
    int Message;
    double DispatchTime;
    CScriptHandle Data;

    bool operator<=( const Telegram& other ) { return DispatchTime <= other.DispatchTime; }
    bool operator==( const Telegram& other ) { return DispatchTime == other.DispatchTime; }
};

class MessageDispatcher
{
public:
    void TransmitMessage( double delay,
                          Object* sender,
                          Object* receiver,
                          int msg,
                          CScriptHandle& data );

    void DispatchDelayedMessages();

private:
    void Discharge(Object* receiver,const Telegram& message);

    std::set<Telegram> m_DelayedTelegrams;
};

}
#endif



#include "MessageDispatcher.h"
#include "../shared/Global.h"
#include "../script/angel/ScriptFunctions.h"
#include "Stage.h"
#include "ObjectManager.h"
#include "Engine.h"

namespace Irre {

void MessageDispatcher::TransmitMessage( double delay,
                             			Object* sender,
                             			Object* receiver,
                             			int msg,
                             			CScriptHandle& data)
{
    float current_time = IR_GetTick();
    Telegram message(0,sender->m_Core,receiver->m_Core,msg,data );

    if( delay == 0 ) Discharge( receiver, message );
}

void MessageDispatcher::Discharge( Object* receiver,const Telegram& message )
{
    receiver->ReceiveMessage( message );
}

void MessageDispatcher::DispatchDelayedMessages()
{
    // Not implemented yet.
}

}

void RegisterDispatchMessage( asIScripeEngine* e )
{
    // Registering the global function.

    r=e->RegisterGlobalFunction("void IR_DispatchMessage(double,int,int,int,ref&in)", asFUNCTION(IR_DispatchMessage), asCALL_CDECL); AS_CHECK(r);
}


/* Dummy */
void TelegramDummy( Telegram* self ) { }
void TelegramDestructor( Telegram* self ) 
{ 
    ((Telegram*)self)->~Telegram();
}


void RegisterTelegram( asIScriptEngine* e )
{

    r=e->RegisterObjectType("Telegram",sizeof(Telegram),asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CD );AS_CHECK(r);

    r=e->RegisterObjectBehaviour("Telegram",asBEHAVE_CONSTRUCT,"void f()",asFUNCTION(TelegramDummy),asCALL_CDECL_OBJLAST);AS_CHECK(r);
    r=e->RegisterObjectBehaviour("Telegram",asBEHAVE_DESTRUCT,"void f()",asFUNCTION(TelegramDestructor),asCALL_CDECL_OBJLAST);AS_CHECK(r);
    r=e->RegisterObjectProperty("Telegram","IObject@ Sender",offsetof(Telegram,Sender));
    r=e->RegisterObjectProperty("Telegram","IObject@ Receiver",offsetof(Telegram,Receiver));
    r=e->RegisterObjectProperty("Telegram","int Message",offsetof(Telegram,Message));
    r=e->RegisterObjectProperty("Telegram","double DispatchTime",offsetof(Telegram,DispatchTime));
    r=e->RegisterObjectProperty("Telegram","ref@ Data",offsetof(Telegram,Data));
}




void OnMessageReceived( const Telegram&in message )
    {
        switch( message.Message )
        {
            case TA_Messages::BODY_WITHIN_RADAR_RANGE:
            {
                TA_Body@ sensed_body = cast<TA_Body@>(message.Data); // The data is null when it gets passed to IsFriendly.
                if( sensed_body is null ) Println("The sensed body was null for whatever reason.");

                if( !IsFriendly(sensed_body) && !IsDead )
                {
                    m_SensoryMemory.SaveMemoryEntry( TA_MemoryRecord(sensed_body.TA_Mind,sensed_body.Position) );
                }
            } break;
            case TA_Messages::AGENT_ORDER_DROP_EVERYTHING:
            case TA_Messages::AGENT_ORDER_PATROL:
            case TA_Messages::AGENT_ORDER_WEAPONS_FREE:
            case TA_Messages::AGENT_ORDER_DEFEND:
            case TA_Messages::AGENT_ORDER_SEEK_AND_DESTROY:
            {
                DispatchMessage( 0,m_ThinkGoal,message.Message,message.Data );
            } break;
        }

By the way, I know for a fact that the data that gets passed to the telegram in the first place is guaranteed to not be null. And yes, I am well aware of interfaces and such, but I find messaging to be much more convenient than using interfaces for everything. I have also tried using a pointer to the CScriptHandle, but that eventually leads to either a segfault or an assertion.

Enhancement Suggestion - Lazy Primitive Initialization

05 October 2011 - 11:31 AM

This behavior of Angelscript just bit me yet again, only this time it caused Bullet to crap itself. I have a double as a member variable that determines how much thrust is applied to an entity. However, because I left this value uninitialized in the base class, at random times I received the "Overflow in AABB" error, with no way to consistently reproduce the problem. It was actually a complete fluke that I discovered the source of the issue. These sorts of problems are one of the reasons that we use scripting languages. Therefore, I would like to recommend that primitive datatypes in Angelscript be initialized with a default value of 0 to mitigate these issues.

True Variant Datatype

29 September 2011 - 08:15 AM

I mentioned in another thread that I was working on a Variant datatype and I think I am on to something. At the moment, it is extremely buggy and to be honest, I am a little embarassed by my ham-handed implementation. It is based off of a bit-stream class I found on code-project a while ago, a link to which I do not have at the moment. It has worked fairly well. The bit stream allows me to represent both primitive datatypes and strings , and then given whatever it is based off of, can run the proper conversions. Of course, any variant type will cause a hit to performance, but I think that a true variant type is a worthwile thing to have in any scripting language, as there are a multitude of uses for them.

Please bear in mind that this currently has a few things in it that are specific to my game engine, but they are mostly utility functions.

What currently works:

  • String concantenation when both vars represent strings.
  • Arithmetic operations between variants regardless whether they represent a string or a primitive.
  • All assignment operators.
What does not work:

  • Arithmetic assignment operators
  • The string constructor (for who knows what reason).
Some sample code from my test-case in my game engine.

void ConsCmd_VarTest( Console@ c, const string@[]@ args )
{
    if( args.length() < 2 ) 
    {
        c.Print( "Not enough arguments. Need at leasst two numbers. Note that they can have decimals in them.");
        return;
    }

    c.Print("Testing the 'var' datatype.");

    var arg1 = args[0],
        arg2 = args[1];
    c.Print(arg1.asString()+" + "+arg2.asString()+" = "+var(arg1+arg2).asString());
    c.Print(arg1.asString()+" - "+arg2.asString()+" = "+var(arg1-arg2).asString());
    c.Print(arg1.asString()+" * "+arg2.asString()+" = "+var(arg1*arg2).asString());
    c.Print(arg1.asString()+" / "+arg2.asString()+" = "+var(arg1/arg2).asString());

    var arg3 = arg1;

    var testconstructor( 10 );
    arg3 += var("10");
    c.Print(arg1.asString()+" += 10 -> "+arg3.asString() );
}


Retrieving Bytecode From Script Section In Module

24 September 2011 - 03:51 PM

I had already brought this up in another thread, but I thought I would make a thread for the idea on its own. We can already retrieve bytecode from script modules easy enough, but some engine designs, such as mine, require that all script be in one single module. However, the problem with this is that when it comes time to deploy, one typically wants to distribute the scripts in bytecode form, not in source form. To do this with single modules would require the distribution of redundant bytecode. My proposal is to alloy the saving of bytecode from not only entire modules, but from individual sections of these modules. In this way, if one had a bytecode file for each source file, the game's bytecode could be put back together at runtime like the C linker links together object code at compile time.

PARTNERS