Skip to content

Commit

Permalink
Register new CName / CName as Hash (#41)
Browse files Browse the repository at this point in the history
* Convert CName from/to u64

allows to use std::hash:Hash with newtype pattern over CName

* Add method to register new CName

* Lint code

* Check CName exists in Rust

also renamed according to IsNameValid (cyberdoc)

* Handle None for CName

* More idiomatic conversion from CName to u64

* Add check for None in CName new

* Rename CName add to new_pooled

* Add unit-test for CName new with empty string

* Refactor check for None in CName new

Co-authored-by: jac3km4 <[email protected]>

* Lint code

* Add annotations to CName functions

---------

Co-authored-by: jac3km4 <[email protected]>
  • Loading branch information
Roms1383 and jac3km4 authored Dec 27, 2023
1 parent 52ee3f3 commit d2d7713
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
5 changes: 5 additions & 0 deletions red4ext-sys/cpp/glue/glue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ rust::Str ResolveCName(const CName& cname)
return rust::Str(CNamePool::Get(cname));
}

CName AddCName(rust::Str text)
{
return CNamePool::Add(std::string(text).c_str());
}

CClassFunction* GetMethod(const CClass& cls, const CName& fullName)
{
auto res = cls.funcsByName.Get(fullName);
Expand Down
35 changes: 34 additions & 1 deletion red4ext-sys/src/interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,41 @@ pub struct CName {
hash: u64,
}

impl From<u64> for CName {
fn from(hash: u64) -> Self {
Self { hash }
}
}

impl From<CName> for u64 {
fn from(value: CName) -> Self {
value.hash
}
}

impl CName {
#[inline]
pub const fn new(str: &str) -> Self {
Self { hash: fnv1a64(str) }
match str.as_bytes() {
b"None" => Self { hash: 0 },
_ => Self { hash: fnv1a64(str) },
}
}

#[cfg(not(test))] // only available in-game
pub fn new_pooled(str: &str) -> Self {
let cname = Self::new(str);
if cname.is_valid() {
return cname;
}
let created = crate::ffi::add_cname(str);
assert_eq!(created, cname);
created
}

#[cfg(not(test))] // only available in-game
pub fn is_valid(&self) -> bool {
!crate::ffi::resolve_cname(self).is_empty()
}
}

Expand Down Expand Up @@ -477,6 +508,8 @@ mod tests {
assert_eq!(CName::new("IScriptable").hash, 3_191_163_302_135_919_211);
assert_eq!(CName::new("Vector2").hash, 7_466_804_955_052_523_504);
assert_eq!(CName::new("Color").hash, 3_769_135_706_557_701_272);
assert_eq!(CName::new("None").hash, 0);
assert_eq!(CName::new("").hash, 0xCBF2_9CE4_8422_2325);
}

#[test]
Expand Down
3 changes: 3 additions & 0 deletions red4ext-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ pub mod ffi {
#[cxx_name = "ResolveCName"]
fn resolve_cname(cname: &CName) -> &'static str;

#[cxx_name = "AddCName"]
fn add_cname(text: &str) -> CName;

#[cxx_name = "GetMethod"]
fn get_method(cls: &CClass, name: &CName) -> *mut CClassFunction;

Expand Down

0 comments on commit d2d7713

Please sign in to comment.