Skip to content

Commit

Permalink
Merge pull request #13 from ohos-rs/feat-build
Browse files Browse the repository at this point in the history
feat: MVP ArkUI
  • Loading branch information
richerfu authored Nov 6, 2024
2 parents 7094014 + 3733bb8 commit 126f169
Show file tree
Hide file tree
Showing 43 changed files with 2,521 additions and 213 deletions.
22 changes: 16 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ resolver = "2"
[workspace.dependencies]
ohos-bundle-binding = { version = "0.0.1", path = "crates/bundle" }
ohos-init-binding = { version = "0.0.3", path = "crates/init" }
ohos-hilog-binding = { version = "0.0.3", path = "crates/hilog" }
ohos-hilog-binding = { version = "0.0.4", path = "crates/hilog" }
ohos-asset-binding = { version = "0.0.1", path = "crates/asset" }
ohos-raw-binding = { version = "0.0.2", path = "crates/raw" }
ohos-resource-manager-binding = { version = "0.0.1", path = "crates/resource_manager" }
ohos-ability-access-control-binding = { version = "0.0.1", path = "crates/ability_access_control" }
ohos-xcomponent-binding = { version = "0.0.1", path = "crates/xcomponent" }
ohos-arkui-binding = { version = "0.0.1", path = "crates/arkui" }

ohos-bundle-sys = { version = "0.0.2", path = "sys/ohos-bundle-sys" }
ohos-init-sys = { version = "0.0.2", path = "sys/ohos-init-sys" }
Expand All @@ -20,10 +21,19 @@ ohos-raw-sys = { version = "0.0.1", path = "sys/ohos-raw-sys"
ohos-resource-manager-sys = { version = "0.0.2", path = "sys/ohos-resource-manager-sys" }
ohos-ability-access-control-sys = { version = "0.0.1", path = "sys/ohos-ability-access-control-sys" }
ohos-xcomponent-sys = { version = "0.0.1", path = "sys/ohos-xcomponent-sys" }
ohos-arkui-sys = { version = "0.0.1", path = "sys/ohos-arkui-sys" }

napi-ohos = { version = "1.0.0-beta.7" }
napi-derive-ohos = { version = "1.0.0-beta.7" }
napi-build-ohos = { version = "1.0.0-beta.7" }
napi-sys-ohos = { version = "1.0.0-beta.7" }
enum_macro = { version = "0.0.1", path = "crates/enum_macro" }

libc = { version = "0.2" }
napi-ohos = { version = "1.0" }
napi-derive-ohos = { version = "1.0" }
napi-build-ohos = { version = "1.0" }
napi-sys-ohos = { version = "1.0" }

libc = { version = "0.2" }
syn = { version = "2.0" }
quote = { version = "1.0" }
proc-macro2 = { version = "1.0" }
convert_case = { version = "0.6" }
regex = { version = "1.0" }
thiserror = { version = "2.0" }
11 changes: 11 additions & 0 deletions crates/arkui/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "ohos-arkui-binding"
version = "0.0.1"
edition = "2021"

[dependencies]
ohos-arkui-sys = { workspace = true }
napi-sys-ohos = { workspace = true }
napi-ohos = { workspace = true }
enum_macro = { workspace = true }
thiserror = { workspace = true }
63 changes: 63 additions & 0 deletions crates/arkui/src/common/attribute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::ffi::CString;

use ohos_arkui_sys::{ArkUI_AttributeItem, ArkUI_NumberValue};

#[derive(Clone, Copy, PartialEq)]
pub enum ArkUINodeAttributeNumber {
Float(f32),
Int(i32),
Uint(u32),
}

pub enum ArkUINodeAttributeItem {
/// Accept number array
NumberValue(Vec<ArkUINodeAttributeNumber>),
/// Accept string
/// value and size will be set to null and 0
String(String),
/// Accept object
/// value and size and string will be set to null and 0 and null
/// TODO: we need to check the type of object
Object(*mut ::std::os::raw::c_void),
}

impl From<ArkUINodeAttributeItem> for ArkUI_AttributeItem {
fn from(value: ArkUINodeAttributeItem) -> Self {
match value {
ArkUINodeAttributeItem::NumberValue(value) => {
let mut v: Vec<ArkUI_NumberValue> = value
.iter()
.map(|v| match v {
ArkUINodeAttributeNumber::Float(f) => ArkUI_NumberValue { f32_: *f },
ArkUINodeAttributeNumber::Int(i) => ArkUI_NumberValue { i32_: *i },
ArkUINodeAttributeNumber::Uint(u) => ArkUI_NumberValue { u32_: *u },
})
.collect();
let value_ptr = v.as_mut_ptr();
let len = v.len();
std::mem::forget(v);
ArkUI_AttributeItem {
value: value_ptr,
size: len as i32,
string: std::ptr::null_mut(),
object: std::ptr::null_mut(),
}
}
ArkUINodeAttributeItem::Object(obj) => ArkUI_AttributeItem {
value: std::ptr::null_mut(),
size: 0,
string: std::ptr::null_mut(),
object: obj,
},
ArkUINodeAttributeItem::String(s) => {
let c_string = CString::new(s).unwrap();
ArkUI_AttributeItem {
value: std::ptr::null_mut(),
size: 0,
string: c_string.into_raw(),
object: std::ptr::null_mut(),
}
}
}
}
}
14 changes: 14 additions & 0 deletions crates/arkui/src/common/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use thiserror::Error;

#[derive(Error, Debug)]
pub enum ArkUIError {
#[error("ArkUI call `{0}` failed with params invalid")]
ParamsInvalid(String),
}

/// This type is used for ArkUI result.
pub type ArkUIResult = Result<(), ArkUIError>;

macro_rules! check_arkui_status {
() => {};
}
48 changes: 48 additions & 0 deletions crates/arkui/src/common/handle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use napi_ohos::bindgen_prelude::{check_status, FromNapiValue, TypeName, ValidateNapiValue};
use napi_sys_ohos as sys;
use ohos_arkui_sys::{ArkUI_NodeContentHandle, OH_ArkUI_GetNodeContentFromNapiValue};
use std::ptr;

#[derive(Clone, Copy)]
pub struct ArkUIHandle {
pub(crate) env: sys::napi_env,
pub(crate) value: sys::napi_value,
raw: ArkUI_NodeContentHandle,
}

impl ArkUIHandle {
pub fn raw(&self) -> ArkUI_NodeContentHandle {
self.raw
}
}

impl TypeName for ArkUIHandle {
fn type_name() -> &'static str {
"ArkUIHandle"
}
fn value_type() -> napi_ohos::ValueType {
napi_ohos::ValueType::Object
}
}

impl ValidateNapiValue for ArkUIHandle {}

impl FromNapiValue for ArkUIHandle {
unsafe fn from_napi_value(
env: sys::napi_env,
napi_val: sys::napi_value,
) -> napi_ohos::Result<Self> {
let mut slot = ptr::null_mut();
unsafe {
check_status!(
OH_ArkUI_GetNodeContentFromNapiValue(env, napi_val, &mut slot),
"Get Node Content Slot failed."
)?
};
Ok(ArkUIHandle {
env,
value: napi_val,
raw: slot,
})
}
}
11 changes: 11 additions & 0 deletions crates/arkui/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mod attribute;
mod error;
mod handle;
mod native_node_api;
mod node;

pub use attribute::*;
pub use error::*;
pub use handle::*;
pub use native_node_api::*;
pub use node::*;
73 changes: 73 additions & 0 deletions crates/arkui/src/common/native_node_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::{cell::LazyCell, ffi::CString};

use napi_ohos::{Error, Result};
use ohos_arkui_sys::{
ArkUI_NativeAPIVariantKind_ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, ArkUI_NodeHandle,
OH_ArkUI_QueryModuleInterfaceByName,
};

use crate::{ArkUINodeAttributeType, ArkUINodeType};

use super::{ArkUINode, ArkUINodeAttributeItem};

/// ArkUI_NativeNodeAPI_1 struct
/// Only can be used in main thread
pub const ARK_UI_NATIVE_NODE_API_1: LazyCell<ArkUINativeNodeAPI1> = LazyCell::new(|| {
let api = ArkUINativeNodeAPI1::new();
api
});

pub struct ArkUINativeNodeAPI1(pub(crate) *mut ArkUI_NativeNodeAPI_1);

impl ArkUINativeNodeAPI1 {
/// allow us to get the pointer of ArkUI_NativeNodeAPI_1 and use it directly
pub fn raw(&self) -> *mut ArkUI_NativeNodeAPI_1 {
self.0
}

pub fn new() -> Self {
let mut api: *mut ArkUI_NativeNodeAPI_1 = std::ptr::null_mut();
let struct_name = CString::new("ArkUI_NativeNodeAPI_1").unwrap();
let raw_ptr = unsafe {
OH_ArkUI_QueryModuleInterfaceByName(
ArkUI_NativeAPIVariantKind_ARKUI_NATIVE_NODE,
struct_name.as_ptr().cast(),
)
};
#[cfg(debug_assertions)]
assert!(!raw_ptr.is_null(), "ArkUI_NativeNodeAPI_1 is NULL");
api = raw_ptr.cast();
Self(api)
}

pub fn create_node(&self, node_type: ArkUINodeType) -> Result<ArkUI_NodeHandle> {
unsafe {
if let Some(create_node) = (*self.0).createNode {
let handle = create_node(node_type.into());
Ok(handle)
} else {
Err(Error::from_reason(
"ArkUI_NativeNodeAPI_1::createNode is None",
))
}
}
}

pub fn set_attribute(
&self,
node: &ArkUINode,
attr: ArkUINodeAttributeType,
value: ArkUINodeAttributeItem,
) -> Result<()> {
unsafe {
if let Some(set_attribute) = (*self.0).setAttribute {
set_attribute(node.raw(), attr.into(), &value.into());
Ok(())
} else {
Err(Error::from_reason(
"ArkUI_NativeNodeAPI_1::setAttribute is None",
))
}
}
}
}
81 changes: 81 additions & 0 deletions crates/arkui/src/common/node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use napi_ohos::bindgen_prelude::{check_status, FromNapiValue, TypeName, ValidateNapiValue};
use napi_sys_ohos as sys;
use ohos_arkui_sys::{ArkUI_NodeHandle, OH_ArkUI_GetNodeHandleFromNapiValue};
use std::ptr;

use crate::ArkUINodeType;

#[derive(Clone)]
pub struct ArkUINode {
pub(crate) raw: ArkUI_NodeHandle,
pub(crate) tag: ArkUINodeType,
pub(crate) children: Vec<Box<ArkUINode>>,
}

impl ArkUINode {
pub fn children(&self) -> &[Box<ArkUINode>] {
self.children.as_slice()
}

pub fn children_mut(&mut self) -> &mut Vec<Box<ArkUINode>> {
self.children.as_mut()
}

pub fn raw(&self) -> ArkUI_NodeHandle {
self.raw
}

pub fn remove_child(&mut self, index: usize) -> Option<Box<ArkUINode>> {
if index < self.children().len() {
Some(self.children_mut().remove(index))
} else {
None
}
}

pub fn add_child(&mut self, child: Box<ArkUINode>) {
self.children_mut().push(child);
}

pub fn insert_child(&mut self, child: Box<ArkUINode>, index: usize) {
self.children_mut().insert(index, child);
}
}

/// Convert ArkUI node to native node
pub struct ArkUINodeRaw {
pub(crate) env: sys::napi_env,
pub(crate) value: sys::napi_value,
pub raw: ArkUI_NodeHandle,
}

impl TypeName for ArkUINodeRaw {
fn type_name() -> &'static str {
"ArkUINode"
}
fn value_type() -> napi_ohos::ValueType {
napi_ohos::ValueType::Object
}
}

impl ValidateNapiValue for ArkUINodeRaw {}

impl FromNapiValue for ArkUINodeRaw {
unsafe fn from_napi_value(
env: sys::napi_env,
napi_val: sys::napi_value,
) -> napi_ohos::Result<Self> {
let mut slot = ptr::null_mut();
unsafe {
check_status!(
OH_ArkUI_GetNodeHandleFromNapiValue(env, napi_val, &mut slot),
"Get Node failed."
)?
};
Ok(ArkUINodeRaw {
env,
value: napi_val,
raw: slot,
})
}
}
3 changes: 3 additions & 0 deletions crates/arkui/src/component/built_in_component/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod text;

pub use text::*;
Loading

0 comments on commit 126f169

Please sign in to comment.