Skip to content
Snippets Groups Projects
Commit 064efa90 authored by Olivier Dion's avatar Olivier Dion Committed by Adrien Béraud
Browse files

agent/README: Update README

Change-Id: I2bcbbf872b54262f8e4406fb01921a1ec07be3b3
parent 26f04d0a
No related branches found
No related tags found
No related merge requests found
...@@ -16,7 +16,7 @@ To build Guile locally, you first need to enable it when building contrib, then ...@@ -16,7 +16,7 @@ To build Guile locally, you first need to enable it when building contrib, then
recompile contrib: recompile contrib:
```sh ```sh
cd daemon/contribu/native cd daemon/contrib/native
../bootstrap --enable-guile ../bootstrap --enable-guile
make list make list
make fetch make fetch
...@@ -35,20 +35,34 @@ make check ...@@ -35,20 +35,34 @@ make check
``` ```
# Running the agent # Running the agent
The agent expects a Scheme file has its first parameter. This scheme file will The agent is actually a wrapper around Guile's Scheme shell. By default, you
be interpreted by Guile. In the script, you can control the agent. enter an interactive prompt that allows you to interact with Jami using the
primitive bindings or by using the agent helper. For help for running the
Usage: agent, run `./agent --help`.
```sh
./agent ./examples/passive-agent.scm
```
# Guile bindings # Guile bindings
In order for Guile to control the agent, bindings have to be added to the global Guile needs primitive bindings to communicate with Jami. Usually, these
environment where the configuration file is being interpreted. This is done in bindings can written in pure Scheme using the foreign function interface (FFI)
`main.cpp` in the function `install_scheme_primitive()`. All scheme bindings and some dlopen() magics. However, this method cannot applies here for two main
should have the prefix `agent:` to be clear that the procedure is one that reasons:
control the agent.
1. Jami source code is in C++ not C.
2. Dynamic loading is not present on some platform supported by Jami.
The first reason makes it hard to interface C++ container types and other
standard types to bytevector used by Guile to interface with foreign functions.
In C, it's trivial to just types and pointers to bytevector.
The second reason is a constraint on the agent. Since the goal is to have a set
of bindings that can run on any platform where Jami is supported, bindings
should be registered in C++.
All bindings can be found under `src/bindings/*`. Bindings should be decouple
into module that reflect their common functionnality. For example,
`src/bindings/account.h` has all the Jami's bindings for managing accounts. When
a set of bindings is to be added to a new module, the latter has to be
registered into Guile. In order accomplish this, one has to include the
bindings and define the module under `src/bindings/bindings.cpp`.
When a binding is called from Guile, the arguments passed are Scheme objects of When a binding is called from Guile, the arguments passed are Scheme objects of
type `SCM`. This is an opaque type that is generic. In order to be clear on type `SCM`. This is an opaque type that is generic. In order to be clear on
...@@ -56,26 +70,17 @@ what the underlying type needed by the primitive procedure is, one should add th ...@@ -56,26 +70,17 @@ what the underlying type needed by the primitive procedure is, one should add th
suffix of the type at the end. suffix of the type at the end.
For example, `my_primitive_procedure()` expects that `some_variable_str` For example, `my_primitive_procedure()` expects that `some_variable_str`
will be of type `string`. This is enforced by using an assertion: will be of type `string`.
```c++
static SCM my_primitive_procedure(SCM some_variable_str)
{
AGENT_ASSERT(scm_is_string(some_variable_str), "`some_variable_str` must be of type string");
...
}
```
Here is another example where `my_second_primitive()` expects that There's also a set of utilities that can be used to convert C++ object to Scheme
`some_variable_vector_or_str` to be of type `string` or `vector`: and vice versa. These utilities can be found under `src/utils.h` and are all
```c++ template based and can usually be used without specifying any type thanks to
static SCM my_second_primitive(SCM some_variable_vector_or_str) type inference.
{
AGENT_ASSERT(scm_is_string(some_variable_vector_or_str) ||
scm_is_simple_vector(some_variable_vector_or_str),
"`scm_some_variable_vector_or_str` must either be of type vector or string");
...
}
```
# Writing scenarios For example, to convert `std::string bar` to `SCM baz`, onw would do
`baz = to_guile(bar)`. One can also do the oposite like so
`bar = from_guile(baz)`.
# Examples
See `examples/` See `examples/`
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment