1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*! Sciter Object Model (SOM passport), native C interface.

See https://sciter.com/native-code-exposure-to-script/
and https://sciter.com/developers/for-native-gui-programmers/sciter-object-model/.

*/

#![allow(non_snake_case, non_camel_case_types)]
#![allow(dead_code)]

use capi::sctypes::*;
use capi::scvalue::VALUE;

/// An atom value that uniquely identifies the name being registered.
pub type som_atom_t = u64;


/// `som_asset_t` is a structure that a custom native object must be derived from.
#[repr(C)]
#[derive(Debug)]
pub struct som_asset_t {
	pub(crate) isa: &'static som_asset_class_t,
}

impl som_asset_t {
	pub(crate) fn get_passport(&self) -> *const som_passport_t {
		(self.isa.get_passport)(self as *const _ as *mut _)
	}
}

/// Is a pack of 4 pointers to functions that define the life time of an asset.
#[repr(C)]
#[derive(Debug)]
pub(crate) struct som_asset_class_t {
	/// Increments the reference count for an interface on an object.
	pub add_ref: extern "C" fn(thing: *mut som_asset_t) -> i32,

	/// Decrements the reference count for an interface on an object.
	pub release: extern "C" fn(thing: *mut som_asset_t) -> i32,

	/// Retrieves a pointer to a supported interface of an object.
	pub get_interface: extern "C" fn(thing: *mut som_asset_t, name: LPCSTR, out: *mut *mut som_asset_t) -> bool,

	/// Retrieves a pointer to the passport declaration of an object.
	pub get_passport: extern "C" fn(thing: *mut som_asset_t) -> *const som_passport_t,
}


/// Defines properties and methods of an asset.
#[repr(C)]
pub struct som_passport_t {
	/// Flags of an asset, see [`som_passport_flags`](enum.som_passport_flags.html).
	pub flags: u64,

	/// The name of the class (asset type).
	pub name: som_atom_t,

	/// Properties: `asset.prop`.
	///
	/// Must be a pointer to an array of structures:
	///
	/// ```rust,no_run
	/// # use sciter::om::*;
	/// let mut pst = Box::new(som_passport_t::default());
	///
	/// type ObjectProps = [som_property_def_t; 2];
	/// let mut props = Box::new(ObjectProps::default());
	///
	/// let mut prop1 = &mut props[0];
	/// prop1.name = atom("age");
	///
	/// let mut prop2 = &mut props[1];
	/// prop2.name = atom("name");
	///
	/// pst.n_properties = 2;
	/// pst.properties = Box::into_raw(props) as *const _;
	/// ```

	pub properties: *const som_property_def_t,

	/// Properties count.
	pub n_properties: usize,

	/// Methods: `asset.func()`
	///
	/// Must be a pointer to an array of structures,
	/// see [`properties`](struct.som_passport_t.html#structfield.properties) for an example.
	pub methods: *const som_method_def_t,

	/// Methods count.
	pub n_methods: usize,

	/// Index access: `var item = asset[key]`.
	pub item_getter: Option<som_item_getter_t>,

	/// Index access: `asset[key] = item`.
	pub item_setter: Option<som_item_setter_t>,

	/// Enumeration: `for(var item in asset)`.
	pub item_next: Option<som_item_next_t>,

	/// Property access interceptor: `var val = asset.prop`.
	pub prop_getter: Option<som_any_prop_getter_t>,

	/// Property set interceptor: `asset.prop = val`.
	pub prop_setter: Option<som_any_prop_setter_t>,
}

/// Empty passport.
impl Default for som_passport_t {
	fn default() -> Self {
		use std::ptr;
		Self {
			flags: 0,
			name: 0,

			prop_getter: None,
			prop_setter: None,

			item_getter: None,
			item_setter: None,
			item_next: None,

			properties: ptr::null(),
			n_properties: 0,

			methods: ptr::null(),
			n_methods: 0,
		}
	}
}


/// [`som_passport_t`](struct.som_passport_t.html#structfield.flags) flags.
#[repr(u64)]
#[derive(Debug, PartialOrd, PartialEq)]
pub enum som_passport_flags {
	/// Not extendable.
	SEALED = 0,

	/// Extendable.
	///
	/// An asset may have new properties added by script.
	EXTENDABLE = 1,
}


/// Property of an asset.
#[repr(C)]
pub struct som_property_def_t {
	pub reserved: LPVOID,

	/// Property name.
	pub name: som_atom_t,

	/// Property getter: `var val = asset.prop`.
	pub getter: Option<som_prop_getter_t>,

	/// Property setter: `asset.prop = val`.
	pub setter: Option<som_prop_setter_t>,
}

/// Empty property.
impl Default for som_property_def_t {
	fn default() -> Self {
		Self {
			reserved: std::ptr::null_mut(),
			name: 0,
			getter: None,
			setter: None,
		}
	}
}

/// Method of an asset.
#[repr(C)]
pub struct som_method_def_t {
	pub reserved: LPVOID,

	/// Method name.
	pub name: som_atom_t,

	/// Parameters count.
	///
	/// The actual arguments count can be lesser then specified here:
	///
	/// ```tiscript,ignore
	/// function asset.func(a,b,c);  // native asset method accepts 3 parameters
	///
	/// asset.func("one"); // call with only one parameter.
	/// ```
	pub params: usize,

	/// Method body.
	pub func: Option<som_method_t>,
}

/// Empty method.
impl Default for som_method_def_t {
	fn default() -> Self {
		Self {
			reserved: std::ptr::null_mut(),
			name: 0,
			params: 0,
			func: None,
		}
	}
}

type som_dispose_t = extern "C" fn(thing: *mut som_asset_t);

type som_prop_getter_t = extern "C" fn(thing: *mut som_asset_t, p_value: &mut VALUE) -> BOOL;
type som_prop_setter_t = extern "C" fn(thing: *mut som_asset_t, p_value: &VALUE) -> BOOL;

type som_any_prop_getter_t = extern "C" fn(thing: *mut som_asset_t, propSymbol: som_atom_t, p_value: &mut VALUE) -> BOOL;
type som_any_prop_setter_t = extern "C" fn(thing: *mut som_asset_t, propSymbol: som_atom_t, p_value: &VALUE) -> BOOL;

type som_item_getter_t = extern "C" fn(thing: *mut som_asset_t, p_key: &VALUE, p_value: &mut VALUE) -> BOOL;
type som_item_setter_t = extern "C" fn(thing: *mut som_asset_t, p_key: &VALUE, p_value: &VALUE) -> BOOL;

type som_item_next_t = extern "C" fn(thing: *mut som_asset_t, p_idx: &mut VALUE, p_value: &mut VALUE) -> BOOL;

type som_method_t = extern "C" fn(thing: *mut som_asset_t, argc: u32, argv: *const VALUE, p_result: &mut VALUE) -> BOOL;