1mod interop;
9mod registry;
10
11pub use interop::Interop;
12pub use registry::{installed_mods, open_ui, server, CServer, Mod, ModInfo, Registry};
13pub use yog_gfx::{core as gfx_core, draw2d as gfx_draw2d, gl as gfx_gl, GfxContext};
14
15pub use yog_abi::{YogApi, ABI_VERSION};
17
18pub use yog_interop::{import, yog_export};
20
21pub use rkyv;
25
26pub use ctor;
31
32#[doc(hidden)]
33pub use std::os::raw::c_void as __c_void;
34
35#[macro_export]
48macro_rules! export_mod {
49 ($mod_ty:ty) => {
50 #[no_mangle]
51 pub extern "C" fn yog_abi_version() -> u32 {
52 $crate::ABI_VERSION
53 }
54
55 #[no_mangle]
56 pub unsafe extern "C" fn yog_mod_register(
57 api: *const $crate::YogApi,
58 mod_id_ptr: *const ::std::os::raw::c_char,
59 ) {
60 let mod_id: &str = if mod_id_ptr.is_null() {
62 "unknown"
63 } else {
64 match ::std::ffi::CStr::from_ptr(mod_id_ptr).to_str() {
65 Ok(s) => s,
66 Err(_) => "unknown",
67 }
68 };
69 $crate::__set_current_mod_id(mod_id);
71 $crate::__set_current_api_ptr(api as usize);
76
77 let outcome = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
80 let mut registry = unsafe { $crate::Registry::from_raw(api) };
83 <$mod_ty as $crate::Mod>::register(&mut registry);
84
85 for entry in $crate::__yog_export_registry().lock().unwrap().iter() {
88 registry
89 .interop()
90 .export(entry.name, entry.ptr as *const ::std::os::raw::c_void);
91 }
92
93 $crate::__yog_resolve_pending_imports(®istry);
96 }));
97 if outcome.is_err() {
98 $crate::error!(
99 "mod {} panicked during register",
100 ::core::stringify!($mod_ty)
101 );
102 }
103 }
104
105 #[no_mangle]
108 pub unsafe extern "C" fn __yog_resolve_imports_final(api: *const $crate::YogApi) {
109 let registry = unsafe { $crate::Registry::from_raw(api) };
110 $crate::__yog_resolve_pending_imports(®istry);
111 }
112 };
113}
114
115#[doc(hidden)]
119pub fn __set_current_mod_id(id: &str) {
120 CURRENT_MOD_ID.with(|cell| cell.replace(Some(id.to_string())));
121}
122
123#[doc(hidden)]
125pub fn __current_mod_id() -> Option<String> {
126 CURRENT_MOD_ID.with(|cell| cell.borrow().clone())
127}
128
129#[doc(hidden)]
135pub fn __set_current_api_ptr(ptr: usize) {
136 API_PTR.store(ptr, std::sync::atomic::Ordering::Release);
137}
138
139#[doc(hidden)]
140pub fn __current_api_ptr() -> usize {
141 API_PTR.load(std::sync::atomic::Ordering::Acquire)
142}
143
144static API_PTR: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
145
146std::thread_local! {
147 static CURRENT_MOD_ID: std::cell::RefCell<Option<String>> = std::cell::RefCell::new(None);
148}
149
150#[doc(hidden)]
153pub struct YogExportEntry {
154 pub name: &'static str,
155 pub ptr: usize,
156}
157
158#[doc(hidden)]
159pub struct YogImportEntry {
160 pub mod_id: &'static str,
161 pub symbol: &'static str,
162 pub bind_fn: usize,
163}
164
165#[doc(hidden)]
166pub fn __yog_export_registry() -> &'static std::sync::Mutex<Vec<YogExportEntry>> {
167 static REG: std::sync::LazyLock<std::sync::Mutex<Vec<YogExportEntry>>> =
168 std::sync::LazyLock::new(|| std::sync::Mutex::new(Vec::new()));
169 ®
170}
171
172#[doc(hidden)]
173pub fn __yog_import_registry() -> &'static std::sync::Mutex<Vec<YogImportEntry>> {
174 static REG: std::sync::LazyLock<std::sync::Mutex<Vec<YogImportEntry>>> =
175 std::sync::LazyLock::new(|| std::sync::Mutex::new(Vec::new()));
176 ®
177}
178
179#[doc(hidden)]
183pub unsafe fn __yog_resolve_pending_imports(registry: &crate::Registry) {
184 let interop = registry.interop();
185 for entry in __yog_import_registry().lock().unwrap().iter() {
186 if let Some(ptr) = interop.import_raw(entry.mod_id, entry.symbol) {
187 let bind: unsafe extern "C" fn(*const std::ffi::c_void) =
188 std::mem::transmute(entry.bind_fn);
189 bind(ptr);
190 }
191 }
192}
193
194pub use yog_book::{
195 crafting_page, entity_page, image_page, pattern_page, relations_page, smelting_page,
196 spotlight_page, text_page, text_page_titled,
197};
198pub use yog_book::{Book, BookCategory, BookEntry, BookMacro, BookPage, BookRegistry};
199pub use yog_book::{BookFontRegistry, BookRenderer};
200pub use yog_command::CommandContext;
201pub use yog_config::Config;
202pub use yog_core::{BlockPos, Server};
203pub use yog_entity::Entity;
204pub use yog_event::{
205 AdvancementEvent, AttackEntityEvent, BlockBreakEvent, ChatEvent, ClientTickEvent,
206 ContainerCloseEvent, ContainerOpenEvent, CraftEvent, EntityDamageEvent, EntityDeathEvent,
207 EntityInteractEvent, EntitySpawnEvent, EventPhase, ExplosionEvent, ItemPickupEvent,
208 KeyPressEvent, PlaceBlockEvent, PlayerDeathEvent, PlayerJoinEvent, PlayerLeaveEvent,
209 PlayerMoveEvent, PlayerRespawnEvent, ProjectileHitEvent, ScreenEvent, UseBlockEvent,
210 UseItemEvent,
211};
212pub use yog_inventory::{InventoryDef, SlotLayout};
213#[doc(inline)]
214pub use yog_network::packet;
215pub use yog_network::{Packet, PacketEvent, PacketField};
216pub use yog_player::Player;
217pub use yog_registry::{
218 AdvancementReward, BlockDef, BookRecipe, FoodDef, FurnaceRecipe, ItemDef, ItemModifier,
219 ShapedRecipe, ShapelessRecipe, StartupGrant,
220};
221pub use yog_storage::{Storage, StorageScope, Value};
222pub use yog_ui::{widget, Align, Dock, FlexDir, FocusStyle, LayoutNode, Rect, UiRoot};
223pub use yog_world::World;
224
225pub use yog_logging::{error, info, warn};
227
228pub mod core {
230 pub use yog_core::*;
231}
232
233pub mod event {
235 pub use yog_event::*;
236}
237
238pub mod world {
240 pub use yog_world::*;
241}
242
243pub mod entity {
245 pub use yog_entity::*;
246}
247
248pub mod player {
250 pub use yog_player::*;
251}
252
253pub mod content {
255 pub use yog_registry::*;
256}
257
258pub mod network {
260 pub use yog_network::*;
261}
262
263pub mod command {
265 pub use yog_command::*;
266}
267
268pub mod storage {
270 pub use yog_storage::*;
271}
272
273pub mod config {
275 pub use yog_config::*;
276}
277
278pub mod book {
280 pub use yog_book::*;
281}
282
283pub mod ui {
285 pub use yog_ui::*;
286}
287
288pub mod inventory {
291 pub use yog_inventory::*;
292}