Jump to content
  • Advertisement
Sign in to follow this  
Chisser98

`asCContext::CallScriptFunction` called with null

Recommended Posts

Hello,

I have run into a bit of an issue that I uncovered when trying to import a shared interface into another module.

More specifically, when I attempt to import my shared interface, I am getting an Access violation error on line 1748 of as_context.cpp. The function is `asCContext::CallScriptFunction`, and it looks like the parameter `asCScriptFunction *func` is null.

The interesting thing is that if I remove the import of the shared interface into the module, the code works fine. I am using this shared interface in my main module, and have not yet started using it in my other modules.

The code that I am building my shared module with looks like this:

external shared interface IPlayer;

The IPlayer code looks like this:

#include "IModel.as"

shared interface IPlayer : IKeyboardEventListener, IMouseMotionEventListener, IMouseButtonEventListener, IMouseWheelEventListener, IModel
{
    array<Entity> selectedUnits() const;
    void setSelectedUnits(const array<Entity>& in units);

    bool owner(const Entity entity) const;
    bool owner(const IGameObject@ gameObject) const;

    uint32 totalCredits() const;
    uint32 totalPopulation() const;
    uint32 totalFood() const;
    uint32 totalMinerals() const;

    uint32 numUnits() const;
    uint32 numBuildings() const;

    uint32 id() const;
    const string& name() const;

    void placeBuilding(Entity entity);
}

mixin class PlayerMixin
{
    protected uint32 totalCredits_ = 0;
    protected uint32 totalPopulation_ = 0;
    protected uint32 totalFood_ = 0;
    protected uint32 totalMinerals_ = 0;

    protected uint32 id_ = 0;
    protected string name_;

    bool owner(const Entity entity) const
    {
        const auto scriptObjectComponent = entity.componentScriptObjectComponent();

        if (bool(scriptObjectComponent) && scriptObjectComponent.get().scriptObjectHandle)
        {
            const auto gameObject = cast<IGameObject>(scriptObjectComponent.get().scriptObjectHandle.get());

            if (gameObject !is null) return owner(gameObject);
        }

        return false;
    }

    bool owner(const IGameObject@ gameObject) const
    {
        auto unit = cast<IUnit>(gameObject);
        if (unit !is null)
        {
            return unit.owner() == @this;
        }
        else
        {
            auto building = cast<IBuilding>(gameObject);
            if (building !is null) return building.owner() == @this;
        }

        return false;
    }

    uint32 totalCredits() const
    {
        return totalCredits_;
    }

    uint32 totalPopulation() const
    {
        return totalPopulation_;
    }

    uint32 totalFood() const
    {
        return totalFood_;
    }

    uint32 totalMinerals() const
    {
        return totalMinerals_;
    }

    uint32 id() const
    {
        return id_;
    }

    const string& name() const
    {
        return name_;
    }
}


IModel looks like this:

#include "IChangeListener.as"

shared interface IModel
{
    void tick(const float delta);
    void addChangeListener(IChangeListener@ changeListener);
    void removeChangeListener(IChangeListener@ changeListener);
}

mixin class ModelMixin
{
    private array<IChangeListener@> changeListeners_;

    void tick(const float delta)
    {
    }

    void addChangeListener(IChangeListener@ changeListener)
    {
        println("adding change listener");
        changeListeners_.push_back(changeListener);
    }

    void removeChangeListener(IChangeListener@ changeListener)
    {
        for (uint i=0; i < changeListeners_.size(); i++)
        {
            if (@changeListeners_[i] == @changeListener)
            {
                changeListeners_.removeAt(i);
                break;
            }
        }
    }

    protected void updateChangeListeners()
    {
        for (uint i=0; i < changeListeners_.size(); i++)
        {
            changeListeners_[i].update();
        }
    }
}

 

IChangeListener looks like this:

shared interface IChangeListener
{
    void update();
}

 

Another way I have found to fix the issue is to make the IPlayer interface not inherit from IModel, and instead copy the definitions from IModel directly into IPlayer.

I have been able to reproduce this in version 2.32.0, as well as the latest from SVN.

Share this post


Link to post
Share on other sites
Advertisement

Hello,

I have been able to reproduce this in a minimal code example. If I build module one with the following code:

shared interface Interface1
{
    void test();
}

shared interface Interface2 : Interface1
{
}

class Object : Interface2
{
    void test()
    {
    }
}

void main()
{
    Object@ object = Object();
    object.test();
}

And then build module two with the following code:

external shared interface Interface2;

This triggers the following assertion: Assertion failed: func->objectType == intfType, file c:\users\jarrett\projects\angelscript\sdk\angelscript\source\as_builder.cpp, line 2754

This is with the latest code from SVN.

Edited by Chisser98

Share this post


Link to post
Share on other sites

Thanks for the detailed report and for finding the minimal code to reproduce the problem.

I'll investigate and have this fixed as soon as possible.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!