Update readme, still incomplete

This commit is contained in:
King_DuckZ 2022-05-15 23:09:36 +02:00
parent 0220529179
commit c59cc03f49

116
README.md
View file

@ -5,6 +5,8 @@ library. It aims to package all the features accessible through the C API in a
modern C++ interface that is easy to use, while keeping the overhead to a modern C++ interface that is easy to use, while keeping the overhead to a
minimum. minimum.
* [Current state](#current-state)
* [Philosophy](#philosophy)
* [Building](#building) * [Building](#building)
* [Wrenpp](#wrenpp) * [Wrenpp](#wrenpp)
* [Wren only](#wren-only) * [Wren only](#wren-only)
@ -13,6 +15,29 @@ minimum.
* [C++](#c) * [C++](#c)
* [Header files](#header-files) * [Header files](#header-files)
* [Initialisation](#initialisation) * [Initialisation](#initialisation)
* [Foreign functions](#foreign-functions)
* [Implementation](#implementation)
## Current state ##
The library is functional and provides access to most of the features of Wren.
Some are better tested than others. There are no known memory leaks. Please
keep in mind this is an early version and more testing and work will be needed.
## Philosophy ##
The overall principle behind this wrapper is to be feature rich while also
being lightweight and allowing fine-grained control for users who need it.
By design, wrenpp hides the Wren C API entirely, but all functions (considered
"low level" relative to this wrapper) are still accessible through the `VM`
class. If the function you need is not available there it's probably just
missing and adding it should be a trivial task.
Wrenpp provides you with convenience functions in `vm_fun.hpp` that are built
on top of the `VM` class and make basic use of Wren simpler. You're still free
to "mix & match" higher level functions with lower level ones, and you can
decide to not use portions of the wrapper entirely.
## Building ## ## Building ##
@ -39,6 +64,12 @@ The build scripts understand the following options (double check in
[random](http://wren.io/modules/random/) support [random](http://wren.io/modules/random/) support
5. `wren_with_meta` set to true to compile Wren with 5. `wren_with_meta` set to true to compile Wren with
[meta](http://wren.io/modules/meta/) support [meta](http://wren.io/modules/meta/) support
6. `wrenpp_with_name_guessing` enable class name guessing in c++ code. It
currently affects only example code and header files, not the library
itself. It controls the `WRENPP_WITH_NAME_GUESSING` preprocessor symbol.
When it's defined, you will have access to better error reporting and extra
functions, such as a `make_wren_object()` overload that doesn't require you
to specify a string class name.
Note that some example projects require random support in Wren, without which Note that some example projects require random support in Wren, without which
they will crash. If you want to run examples or you are getting "Address they will crash. If you want to run examples or you are getting "Address
@ -112,6 +143,8 @@ meson wrap promote subprojects/wrenpp/subprojects/wren
### C++ ### ### C++ ###
For working examples refer to the source files in the `examples/` directory. For working examples refer to the source files in the `examples/` directory.
"Greet" is the simplest example, while "math_vector" is showing off more
features.
#### Header files #### #### Header files ####
@ -155,4 +188,87 @@ int main() {
} }
``` ```
#### Foreign functions ####
You have two options to register foreign functions with wrenpp: the easiest one
is to just use the callback manager available through the `VM` object:
```
#include <wrenpp/vm.hpp>
#include <wrenpp/def_configuration.hpp>
#include <wrenpp/callback_manager.hpp> //necessary if you want to use the callback manager
int main() {
wren::DefConfiguration config;
wren::VM vm(&config, nullptr);
vm.callback_manager()
.add_callback(true, "your_module", "YourClass", "your_method(_,_)", &your_method);
vm.interpret("main", your_fun_script_here);
return 0;
}
```
The current implementation available in `DefConfiguration` registers a callback
to Wren that looks up a `std::unordered_map` for the correct c++ function and
then forwards the call to it. This should be good enough for most cases,
however you are free to provide your own callback for wren by writing your own
Configuration class. Wrenpp tries to not impose you any particular helper code,
in fact if you don't wish to use the `CallbackManager` returned by
`vm.callback_manager()` then you don't even need to include the relative header
file! There will still be a `std::unordered_map` in memory (because that's
owned by `vm`) but it will never be used.
The second method requires you to provide the full Wren foreign functions
callback:
```
#include <wrenpp/vm.hpp>
#include <wrenpp/def_configuration.hpp>
class MyConf : public wren::DefConfiguration {
public:
//This is the callback that Wren will call, refer to the C API documentation
//for more details.
wren::foreign_method_t foreign_method_fn(
wren::VM* vm,
std::string_view module,
std::string_view class_name,
bool is_static,
std::string_view signature
) {
if (module == "your_module" and class_name == "YourClass") {
if (is_static and signature == "your_method(_,_)")
return &your_method;
}
return nullptr;
}
}
int main() {
MyConf config;
wren::VM vm(&config, nullptr);
vm.interpret("main", your_fun_script_here);
return 0;
}
```
The above code is very close to what you'd do with the C API. If you need, you
can even pass a user data pointer to the `VM` constructor (`nullptr` in this
snippet) and retrieve it later from within `foreign_method_fn()` via
`vm.void_user_data()` or `vm.user_data()`. You're unlikely to need it as, as
you can see, `foreign_method_fn()` is not static and so you can have some state
stored in your `MyConf` object, however you still get the chance to use the
C-like user data mechanism if you wish to.
Note that for the above to work the `foreign_method_fn()` method in `MyConf`
must be named exactly like that, and the signature must match (except for the
`static` and `const` keywords). Ideally the code above should alse be
`noexcept` as there will be C code in the call stack when that method is
invoked.
## Implementation ##
*Work in progress* *Work in progress*