Comments (7)
btw Being able to call those functions directly without class will also work for me.
from wrenbind17.
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.
Hi matsunovak, thank you for writing a example for me and yes it will work for me so thank you once again.
from wrenbind17.
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.
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.
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.
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)
- binding operator method HOT 2
- Binding multiple constructors from C++ class HOT 1
- Base class construction in Wren script leaks destructor calls from derived class HOT 4
- Add mode without exceptions HOT 1
- CMake: Allow to skip install HOT 1
- Support std::string_view HOT 1
- Unable to assign values to binded classes which has binded class members. HOT 2
- Passing a map to C++ HOT 2
- Unable to use properties of a derived class in an object instantiated in Wren HOT 1
- Derived class returned as a base class from C++ cannot use derived methods HOT 3
- Non-copyable types cannot have a constructor HOT 3
- Binding C++ functions HOT 2
- calling method with std::list throws assertion error HOT 1
- random HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wrenbind17.