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