Choices complete, prep for merge into master

This commit is contained in:
Dane Johnson 2022-01-20 10:52:32 -06:00
parent e0e54bd34b
commit 5b53c8e18b
3 changed files with 74 additions and 24 deletions

View File

@ -35,12 +35,16 @@ int main() {
storybook_advance_nooption(book); storybook_advance_nooption(book);
break; break;
case (FOOTER_CHOICES): case (FOOTER_CHOICES):
int n = storybook_get_num_choices(book); ChoiceList *list = storybook_get_choices(book);
for (int i = 1; i <= n; i++) { for (ChoiceList *curr = list; curr; curr = curr->next) {
Choice* choice = storybook_get_choice(book, i); const StatCheck *sk = curr->choice.statcheck;
printf("%d) %s\n", choice->option, choice->flavor); if (sk) {
storybook_free_choice(choice); printf("\e[0;31m");
}
printf("%d) %s", curr->choice.option, curr->choice.flavor);
printf("\n\e[0m");
} }
storybook_free_choices(list);
uint32_t option; uint32_t option;
printf("Make a choice: "); printf("Make a choice: ");
scanf("%d", &option); scanf("%d", &option);

View File

@ -1,4 +1,6 @@
language = "C" language = "C"
sys_includes = ["stdbool.h", "stdint.h"]
include_guard = "STORYBOOK_H"
[export.rename] [export.rename]

View File

@ -185,6 +185,14 @@ pub mod ffi {
pub struct Choice { pub struct Choice {
option: usize, option: usize,
flavor: *const c_char, flavor: *const c_char,
statcheck: *const StatCheck,
statchange: *const StatChange,
}
#[repr(C)]
pub struct ChoiceList {
choice: Choice,
next: *mut ChoiceList,
} }
#[repr(C)] #[repr(C)]
@ -205,6 +213,42 @@ pub mod ffi {
Choice { Choice {
option: choice.option, option: choice.option,
flavor: CString::new(choice.flavor.clone()).unwrap().into_raw(), flavor: CString::new(choice.flavor.clone()).unwrap().into_raw(),
statcheck: match &choice.stat_check {
Some(statcheck) => {
let statcheck = StatCheck::new(&statcheck);
let statcheck = Box::from(statcheck);
Box::into_raw(statcheck)
}
None => std::ptr::null(),
},
statchange: match &choice.stat_change {
Some(statchange) => {
let statchange = StatChange::new(&statchange);
let statchange = Box::from(statchange);
Box::into_raw(statchange)
},
None => std::ptr::null(),
},
}
}
}
impl StatCheck {
pub fn new(statcheck: &super::StatCheck) -> Self {
StatCheck {
stat: CString::new(statcheck.stat.clone()).unwrap().into_raw(),
value: statcheck.value,
rel: statcheck.rel as c_char,
}
}
}
impl StatChange {
pub fn new(statchange: &super::StatChange) -> Self {
StatChange {
stat: CString::new(statchange.stat.clone()).unwrap().into_raw(),
addend: statchange.addend,
} }
} }
} }
@ -272,6 +316,7 @@ pub mod ffi {
book.advance_nooption(); book.advance_nooption();
} }
#[no_mangle] #[no_mangle]
pub extern fn storybook_advance_option(book: *mut Book, option: usize) { pub extern fn storybook_advance_option(book: *mut Book, option: usize) {
let book = get_book_from_ref(book); let book = get_book_from_ref(book);
@ -279,34 +324,33 @@ pub mod ffi {
} }
#[no_mangle] #[no_mangle]
pub extern fn storybook_get_num_choices(book: *mut Book) -> usize { pub extern fn storybook_get_choices (book: *mut Book) -> *mut ChoiceList {
let book = get_book_from_ref(book); let book = get_book_from_ref(book);
let footer = &book.get_current().footer; let footer = &book.get_current().footer;
if let super::Footer::Choices(choices) = footer { if let super::Footer::Choices(choices) = footer {
choices.len() let mut list = std::ptr::null_mut();
let mut choices = choices.iter().collect::<Vec<(&usize, &super::Choice)>>();
choices.sort_by_key(|(&o, _)| o);
for (_, choice) in choices.into_iter().rev() {
let choice = Choice::new(choice);
let node = Box::from(ChoiceList {
choice,
next: list,
});
list = Box::into_raw(node);
}
return list
} else { } else {
panic!("Requested num choices but page is not choices."); panic!("Requested choices but page is not choices.");
} }
} }
#[no_mangle] #[no_mangle]
pub extern fn storybook_get_choice(book: *mut Book, n: usize) -> *mut Choice { pub extern fn storybook_free_choices(mut list: *mut ChoiceList) {
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 { unsafe {
Box::from_raw(choice); while !list.is_null() {
list = Box::from_raw(list).next;
}
} }
} }
} }