How much C++ really improves Love?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Rick Astley
Prole
Posts: 4
Joined: Sat Mar 13, 2021 11:51 am

How much C++ really improves Love?

Post by Rick Astley »

~We're (no) strangers to C++, you know the benefits but sure don't I

After this silly introduction, I want to say hello everybody: this is my first topic ever in this forum!
It's been a year since I discovered this awesome framework, and I decided to join the community one month ago(~Feb 2021) to work on the wiki's italian translation(cosider it my way to say thanks).
But let's jump into it!

A little bit of context

Lately, I've been working hard on a Graphic User Interface library+engine for Love. I went to the point where I coded all of the basic components (e.g. AABB class) in Lua.
I was ready to move on to the implementation of the library itself, but a critical dilemma came up to my mind.
When I figured out that C and C++ could be used to integrate Lua fairly easily, I really couldn't ignore this opportunity; being the project in a early stage of development, I have no excuses for not even considering the idea.
So I decided to dig deeper in the subject... keep in mind that I'm a total noob about how C/C++ developers actually work.

Slowly descending a hell of confusion

I decided to pick the AABB class as test case, since it will be used in many ways in the library.
The first feature to accomplish a this "improvement" I tried was LuaJit's FFI. I admit that this introduction here https://luajit.org/ext_ffi.html, really catched my interest.
My first approach was to simply put the viewport properties x,y,with,height inside a C struct and let the AABB use a instance of this c object.
Well that's cool, it means that now a AABB instance uses a lot less memory but... is it really the improvement I'm looking for?
I mean, this object must be fast at computing intersections with its siblings.

Playing with ffi I noticed that it can run custom C functions, but they must be defined in a shared library so the module can load them.
Well, I grabbed my rusty knowledge about C and tried coding the entire AABB type.
With no oop it was quite a pain, but I managed to code the set of functions needed with the help of pointers.
Good, now let's wrap this into a Lua class and test it.

Love2D ingloriously crashes.

Long story short, managing memory (using malloc(), free()) inside the C given to FFI is a big nono.
At this point my frustration was already building up, but that was ok, I had to try the last option yet: writing a C++ module that could be loaded directly from require.

And now we're coming to the epilogue

Thank you for your patience, I promise this is almost it.
Here my ignorance about how a compiler works, the differences between compilers etc. made me wasted a lot of time, building up frustration and desperation.
To build the shared libraries (.so files) to use in FFI I used g++, that was fine.
Understanding how to include Lua source on the other hand, with no clear tutorials was a nightmare; the worst thing is that everybody makes it like it is the easiest thing in the world.
Finally I installed Visual Studio since I have Windows on my machine, and found out this video by this blessed man.
https://youtu.be/4l5HdmPoynw.

After failing in the attempt to make a dll with the help of Visual Studio, I decided that the best thing to do was to ask directly to the Love community to stop this unhealthy race.

At this point you probably understood my condition, so it's time for the question.

1. Is it really worthy to write a module in C++, instead of Lua in the context of Love? If so, any good suggestions on how to actually do it?

2. Was I wrong on my considerations about FFI? Is a simple change like the first one I described for AABB actually a significant improvement?

Thank you again for your attention, if you need any information in particular feel free to ask!

Code: Select all

if self.thoughts[1] == 'give you up' then
   table.remove(self.thoughts,1)
end
 
User avatar
pgimeno
Party member
Posts: 2611
Joined: Sun Oct 18, 2015 2:58 pm

Re: How much C++ really improves Love?

Post by pgimeno »

Assuming I have not been rickrolled... :D
Rick Astley wrote: Sun Apr 11, 2021 10:42 pm 1. Is it really worthy to write a module in C++, instead of Lua in the context of Love? If so, any good suggestions on how to actually do it?
Hard to say whether it's worth or not. Probably not, at least from the perspective of the multi-platform compilation and subsequent distribution. If the calls use FFI, I think they don't interrupt traces, so that's a gain, but probably small.

In general, you can't call C++ functions with FFI, unless you stick to a specific compiler and abide to its rules for identifier mangling. Identifier mangling is something that C++ compilers do, in order to create symbols that are valid for the linker, but that contain all the information about the types and return values involved in order to allow for function overloading and that kind of stuff. And there's no standard, so every compiler does it in its own way, which means that a .so or .dll created with g++ might have symbols that are not compatible with those in a .dll created with Visual Studio, therefore trying to dynamically link to them from FFI is a lost cause.

That doesn't mean that everything is lost and you have to give up on C++; it just means that you need extern "C" functions for interfacing with FFI. However, as I said, I don't recommend it. I always prefer a Lua-only solution because I don't run binaries without source, but that's me.

Rick Astley wrote: Sun Apr 11, 2021 10:42 pm 2. Was I wrong on my considerations about FFI? Is a simple change like the first one I described for AABB actually a significant improvement?
Probably not. Something like an AABB class sounds fairly easy to swap after the fact; if you run into performance problems, and profiling shows that the AABB class is the bottleneck, you can always go that route.
User avatar
Rick Astley
Prole
Posts: 4
Joined: Sat Mar 13, 2021 11:51 am

Re: How much C++ really improves Love?

Post by Rick Astley »

Thank you pgimeno, from the heart of a living rickroll. :nyu:
pgimeno wrote: Mon Apr 12, 2021 1:37 am Hard to say whether it's worth or not. Probably not, at least from the perspective of the multi-platform compilation and subsequent distribution. If the calls use FFI, I think they don't interrupt traces, so that's a gain, but probably small.
Yes, I understood why for many native libraries, like luafilesystem, have their source files distributed instead of compiled binaries.
About FFI, you confirmed what I was thinking.
pgimeno wrote: Mon Apr 12, 2021 1:37 am In general, you can't call C++ functions with FFI, unless you stick to a specific compiler and abide to its rules for identifier mangling. Identifier mangling is something that C++ compilers do, in order to create symbols that are valid for the linker, but that contain all the information about the types and return values involved in order to allow for function overloading and that kind of stuff. And there's no standard, so every compiler does it in its own way, which means that a .so or .dll created with g++ might have symbols that are not compatible with those in a .dll created with Visual Studio, therefore trying to dynamically link to them from FFI is a lost cause.
In my wandering I had the way to learn what you just wrote. I tried many solutions, but with incomplete knowledge the I never got a result.
pgimeno wrote: Mon Apr 12, 2021 1:37 am That doesn't mean that everything is lost and you have to give up on C++; it just means that you need extern "C" functions for interfacing with FFI. However, as I said, I don't recommend it. I always prefer a Lua-only solution because I don't run binaries without source, but that's me.
Thank you for your opinion, after all I'm developing my project for the community, so thoughts from users are gold to me.

I'd like to add a couple questions:

There are modules wrote in C/C++ that can be loaded simply by require(), since they implement functions that can be exposed directly to Lua.
I tried that and it's pretty easy, but I can't compile the code of the library into a dll so that Love can require it.
So my question is:


Is there any guideline to write a dll to use in Love in this way? What path should I follow?


I don't wanto to give u-... ehm... put this on hold, before I haven't tried all the possibilities.

Thank you much.

Code: Select all

if self.thoughts[1] == 'give you up' then
   table.remove(self.thoughts,1)
end
 
User avatar
pgimeno
Party member
Posts: 2611
Joined: Sun Oct 18, 2015 2:58 pm

Re: How much C++ really improves Love?

Post by pgimeno »

Rick Astley wrote: Mon Apr 12, 2021 9:05 am There are modules wrote in C/C++ that can be loaded simply by require(), since they implement functions that can be exposed directly to Lua.
I tried that and it's pretty easy, but I can't compile the code of the library into a dll so that Love can require it.
So my question is:


Is there any guideline to write a dll to use in Love in this way? What path should I follow?
First and foremost, I don't recommend to follow this route. Normal calls to Lua functions do interrupt traces in LuaJIT 2.0, and that degrades their performance a lot. In LuaJIT 2.1, the traces are not interrupted by function calls, but the JIT machinery needs to stop the trace, switch to interpreter mode, execute the function, switch back to compiled mode and finally resume the trace, which isn't very efficient.

That said, if you still want to try it (most of Löve is written like that, after all), you need to have a public luaopen_XXXX function, where XXXX is the name of your module; details are in the Lua manual under package.loaders: https://www.lua.org/manual/5.1/manual.h ... ge.loaders and you'll need to register the functions with lua_register or lua_pushcfunction or lua_pushcclosure.
User avatar
Rick Astley
Prole
Posts: 4
Joined: Sat Mar 13, 2021 11:51 am

Re: How much C++ really improves Love?

Post by Rick Astley »

Thank you for this clear explanation about LuaJIT, that's exactly what I was looking for; it will help me much. :)

In conclusion I'm going to continue on the Lua path for this project, it seems the best way for me.

I hope people looking forward to this subject in future will find this topic useful.

Code: Select all

if self.thoughts[1] == 'give you up' then
   table.remove(self.thoughts,1)
end
 
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 23 guests