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
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
72 let outcome = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
75 let mut registry = unsafe { $crate::Registry::from_raw(api) };
78 <$mod_ty as $crate::Mod>::register(&mut registry);
79
80 for entry in $crate::__yog_export_registry().lock().unwrap().iter() {
82 registry.interop().export(entry.name, entry.ptr as *const ::std::os::raw::c_void);
83 }
84
85 $crate::__yog_resolve_pending_imports(®istry);
88 }));
89 if outcome.is_err() {
90 $crate::error!("mod {} panicked during register", ::core::stringify!($mod_ty));
91 }
92 }
93
94 #[no_mangle]
97 pub unsafe extern "C" fn __yog_resolve_imports_final(
98 api: *const $crate::YogApi,
99 ) {
100 let registry = unsafe { $crate::Registry::from_raw(api) };
101 $crate::__yog_resolve_pending_imports(®istry);
102 }
103 };
104}
105
106#[doc(hidden)]
110pub fn __set_current_mod_id(id: &str) {
111 CURRENT_MOD_ID.with(|cell| cell.replace(Some(id.to_string())));
112}
113
114#[doc(hidden)]
116pub fn __current_mod_id() -> Option<String> {
117 CURRENT_MOD_ID.with(|cell| cell.borrow().clone())
118}
119
120std::thread_local! {
121 static CURRENT_MOD_ID: std::cell::RefCell<Option<String>> = std::cell::RefCell::new(None);
122}
123
124#[doc(hidden)]
127pub struct YogExportEntry { pub name: &'static str, pub ptr: usize }
128
129#[doc(hidden)]
130pub struct YogImportEntry { pub mod_id: &'static str, pub symbol: &'static str, pub bind_fn: usize }
131
132#[doc(hidden)]
133pub fn __yog_export_registry() -> &'static std::sync::Mutex<Vec<YogExportEntry>> {
134 static REG: std::sync::LazyLock<std::sync::Mutex<Vec<YogExportEntry>>> =
135 std::sync::LazyLock::new(|| std::sync::Mutex::new(Vec::new()));
136 ®
137}
138
139#[doc(hidden)]
140pub fn __yog_import_registry() -> &'static std::sync::Mutex<Vec<YogImportEntry>> {
141 static REG: std::sync::LazyLock<std::sync::Mutex<Vec<YogImportEntry>>> =
142 std::sync::LazyLock::new(|| std::sync::Mutex::new(Vec::new()));
143 ®
144}
145
146#[doc(hidden)]
150pub unsafe fn __yog_resolve_pending_imports(registry: &crate::Registry) {
151 let interop = registry.interop();
152 for entry in __yog_import_registry().lock().unwrap().iter() {
153 if let Some(ptr) = interop.import_raw(entry.mod_id, entry.symbol) {
154 let bind: unsafe extern "C" fn(*const std::ffi::c_void) = std::mem::transmute(entry.bind_fn);
155 bind(ptr);
156 }
157 }
158}
159
160pub use yog_command::CommandContext;
161pub use yog_core::{BlockPos, Server};
162pub use yog_event::{
163 AdvancementEvent, AttackEntityEvent, BlockBreakEvent, ChatEvent, ClientTickEvent,
164 ContainerCloseEvent, ContainerOpenEvent, CraftEvent, EntityDamageEvent, EntityDeathEvent,
165 EntityInteractEvent, EntitySpawnEvent, EventPhase, ExplosionEvent,
166 ItemPickupEvent, KeyPressEvent, PlaceBlockEvent, PlayerDeathEvent, PlayerJoinEvent,
167 PlayerLeaveEvent, PlayerMoveEvent, PlayerRespawnEvent, ProjectileHitEvent, ScreenEvent,
168 UseBlockEvent, UseItemEvent,
169};
170pub use yog_entity::Entity;
171pub use yog_network::{Packet, PacketEvent, PacketField};
172#[doc(inline)]
173pub use yog_network::packet;
174pub use yog_player::Player;
175pub use yog_registry::{BlockDef, FoodDef, FurnaceRecipe, ItemDef, ShapedRecipe, ShapelessRecipe, BookRecipe, ItemModifier, AdvancementReward, StartupGrant};
176pub use yog_config::Config;
177pub use yog_storage::{Storage, StorageScope, Value};
178pub use yog_world::World;
179pub use yog_book::{Book, BookCategory, BookEntry, BookPage, BookMacro, BookRegistry};
180pub use yog_book::{BookRenderer, BookFontRegistry};
181pub use yog_book::{text_page, text_page_titled, spotlight_page, crafting_page, smelting_page, image_page, entity_page, relations_page, pattern_page};
182pub use yog_ui::{UiRoot, LayoutNode, Rect, widget, Align, FlexDir, Dock, FocusStyle};
183pub use yog_inventory::{InventoryDef, SlotLayout};
184
185pub use yog_logging::{error, info, warn};
187
188pub mod core {
190 pub use yog_core::*;
191}
192
193pub mod event {
195 pub use yog_event::*;
196}
197
198pub mod world {
200 pub use yog_world::*;
201}
202
203pub mod entity {
205 pub use yog_entity::*;
206}
207
208pub mod player {
210 pub use yog_player::*;
211}
212
213pub mod content {
215 pub use yog_registry::*;
216}
217
218pub mod network {
220 pub use yog_network::*;
221}
222
223pub mod command {
225 pub use yog_command::*;
226}
227
228pub mod storage {
230 pub use yog_storage::*;
231}
232
233pub mod config {
235 pub use yog_config::*;
236}
237
238pub mod book {
240 pub use yog_book::*;
241}
242
243pub mod ui {
245 pub use yog_ui::*;
246}
247
248pub mod inventory {
251 pub use yog_inventory::*;
252}