Skip to content

Commit

Permalink
Merge pull request #233 from IntQuant/rust-api
Browse files Browse the repository at this point in the history
Implement rust api to allow writing modules in rust.
  • Loading branch information
IntQuant authored Nov 26, 2024
2 parents 8d40e2f + 2c065fc commit 5628b78
Show file tree
Hide file tree
Showing 19 changed files with 9,527 additions and 252 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ save_state
*png~
/quant.ew/files/system/player/tmp/
/quant.ew/ewext.dll
/quant.ew/ewext0.dll
/quant.ew/ewext0.dll
132 changes: 131 additions & 1 deletion ewext/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion ewext/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ewext"
version = "0.3.0"
version = "0.4.0"
edition = "2021"

[lib]
Expand All @@ -15,3 +15,6 @@ strip = true
libloading = "0.8.5"
backtrace = "0.3.74"
iced-x86 = "1.21.0"
noita_api_macro = {path = "noita_api_macro"}
eyre = "0.6.12"
noita_api = {path = "noita_api"}
9 changes: 9 additions & 0 deletions ewext/noita_api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "noita_api"
version = "0.1.0"
edition = "2021"

[dependencies]
eyre = "0.6.12"
libloading = "0.8.5"
noita_api_macro = {path = "../noita_api_macro"}
81 changes: 81 additions & 0 deletions ewext/noita_api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use std::{borrow::Cow, num::NonZero};

use eyre::{eyre, Context};

pub mod lua;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EntityID(pub NonZero<isize>);

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ComponentID(pub NonZero<isize>);

pub struct Obj(pub usize);

pub struct Color(pub u32);

pub trait Component: From<ComponentID> {
const NAME_STR: &'static str;
}

noita_api_macro::generate_components!();

impl EntityID {
pub fn try_get_first_component<C: Component>(
self,
tag: Option<Cow<'_, str>>,
) -> eyre::Result<Option<C>> {
raw::entity_get_first_component(self, C::NAME_STR.into(), tag)
.map(|x| x.flatten().map(Into::into))
.wrap_err_with(|| eyre!("Failed to get first component {} for {self:?}", C::NAME_STR))
}
pub fn get_first_component<C: Component>(self, tag: Option<Cow<'_, str>>) -> eyre::Result<C> {
self.try_get_first_component(tag)?
.ok_or_else(|| eyre!("Entity {self:?} has no component {}", C::NAME_STR))
}
}

pub mod raw {
use eyre::eyre;
use eyre::Context;

use super::{Color, ComponentID, EntityID, Obj};
use crate::lua::LuaGetValue;
use crate::lua::LuaPutValue;
use std::borrow::Cow;

use crate::lua::LuaState;

noita_api_macro::generate_api!();

pub(crate) fn component_get_value<T>(component: ComponentID, field: &str) -> eyre::Result<T>
where
T: LuaGetValue,
{
let lua = LuaState::current()?;
lua.get_global(c"ComponentGetValue2");
lua.push_integer(component.0.into());
lua.push_string(field);
lua.call(2, T::size_on_stack());
let ret = T::get(lua, -1);
lua.pop_last_n(T::size_on_stack());
ret.wrap_err_with(|| eyre!("Getting {field} for {component:?}"))
}

pub(crate) fn component_set_value<T>(
component: ComponentID,
field: &str,
value: T,
) -> eyre::Result<()>
where
T: LuaPutValue,
{
let lua = LuaState::current()?;
lua.get_global(c"ComponentSetValue2");
lua.push_integer(component.0.into());
lua.push_string(field);
value.put(lua);
lua.call(2 + T::size_on_stack(), 0);
Ok(())
}
}
Loading

0 comments on commit 5628b78

Please sign in to comment.