How to get dmScript::HContext from within native extension?

How I can get dmScript::HContext in extension?
I am trying this:

#include <dmsdk/gamesys/script.h>
#include <dmsdk/resource/resource.h>
#include <dmsdk/sdk.h>
...
dmScript::HContext context = dmScript::GetScriptContext(L);
...

and get:

... no member named 'GetScriptContext' in namespace 'dmScript'
    dmScript::HContext context = dmScript::GetScriptContext(L);
                                 ~~~~~~~~~~^

Our current recommendation for the Lua context, is to save it when you initialize the extension, in the init function.

However, since you asked about the dmScript::HScript, the extension context doesn’t (currently) have access to that context. It might be a good addition.

(E.g. we have it for the component type api)

May I ask what you want to use it for?

1 Like

I want to reimplement sys.load_resource in an extension.
I am currently loading a custom resource in two steps:

local data = sys.load_resource ("/ ...")
extension.load_from_mem (data)

and I want to combine this in just one extension function call.

As a temporary alternative, the following snippet calls sys.load_resource from C++:


#include <cassert>
#include <cstdlib>
#include <cstring>

/**
* Usage:
*      size_t buf_len;
*      unsigned char* buf = LoadResource(L, "/path/to/resource.bin", &buf_len);
*      // do something
*      free(buf);
*/
static unsigned char* LoadResource(lua_State* L, const char* res_name, size_t* result_len)
{
    int top = lua_gettop(L);

    lua_getfield(L, LUA_ENVIRONINDEX, "sys");
    lua_pushliteral(L, "load_resource");
    lua_gettable(L, -2);
    lua_remove(L, -2);
    lua_pushstring(L, res_name);
    lua_call(L, 1, 2);

    assert(top + 2 == lua_gettop(L));
    assert(lua_isnil(L, -1));

    // lua_tolstring returns a fully aligned pointer to a string inside the 
    // Lua state. This string always has a zero ('\0') after its last character
    // (as in C), but can contain other zeros in its body. Because Lua has
    // garbage collection, there is no guarantee that the pointer returned by
    // lua_tolstring will be valid after the corresponding value is removed
    // from the stack.
    const char* buf = lua_tolstring(L, -2, result_len);
    lua_pop(L, 2);

    unsigned char* result = (unsigned char*) malloc(*result_len);
    memcpy(result, buf, *result_len);

    return result;
}

Are you also doing this in your code @aglitchman ? It might be an indication that we should expose a dmResource::LoadResource() function.

2 Likes

Yes! I was doing that to load MagicaVoxel data in this project from custom resources.

I can’t remember the reason, but later I changed the code to use resource.load() to load all data as Buffer from resources…

#define CHECK_BUF_OK(_call) \
    { \
        dmBuffer::Result r = _call; \
        if (r != dmBuffer::RESULT_OK) \
        { \
            dmLogError("Can't create buffer or get stream: %d, line %d", r, __LINE__); \
            DbgBreak(); \
        } \
    }

const unsigned char* LoadResourceAsBuffer(lua_State* L, const char* res_name, unsigned int* buf_size)
{
    lua_getfield(L, LUA_ENVIRONINDEX, "resource");
    lua_pushliteral(L, "load");
    lua_gettable(L, -2);
    lua_remove(L, -2);
    lua_pushstring(L, res_name);
    lua_call(L, 1, 1);

    dmScript::LuaHBuffer* buffer = dmScript::CheckBuffer(L, -1);
    dmBuffer::HBuffer hbuffer    = UnpackLuaBuffer(buffer);

    lua_pop(L, 1);

    unsigned char* buf_data = 0;
    CHECK_BUF_OK(dmBuffer::GetStream(hbuffer, dmHashString64("data"), (void**)&buf_data, buf_size, NULL, NULL));

    return buf_data;
}

1 Like

You dont have to saw this skrib library licence
Is a dash file dont touch

What?

2 Likes