int NativeDelegate::__op_assignment(lua_State *L)
{
    NativeDelegate *delegate = (NativeDelegate *)lualoom_getnativepointer(L, 1,
                                                                          true, "system.NativeDelegate");

    if (!delegate)
    {
        LSError("Unable to get native delegate on += operator");
    }

    // set the VM, and recreate callbacks table
    delegate->setVM(L, true);

    delegate->getCallbacks(L);

    if (!lua_istable(L, -1))
    {
        LSError("Bad native delegates table");
    }

    // clear current callbacks
    for (int i = 0; i < delegate->_callbackCount; i++)
    {
        lua_pushnumber(L, (double)i);
        lua_pushnil(L);
        lua_settable(L, -3);
    }

    // reset
    delegate->_callbackCount = 0;

    if (lua_isnil(L, 2))
    {
        return 0;
    }

    if (!lua_isfunction(L, 2) && !lua_iscfunction(L, 2))
    {
        LSError("Unknown type on NativeDelegate assignment operator");
    }

    // add the lua function or cfunction to our delegate's callback table
    lua_pushnumber(L, (double)0);
    lua_pushvalue(L, 2);
    lua_settable(L, -3);
    lua_pop(L, 1);
    // pop __lscallbacks

    delegate->_callbackCount++;

    return 0;
}
Beispiel #2
0
int Assembly::loadBytes(lua_State *L) {

    utByteArray *bytes = static_cast<utByteArray*>(lualoom_getnativepointer(L, 1, false, "system.ByteArray"));
    
    Assembly *assembly = LSLuaState::getExecutingVM(L)->loadExecutableAssemblyBinary(static_cast<const char*>(bytes->getDataPtr()), bytes->getSize());

    lmAssert(assembly, "Error loading assembly bytes");

	lualoom_pushnative(L, assembly);

	assembly->freeByteCode();

    return 1;
}
int NativeDelegate::__op_plusassignment(lua_State *L)
{
    NativeDelegate *delegate = (NativeDelegate *)lualoom_getnativepointer(L, 1,
                                                                          "system.NativeDelegate");

    if (!delegate)
    {
        LSError("Unable to get native delegate on += operator");
    }

    delegate->setVM(L);

    delegate->getCallbacks(L);

    int tidx = lua_gettop(L);

    if (!lua_istable(L, -1))
    {
        LSError("Bad native delegates table");
    }

    if (lua_isfunction(L, 2) || lua_iscfunction(L, 2))
    {
        // check if we already added this callback
        for (int i = 0; i < delegate->_callbackCount; i++)
        {
            lua_rawgeti(L, tidx, i);
            if (lua_equal(L, 2, -1))
            {
                lua_pop(L, 1);
                return 0; // already added
            }
            lua_pop(L, 1);
        }

        // add the lua function or cfunction to our delegate's callback table
        lua_pushnumber(L, (double)delegate->_callbackCount++);
        lua_pushvalue(L, 2);
        lua_settable(L, -3);
        lua_pop(L, 1);
        // pop __lscallbacks
    }
    else
    {
        LSError("Unknown type on NativeDelegate += operator");
    }

    return 0;
}
int NativeDelegate::__op_minusassignment(lua_State *L)
{
    NativeDelegate *delegate = (NativeDelegate *)lualoom_getnativepointer(L, 1,
                                                                          "system.NativeDelegate");

    if (!delegate)
    {
        LSError("Unable to get native delegate on += operator");
    }

    if (!delegate->_callbackCount)
    {
        return 0;
    }

    delegate->setVM(L);

    delegate->getCallbacks(L);

    int tidx = lua_gettop(L);

    if (!lua_istable(L, tidx))
    {
        LSError("Bad native delegates table");
    }

    if (lua_isfunction(L, 2) || lua_iscfunction(L, 2))
    {
        int idx = -1;
        for (int i = 0; i < delegate->_callbackCount; i++)
        {
            lua_rawgeti(L, tidx, i);
            if (lua_equal(L, 2, -1))
            {
                idx = i;
                lua_pop(L, 1);
                break;
            }
            lua_pop(L, 1);
        }


        // this function was never added in the first place
        if (idx == -1)
        {
            return 0;
        }

        // shift the other delegates down
        lua_pushnumber(L, (double)idx);
        lua_pushnil(L);
        lua_settable(L, tidx);

        int ntable = 0;
        if (delegate->_callbackCount > 1)
        {
            // temp table
            lua_newtable(L);
            ntable = lua_gettop(L);

            int c = 0;
            for (int nidx = 0; nidx < delegate->_callbackCount; nidx++)
            {
                lua_pushnumber(L, (double)nidx);
                lua_gettable(L, tidx);
                if (lua_isnil(L, -1))
                {
                    lua_pop(L, 1);
                    continue;
                }

                lua_pushnumber(L, (double)c);
                lua_pushvalue(L, -2);
                lua_settable(L, ntable);
                // pop lua_function
                lua_pop(L, 1);
                c++;
            }
        }

        // clear it
        delegate->_callbackCount--;

        // and copy from new temp table
        for (int nidx = 0; nidx < delegate->_callbackCount; nidx++)
        {
            lua_pushnumber(L, (double)nidx);
            lua_pushnumber(L, (double)nidx);
            lua_gettable(L, ntable);
            lua_settable(L, tidx);
        }
    }
    else
    {
        LSError("Unknown type on NativeDelegate -= operator");
    }

    return 0;
}
void DisplayObjectContainer::renderChildren(lua_State *L)
{
    if (!visible)
    {
        return;
    }

    // containers can set a new view to render into, but we must restore the
    // current view after, so take a snapshot
    int viewRestore = GFX::Graphics::getView();

    // set the current view we will be rendering into.
    if (viewRestore != _view)
    {
        GFX::Graphics::setView(_view);
    }

    renderState.alpha          = parent ? parent->renderState.alpha * alpha : alpha;
    renderState.cachedClipRect = parent ? parent->renderState.cachedClipRect : (unsigned short)-1;

    int docidx = lua_gettop(L);

    lua_rawgeti(L, docidx, (int)childrenOrdinal);

    lua_rawgeti(L, -1, LSINDEXVECTOR);
    int childrenVectorIdx = lua_gettop(L);

    int numChildren = lsr_vector_get_length(L, -2);


    if (_depthSort && ((int)sSortBucket.size() < numChildren))
    {
        sSortBucket.resize(numChildren);
    }

    // Is there a cliprect? If so, set it.
    if ((clipX != 0) || (clipY != 0) || (clipWidth != 0) || (clipHeight != 0))
    {
        GFX::QuadRenderer::submit();

        Matrix        res;
        DisplayObject *stage = this;
        while (stage->parent)
        {
            stage = stage->parent;
        }

        getTargetTransformationMatrix(NULL, &res);

        int x1 = (int) ((float)clipX * res.a + res.tx) ;
        int y1 = (int) ((float)clipY * res.d + res.ty);
        int x2 = (int) ((float)clipWidth * res.a);
        int y2 = (int) ((float)clipHeight * res.d);

        renderState.cachedClipRect = GFX::Graphics::setClipRect(x1, y1, x2, y2);
    }
    else
    {
        GFX::Graphics::setClipRect(renderState.cachedClipRect);
    }

    for (int i = 0; i < numChildren; i++)
    {
        lua_rawgeti(L, childrenVectorIdx, i);

        DisplayObject *dobj = (DisplayObject *)lualoom_getnativepointer(L, -1);

        lua_rawgeti(L, -1, LSINDEXTYPE);
        dobj->type = (Type *)lua_topointer(L, -1);
        lua_pop(L, 1);

        dobj->validate(L, lua_gettop(L));

        if (!_depthSort)
        {
            renderType(L, dobj->type, dobj);
        }
        else
        {
            sSortBucket[i].index         = i;
            sSortBucket[i].displayObject = dobj;
        }

        // pop instance
        lua_pop(L, 1);
    }

    if (_depthSort)
    {
        qsort(sSortBucket.ptr(), numChildren, sizeof(DisplayObjectSort), DisplayObjectSortFunction);

        for (int i = 0; i < numChildren; i++)
        {
            DisplayObjectSort *ds = &sSortBucket[i];

            lua_rawgeti(L, childrenVectorIdx, ds->index);

            renderType(L, ds->displayObject->type, ds->displayObject);

            // pop instance
            lua_pop(L, 1);
        }
    }

    lua_settop(L, docidx);

    // Restore clip state.
    if ((clipX != 0) || (clipY != 0) || (clipWidth != 0) || (clipHeight != 0))
    {
        GFX::QuadRenderer::submit();
        GFX::Graphics::clearClipRect();
    }

    // restore view
    if (viewRestore != _view)
    {
        GFX::Graphics::setView(viewRestore);
    }
}
Beispiel #6
0
void DisplayObject::render(lua_State *L) {
    // Disable reentrancy for this function (read: don't cache to texture while caching to a texture)
    if (cacheAsBitmapInProgress) return;

    // Clear and free the cached image if the conditions apply
    if ((!cacheAsBitmap || !cacheAsBitmapValid) && cachedImage != NULL) {
        Quad* quad = static_cast<Quad*>(cachedImage);

        lmAssert(quad != NULL, "Cached image is invalid");

        GFX::Texture::dispose(quad->getNativeTextureID());
        quad->setNativeTextureID(-1);

        lmDelete(NULL, quad);
        cachedImage = NULL;
        cacheAsBitmapValid = false;
    }

    // Cache the contents into an image if the conditions apply
    if (cacheAsBitmap && !cacheAsBitmapValid && cachedImage == NULL) {
        cacheAsBitmapInProgress = true;
        
        // Used for displaying the texture
        Quad* quad = lmNew(NULL) Quad();
        
        // Setup for getmember
        lualoom_pushnative<DisplayObject>(L, this);
        
        // Push function and arguments
        lualoom_getmember(L, -1, "getBounds");
        lualoom_pushnative<DisplayObject>(L, this);
        lua_pushnil(L);
        // Call getBounds
        lua_call(L, 2, 1);
        
        // Returned result
        Loom2D::Rectangle *bounds = (Loom2D::Rectangle*) lualoom_getnativepointer(L, -1);
        cacheAsBitmapOffsetX = bounds->x;
        cacheAsBitmapOffsetY = bounds->y;
        lmscalar fracWidth = bounds->width;
        lmscalar fracHeight = bounds->height;

        // pop bounds Rectangle and the DisplayObject at the top
        lua_pop(L, 1+1);

        if (cacheApplyScale)
        {
            fracWidth *= scaleX;
            fracHeight *= scaleY;
        }

        // Convert to integers for the following math
        int texWidthI = static_cast<int>(ceil(fracWidth));
        int texHeightI = static_cast<int>(ceil(fracHeight));

        // Calculate power of 2 sizes
        if (cacheUseTexturesPot)
        {
            _UT_UTHASHTABLE_POW2(texWidthI);
            _UT_UTHASHTABLE_POW2(texHeightI);
        }

        // Calculate the resulting scale (as a consequence of pow2 sizes)
        // Used for 'trans' matrix
        lmscalar calcScaleX = texWidthI / bounds->width;
        lmscalar calcScaleY = texHeightI / bounds->height;

        // Setup texture
        TextureInfo *tinfo = Texture::initEmptyTexture(texWidthI, texHeightI);
        Texture::clear(tinfo->id, 0x000000, 0);
        tinfo->smoothing = TEXTUREINFO_SMOOTHING_BILINEAR;
        tinfo->wrapU = TEXTUREINFO_WRAP_CLAMP;
        tinfo->wrapV = TEXTUREINFO_WRAP_CLAMP;
        TextureID id = tinfo->id;

        // Setup quad for rendering the texture
        quad->setNativeTextureID(id);
        
        VertexPosColorTex* qv;

        qv = &quad->quadVertices[0];  qv->x =                    0;  qv->y =                     0;  qv->z = 0; qv->abgr = 0xFFFFFFFF; qv->u = 0; qv->v = 0;
        qv = &quad->quadVertices[1];  qv->x = (float)bounds->width;  qv->y =                     0;  qv->z = 0; qv->abgr = 0xFFFFFFFF; qv->u = 1; qv->v = 0;
        qv = &quad->quadVertices[2];  qv->x =                    0;  qv->y = (float)bounds->height;  qv->z = 0; qv->abgr = 0xFFFFFFFF; qv->u = 0; qv->v = 1;
        qv = &quad->quadVertices[3];  qv->x = (float)bounds->width;  qv->y = (float)bounds->height;  qv->z = 0; qv->abgr = 0xFFFFFFFF; qv->u = 1; qv->v = 1;
        quad->setNativeVertexDataInvalid(false);

        lmAssert(Texture::getRenderTarget() == -1, "Unsupported render target state: %d", Texture::getRenderTarget());

        // Set render target to texture
        Texture::setRenderTarget(id);
        
        // Shift the contents down and to the right so that the elements extending
        // past the left and top edges don't get cut off, ignore other existing transforms
        Matrix trans;
        trans.translate(-cacheAsBitmapOffsetX, -cacheAsBitmapOffsetY);

        trans.scale(calcScaleX, calcScaleY);

        // Setup for Graphics::render
        lualoom_pushnative<DisplayObject>(L, this);
        lualoom_pushnative<Matrix>(L, &trans);
        lua_pushnumber(L, 1);

        // Render the contents into the texture
        Graphics::render(L);

        // Pop previous arguments
        lua_pop(L, 3);

        // Restore render target
        Texture::setRenderTarget(-1);

        // Set valid cached state
        cachedImage = quad;
        cacheAsBitmapValid = true;
        cacheAsBitmapInProgress = false;
    }
}