Coder Social home page Coder Social logo

Comments (7)

mastercuber55 avatar mastercuber55 commented on August 21, 2024

btw Being able to call those functions directly without class will also work for me.

from wrenbind17.

matusnovak avatar matusnovak commented on August 21, 2024

Hi @mastercuber55

Unfortunately having purely global functions is not supported. However, you could do the following:

Create a dummy class on the C++ side. It does not have to define anything. You can leave it blank.

class RayLib {
};

Then register any ray lib functions. Something like this should work:

// Assuming this global function is from raylib
extern void DrawRectangle(int x, int y, int w, int h, int color);

wren::VM vm;
auto& m = vm.module("mymodule");
auto& cls = m.klass<RayLib>("RayLib"); // Dummy
cls.funcStaticExt<&DrawRectangle>("DrawRectangle");  // Here, use "funcStaticExt"

But that would force you to create an instance of RayLib class in the Wren user code. There is one trick for that! Create an instance of the RayLib in Wren and make it a global variable (has to start with an upper case letter):

m.append("var RL = RayLib.new()\n");

The m.append appends any kind of Wren code into the module you have created with vm.module("mymodule").

Then, in your Wren user code, you can do this:

import "mymodule" for RL

RL.DrawRectangle(10, 20, 100, 200, 255)

A similar concept is here: https://matusnovak.github.io/wrenbind17/tutorial/custom_types/#656-class-static-variables (section "6.5.6 Class static variables").

Would this little hack work for you?

from wrenbind17.

mastercuber55 avatar mastercuber55 commented on August 21, 2024

Hi matsunovak, thank you for writing a example for me and yes it will work for me so thank you once again.

from wrenbind17.

mastercuber55 avatar mastercuber55 commented on August 21, 2024

I'm unforunately unable to get it working, I'm getting this wrenbind17::CompileError on running my wren code

terminate called after throwing an instance of 'wrenbind17::CompileError'
  what():  Runtime error: raylib does not implement 'InitWindow(_,_,_)'.
  at: wrenbind17.wren:3

Here's the wren code

import "raylib" for rl

rl.InitWindow(640, 480, "Hello Wren")

and here is the code on c++ side

auto& Raylibm = VM.module("raylib");
	
	auto& Raylibc = Raylibm.klass<raylib>("raylib");
	Raylibc.ctor<>();
	Raylibc.funcStaticExt<&InitWindow>("InitWindow");
	Raylibm.append("var rl = raylib.new()\n");

and this is the raylib function
RLAPI void InitWindow(int width, int height, const char *title);

from wrenbind17.

matusnovak avatar matusnovak commented on August 21, 2024

Oh! My bad! I told you to create an instance but to use a static function :D I probably should not write code at midnight.

So, problem number one, the raylib does not implement is because Wren is looking for a function with 4 parameters where the first one is "this" an instance of the class and the 3 other parameters x, y, and the title. I gave you a wrong code.

Problem number two is that you can't use const char* in the function arguments. Wren is the owner of the strings, so taking a pointer out of them and using it in a C++ class is dangerous and can cause segmentation fault. Therefore I have not implemented that conversion into this library on purpose. You have to create a wrapper function that accepts std::string and calls the real RayLib function with .c_str().

Therefore, you need something like this:

// This should be the real RayLib function, for the purpose of this example
// I am just defining it here like this to print out the arguments.
static void InitWindow(int x, int y, const char* title) {
    std::cout << "InitWindow called with x: " << x << " y: " << y << " title: " << title << std::endl;
}

// A wrapper class
class Raylib {
public:
    // A function that accepts std::string instead of const char
    static void wrenInitWindow(int x, int y, const std::string& title) {
        // Call the real RayLib function with the const char* from the std::string
        // It assumes that RayLib's function InitWindow() makes a copy of the const char*
        // Otherwise there will be a segmentation fault at some point later.
        InitWindow(x, y, title.c_str());
    }
};

int main() {
    wren::VM vm;

    auto& m = vm.module("raylib");
    auto& cls = m.klass<Raylib>("RL");
    // Bind the custom function, not the real InitWindow.
    cls.funcStaticExt<&Raylib::wrenInitWindow>("InitWindow");
    
    // Sample code to run
    static const std::string code = R"(
        import "raylib" for RL

        RL.InitWindow(640, 480, "Hello Wren")
    )";

    vm.runFromSource("main", code);

    return 0;
}

Should print:

InitWindow called with x: 640 y: 480 title: Hello Wren

An alternative version, not using static functions, but creating an instance of the wrapper class.

static void InitWindow(int x, int y, const char* title) {
    std::cout << "InitWindow called with x: " << x << " y: " << y << " title: " << title << std::endl;
}

class Raylib {
public:
    void wrenInitWindow(int x, int y, const std::string& title) { // No longer static
        InitWindow(x, y, title.c_str());
    }
};

int main() {
    wren::VM vm;

    auto& m = vm.module("raylib");
    auto& cls = m.klass<Raylib>("Raylib");
    cls.ctor<>(); // Added empty constructor
    cls.func<&Raylib::wrenInitWindow>("InitWindow"); // Changed from "funcStaticExt" to "func"

    m.append("var RL = Raylib.new()\n"); // Added

    // Remains the same
    const std::string code = R"(
        import "raylib" for RL

        RL.InitWindow(640, 480, "Hello Wren")
    )";

    vm.runFromSource("main", code);

    return 0;
}

Tested on my PC, should work out of the box.

from wrenbind17.

mastercuber55 avatar mastercuber55 commented on August 21, 2024

Yea, that worked so thanks again a bunch and I hope I don't have to reopen this issue and bother you anymore.

btw I think you make a discord server for this amazing library.

from wrenbind17.

matusnovak avatar matusnovak commented on August 21, 2024

Yea, that worked so thanks again a bunch and I hope I don't have to reopen this issue and bother you anymore.

No problem. Feel free to ask for more help.

btw I think you make a discord server for this amazing library.

Good idea but I do not want to manage a Discord server :D Too much work. GitHub issues seem easier to me.

from wrenbind17.

Related Issues (15)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.