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::{GfxContext, core as gfx_core, gl as gfx_gl, draw2d as gfx_draw2d};
14
15pub use yog_abi::{ABI_VERSION, YogApi};
17
18pub use yog_interop::{yog_export, import};
20
21pub use rkyv;
25
26#[doc(hidden)]
27pub use std::os::raw::c_void as __c_void;
28
29#[macro_export]
42macro_rules! export_mod {
43 ($mod_ty:ty) => {
44 #[no_mangle]
45 pub extern "C" fn yog_abi_version() -> u32 {
46 $crate::ABI_VERSION
47 }
48
49 #[no_mangle]
50 pub unsafe extern "C" fn yog_mod_register(
51 api: *const $crate::YogApi,
52 mod_id_ptr: *const ::std::os::raw::c_char,
53 ) {
54 let mod_id: &str = if mod_id_ptr.is_null() {
56 "unknown"
57 } else {
58 match ::std::ffi::CStr::from_ptr(mod_id_ptr).to_str() {
59 Ok(s) => s,
60 Err(_) => "unknown",
61 }
62 };
63 $crate::__set_current_mod_id(mod_id);
65
66 let outcome = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
69 let mut registry = unsafe { $crate::Registry::from_raw(api) };
72 <$mod_ty as $crate::Mod>::register(&mut registry);
73
74 for (name, ptr) in $crate::__yog_export_registry().lock().unwrap().iter() {
76 registry.interop().export(name, *ptr as *const ::std::os::raw::c_void);
77 }
78
79 $crate::__yog_resolve_pending_imports(®istry);
82 }));
83 if outcome.is_err() {
84 $crate::error!("mod {} panicked during register", ::core::stringify!($mod_ty));
85 }
86 }
87
88 #[no_mangle]
91 pub unsafe extern "C" fn __yog_resolve_imports_final(
92 api: *const $crate::YogApi,
93 ) {
94 let registry = unsafe { $crate::Registry::from_raw(api) };
95 $crate::__yog_resolve_pending_imports(®istry);
96 }
97 };
98}
99
100#[doc(hidden)]
104pub fn __set_current_mod_id(id: &str) {
105 CURRENT_MOD_ID.with(|cell| cell.replace(Some(id.to_string())));
106}
107
108#[doc(hidden)]
110pub fn __current_mod_id() -> Option<String> {
111 CURRENT_MOD_ID.with(|cell| cell.borrow().clone())
112}
113
114std::thread_local! {
115 static CURRENT_MOD_ID: std::cell::RefCell<Option<String>> = std::cell::RefCell::new(None);
116}
117
118#[doc(hidden)]
123pub fn __yog_export_registry() -> &'static std::sync::Mutex<Vec<(&'static str, usize)>> {
124 static REG: std::sync::LazyLock<std::sync::Mutex<Vec<(&'static str, usize)>>> =
125 std::sync::LazyLock::new(|| std::sync::Mutex::new(Vec::new()));
126 ®
127}
128
129#[doc(hidden)]
132pub fn __yog_pending_imports() -> &'static std::sync::Mutex<Vec<(&'static str, &'static str, usize)>> {
133 static REG: std::sync::LazyLock<std::sync::Mutex<Vec<(&'static str, &'static str, usize)>>> =
134 std::sync::LazyLock::new(|| std::sync::Mutex::new(Vec::new()));
135 ®
136}
137
138#[doc(hidden)]
142pub unsafe fn __yog_resolve_pending_imports(registry: &crate::Registry) {
143 let interop = registry.interop();
144 for (mod_id, symbol, bind_fn_ptr) in __yog_pending_imports().lock().unwrap().iter() {
145 if let Some(ptr) = interop.import_raw(mod_id, symbol) {
146 let bind: unsafe extern "C" fn(*const std::ffi::c_void) = std::mem::transmute(*bind_fn_ptr);
147 bind(ptr);
148 }
149 }
150}
151
152pub use yog_command::CommandContext;
153pub use yog_core::{BlockPos, Server};
154pub use yog_event::{
155 AdvancementEvent, AttackEntityEvent, BlockBreakEvent, ChatEvent, ClientTickEvent,
156 ContainerCloseEvent, ContainerOpenEvent, CraftEvent, EntityDamageEvent, EntityDeathEvent,
157 EntityInteractEvent, EntitySpawnEvent, EventPhase, ExplosionEvent,
158 ItemPickupEvent, KeyPressEvent, PlaceBlockEvent, PlayerDeathEvent, PlayerJoinEvent,
159 PlayerLeaveEvent, PlayerMoveEvent, PlayerRespawnEvent, ProjectileHitEvent, ScreenEvent,
160 UseBlockEvent, UseItemEvent,
161};
162pub use yog_entity::Entity;
163pub use yog_network::{Packet, PacketEvent, PacketField};
164#[doc(inline)]
165pub use yog_network::packet;
166pub use yog_player::Player;
167pub use yog_registry::{BlockDef, FoodDef, FurnaceRecipe, ItemDef, ShapedRecipe, ShapelessRecipe, BookRecipe, ItemModifier, AdvancementReward, StartupGrant};
168pub use yog_config::Config;
169pub use yog_storage::{Storage, StorageScope, Value};
170pub use yog_world::World;
171pub use yog_book::{Book, BookCategory, BookEntry, BookPage, BookMacro, BookRegistry};
172pub use yog_book::{BookRenderer, BookFontRegistry};
173pub use yog_book::{text_page, text_page_titled, spotlight_page, crafting_page, smelting_page, image_page, entity_page, relations_page, pattern_page};
174pub use yog_ui::{UiRoot, LayoutNode, Rect, widget, Align, FlexDir, Dock, FocusStyle};
175pub use yog_inventory::{InventoryDef, SlotLayout};
176
177pub use yog_logging::{error, info, warn};
179
180pub mod core {
182 pub use yog_core::*;
183}
184
185pub mod event {
187 pub use yog_event::*;
188}
189
190pub mod world {
192 pub use yog_world::*;
193}
194
195pub mod entity {
197 pub use yog_entity::*;
198}
199
200pub mod player {
202 pub use yog_player::*;
203}
204
205pub mod content {
207 pub use yog_registry::*;
208}
209
210pub mod network {
212 pub use yog_network::*;
213}
214
215pub mod command {
217 pub use yog_command::*;
218}
219
220pub mod storage {
222 pub use yog_storage::*;
223}
224
225pub mod config {
227 pub use yog_config::*;
228}
229
230pub mod book {
232 pub use yog_book::*;
233}
234
235pub mod ui {
237 pub use yog_ui::*;
238}
239
240pub mod inventory {
243 pub use yog_inventory::*;
244}