-
Greetings,
I am new to SFML and am going to be using the library in a project powered by the V8 JavaScript engine. I wanted to share with the community my V8 Binding for SFML 2.0.
If you identify any major issues with the binding please let me know. You can post your issues to this thread and I will attempt to address them if they are within the scope of the project. I will release new versions as needed to address the issues reported.
Before using the binding in a project you may want to consider looking at the ISSUES.TXT file. If that doesn't scare you off then go for it. So far though, everything appears stable. The binding works on Linux and Windows.
---- Update ----
I have updated the binding to version 0.5. Version 0.5 adds some important features such as the ability to copy and delete objects. Also, the JavaScript instanceof operator now works with the classes so one can distinguish between an sf.Image and an sf.Texture without testing for specific methods.
v0.5.1. The binding project now includes a sf_v8.js file. This JavaScript file contains definitions for context sensitive help for Eclipse. You will need to "link the file" to your Eclipse JavaScript project and then Eclipse will give you tool tips when using SFML JavaScript objects. This should make it 1000 times easier to write SFML code in JavaScript. Note: Full descriptions of methods and variables are still only available using the C++ documentation.
Updated to version 0.6.0 - The binding is now in the beta stage. It is stable and supports type-checking for classes to prevent crashes. I've tested it quite a bit internally and feel it is probably good enough for production use. It does need more testing though before I am ready to say that it is finished.
The binding is available for download on GitHub:
https://github.com/StevenChristy/SFML2-V8-Binding (https://github.com/StevenChristy/SFML2-V8-Binding)
-
Accessing a static class method:
var modes = sf.VideoMode.getFullscreenModes(); // Returns an Array of VideoMode objects.
Creating new objects:
var vm = new sf.VideoMode(1024, 768);
var window = new sf.RenderWindow(vm, 'Hello World');
Accessing enumeration constants:
if ( ev.key.code = sf.Keyboard.G ) { // User pressed the letter 'G'
// do something
}
Essentially you should be able to turn C++ code into JavaScript code fairly easily with just a few syntax changes.
-
that's pretty neat actually.
so how should I look at this? you have a C++ project with V8 JS as a sandboxed scripting environment? or would one be running the V8 JS VM and all code would be in JS?
-
so how should I look at this? you have a C++ project with V8 JS as a sandboxed scripting environment? or would one be running the V8 JS VM and all code would be in JS?
Either way. For my project I am writing everything in JS. It is possible to register only certain classes in the V8 engine, although its intended use is to expose everything SFML has to offer.
You could probably do half and half where maybe your core engine is written in C++ and you draw the UI using JavaScript or you could also make it so your application supports event handlers written in JavaScript.
I am open to suggestions on how to improve it. Some things I am considering or working on for future versions:
1. Make it modular to match how SFML is already divided up.
2. Expose C++ operators as methods in JavaScript.
3. Add a copy method to clone an object from within JavaScript (Copy constructors are not supported in the current implementation.)
4. Allow parameters to be passed using a Javascript object, i.e. sprite.setPosition({x: 100, y: 50}).
The time frame for these improvements depend on what other people request. Otherwise I will implement the features as I run into problems on my project.
In a couple weeks (or months) I will release my project as open source so there will be an example of a JS game engine written in JavaScript using SFML.
-Steven
-
Version 0.4 adds support for passing parameters in a JavaScript object. For example, one could construct a vector like:
var vec = new sf.Vector2f( { y: 100, x: 50 } );
This could be used in other ways too. For example, if you already have a JS object in your code that has an x and y variable you could pass that object to construct a Vector, as any additional object properties would be ignored.
Like:
var PlayerActor = { x: 1, y: 1, name: 'Bob', otherstuff: { ... } };
var vec = new sf.Vector2f(PlayerActor);
The names of the parameters are the same as those found in the SFML 2.0 documentation except that they are always lowercase.
-
I was thinking of doing something similar but as a node extension, so I'm quite interested in your project.
After a quick scan of your project, there are some things that I think would help you to improve it:
- If you haven't already, you may check how node.js ( http://nodejs.org (http://nodejs.org) ) does things. node.js is an example of an application "on the wild" which uses V8.
- A more "formal" documentation would help. Examples which show how to interact between JavaScript and C++, as well as some sample applications showing this will be a great help for people who want to try the bindings.
- You mention that you want to support linux but are only using VS, thus I suggest you to also use the mingw compiler, making the project compile with mingw will cause less headaches when porting to linux.
Finally, I don't claim to be neither a guru nor an expert, but anyway I would like to offer my help with the linux aspect of the project.
-
Hello Rogof,
First, before I comment on your feedback, I want to thank you for taking the time to give feedback.
Regarding node.js:
My position on node.js is that it is a great platform which I know very little about and have absolutely no free time with which to learn more of. From what little I currently know, my objectives put my implementation at odds with some of the design goals of node.js. The biggest difference is that node.js emphasizes asynchronous JavaScript. My design is adherence to the SFML API design and not to make it asynchronous. So if I brush off any comments about doing things along the lines of node.js it is simply because I cannot resolve my own design goals with my understanding of node.js's design goals. Because I can't find a common ground, I disregard it completely.
Still, I am open to compatibility with the node.js code base. If there is anything that I've done with the C++ side of the wrapper that makes it incompatible with node.js I would love to know how to improve it (within the design goals that I have already set forth.) Changing the C++ wrapper code to make it more node.js friendly is not against my design goals. AFAIK though all one needs to do is write an NPM module include the wrapper code. Not really my thing, someone else can do it.. its probably a dozen lines of code.
Regarding formal documentation:
The purpose of the wrapper is to implement such a complete implementation of SFML that documentation is largely unnecessary. Some conversions need to made. For example, JavaScript has no concept of namespace or classes so both are implemented as JavaScript objects. Ideally the 'sf' namespace should be implemented as the 'sf' object and if one does that then one need only convert the C++ syntax to the appropriate JavaScript syntax. There are probably a few exceptions to do this, but for the most part everything works as expected.
var myobj = new sf.RenderWindow(...);
is equivalent to:
sf::RenderWindow *myobj = new sf::RenderWindow(...);
Any place where the C++ and JavaScript don't match up 100% is either a defect in the wrapper or a limitation that I will need to add a workaround for.
You wrote "show how to interact between JavaScript and C++." That is a good idea. I definitely hope to add some examples showing how to do clever things with the wrapper code if the project gains enough traction and people are asking for it. One thing I ask you to consider though, calling C++ from JavaScript or vice versa is not really specific to my project. My project only makes it possible to use SFML within JavaScript, nothing more or less so most documentation that I will write will focus on differences between the SFML C++ and JavaScript syntax.
That said, if you need help with C++/V8 just let me know. I am happy to help, but I am a still a complete noob with both so don't be surprised if I have no clue. :) Maybe in a few months this will have changed.
Regarding linux and mingw:
I wish I had the patience to try and compile V8 in MingW. I was thinking about trying it last night, though after a few Google searches I decided it was a waste of time. SFML would compile easily, but the V8 dev team doesn't seem interested in supporting MingW out of the box. GYP is alien to me and I refuse to learn python (hence why I made this project). So, I will probably never bother with mingw even though I would love to have it working. Contributions and suggestions enabling support for mingw compilation are welcome.
Linux is a big priority for me. Although I am a windows guy, I really love the idea of giving users the freedom to choose their OS so Linux is a must-have. I haven't had time to setup the tool chain yet. Last I tried. I ran into a snag with getting SFML v2.0 RC1 to link. Laurent linked it against versions of libraries that I could not find releases for in my Ubuntu VM... More libs to compile I guess. I am sure in a few weeks I will have some time to set it all up.
The main issues I am anticipating with Linux have to do with the overloaded casting operators. It is entirely possible though that it would actually compile, the code is massive but not very complex.
Regarding help with the Linux port:
Your assistance is appreciated and welcome. If you attach a list of any compiler errors or warnings you get, I address them ASAP (assuming I know what is wrong). Changes can be safely made to v8wrap.h/.cpp too if you want to contribute modifications using GitHub I would definitely accept the assistance. (Avoid changing the wrapper itself since those changes made will not be compatible with future versions.)
Thank you,
-Steven
-
Thank you for your quick reply.
About node:
First, I did mention that I wanted to use node, however my goal is to have JavaScript as a scripting language in my application, pretty much like you do. I choose node because it has a good environment and I have prior experience building applications with it (not much, I admit).
And although your goals does not match with node's, I still feel that something can be learned from it, for example, how node manages its modules (it's not asynchronous) or how its ObjectWrap class is used. Either way is just what I think.
About the compatibility with node, I don't know enough so can't say much (just started to fiddle with when I found your project).
Also, I forgot to include it in the other post, but the v8-juice project (http://code.google.com/p/v8-juice/ (http://code.google.com/p/v8-juice/)) can be helpful too.
About the documentation:
I understand your position, in that regard I suggest to simply link to the sfml documentation and point the differences whenever is necessary. Anyway, code examples are always nice to have.
About the port:
I have attached some patches and the compiler error log, eventually I will setup github.
The v8wrap-gcc.patch fixes:
- Header Windows.h not found, in linux and mingw.
- `invalid initialization of non-const reference of type 'v8::Local<v8::Value>&' from an rvalue of type 'v8::Local<v8::Value>'` (lines 82 and 126).
The error log (http://pastebin.com/8vhzAdyR (http://pastebin.com/8vhzAdyR)) is quite long, but most of the errors in sf_v8.cpp can be avoided simply by adding spaces inside the angle brackets, ie.
CastToCPP< ::sf::InputStream* >
CastToCPP< ::sf::Vector2<float> >
instead of
CastToCPP<::sf::InputStream*>
CastToCPP<::sf::Vector2<float>>
This is because expressions like `<:` and `>>` are ambiguous to gcc.
Note: as an extra I've added a patch that formats the readme using GFM + fix a typo.
[attachment deleted by admin]
-
This is because expressions like `<:` and `>>` are ambiguous to gcc.
The old C++03 standard has >> and << as ambiguous and required spaces. The C++11 standard fixed this, which can be enabled in gcc. The nuwen build of the latest version of gcc at least uses the C++11 support by default now, not sure if that's becoming a standard gcc feature for the linux builds post 4.6 too.
-
The builds of gcc I have (v4.7.1 linux, v4.7.0 mingw) uses C++03 as default, and even compiling with C++11 the `<:` are still a problem, I get:
error: '<::' cannot begin a template-argument list
By the way, first time I heard of the nuwen build.
-
Rogof,
Your changes have been applied. The latest version adds spaces to prevent the <:: issue. I was a little concerned about some of the warnings related to the casting function overloads... Hopefully they were caused by the spacing issue, but I am not certain.
I have setup a wiki on the github page. I will try and make a few entries with every major version release.
-Steven
-
The builds of gcc I have (v4.7.1 linux, v4.7.0 mingw) uses C++03 as default, and even compiling with C++11 the `<:` are still a problem, I get:
error: '<::' cannot begin a template-argument list
That's because <: is an alternative token for [, and [: obviously cannot begin a template parameter list.
-
Here is a complete explanation for people who don't know about this C++ stuff that was used when dinosaurs were still on earth:
http://en.wikipedia.org/wiki/Digraphs_and_trigraphs
-
Thank you all for the information.
That's because <: is an alternative token for [, and [: obviously cannot begin a template parameter list.
Yes, thankfully gcc output also explains it:
...
note: '<:' is an alternate spelling for '['. Insert whitespace between '<' and '::'
...
Here is a complete explanation for people who don't know about this C++ stuff that was used when dinosaurs were still on earth:
http://en.wikipedia.org/wiki/Digraphs_and_trigraphs
Sadly, when I was born there weren't any dinosaurs around... so I guess is normal that I don't know such stuff XD.
Actually, after reading the article, I (faintly) remember seeing something about trigraphs (but not digraphs) in my C class some years ago.
I've added two more patches, one fixes the HWND__ reference in linux + a typo with one the `AutoCastToCPP` overloaded function name, and the other fixes a formatting issue in the README file introduced with my "bonus" patch.
The new error log is here: http://pastebin.com/C2RSx5L2 (http://pastebin.com/C2RSx5L2)
[attachment deleted by admin]
-
Hello Rogof,
The function that your patch adds a WIN32 ifdef around is an artifact. I'm going to remove it since it is not being used at all. It is not even declared in the header.
The error log is very interesting.. It confirms what I was most concerned about. GCC is not nearly as good with resolving overloads as VC++ and will need some help.. What that help is I am not sure just by looking at the log. From what I can tell it cannot match the class specific AutoCastToCPP functions. For example, the first error:
v8wrap.h:274:2: error: no matching function for call to 'AutoCastToCPP(v8::Handle<v8::Value>&, sf::InputStream*&)'
Should match:
sf_v8.h (1962): inline void AutoCastToCPP(v8::Handle<v8::Value> Value, ::sf::InputStream *&CPP);
But it doesn't seem to even try. The list of matches it tried was limited to those in v8wrap.h. It might be because the inline added to the autocasts in the sf_v8.h. The ones in v8wrap are not inline.
Would you try removing all "inline " from the sf_v8.h./.cpp file and recompiling and let me know if works?
Thank you,
-Steven
-
On second thought Rogof, don't waste time on this. I just realized I should be able to fix these issues without a complete toolchain.. I just need to be able to compile not link. I'll go work on it.
-Steven
-
Hello Rogof,
I found the problem. Apparently GCC is sensitive to the order of overloaded functions. I reorganized the code to make it happy and it now compiles.
Let me know if you find any bugs.
-Steven
-
Yes, it builds with mingw now, however apart from the v8 and the sfml libs, it needs to be linked against winmm and ws2_32, I don't know if this is also true for msvc though.
I think a 32bit linux binary can be compiled without problems, but I can't check it right now since I have a 64bit installation and compiling 32bit binaries is a pain (need to compile the 32bit libraries first).
A 64bit binary can't be compiled yet since both gcc and clang complains about ambiguous overloaded functions.
I will report more about the linux builds later since right now is night and don't have much caffeine left.
-
I confirmed it, 32bit linux binaries can build without problems.
The error log is longer of what pastebin allows me to paste, so should I email it to you?
-
Hello Rogof,
Is the error log for the 64-bit Linux? I am downloading a 64-bit Linux iso now so hopefully can do a few test compiles and figure out what is incompatible. I am committed to getting this working on Linux even if I have to redesign it... Though I hope it is not necessary.
Also, I've added a few pages to the GitHub wiki and will try and work on documentation a bit more before the next minor release.
-Steven
-
Yes, the bindings build in linux 32bit but not in linux 64bit.
-
Hello Rogof,
The binding should compile on 64-bit Linux now.
-Steven
-
Indeed, no issues found this time, but then I've only tested it with a hello world project.
By the way, you can add mingw to the windows supported platforms since it does compiles in it (and I'm able to test it to some extend). Also, the bindings compile with clang, so you might want to include it.
You might want to specify the versions which are reported to work. In my case is gcc 4.7 and clang 3.1.
-
I've posted a new update to the binding. The binding is getting really close to being feature complete. The next project I am working on is a fully moddable JavaScript game engine using SFML. It will be open source, but it is not yet even close to being ready for the first release.
-
Rogof I am interested to hear how you managed to get V8 built on mingw. I have tried before but the new v8 build system doesn't seem to support it. I tried a hack someone suggested for the old build system but it would not build either.
Any chance of a compiled version of this project being available? would love to test it but I am just a bit buisy to be trying to compile and link things.
-
Hello greeniekin,
What you would need is my GitHub project JSGameClient. It will be a few weeks before it is supports most of the core feature set but I could get you some windows binaries to play with. You should be able to build it for Visual Studio using CMake.
Regarding v8 libs for mingw, you may be able to obtain them indirectly from building JSGameClient or the project it was derived from HammerJS (https://github.com/hatsuseno/hammerjs). (Static libs of a slightly older version v8 are created as part of these two project's build process.)
-Steven
-
The binding has been updated to version 0.5.1. I've added a JavaScript file called sf_v8.js which when linked to your Eclipse JavaScript project can give you context sensitive help for the SFML JavaScript classes.
-
Hello greeniekin
This are the instructions I followed to build an (slightly) outdated version of the library (v3.9.9).
First you need to have:
- A working mingw gcc compiler
- A working scons installation
- An svn client
Then get the source code using the svn client from this url: http://v8.googlecode.com/svn/tags/3.9.9
For this version, you need to comment, or remove the line 888 of the file 'src/platform-win32.cc':
void* address = 0;
otherwise the compiler will complain about an unused variable and stop the compilation.
Once you edited the code, open a console in the directory where the source code is and issue this command:
scons mode=release library=static arch=ia32 os=win32
This should build a static library 'libv8.a'.
I know this are a somewhat vague instructions, so ask me if you don't understand something or need more details.
-
Hi
An `#include <cstring>` is missing from the v8wrap.h header in the latest version (v0.6.0 according to the changelog). Without it, gcc complains about the missing declarations of ‘strlen` and `strcmp`.
-
Thanks Rogof, I'll get it updated. I'll have to remember to test with Linux.. I tested with MinGW but didn't encounter the problem. Those functions must be included by including windows.h. I'll make sure to start testing it with Linux again.
Have you had any luck using the binding with node?
-
I tested with MinGW but didn't encounter the problem.
mingw is very permissive. do you use options ? you should use some like :
-Wall -Wextra -Wwrite-strings -Wstrict-prototypes
and you can try the "paranoiac" mode (it can trigger errors/warning in the standard headers) :
-ansi -O2 -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Werror-implicit-function-declaration -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings -Wconversion -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wunreachable-code
-
I have successfully build a Node Addon whit your bindings. However I'm not using the `sf::Init` but the individual `InitP*` functions.
I'm doing this because:
- The `sf::Init` returns an already constructed object, however node modules are expected to set the properties to a given object, see http://nodejs.org/api/addons.html (http://nodejs.org/api/addons.html)
- I only need a subset of the functionality provided with sfml, by using the individual init functions I only include what I need.
Btw, here is a list of some of the gcc invocation flags and their descriptions http://gcc.gnu.org/onlinedocs/gcc-4.6.3/cpp/Invocation.html (http://gcc.gnu.org/onlinedocs/gcc-4.6.3/cpp/Invocation.html)
-
I have successfully build a Node Addon whit your bindings. However I'm not using the `sf::Init` but the individual `InitP*` functions.
Yes, that makes sense. You don't need any of the networking code as node.js already has it all.
-
Yes, that makes sense. You don't need any of the networking code as node.js already has it all.
About that, I would like a more "decoupled" bindings, I still have to link the network library even if I don't use it.
EDIT: I have disabled the bindings for the classes listed here: http://www.sfml-dev.org/documentation/2.0/group__network.php (http://www.sfml-dev.org/documentation/2.0/group__network.php). Does something else depends on the network library?
-
Regarding node.js, wouldn't something like this work?
void Init( v8::Handle<v8::Object> target ) {
target->SetPrototype(sf_v8::sf::Init());
}
-
About that, I would like a more "decoupled" bindings, I still have to link the network library even if I don't use it.
The issue is that the linker needs it because the compiler said the linker needs it. If you remove #include <SFML/Network.hpp> and delete all the classes that need stuff declared there then your linker problems would go away..
If you would like I can wrap all the network stuff with #ifndef NO_SFML_NETWORK so that you can exclude it through a define.
-Steven
-
Regarding node.js, wouldn't something like this work?
void Init( v8::Handle<v8::Object> target ) {
target->SetPrototype(sf_v8::sf::Init());
}
That is my current solution (but using the individual init functions).
If you would like I can wrap all the network stuff with #ifndef NO_SFML_NETWORK so that you can exclude it through a define.
That would be good.
-
Helllo Rogof,
I've updated the binding to version 0.6.2. Now when you add -DNO_SFML_NETWORK the network library will not be used.
-Steven