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 entry in $crate::__yog_export_registry().lock().unwrap().iter() {
76 registry.interop().export(entry.name, entry.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)]
122pub struct YogExportEntry {
123 pub name: &'static str,
124 pub ptr: usize,
125}
126
127#[doc(hidden)]
129pub struct YogImportEntry {
130 pub mod_id: &'static str,
131 pub symbol: &'static str,
132 pub bind_fn: usize,
133}
134
135#[doc(hidden)]
138pub fn __yog_export_registry() -> &'static std::sync::Mutex<Vec<YogExportEntry>> {
139 static REG: std::sync::LazyLock<std::sync::Mutex<Vec<YogExportEntry>>> =
140 std::sync::LazyLock::new(|| std::sync::Mutex::new(Vec::new()));
141 ®
142}
143
144#[doc(hidden)]
147pub fn __yog_import_registry() -> &'static std::sync::Mutex<Vec<YogImportEntry>> {
148 static REG: std::sync::LazyLock<std::sync::Mutex<Vec<YogImportEntry>>> =
149 std::sync::LazyLock::new(|| std::sync::Mutex::new(Vec::new()));
150 ®
151}
152
153#[doc(hidden)]
157pub unsafe fn __yog_resolve_pending_imports(registry: &crate::Registry) {
158 let interop = registry.interop();
159 for entry in __yog_import_registry().lock().unwrap().iter() {
160 if let Some(ptr) = interop.import_raw(entry.mod_id, entry.symbol) {
161 let bind: unsafe extern "C" fn(*const std::ffi::c_void) = std::mem::transmute(entry.bind_fn);
162 bind(ptr);
163 }
164 }
165}
166
167pub use yog_command::CommandContext;
168pub use yog_core::{BlockPos, Server};
169pub use yog_event::{
170 AdvancementEvent, AttackEntityEvent, BlockBreakEvent, ChatEvent, ClientTickEvent,
171 ContainerCloseEvent, ContainerOpenEvent, CraftEvent, EntityDamageEvent, EntityDeathEvent,
172 EntityInteractEvent, EntitySpawnEvent, EventPhase, ExplosionEvent,
173 ItemPickupEvent, KeyPressEvent, PlaceBlockEvent, PlayerDeathEvent, PlayerJoinEvent,
174 PlayerLeaveEvent, PlayerMoveEvent, PlayerRespawnEvent, ProjectileHitEvent, ScreenEvent,
175 UseBlockEvent, UseItemEvent,
176};
177pub use yog_entity::Entity;
178pub use yog_network::{Packet, PacketEvent, PacketField};
179#[doc(inline)]
180pub use yog_network::packet;
181pub use yog_player::Player;
182pub use yog_registry::{BlockDef, FoodDef, FurnaceRecipe, ItemDef, ShapedRecipe, ShapelessRecipe, BookRecipe, ItemModifier, AdvancementReward, StartupGrant};
183pub use yog_config::Config;
184pub use yog_storage::{Storage, StorageScope, Value};
185pub use yog_world::World;
186pub use yog_book::{Book, BookCategory, BookEntry, BookPage, BookMacro, BookRegistry};
187pub use yog_book::{BookRenderer, BookFontRegistry};
188pub use yog_book::{text_page, text_page_titled, spotlight_page, crafting_page, smelting_page, image_page, entity_page, relations_page, pattern_page};
189pub use yog_ui::{UiRoot, LayoutNode, Rect, widget, Align, FlexDir, Dock, FocusStyle};
190pub use yog_inventory::{InventoryDef, SlotLayout};
191
192pub use yog_logging::{error, info, warn};
194
195pub mod core {
197 pub use yog_core::*;
198}
199
200pub mod event {
202 pub use yog_event::*;
203}
204
205pub mod world {
207 pub use yog_world::*;
208}
209
210pub mod entity {
212 pub use yog_entity::*;
213}
214
215pub mod player {
217 pub use yog_player::*;
218}
219
220pub mod content {
222 pub use yog_registry::*;
223}
224
225pub mod network {
227 pub use yog_network::*;
228}
229
230pub mod command {
232 pub use yog_command::*;
233}
234
235pub mod storage {
237 pub use yog_storage::*;
238}
239
240pub mod config {
242 pub use yog_config::*;
243}
244
245pub mod book {
247 pub use yog_book::*;
248}
249
250pub mod ui {
252 pub use yog_ui::*;
253}
254
255pub mod inventory {
258 pub use yog_inventory::*;
259}