Saturday, April 18, 2015

Unreal Engine4 - CPython Plugin


Rusthon has special syntax for directly using PyObject's from the CPython CAPI. The -> operator is used on PyObject's, and is transpiled into: PyObject_GetAttrString(ob,name), for more info see this wiki page. This allows you to directly manage calling CPython functions, cast and move data back and forth from C++ to the CPython interpreter. This makes using complex libraries simple and safer, you do not need to depend on complex wrapper generators, or depend on C++ reflection to dynamically bind CPython to C++.

Unreal has a C++ reflection system, and this can be used to generate bindings to a scripting language. Unreal users want scripting support, see this thread, and this one asking about CPython in Unreal.

Scripting is great when you have a command-prompt and can type code at runtime, or write quick scripts and simply run them. Scripting fails when you need to do something complex and use multiple threads, for this you need C++. Rusthon allows you to write in a Python-like language and create fast glue code that bridges CPython together with any other C++ library, no reflection or generated bindings required.

This example: unreal_cpython.md shows you how to connect CPython2.7 with Unreal. The example contains no handwritten C++, instead the code is transpiled to C++ at compile time. The embedded Python script is also inlined into the final binary.

Friday, April 17, 2015

C++ Backend Part3


Calling into C++ from another language normally requires an FFI and writing extra broiler plate code and having to worry about garbage collection and threading issues. Just take a look at how fucked up interfacing D is with C++. Don't miss the bottom of that doc on C++ Templates, from the doc: "D templates have little in common with C++ templates, and it is very unlikely that any sort of reasonable method could be found to express C++ templates in a link-compatible way with D. This means that the C++ STL, and C++ Boost, likely will never be accessible from D." There are many other system languages, like Rust, that want to kill off C++, but do not have a good way of interfacing with C++.

C++ is deeply entrenched, its not going anywhere. Rusthon transpiles to human readable C++, and you can configure the transpiler to use regular or smart pointers. Interfacing with an external C++ library is simple and requires no FFI, you can use C++ namespaces, template classes (via macros) and directly handle memory, passing the address of some variable or returning a pointer.

Caffe Deep Learning

Caffe is a large deep learning framework with many different types of neural networks. Getting it to compile and working on Fedora took me a couple of days, along the way I had to make lots of notes on the build and defines it required. The notes, build script, and code is all put into a single markdown file, see hello_caffe.md.

Testing Caffe with Rusthon has given me the chance to iron out the last details for working with external C++. Some functions in Caffe need to be passed the address of a variable, not the value or a pointer to it, the new builtin addr(X) takes the address of X and passes it to the function. If you need to initialize an array of template classes you can now use this trick.

with MyType as "some_template<float>":
    x = new( MyType() )
    y = []MyType()
    y.append( x )

Wednesday, April 8, 2015

C++ Backend Part2


New syntax and built-in functions have been added to Rusthon's C++ transpiler to make interfacing with external C++ libraries as simple as possible. Namespace syntax is supported using ::, just like in normal C++, more info here. Macro syntax is support with the macro function (to inline simple macros) and new with statement with T as "foo(%s)": that makes T a callable macro, this is useful for calling template functions from external libraries, more info see here.

Functions can also now use C++ type syntax to define the function return type. This allows you to override the default behavior of returning shared pointers (to objects, arrays, and maps).

  • def f()->T* returns a pointer to T
  • def f()->T& returns a reference to T

Calling methods on strings has now been fixed and always works, before there was the problem of pointers|references (which the transpiler had to keep track of). This has been fixed with a c++ template class function, the transpiler when it is not sure what the type of something is will use this template function to properly wrap the value. This also solves the general problem of working with objects from external c++ libs, where you are not sure if something is a pointer, or a pointer to something.

Tuesday, April 7, 2015

Unreal Engine4 Test Plugin


Above, screen shot of Unreal Editor being opened by the installer script in Fedora21, and starting the compile process. update: april 14: got the plugin to compile and load, fixed a bug in the Unreal source code (3dluvr's version), get my fork of Unreal4.7 here that is compatible with Rusthon. The command below will compile the plugin and launch Unreal Editor.

./rusthon.py ./examples/unreal_plugin.md --run=install-plugin.py --output-dir=~/Documents/Unreal\ Projects/MyProject/

source code

https://github.com/rusthon/Rusthon/blob/master/examples/unreal_plugin.md

Friday, April 3, 2015

Custom C++ Types


custom types wiki page

Which is the best smart pointer library for C++, that works everywhere and is fast? The standard smart pointers in C++11 can raise exceptions for some operations and this adds performance overhead. High performance libraries often use custom smart pointers because of this. Each custom smart pointer library has a similar API and behavior, and sometimes it is just the method names that differ. These implementation details get in the way of clear and readable code.

Rusthon solves this problem by allowing you to configure which smart pointers to use, for each block of code. This allows you to write code at a higher level, and control the low level details of translation using a single line with syntax('mytypes.json'). Code in that block will use the custom types and methods you define for: vectors, maps, shared and weak references. Outside of the block it defaults back to standard C++11 types.

Unreal Engine4

This example shows you how to configure the translator to use Unreal Engine smart pointers, string type, and template arrays. The translator configuration is at the top of the markdown, and redefines template and method names. Here is the output of main:

int main() {
 TArray<TSharedRef<Child>> children = {};
 auto p = TSharedRef<Parent>(
  (new Parent())->__init__(1000, children)
 );
 std::cout << TEXT("parent:");
 std::cout << p;std::cout << std::endl;
 auto c1 = make_child(p, 1);
 auto c2 = make_child(p, 20);
 auto c3 = make_child(p, 300);
 std::cout << TEXT("children:") << std::endl;
 std::cout << c1 << std::endl;
 std::cout << c2 << std::endl;
 std::cout << c3 << std::endl;
 std::cout << TEXT("calling foo") << std::endl;
 std::cout << c1->foo() << std::endl;
 std::cout << TEXT("calling bar") << std::endl;
 c1->bar();
 p.Reset();
 std::cout << c1->foo() << std::endl;
 c1->bar();
 return 0;
}