docs(example/main): Update to include newly added callbacks

This commit is contained in:
Benedikt Peetz 2024-03-27 22:19:07 +01:00
parent c69c00e1e9
commit 7f6c76a6a6
Signed by: bpeetz
GPG Key ID: A5E94010C3A642AD
8 changed files with 132 additions and 17 deletions

View File

@ -25,7 +25,7 @@ edition = "2021"
default-run = "main" default-run = "main"
[dependencies] [dependencies]
libloading = "0.8.1" libloading = "0.8.3"
trixy = { path = "../../." } trixy = { path = "../../." }
[build-dependencies] [build-dependencies]

View File

@ -22,7 +22,8 @@ BIN_NAME := ./target/plugin.so
BUILD_DIR := ./target/c_build/ BUILD_DIR := ./target/c_build/
SRC := $(wildcard c/*.c) # SRC := $(wildcard c/*.c)
SRC := c/main.c
OBJ := $(SRC:.c=.o) OBJ := $(SRC:.c=.o)
DEP := $(OBJ:.o=.d) DEP := $(OBJ:.o=.d)

View File

@ -20,15 +20,15 @@
* If not, see <https://www.gnu.org/licenses/>. * If not, see <https://www.gnu.org/licenses/>.
*/ */
use trixy::macros::config::TrixyConfig; use trixy::macros::config::trixy::TrixyConfig;
fn main() { fn main() {
println!("cargo:rerun-if-changed=./dist/*"); println!("cargo:rerun-if-changed=./dist/*");
println!("cargo:rerun-if-changed=./src/bin/main/api.tri"); println!("cargo:rerun-if-changed=./src/bin/main/api.tri");
println!("cargo:rerun-if-changed=./src/bin/main/trinitrix_api.tri"); println!("cargo:rerun-if-changed=./src/bin/main/trinitrix_api.tri");
TrixyConfig::new("handle_cmd") let file_tree = TrixyConfig::new("handle_cmd")
.trixy_path("./src/bin/main/trinitrix_api.tri") .trixy_path("./src/bin/main/api.tri")
.dist_dir_path("./dist") .dist_dir_path("./dist")
.generate_debug(true)
.generate(); .generate();
file_tree.materialize().unwrap();
} }

View File

@ -47,6 +47,21 @@ handle_error ()
free (error); free (error);
} }
struct Dog
guess (const char *pers_name, uint32_t age)
{
println ("Rust wants to name the dog %s, but that's not good!", pers_name);
// The callback must free all its owned arguments, as rust just moved these
// here and is not going to free them.
string_free (pers_name);
struct Dog dog = {
.name = "James",
};
return dog;
}
int int
plugin_main () plugin_main ()
{ {
@ -64,7 +79,7 @@ plugin_main ()
println ("Saying hi!"); println ("Saying hi!");
const char *hi; const char *hi;
if (!one.hi (&hi, "Adam")) if (!dogs.hi (&hi, "Adam"))
handle_error (); handle_error ();
println ("Rust returned: %s", hi); println ("Rust returned: %s", hi);
@ -74,7 +89,7 @@ plugin_main ()
// types are defined in the `api.tri` file) // types are defined in the `api.tri` file)
struct Dog dog = { .name = "Bruce" }; struct Dog dog = { .name = "Bruce" };
struct TrainedDog tDog; struct TrainedDog tDog;
if (!one.train_dog (&tDog, dog)) if (!dogs.train_dog (&tDog, dog))
handle_error (); handle_error ();
println ("Dog %s is now trained with specialization %i", tDog.name, println ("Dog %s is now trained with specialization %i", tDog.name,
@ -82,5 +97,11 @@ plugin_main ()
// Beware that you need to free them with the appropriate free functions // Beware that you need to free them with the appropriate free functions
string_free (tDog.name); string_free (tDog.name);
// Trixy also supports functions (i.e. callbacks):
enum DogType output_dog;
if (!dogs.guess_my_favourite_dog (&output_dog, guess))
handle_error ();
println ("Rust guessed %d", output_dog);
return 0; return 0;
} }

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2023 - 2024:
* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
* SPDX-License-Identifier: LGPL-3.0-or-later
*
* This file is part of the Trixy crate for Trinitrix.
*
* Trixy is free software: you can redistribute it and/or modify
* it under the terms of the Lesser GNU General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* and the Lesser GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "../dist/interface.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define println(args...) \
printf ("\33[32;1m(plugin):\33[0m \33[34;1m"); \
printf (args); \
printf ("\n\33[0m"); \
fflush (stdout);
#define eprintln(args...) \
printf ("\33[32;1m(plugin):\33[0m\33[31;1m "); \
printf (args); \
printf ("\n\33[0m"); \
fflush (stdout);
void
handle_error ()
{
int error_length = last_error_length ();
char *error = malloc (error_length);
last_error_message (error, error_length);
eprintln ("Encountered error: %s", error);
free (error);
}
int
plugin_main ()
{
if (!trinitrix.api.room_message_send ("Hi!"))
handle_error ();
return EXIT_SUCCESS;
}

View File

@ -37,7 +37,21 @@ enum TrainingMistake {
Died, Died,
} }
mod one { struct Dog {
name: String,
}
mod dogs {
/// The possible types a dog can have
///
/// Beware that [`DogType::Cat`] and [`DogType::Lion`] are not really recognized as
/// dogs.
enum DogType {
Akita,
Cat,
Lion,
}
/// A Dog after extensive training /// A Dog after extensive training
struct TrainedDog { struct TrainedDog {
name: String, name: String,
@ -46,15 +60,10 @@ mod one {
/// Say hi to a name /// Say hi to a name
fn hi(name: String) -> String; fn hi(name: String) -> String;
/// Train a dog without using any resources
// fn cheaply_train_dog(dog: Dog) -> Result<TrainedDog, TrainingMistake>;
/// Train a dog /// Train a dog
fn train_dog(dog: Dog) -> TrainedDog; fn train_dog(dog: Dog) -> TrainedDog;
}
struct Dog { fn guess_my_favourite_dog(callback: fn(name: String, age: u32) -> Dog) -> DogType;
name: String,
} }
// Trixy is a subset of Rust // Trixy is a subset of Rust

View File

@ -22,8 +22,11 @@
use std::{env, ffi::c_int, mem}; use std::{env, ffi::c_int, mem};
use dogs::TrainedDog;
use libloading::{Library, Symbol}; use libloading::{Library, Symbol};
use crate::dogs::DogType;
include!(concat!(env!("OUT_DIR"), "/api.rs")); include!(concat!(env!("OUT_DIR"), "/api.rs"));
// run `cargo r --bin api > ./src/bin/main/api.rs` to output the generated api // run `cargo r --bin api > ./src/bin/main/api.rs` to output the generated api
@ -32,13 +35,37 @@ include!(concat!(env!("OUT_DIR"), "/api.rs"));
fn handle_cmd(cmd: Commands) { fn handle_cmd(cmd: Commands) {
match cmd { match cmd {
Commands::One(one) => match one { Commands::Dogs(one) => match one {
one::One::hi { trixy_output, name } => { dogs::Dogs::hi { trixy_output, name } => {
let output = format!("Hi {}!", name); let output = format!("Hi {}!", name);
println!("(rust): {}", output); println!("(rust): {}", output);
trixy_output.send(output.into()).expect("Will work"); trixy_output.send(output.into()).expect("Will work");
mem::forget(name); mem::forget(name);
} }
dogs::Dogs::train_dog { trixy_output, dog } => {
trixy_output
.send(
TrainedDog {
name: "Willis".into(),
training: DogTraining::Wolf,
}
.try_into()
.unwrap(),
)
.unwrap();
mem::forget(dog);
}
dogs::Dogs::guess_my_favourite_dog {
trixy_output,
callback,
} => {
let fav_dog = callback("Frank".into(), 30);
let dog_name: String = fav_dog.name.clone().try_into().unwrap();
println!("(rust): They want a dog named: {}", dog_name);
trixy_output.send(DogType::Cat.into()).unwrap();
mem::forget(dog_name);
}
}, },
Commands::outstanding { name } => { Commands::outstanding { name } => {
println!("(rust): {} is outstanding!", name); println!("(rust): {} is outstanding!", name);

View File

@ -0,0 +1 @@
../../../../../tests/trinitrix_api/input.tri