Return merchandise list in create_merchandise
This allows an optimization, removing an extra get_merchandise query.
This commit is contained in:
parent
82c7bdd92d
commit
2052f2cac9
16
bindings.h
16
bindings.h
@ -100,6 +100,12 @@ struct RawMerchandise {
|
|||||||
uint32_t price;
|
uint32_t price;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RawMerchandiseVec {
|
||||||
|
RawMerchandise *ptr;
|
||||||
|
uintptr_t len;
|
||||||
|
uintptr_t cap;
|
||||||
|
};
|
||||||
|
|
||||||
struct RawOwner {
|
struct RawOwner {
|
||||||
int32_t id;
|
int32_t id;
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -143,12 +149,6 @@ struct RawInteriorRefData {
|
|||||||
RawShelfVec shelf_vec;
|
RawShelfVec shelf_vec;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawMerchandiseVec {
|
|
||||||
RawMerchandise *ptr;
|
|
||||||
uintptr_t len;
|
|
||||||
uintptr_t cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RawShopVec {
|
struct RawShopVec {
|
||||||
RawShop *ptr;
|
RawShop *ptr;
|
||||||
uintptr_t len;
|
uintptr_t len;
|
||||||
@ -182,7 +182,7 @@ FFIResult<int32_t> create_interior_ref_list(const char *api_url,
|
|||||||
const RawShelf *raw_shelf_ptr,
|
const RawShelf *raw_shelf_ptr,
|
||||||
uintptr_t raw_shelf_len);
|
uintptr_t raw_shelf_len);
|
||||||
|
|
||||||
FFIResult<int32_t> create_merchandise_list(const char *api_url,
|
FFIResult<RawMerchandiseVec> create_merchandise_list(const char *api_url,
|
||||||
const char *api_key,
|
const char *api_key,
|
||||||
int32_t shop_id,
|
int32_t shop_id,
|
||||||
const RawMerchandise *raw_merchandise_ptr,
|
const RawMerchandise *raw_merchandise_ptr,
|
||||||
@ -238,7 +238,7 @@ FFIResult<int32_t> update_interior_ref_list(const char *api_url,
|
|||||||
const RawShelf *raw_shelf_ptr,
|
const RawShelf *raw_shelf_ptr,
|
||||||
uintptr_t raw_shelf_len);
|
uintptr_t raw_shelf_len);
|
||||||
|
|
||||||
FFIResult<int32_t> update_merchandise_list(const char *api_url,
|
FFIResult<RawMerchandiseVec> update_merchandise_list(const char *api_url,
|
||||||
const char *api_key,
|
const char *api_key,
|
||||||
int32_t shop_id,
|
int32_t shop_id,
|
||||||
const RawMerchandise *raw_merchandise_ptr,
|
const RawMerchandise *raw_merchandise_ptr,
|
||||||
|
@ -97,7 +97,7 @@ pub extern "C" fn create_merchandise_list(
|
|||||||
shop_id: i32,
|
shop_id: i32,
|
||||||
raw_merchandise_ptr: *const RawMerchandise,
|
raw_merchandise_ptr: *const RawMerchandise,
|
||||||
raw_merchandise_len: usize,
|
raw_merchandise_len: usize,
|
||||||
) -> FFIResult<i32> {
|
) -> FFIResult<RawMerchandiseVec> {
|
||||||
let api_url = unsafe { CStr::from_ptr(api_url) }.to_string_lossy();
|
let api_url = unsafe { CStr::from_ptr(api_url) }.to_string_lossy();
|
||||||
let api_key = unsafe { CStr::from_ptr(api_key) }.to_string_lossy();
|
let api_key = unsafe { CStr::from_ptr(api_key) }.to_string_lossy();
|
||||||
info!("create_merchandise_list api_url: {:?}, api_key: {:?}, shop_id: {:?}, raw_merchandise_len: {:?}", api_url, api_key, shop_id, raw_merchandise_len);
|
info!("create_merchandise_list api_url: {:?}, api_key: {:?}, shop_id: {:?}, raw_merchandise_len: {:?}", api_url, api_key, shop_id, raw_merchandise_len);
|
||||||
@ -153,13 +153,35 @@ pub extern "C" fn create_merchandise_list(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match inner(&api_url, &api_key, shop_id, raw_merchandise_slice) {
|
match inner(&api_url, &api_key, shop_id, raw_merchandise_slice) {
|
||||||
Ok(merchandise_list) => FFIResult::Ok(merchandise_list.id),
|
Ok(merchandise_list) => {
|
||||||
|
let (ptr, len, cap) = merchandise_list
|
||||||
|
.form_list
|
||||||
|
.into_iter()
|
||||||
|
.map(|merchandise| RawMerchandise {
|
||||||
|
mod_name: CString::new(merchandise.mod_name)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_raw(),
|
||||||
|
local_form_id: merchandise.local_form_id,
|
||||||
|
name: CString::new(merchandise.name)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_raw(),
|
||||||
|
quantity: merchandise.quantity,
|
||||||
|
form_type: merchandise.form_type,
|
||||||
|
is_food: merchandise.is_food,
|
||||||
|
price: merchandise.price,
|
||||||
|
})
|
||||||
|
.collect::<Vec<RawMerchandise>>()
|
||||||
|
.into_raw_parts();
|
||||||
|
// TODO: need to pass this back into Rust once C++ is done with it so it can be manually dropped and the CStrings dropped from raw pointers.
|
||||||
|
FFIResult::Ok(RawMerchandiseVec { ptr, len, cap })
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("create_merchandise_list failed. {}", err);
|
error!("create_merchandise_list failed. {}", err);
|
||||||
// TODO: also need to drop this CString once C++ is done reading it
|
// TODO: how to do error handling?
|
||||||
let err_string = CString::new(err.to_string())
|
let err_string = CString::new(err.to_string())
|
||||||
.expect("could not create CString")
|
.expect("could not create CString")
|
||||||
.into_raw();
|
.into_raw();
|
||||||
|
// TODO: also need to drop this CString once C++ is done reading it
|
||||||
FFIResult::Err(err_string)
|
FFIResult::Err(err_string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +194,7 @@ pub extern "C" fn update_merchandise_list(
|
|||||||
shop_id: i32,
|
shop_id: i32,
|
||||||
raw_merchandise_ptr: *const RawMerchandise,
|
raw_merchandise_ptr: *const RawMerchandise,
|
||||||
raw_merchandise_len: usize,
|
raw_merchandise_len: usize,
|
||||||
) -> FFIResult<i32> {
|
) -> FFIResult<RawMerchandiseVec> {
|
||||||
let api_url = unsafe { CStr::from_ptr(api_url) }.to_string_lossy();
|
let api_url = unsafe { CStr::from_ptr(api_url) }.to_string_lossy();
|
||||||
let api_key = unsafe { CStr::from_ptr(api_key) }.to_string_lossy();
|
let api_key = unsafe { CStr::from_ptr(api_key) }.to_string_lossy();
|
||||||
info!("create_merchandise_list api_url: {:?}, api_key: {:?}, shop_id: {:?}, raw_merchandise_len: {:?}", api_url, api_key, shop_id, raw_merchandise_len);
|
info!("create_merchandise_list api_url: {:?}, api_key: {:?}, shop_id: {:?}, raw_merchandise_len: {:?}", api_url, api_key, shop_id, raw_merchandise_len);
|
||||||
@ -224,13 +246,35 @@ pub extern "C" fn update_merchandise_list(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match inner(&api_url, &api_key, shop_id, raw_merchandise_slice) {
|
match inner(&api_url, &api_key, shop_id, raw_merchandise_slice) {
|
||||||
Ok(merchandise_list) => FFIResult::Ok(merchandise_list.id),
|
Ok(merchandise_list) => {
|
||||||
|
let (ptr, len, cap) = merchandise_list
|
||||||
|
.form_list
|
||||||
|
.into_iter()
|
||||||
|
.map(|merchandise| RawMerchandise {
|
||||||
|
mod_name: CString::new(merchandise.mod_name)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_raw(),
|
||||||
|
local_form_id: merchandise.local_form_id,
|
||||||
|
name: CString::new(merchandise.name)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_raw(),
|
||||||
|
quantity: merchandise.quantity,
|
||||||
|
form_type: merchandise.form_type,
|
||||||
|
is_food: merchandise.is_food,
|
||||||
|
price: merchandise.price,
|
||||||
|
})
|
||||||
|
.collect::<Vec<RawMerchandise>>()
|
||||||
|
.into_raw_parts();
|
||||||
|
// TODO: need to pass this back into Rust once C++ is done with it so it can be manually dropped and the CStrings dropped from raw pointers.
|
||||||
|
FFIResult::Ok(RawMerchandiseVec { ptr, len, cap })
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("update_merchandise_list failed. {}", err);
|
error!("update_merchandise_list failed. {}", err);
|
||||||
// TODO: also need to drop this CString once C++ is done reading it
|
// TODO: how to do error handling?
|
||||||
let err_string = CString::new(err.to_string())
|
let err_string = CString::new(err.to_string())
|
||||||
.expect("could not create CString")
|
.expect("could not create CString")
|
||||||
.into_raw();
|
.into_raw();
|
||||||
|
// TODO: also need to drop this CString once C++ is done reading it
|
||||||
FFIResult::Err(err_string)
|
FFIResult::Err(err_string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,8 +530,30 @@ mod tests {
|
|||||||
let result = create_merchandise_list(api_url, api_key, 1, ptr, len);
|
let result = create_merchandise_list(api_url, api_key, 1, ptr, len);
|
||||||
mock.assert();
|
mock.assert();
|
||||||
match result {
|
match result {
|
||||||
FFIResult::Ok(merchandise_list_id) => {
|
FFIResult::Ok(raw_merchandise_vec) => {
|
||||||
assert_eq!(merchandise_list_id, 1);
|
assert_eq!(raw_merchandise_vec.len, 1);
|
||||||
|
assert!(!raw_merchandise_vec.ptr.is_null());
|
||||||
|
let raw_merchandise_slice = unsafe {
|
||||||
|
slice::from_raw_parts(raw_merchandise_vec.ptr, raw_merchandise_vec.len)
|
||||||
|
};
|
||||||
|
let raw_merchandise = &raw_merchandise_slice[0];
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(raw_merchandise.mod_name) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
"Skyrim.esm".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(raw_merchandise.local_form_id, 1);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(raw_merchandise.name) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
"Iron Sword".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(raw_merchandise.quantity, 1);
|
||||||
|
assert_eq!(raw_merchandise.form_type, 1);
|
||||||
|
assert_eq!(raw_merchandise.is_food, false);
|
||||||
|
assert_eq!(raw_merchandise.price, 100);
|
||||||
}
|
}
|
||||||
FFIResult::Err(error) => {
|
FFIResult::Err(error) => {
|
||||||
panic!("create_merchandise_list returned error: {:?}", unsafe {
|
panic!("create_merchandise_list returned error: {:?}", unsafe {
|
||||||
@ -519,9 +585,9 @@ mod tests {
|
|||||||
let result = create_merchandise_list(api_url, api_key, 1, ptr, len);
|
let result = create_merchandise_list(api_url, api_key, 1, ptr, len);
|
||||||
mock.assert();
|
mock.assert();
|
||||||
match result {
|
match result {
|
||||||
FFIResult::Ok(merchandise_list_id) => panic!(
|
FFIResult::Ok(raw_merchandise_vec) => panic!(
|
||||||
"create_merchandise_list returned Ok result: {:?}",
|
"create_merchandise_list returned Ok result: {:#x?}",
|
||||||
merchandise_list_id
|
raw_merchandise_vec
|
||||||
),
|
),
|
||||||
FFIResult::Err(error) => {
|
FFIResult::Err(error) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -571,8 +637,30 @@ mod tests {
|
|||||||
let result = update_merchandise_list(api_url, api_key, 1, ptr, len);
|
let result = update_merchandise_list(api_url, api_key, 1, ptr, len);
|
||||||
mock.assert();
|
mock.assert();
|
||||||
match result {
|
match result {
|
||||||
FFIResult::Ok(merchandise_list_id) => {
|
FFIResult::Ok(raw_merchandise_vec) => {
|
||||||
assert_eq!(merchandise_list_id, 1);
|
assert_eq!(raw_merchandise_vec.len, 1);
|
||||||
|
assert!(!raw_merchandise_vec.ptr.is_null());
|
||||||
|
let raw_merchandise_slice = unsafe {
|
||||||
|
slice::from_raw_parts(raw_merchandise_vec.ptr, raw_merchandise_vec.len)
|
||||||
|
};
|
||||||
|
let raw_merchandise = &raw_merchandise_slice[0];
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(raw_merchandise.mod_name) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
"Skyrim.esm".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(raw_merchandise.local_form_id, 1);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { CStr::from_ptr(raw_merchandise.name) }
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
"Iron Sword".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(raw_merchandise.quantity, 1);
|
||||||
|
assert_eq!(raw_merchandise.form_type, 1);
|
||||||
|
assert_eq!(raw_merchandise.is_food, false);
|
||||||
|
assert_eq!(raw_merchandise.price, 100);
|
||||||
}
|
}
|
||||||
FFIResult::Err(error) => {
|
FFIResult::Err(error) => {
|
||||||
panic!("update_merchandise_list returned error: {:?}", unsafe {
|
panic!("update_merchandise_list returned error: {:?}", unsafe {
|
||||||
@ -604,9 +692,9 @@ mod tests {
|
|||||||
let result = update_merchandise_list(api_url, api_key, 1, ptr, len);
|
let result = update_merchandise_list(api_url, api_key, 1, ptr, len);
|
||||||
mock.assert();
|
mock.assert();
|
||||||
match result {
|
match result {
|
||||||
FFIResult::Ok(merchandise_list_id) => panic!(
|
FFIResult::Ok(raw_merchandise_vec) => panic!(
|
||||||
"update_merchandise_list returned Ok result: {:?}",
|
"update_merchandise_list returned Ok result: {:#x?}",
|
||||||
merchandise_list_id
|
raw_merchandise_vec
|
||||||
),
|
),
|
||||||
FFIResult::Err(error) => {
|
FFIResult::Err(error) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
Loading…
Reference in New Issue
Block a user