diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cb43d79 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,63 @@ +name: CI + +on: + push: + branches: [ "dev" ] + pull_request: + branches: [ "dev", "main" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + rust-lint: + name: Rust Check & Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: clippy, rustfmt + + - name: Check Rust Formatting + run: cargo fmt --all -- --check + + - name: Run Clippy + # -D warnings turns all clippy warnings into hard errors that fail the build + run: cargo clippy --all-targets --all-features -- -D warnings + + lua-lint: + name: Lua Lint & Format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install StyLua + uses: JohnnyMorganz/stylua-action@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + version: latest + + - name: Check Lua Formatting + # We use a glob that won't fail if the directories don't exist yet + run: | + if [ -d "assets/scripts" ] || [ -d "mods" ]; then + stylua --check assets/scripts/ mods/ 2>/dev/null || true + else + echo "No Lua scripts found to format yet." + fi + + - name: Install Selene + uses: NTBBloodbath/selene-action@v1.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Run Selene + run: | + if [ -d "assets/scripts" ] || [ -d "mods" ]; then + selene assets/scripts/ mods/ 2>/dev/null || true + else + echo "No Lua scripts found to lint yet." + fi diff --git a/Cargo.toml b/Cargo.toml index a32b8d7..d0170a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,24 @@ [workspace] resolver = "3" -members = ["crates/*"] \ No newline at end of file +members = ["crates/*"] + +[workspace.lints.rust] +unsafe_code = "warn" +missing_docs = "warn" + +[workspace.lints.clippy] +unwrap_used = "warn" +expect_used = "warn" +print_stdout = "warn" +print_stderr = "warn" + +pedantic = { level = "warn", priority = -1 } +clone_on_ref_ptr = "warn" + +todo = "warn" +unimplemented = "warn" + +# Pedantic exceptions (too noisy) +module_name_repetitions = "allow" +must_use_candidate = "allow" +missing_errors_doc = "allow" \ No newline at end of file diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml index 9a668ed..f892266 100644 --- a/crates/client/Cargo.toml +++ b/crates/client/Cargo.toml @@ -3,6 +3,9 @@ name = "client" version = "0.1.0" edition = "2024" +[lints] +workspace = true + [dependencies] anyhow = "1.0.102" tracing = "0.1.44" diff --git a/crates/client/src/main.rs b/crates/client/src/main.rs index f0d7cf5..b0ae060 100644 --- a/crates/client/src/main.rs +++ b/crates/client/src/main.rs @@ -14,17 +14,21 @@ struct App { impl ApplicationHandler for App { fn resumed(&mut self, event_loop: &ActiveEventLoop) { - let attributes = Window::default_attributes() - .with_title("Project Catalyst"); + let attributes = Window::default_attributes().with_title("Project Catalyst"); self.window = Some(event_loop.create_window(attributes).unwrap()); - let display_handle = event_loop.display_handle() + let display_handle = event_loop + .display_handle() .expect("Failed to get display handle") .as_raw(); // Get the window handle for surface creation - let window_handle = self.window.as_ref().unwrap().window_handle() + let window_handle = self + .window + .as_ref() + .unwrap() + .window_handle() .expect("Failed to get window handle") .as_raw(); @@ -48,7 +52,7 @@ impl ApplicationHandler for App { match event { WindowEvent::CloseRequested => { event_loop.exit(); - }, + } WindowEvent::RedrawRequested => { if let Some(renderer) = self.renderer.as_mut() { renderer.draw_frame().expect("Failed to draw frame"); @@ -74,6 +78,8 @@ fn main() -> Result<()> { event_loop.set_control_flow(ControlFlow::Poll); let mut app = App::default(); - event_loop.run_app(&mut app).context("Failed to run event loop")?; + event_loop + .run_app(&mut app) + .context("Failed to run event loop")?; Ok(()) -} \ No newline at end of file +} diff --git a/crates/renderer/Cargo.toml b/crates/renderer/Cargo.toml index 96b65d7..6a68620 100644 --- a/crates/renderer/Cargo.toml +++ b/crates/renderer/Cargo.toml @@ -3,6 +3,9 @@ name = "renderer" version = "0.1.0" edition = "2024" +[lints] +workspace = true + [dependencies] ash = "0.38.0" ash-window = "0.13.0" diff --git a/crates/renderer/src/device.rs b/crates/renderer/src/device.rs index e572d16..efc6cad 100644 --- a/crates/renderer/src/device.rs +++ b/crates/renderer/src/device.rs @@ -1,5 +1,5 @@ -use ash::{Device, Instance, khr, vk}; use crate::error::RendererError; +use ash::{Device, Instance, khr, vk}; /// Picks a physical device (GPU) that supports the required features and extensions. pub fn pick_physical_device( @@ -12,7 +12,8 @@ pub fn pick_physical_device( for device in devices { if is_device_suitable(instance, device, surface_loader, surface) { let props = unsafe { instance.get_physical_device_properties(device) }; - let name = unsafe { std::ffi::CStr::from_ptr(props.device_name.as_ptr()).to_string_lossy() }; + let name = + unsafe { std::ffi::CStr::from_ptr(props.device_name.as_ptr()).to_string_lossy() }; tracing::info!("Selected GPU: \"{name}\""); return Ok(device); } @@ -35,10 +36,10 @@ pub fn create_logical_device( let device_extensions = [khr::swapchain::NAME.as_ptr()]; // Enable Vulkan 1.3 features - let mut synchronization2_features = vk::PhysicalDeviceSynchronization2Features::default() - .synchronization2(true); - let mut dynamic_rendering_features = vk::PhysicalDeviceDynamicRenderingFeatures::default() - .dynamic_rendering(true); + let mut synchronization2_features = + vk::PhysicalDeviceSynchronization2Features::default().synchronization2(true); + let mut dynamic_rendering_features = + vk::PhysicalDeviceDynamicRenderingFeatures::default().dynamic_rendering(true); let create_info = vk::DeviceCreateInfo::default() .queue_create_infos(std::slice::from_ref(&queue_info)) @@ -64,8 +65,8 @@ pub fn find_graphics_queue_family( for (index, prop) in props.iter().enumerate() { let index = index as u32; let graphics = prop.queue_flags.contains(vk::QueueFlags::GRAPHICS); - let present = unsafe { - surface_loader.get_physical_device_surface_support(physical_device, index, surface)? + let present = unsafe { + surface_loader.get_physical_device_surface_support(physical_device, index, surface)? }; if graphics && present { @@ -82,16 +83,24 @@ fn is_device_suitable( surface_loader: &khr::surface::Instance, surface: vk::SurfaceKHR, ) -> bool { - let extensions = unsafe { instance.enumerate_device_extension_properties(device).unwrap_or_default() }; - let has_swapchain = extensions.iter().any(|ext| { - unsafe { std::ffi::CStr::from_ptr(ext.extension_name.as_ptr()) == khr::swapchain::NAME } + let extensions = unsafe { + instance + .enumerate_device_extension_properties(device) + .unwrap_or_default() + }; + let has_swapchain = extensions.iter().any(|ext| unsafe { + std::ffi::CStr::from_ptr(ext.extension_name.as_ptr()) == khr::swapchain::NAME }); - let formats = unsafe { - surface_loader.get_physical_device_surface_formats(device, surface).unwrap_or_default() + let formats = unsafe { + surface_loader + .get_physical_device_surface_formats(device, surface) + .unwrap_or_default() }; - let present_modes = unsafe { - surface_loader.get_physical_device_surface_present_modes(device, surface).unwrap_or_default() + let present_modes = unsafe { + surface_loader + .get_physical_device_surface_present_modes(device, surface) + .unwrap_or_default() }; has_swapchain && !formats.is_empty() && !present_modes.is_empty() diff --git a/crates/renderer/src/error.rs b/crates/renderer/src/error.rs index ac3c6e1..1514ab6 100644 --- a/crates/renderer/src/error.rs +++ b/crates/renderer/src/error.rs @@ -14,4 +14,4 @@ pub enum RendererError { /// An error occurred during GPU memory allocation. #[error("GPU allocation error")] AllocationError(#[from] gpu_allocator::AllocationError), -} \ No newline at end of file +} diff --git a/crates/renderer/src/instance.rs b/crates/renderer/src/instance.rs index 0446e7a..a627677 100644 --- a/crates/renderer/src/instance.rs +++ b/crates/renderer/src/instance.rs @@ -1,13 +1,20 @@ -use std::ffi::{CStr, c_char}; -use ash::{Entry, Instance, ext, vk}; -use tracing::{debug, error, info, warn}; use crate::error::RendererError; +use ash::{Entry, Instance, ext, vk}; +use std::ffi::{CStr, c_char}; +use tracing::{debug, error, info, warn}; /// Creates a Vulkan instance and optionally a debug messenger. pub fn create_instance( entry: &Entry, required_extensions: &[*const c_char], -) -> Result<(Instance, Option, vk::DebugUtilsMessengerEXT), RendererError> { +) -> Result< + ( + Instance, + Option, + vk::DebugUtilsMessengerEXT, + ), + RendererError, +> { let mut extensions = required_extensions.to_vec(); let mut layers = Vec::new(); @@ -17,8 +24,7 @@ pub fn create_instance( layers.push(c"VK_LAYER_KHRONOS_validation".as_ptr()); } - let app_info = vk::ApplicationInfo::default() - .api_version(vk::API_VERSION_1_3); + let app_info = vk::ApplicationInfo::default().api_version(vk::API_VERSION_1_3); let create_info = vk::InstanceCreateInfo::default() .application_info(&app_info) @@ -31,13 +37,13 @@ pub fn create_instance( let (debug_utils, debug_messenger) = { let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default() .message_severity( - vk::DebugUtilsMessageSeverityFlagsEXT::WARNING | - vk::DebugUtilsMessageSeverityFlagsEXT::ERROR + vk::DebugUtilsMessageSeverityFlagsEXT::WARNING + | vk::DebugUtilsMessageSeverityFlagsEXT::ERROR, ) .message_type( - vk::DebugUtilsMessageTypeFlagsEXT::GENERAL | - vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION | - vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE + vk::DebugUtilsMessageTypeFlagsEXT::GENERAL + | vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION + | vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE, ) .pfn_user_callback(Some(vulkan_debug_callback)); @@ -61,7 +67,7 @@ unsafe extern "system" fn vulkan_debug_callback( _user_data: *mut std::ffi::c_void, ) -> vk::Bool32 { let callback_data = unsafe { *p_callback_data }; - + let message = if callback_data.p_message.is_null() { "".into() } else { diff --git a/crates/renderer/src/lib.rs b/crates/renderer/src/lib.rs index 9b706c6..e253283 100644 --- a/crates/renderer/src/lib.rs +++ b/crates/renderer/src/lib.rs @@ -112,9 +112,18 @@ impl Renderer { // 13. Vertex Buffer Initialization // A simple triangle is defined in normalized device coordinates and moved to GPU memory. let vertices = [ - mesh::Vertex { position: [0.0, -0.5, 0.0], tex_coord: [0.5, 0.0] }, - mesh::Vertex { position: [0.5, 0.5, 0.0], tex_coord: [1.0, 1.0] }, - mesh::Vertex { position: [-0.5, 0.5, 0.0], tex_coord: [0.0, 1.0] }, + mesh::Vertex { + position: [0.0, -0.5, 0.0], + tex_coord: [0.5, 0.0], + }, + mesh::Vertex { + position: [0.5, 0.5, 0.0], + tex_coord: [1.0, 1.0], + }, + mesh::Vertex { + position: [-0.5, 0.5, 0.0], + tex_coord: [0.0, 1.0], + }, ]; // Create the buffer handle and query its memory requirements. @@ -128,26 +137,33 @@ impl Renderer { let mut allocator = allocator; // Allocate memory that is visible to the CPU for data transfer. - let vertex_allocation = allocator.allocate(&gpu_allocator::vulkan::AllocationCreateDesc { - name: "Vertex Buffer", - requirements, - location: gpu_allocator::MemoryLocation::CpuToGpu, - linear: true, - allocation_scheme: gpu_allocator::vulkan::AllocationScheme::GpuAllocatorManaged, - })?; + let vertex_allocation = + allocator.allocate(&gpu_allocator::vulkan::AllocationCreateDesc { + name: "Vertex Buffer", + requirements, + location: gpu_allocator::MemoryLocation::CpuToGpu, + linear: true, + allocation_scheme: gpu_allocator::vulkan::AllocationScheme::GpuAllocatorManaged, + })?; // Bind the allocated memory to the buffer handle and copy the vertex data. - unsafe { - device.bind_buffer_memory(vertex_buffer, vertex_allocation.memory(), vertex_allocation.offset())?; + unsafe { + device.bind_buffer_memory( + vertex_buffer, + vertex_allocation.memory(), + vertex_allocation.offset(), + )?; - let ptr = vertex_allocation.mapped_ptr() + let ptr = vertex_allocation + .mapped_ptr() .expect("Failed to map vertex buffer memory") .as_ptr(); std::ptr::copy_nonoverlapping( - vertices.as_ptr() as *const u8, - ptr as *mut u8, - std::mem::size_of_val(&vertices)); + vertices.as_ptr() as *const u8, + ptr as *mut u8, + std::mem::size_of_val(&vertices), + ); } Ok(Self { diff --git a/crates/renderer/src/mesh.rs b/crates/renderer/src/mesh.rs index fa1ab4b..5f3d455 100644 --- a/crates/renderer/src/mesh.rs +++ b/crates/renderer/src/mesh.rs @@ -1,7 +1,7 @@ use bytemuck::{Pod, Zeroable}; /// Represents a single vertex in 3D space with position and texture coordinates. -/// +/// /// Uses `repr(C)` to ensure the memory layout matches what the GPU expects (no Rust-specific reordering). /// `Pod` and `Zeroable` allows safely casting this struct to a raw byte slice. #[repr(C)] @@ -15,7 +15,7 @@ pub struct Vertex { impl Vertex { /// Describes how Vulkan should read the vertex data from a buffer. - /// + /// /// This defines the 'stride' (distance between vertices) and specifies that /// data is read per-vertex rather than per-instance. pub fn get_binding_description() -> ash::vk::VertexInputBindingDescription { @@ -26,7 +26,7 @@ impl Vertex { } /// Describes the layout of individual fields (attributes) within a single vertex. - /// + /// /// These 'locations' must match the `layout(location = X)` qualifiers in the vertex shader. pub fn get_attribute_descriptions() -> [ash::vk::VertexInputAttributeDescription; 2] { [ diff --git a/crates/renderer/src/pipeline.rs b/crates/renderer/src/pipeline.rs index 8dd7e83..015b499 100644 --- a/crates/renderer/src/pipeline.rs +++ b/crates/renderer/src/pipeline.rs @@ -1,27 +1,28 @@ -use ash::{vk, Device}; -use std::io::Cursor; use crate::mesh::Vertex; +use ash::{Device, vk}; +use std::io::Cursor; /// Helper to load SPIR-V bytes and create a Vulkan Shader Module. -/// +/// /// Vulkan expects shader code to be 32-bit aligned; `ash::util::read_spv` is /// used to correctly interpret the raw bytes as a slice of `u32`. pub fn create_shader_module(device: &Device, bytes: &[u8]) -> vk::ShaderModule { let mut cursor = Cursor::new(bytes); - + let code = ash::util::read_spv(&mut cursor) .expect("Failed to read SPIR-V binary; check if the file is valid"); let create_info = vk::ShaderModuleCreateInfo::default().code(&code); unsafe { - device.create_shader_module(&create_info, None) + device + .create_shader_module(&create_info, None) .expect("Failed to create Vulkan shader module") } } /// Defines the 'interface' of the pipeline (what data we can pass to the shaders). -/// +/// /// This layout defines any push constants or descriptor sets (textures/UBOs) /// accessed by the shaders during execution. pub fn create_pipeline_layout(device: &Device) -> vk::PipelineLayout { @@ -36,19 +37,20 @@ pub fn create_pipeline_layout(device: &Device) -> vk::PipelineLayout { .push_constant_ranges(std::slice::from_ref(&push_constant_range)); unsafe { - device.create_pipeline_layout(&layout_create_info, None) + device + .create_pipeline_layout(&layout_create_info, None) .expect("Failed to create pipeline layout") } } /// Creates a Graphics Pipeline for voxel rendering using Vulkan 1.3 Dynamic Rendering. -/// +/// /// The pipeline encapsulates the entire state of the GPU for a specific draw operation, /// including shader stages, vertex input layout, rasterization settings, and blending. pub fn create_graphics_pipeline( - device: &Device, - layout: vk::PipelineLayout, - color_format: vk::Format + device: &Device, + layout: vk::PipelineLayout, + color_format: vk::Format, ) -> vk::Pipeline { // 1. Load and compile shader modules // Using include_bytes! embeds the shaders directly into the engine binary. @@ -116,13 +118,13 @@ pub fn create_graphics_pipeline( // 8. Define Dynamic States // This allows the window to be resized without recreating the entire pipeline. let dynamic_states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; - let dynamic_state_info = vk::PipelineDynamicStateCreateInfo::default() - .dynamic_states(&dynamic_states); + let dynamic_state_info = + vk::PipelineDynamicStateCreateInfo::default().dynamic_states(&dynamic_states); // 9. Configure Dynamic Rendering (Vulkan 1.3) let color_formats = [color_format]; - let mut rendering_info = vk::PipelineRenderingCreateInfo::default() - .color_attachment_formats(&color_formats); + let mut rendering_info = + vk::PipelineRenderingCreateInfo::default().color_attachment_formats(&color_formats); // 10. Finalize Pipeline Creation let pipeline_info = vk::GraphicsPipelineCreateInfo::default() @@ -138,7 +140,8 @@ pub fn create_graphics_pipeline( .layout(layout); let pipeline = unsafe { - device.create_graphics_pipelines(vk::PipelineCache::null(), &[pipeline_info], None) + device + .create_graphics_pipelines(vk::PipelineCache::null(), &[pipeline_info], None) .expect("Failed to create graphics pipeline")[0] }; diff --git a/crates/renderer/src/renderer.rs b/crates/renderer/src/renderer.rs index 66c4a3b..21a9c9f 100644 --- a/crates/renderer/src/renderer.rs +++ b/crates/renderer/src/renderer.rs @@ -3,8 +3,6 @@ use crate::sync::SyncPrimitives; use ash::{Device, Instance, khr, vk}; use gpu_allocator::vulkan::{Allocation, Allocator}; - - /// The core renderer structure holding the Vulkan resources. pub struct Renderer { /// Entry point to the Vulkan library. @@ -206,7 +204,8 @@ impl Drop for Renderer { self.device .destroy_pipeline_layout(self.pipeline_layout, None); - self.allocator.free(std::ptr::read(&self.vertex_allocation)) + self.allocator + .free(std::ptr::read(&self.vertex_allocation)) .expect(" Failed to free vertex buffer allocation"); self.device.destroy_buffer(self.vertex_buffer, None); diff --git a/crates/renderer/src/surface.rs b/crates/renderer/src/surface.rs index 086c6ab..fd921d8 100644 --- a/crates/renderer/src/surface.rs +++ b/crates/renderer/src/surface.rs @@ -1,6 +1,6 @@ +use crate::error::RendererError; use ash::{Entry, Instance, khr, vk}; use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; -use crate::error::RendererError; /// Creates a Vulkan surface for the given window. pub fn create_surface( @@ -9,10 +9,10 @@ pub fn create_surface( display_handle: RawDisplayHandle, window_handle: RawWindowHandle, ) -> Result<(khr::surface::Instance, vk::SurfaceKHR), RendererError> { - let surface = unsafe { - ash_window::create_surface(entry, instance, display_handle, window_handle, None)? + let surface = unsafe { + ash_window::create_surface(entry, instance, display_handle, window_handle, None)? }; let surface_loader = khr::surface::Instance::new(entry, instance); - + Ok((surface_loader, surface)) } diff --git a/crates/renderer/src/swapchain.rs b/crates/renderer/src/swapchain.rs index 004ffec..52c2b18 100644 --- a/crates/renderer/src/swapchain.rs +++ b/crates/renderer/src/swapchain.rs @@ -1,5 +1,5 @@ -use ash::{Device, Instance, khr, vk}; use crate::error::RendererError; +use ash::{Device, Instance, khr, vk}; /// Creates a swapchain and retrieves its images. pub fn create_swapchain( @@ -10,19 +10,31 @@ pub fn create_swapchain( surface: vk::SurfaceKHR, width: u32, height: u32, -) -> Result<(khr::swapchain::Device, vk::SwapchainKHR, Vec, vk::Format, vk::Extent2D), RendererError> { - let surface_capabilities = unsafe { - surface_loader.get_physical_device_surface_capabilities(physical_device, surface)? +) -> Result< + ( + khr::swapchain::Device, + vk::SwapchainKHR, + Vec, + vk::Format, + vk::Extent2D, + ), + RendererError, +> { + let surface_capabilities = unsafe { + surface_loader.get_physical_device_surface_capabilities(physical_device, surface)? }; - let surface_formats = unsafe { - surface_loader.get_physical_device_surface_formats(physical_device, surface)? - }; - let _surface_present_modes = unsafe { - surface_loader.get_physical_device_surface_present_modes(physical_device, surface)? + let surface_formats = + unsafe { surface_loader.get_physical_device_surface_formats(physical_device, surface)? }; + let _surface_present_modes = unsafe { + surface_loader.get_physical_device_surface_present_modes(physical_device, surface)? }; - let format = surface_formats.iter() - .find(|f| f.format == vk::Format::B8G8R8A8_SRGB && f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR) + let format = surface_formats + .iter() + .find(|f| { + f.format == vk::Format::B8G8R8A8_SRGB + && f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR + }) .unwrap_or(&surface_formats[0]); let present_mode = vk::PresentModeKHR::FIFO; @@ -31,12 +43,20 @@ pub fn create_swapchain( surface_capabilities.current_extent } else { vk::Extent2D { - width: width.clamp(surface_capabilities.min_image_extent.width, surface_capabilities.max_image_extent.width), - height: height.clamp(surface_capabilities.min_image_extent.height, surface_capabilities.max_image_extent.height), + width: width.clamp( + surface_capabilities.min_image_extent.width, + surface_capabilities.max_image_extent.width, + ), + height: height.clamp( + surface_capabilities.min_image_extent.height, + surface_capabilities.max_image_extent.height, + ), } }; - let image_count = if surface_capabilities.max_image_count > 0 && surface_capabilities.min_image_count + 1 > surface_capabilities.max_image_count { + let image_count = if surface_capabilities.max_image_count > 0 + && surface_capabilities.min_image_count + 1 > surface_capabilities.max_image_count + { surface_capabilities.max_image_count } else { surface_capabilities.min_image_count + 1 diff --git a/crates/renderer/src/sync.rs b/crates/renderer/src/sync.rs index 00f050b..b8c8594 100644 --- a/crates/renderer/src/sync.rs +++ b/crates/renderer/src/sync.rs @@ -1,5 +1,5 @@ -use ash::{Device, vk}; use crate::error::RendererError; +use ash::{Device, vk}; /// Groups all synchronization primitives for the renderer. pub struct SyncPrimitives { @@ -18,8 +18,7 @@ pub fn create_sync_primitives( image_count: usize, ) -> Result { let semaphore_info = vk::SemaphoreCreateInfo::default(); - let fence_info = vk::FenceCreateInfo::default() - .flags(vk::FenceCreateFlags::SIGNALED); + let fence_info = vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED); let mut image_available = Vec::with_capacity(max_frames_in_flight); let mut render_finished = Vec::with_capacity(image_count); diff --git a/crates/scripting/Cargo.toml b/crates/scripting/Cargo.toml index 6139403..3bca369 100644 --- a/crates/scripting/Cargo.toml +++ b/crates/scripting/Cargo.toml @@ -3,4 +3,7 @@ name = "scripting" version = "0.1.0" edition = "2024" +[lints] +workspace = true + [dependencies] diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml index ff06670..fdfa381 100644 --- a/crates/server/Cargo.toml +++ b/crates/server/Cargo.toml @@ -3,4 +3,7 @@ name = "server" version = "0.1.0" edition = "2024" +[lints] +workspace = true + [dependencies] diff --git a/crates/shared/Cargo.toml b/crates/shared/Cargo.toml index 5e22169..9733483 100644 --- a/crates/shared/Cargo.toml +++ b/crates/shared/Cargo.toml @@ -3,4 +3,7 @@ name = "shared" version = "0.1.0" edition = "2024" +[lints] +workspace = true + [dependencies] diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..c5f685d --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,3 @@ +edition = "2024" +# By default, rustfmt enforces standard Rust formatting rules. +# You can override specific rules here if you disagree with the standard. diff --git a/selene.toml b/selene.toml new file mode 100644 index 0000000..21baf27 --- /dev/null +++ b/selene.toml @@ -0,0 +1,4 @@ +std = "lua54" + +[rules] +unknown_variable = "error" diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..c537618 --- /dev/null +++ b/stylua.toml @@ -0,0 +1,5 @@ +column_width = 120 +line_endings = "Unix" +indent_type = "Spaces" +indent_width = 4 +quote_style = "AutoPreferDouble"