More ffi for choices and the like

This commit is contained in:
Dane Johnson 2022-01-19 09:57:20 -06:00
parent 8d23af431e
commit e0e54bd34b
2 changed files with 70 additions and 4 deletions

View File

@ -35,6 +35,12 @@ int main() {
storybook_advance_nooption(book);
break;
case (FOOTER_CHOICES):
int n = storybook_get_num_choices(book);
for (int i = 1; i <= n; i++) {
Choice* choice = storybook_get_choice(book, i);
printf("%d) %s\n", choice->option, choice->flavor);
storybook_free_choice(choice);
}
uint32_t option;
printf("Make a choice: ");
scanf("%d", &option);

View File

@ -13,12 +13,12 @@ pub struct Page {
pub enum Footer {
Ending,
Goto(String),
Choices(HashMap<u32, Choice>),
Choices(HashMap<usize, Choice>),
}
#[derive(Debug, PartialEq)]
pub struct Choice {
option: u32,
option: usize,
flavor: String,
redirect: String,
stat_check: Option<StatCheck>,
@ -130,7 +130,7 @@ impl Book {
Footer::Choices(_) => panic!("No option for advance on choices page!"),
}
}
pub fn advance_option(&mut self, option: u32) {
pub fn advance_option(&mut self, option: usize) {
let footer = &self.get_current().footer;
match footer {
Footer::Ending => panic!("Option provided for advance on ending page!"),
@ -181,6 +181,34 @@ pub mod ffi {
Choices,
}
#[repr(C)]
pub struct Choice {
option: usize,
flavor: *const c_char,
}
#[repr(C)]
pub struct StatCheck {
stat: *const c_char,
value: i32,
rel: c_char,
}
#[repr(C)]
pub struct StatChange {
stat: *const c_char,
addend: i32,
}
impl Choice {
pub fn new(choice: &super::Choice) -> Self {
Choice {
option: choice.option,
flavor: CString::new(choice.flavor.clone()).unwrap().into_raw(),
}
}
}
#[no_mangle]
pub extern fn storybook_make_book(string: *const c_char) -> *mut Book {
let string = unsafe {
@ -245,10 +273,42 @@ pub mod ffi {
}
#[no_mangle]
pub extern fn storybook_advance_option(book: *mut Book, option: u32) {
pub extern fn storybook_advance_option(book: *mut Book, option: usize) {
let book = get_book_from_ref(book);
book.advance_option(option);
}
#[no_mangle]
pub extern fn storybook_get_num_choices(book: *mut Book) -> usize {
let book = get_book_from_ref(book);
let footer = &book.get_current().footer;
if let super::Footer::Choices(choices) = footer {
choices.len()
} else {
panic!("Requested num choices but page is not choices.");
}
}
#[no_mangle]
pub extern fn storybook_get_choice(book: *mut Book, n: usize) -> *mut Choice {
let book = get_book_from_ref(book);
let footer = &book.get_current().footer;
if let super::Footer::Choices(choices) = footer {
let choice = choices.get(&n).expect("Requested option isn't present in choices.");
let choice = Choice::new(choice);
let choice = Box::from(choice);
Box::into_raw(choice)
} else {
panic!("Requested a choice but page is not choices.");
}
}
#[no_mangle]
pub extern fn storybook_free_choice(choice: *mut Choice) {
unsafe {
Box::from_raw(choice);
}
}
}
#[cfg(test)]