minecraftts / glfw

MIT License
7 stars 0 forks source link

Vulkan API support #1

Open ghost opened 1 year ago

ghost commented 1 year ago

I would to get Vulkan API support (surface) from GLFW. For my Vulkan API bindings.

Zxnii commented 1 year ago

I see no reason why this wouldn't be possible. I'm a bit busy right now though, so it'd probably be a while before I'm able to implement it (probably a week or two).

ghost commented 1 year ago

As it turned out, not only Vulkan API support is needed, but also BigInt, Typed Arrays, and essentially native pointers. Because my project is built mainly on the principles of low-level API. I give for you some helper code. Address needs use directly with GLFW methods.

static uint64_t GetAddress(Napi::Env env, Napi::Value const& value_) {
    bool lossless = true;
    uint64_t address = 0ull;

    if (value_.IsNull()) { /* Skip, it's null... */ } else
    if (value_.IsNumber()) {
        address = value_.As<Napi::Number>().Int64Value();
    } else
    if (value_.IsBigInt()) {
        address = value_.As<Napi::BigInt>().Uint64Value(&lossless);
    } else
    //if (value_.IsString()) {
        // Broken address, and have broken Null termination issues.
        //decltype(auto) STR = value_.As<Napi::String>().Utf8Value();
        //decltype(auto) ptr = Napi::Uint8Array::New(env, STR.size()+1);
        //memcpy(ptr.Data(), STR.c_str(), STR.size());
        //address = uint64_t(ptr.Data());
    //} else
    if (value_.IsTypedArray()) {
        decltype(auto) TA = value_.As<Napi::TypedArray>();
        decltype(auto) AB = TA.ArrayBuffer();
        address = uint64_t(AB.Data()) + TA.ByteOffset();
    } else
    if (value_.IsDataView()) {
        decltype(auto) TA = value_.As<Napi::DataView>();
        decltype(auto) AB = TA.ArrayBuffer();
        address = uint64_t(AB.Data()) + TA.ByteOffset();
    } else
    if (value_.IsArrayBuffer()) {
        decltype(auto) AB = value_.As<Napi::ArrayBuffer>();
        address = uint64_t(AB.Data());
    } else
    if (value_.IsBuffer()) {
        decltype(auto) AB = value_.As<Napi::Buffer<uint8_t>>();
        address = uint64_t(AB.Data());
    } else
    if (value_.IsExternal()) {
        decltype(auto) AB = value_.As<Napi::External<void>>();
        address = uint64_t(AB.Data());
    } else
    if (value_.IsObject()) {
        decltype(auto) OBJ = value_.As<Napi::Object>();
        if (OBJ.Has("address")) {
            decltype(auto) MTD = OBJ.Get("address");
            if (MTD.IsFunction()) {
                address = MTD.As<Napi::Function>().Call(std::vector<napi_value>{}).As<Napi::BigInt>().Uint64Value(&lossless);
            }
        }
    } else {
        Napi::TypeError::New(env, "Wrong type, needs BigInt (pointer of pointers) at ${I} argument (${param.name})").ThrowAsJavaScriptException(); return address;
    }

    return address;
}

//
template <typename T>
T getObjPtr(Napi::Env env, Napi::Value obj) {
    if (obj.IsObject() && obj.As<Napi::Object>().Has("$")) { return obj.As<Napi::Object>().Get("$").As<T>(); };
    return *(T*)GetAddress(env, obj);
}