Compare commits
	
		
			No commits in common. "d58c9e67c4ab54636b720a6bf31e54976936ee33" and "5d4f40393b8b98a984315c2f5273757185a3afc6" have entirely different histories.
		
	
	
		
			d58c9e67c4
			...
			5d4f40393b
		
	
		
							
								
								
									
										4
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@ -4,7 +4,5 @@
 | 
			
		||||
        "cassert": "cpp",
 | 
			
		||||
        "cstddef": "cpp",
 | 
			
		||||
        "string_view": "cpp"
 | 
			
		||||
    },
 | 
			
		||||
    "editor.detectIndentation": false,
 | 
			
		||||
    "editor.insertSpaces": false
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,6 @@ export module app;
 | 
			
		||||
import coral;
 | 
			
		||||
import coral.files;
 | 
			
		||||
import coral.image;
 | 
			
		||||
import coral.io;
 | 
			
		||||
import coral.math;
 | 
			
		||||
 | 
			
		||||
import oar;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										197
									
								
								source/coral.cpp
									
									
									
									
									
								
							
							
						
						
									
										197
									
								
								source/coral.cpp
									
									
									
									
									
								
							@ -94,14 +94,17 @@ export namespace coral {
 | 
			
		||||
		/**
 | 
			
		||||
		 * Number of `type` elements referenced.
 | 
			
		||||
		 */
 | 
			
		||||
		usize length{0};
 | 
			
		||||
		usize length;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Base element address referenced.
 | 
			
		||||
		 */
 | 
			
		||||
		type * pointer{nullptr};
 | 
			
		||||
		type * pointer;
 | 
			
		||||
 | 
			
		||||
		constexpr slice() = default;
 | 
			
		||||
		constexpr slice() {
 | 
			
		||||
			this->length = 0;
 | 
			
		||||
			this->pointer = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr slice(char const *&& zstring) {
 | 
			
		||||
			this->pointer = zstring;
 | 
			
		||||
@ -265,24 +268,6 @@ export [[nodiscard]] void * operator new[](coral::usize requested_size, coral::a
 | 
			
		||||
	return allocator.reallocate(nullptr, requested_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * If `pointer` is a non-`nullptr` value, the referenced memory will be deallocated using
 | 
			
		||||
 * `allocator`. Otherwise, the function has no side-effects.
 | 
			
		||||
 *
 | 
			
		||||
 * *Note*: passing a `pointer` value that was not allocated by `allocator` will result in erroneous
 | 
			
		||||
 * behavior defined by the [coral::allocator] implementation.
 | 
			
		||||
 */
 | 
			
		||||
export void operator delete(void * pointer, coral::allocator & allocator) {
 | 
			
		||||
	return allocator.deallocate(pointer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
export void operator delete[](void * pointer, coral::allocator & allocator) {
 | 
			
		||||
	return allocator.deallocate(pointer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Wrapper types.
 | 
			
		||||
export namespace coral {
 | 
			
		||||
	/**
 | 
			
		||||
@ -573,4 +558,174 @@ export namespace coral {
 | 
			
		||||
		a = b;
 | 
			
		||||
		b = temp;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Streams the data from `input` to `output`, using `buffer` as temporary transfer space.
 | 
			
		||||
	 *
 | 
			
		||||
	 * The returned [expected] can be used to introspect if `input` or `output` encountered any
 | 
			
		||||
	 * issues during streaming, otherwise it will contain the number of bytes streamed.
 | 
			
		||||
	 *
 | 
			
		||||
	 * *Note*: if `buffer` has a length of `0`, no data will be streamed as there is nowhere to
 | 
			
		||||
	 * temporarily place data during streaming.
 | 
			
		||||
	 */
 | 
			
		||||
	expected<usize, io_error> stream(writer & output, reader & input, slice<u8> const & buffer) {
 | 
			
		||||
		usize total_bytes_written = 0;
 | 
			
		||||
		expected bytes_read = input.read(buffer);
 | 
			
		||||
 | 
			
		||||
		if (!bytes_read.is_ok()) return bytes_read.error();
 | 
			
		||||
 | 
			
		||||
		usize read = bytes_read.value();
 | 
			
		||||
 | 
			
		||||
		while (read != 0) {
 | 
			
		||||
			expected const bytes_written = output.write(buffer.sliced(0, read));
 | 
			
		||||
 | 
			
		||||
			if (!bytes_written.is_ok()) return bytes_read.error();
 | 
			
		||||
 | 
			
		||||
			total_bytes_written += bytes_written.value();
 | 
			
		||||
			bytes_read = input.read(buffer);
 | 
			
		||||
 | 
			
		||||
			if (!bytes_read.is_ok()) return bytes_read.error();
 | 
			
		||||
 | 
			
		||||
			read = bytes_read.value();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return total_bytes_written;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Attempts to format and print `value` as an unsigned integer out to `output`.
 | 
			
		||||
	 *
 | 
			
		||||
	 * The returned [expected] can be used to introspect if `output` encountered any issues during
 | 
			
		||||
	 * printing, otherwise it will contain the number of characters used to print `value` as text.
 | 
			
		||||
	 */
 | 
			
		||||
	expected<usize, io_error> print_unsigned(writer & output, u64 value) {
 | 
			
		||||
		if (value == 0) return output.write(slice{"0"}.as_bytes());
 | 
			
		||||
 | 
			
		||||
		u8 buffer[20]{0};
 | 
			
		||||
		usize buffer_count{0};
 | 
			
		||||
 | 
			
		||||
		while (value != 0) {
 | 
			
		||||
			constexpr usize radix{10};
 | 
			
		||||
 | 
			
		||||
			buffer[buffer_count] = static_cast<u8>((value % radix) + '0');
 | 
			
		||||
			value = (value / radix);
 | 
			
		||||
			buffer_count += 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		usize const half_buffer_count{buffer_count / 2};
 | 
			
		||||
 | 
			
		||||
		for (usize i = 0; i < half_buffer_count; i += 1)
 | 
			
		||||
			swap(buffer[i], buffer[buffer_count - i - 1]);
 | 
			
		||||
 | 
			
		||||
		return output.write({buffer, buffer_count});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns a reference to a shared [allocator] which will always return `nullptr` on calls to
 | 
			
		||||
	 * [allocator::reallocate].
 | 
			
		||||
	 */
 | 
			
		||||
	allocator & null_allocator() {
 | 
			
		||||
		static struct : public allocator {
 | 
			
		||||
			u8 * reallocate(u8 * maybe_allocation, usize requested_size) override {
 | 
			
		||||
				if (maybe_allocation != nullptr) unreachable();
 | 
			
		||||
 | 
			
		||||
				return nullptr;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			void deallocate(void * allocation) override {
 | 
			
		||||
				if (allocation != nullptr) unreachable();
 | 
			
		||||
			}
 | 
			
		||||
		} a;
 | 
			
		||||
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Multiplexing byte-based ring buffer of `capacity` size that may be used for memory-backed
 | 
			
		||||
	 * I/O operations and lightweight data construction.
 | 
			
		||||
	 */
 | 
			
		||||
	template<usize capacity> struct fixed_buffer : public writer, public reader {
 | 
			
		||||
		fixed_buffer(coral::u8 fill_value) : data{fill_value} {}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns the base pointer of the buffer data.
 | 
			
		||||
		 */
 | 
			
		||||
		u8 * begin() {
 | 
			
		||||
			return this->data;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns the base pointer of the buffer data.
 | 
			
		||||
		 */
 | 
			
		||||
		u8 const * begin() const {
 | 
			
		||||
			return this->data;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns the tail pointer of the buffer data.
 | 
			
		||||
		 */
 | 
			
		||||
		u8 * end() {
 | 
			
		||||
			return this->data + this->cursor;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns the tail pointer of the buffer data.
 | 
			
		||||
		 */
 | 
			
		||||
		u8 const * end() const {
 | 
			
		||||
			return this->data + this->cursor;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns `true` if the buffer has been completely filled with data.
 | 
			
		||||
		 */
 | 
			
		||||
		bool is_full() const {
 | 
			
		||||
			return this->filled == capacity;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Reads whatever data is in the buffer into `data`, returning the number of bytes read
 | 
			
		||||
		 * from the buffer.
 | 
			
		||||
		 */
 | 
			
		||||
		expected<usize, io_error> read(slice<u8> const & data) override {
 | 
			
		||||
			slice const readable_data{this->data, min(this->filled, data.length)};
 | 
			
		||||
 | 
			
		||||
			this->filled -= readable_data.length;
 | 
			
		||||
 | 
			
		||||
			for (usize index = 0; index < readable_data.length; index += 1) {
 | 
			
		||||
				data[index] = this->data[this->read_index];
 | 
			
		||||
				this->read_index = (this->read_index + 1) % capacity;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return readable_data.length;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Attempts to write `data` to the buffer, returning the number of bytes written or
 | 
			
		||||
		 * [io_error::unavailable] if it has been completely filled and no more bytes can be
 | 
			
		||||
		 * written.
 | 
			
		||||
		 */
 | 
			
		||||
		expected<usize, io_error> write(slice<u8 const> const & data) override {
 | 
			
		||||
			if (this->is_full()) return io_error::unavailable;
 | 
			
		||||
 | 
			
		||||
			slice const writable_data{data.sliced(0, min(data.length, this->filled))};
 | 
			
		||||
 | 
			
		||||
			this->filled += writable_data.length;
 | 
			
		||||
 | 
			
		||||
			for (usize index = 0; index < writable_data.length; index += 1) {
 | 
			
		||||
				this->data[this->write_index] = data[index];
 | 
			
		||||
				this->write_index = (this->write_index + 1) % capacity;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return writable_data.length;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
		usize filled = 0;
 | 
			
		||||
 | 
			
		||||
		usize read_index = 0;
 | 
			
		||||
 | 
			
		||||
		usize write_index = 0;
 | 
			
		||||
 | 
			
		||||
		u8 data[capacity];
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,175 +0,0 @@
 | 
			
		||||
export module coral.io;
 | 
			
		||||
 | 
			
		||||
import coral;
 | 
			
		||||
 | 
			
		||||
export namespace coral {
 | 
			
		||||
	/**
 | 
			
		||||
	 * Multiplexing byte-based ring buffer of `capacity` size that may be used for memory-backed
 | 
			
		||||
	 * I/O operations and lightweight data construction.
 | 
			
		||||
	 */
 | 
			
		||||
	template<usize capacity> struct fixed_buffer : public writer, public reader {
 | 
			
		||||
		fixed_buffer(coral::u8 fill_value) : data{fill_value} {}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns the base pointer of the buffer data.
 | 
			
		||||
		 */
 | 
			
		||||
		u8 * begin() {
 | 
			
		||||
			return this->data;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns the base pointer of the buffer data.
 | 
			
		||||
		 */
 | 
			
		||||
		u8 const * begin() const {
 | 
			
		||||
			return this->data;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns the tail pointer of the buffer data.
 | 
			
		||||
		 */
 | 
			
		||||
		u8 * end() {
 | 
			
		||||
			return this->data + this->cursor;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns the tail pointer of the buffer data.
 | 
			
		||||
		 */
 | 
			
		||||
		u8 const * end() const {
 | 
			
		||||
			return this->data + this->cursor;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Returns `true` if the buffer has been completely filled with data.
 | 
			
		||||
		 */
 | 
			
		||||
		bool is_full() const {
 | 
			
		||||
			return this->filled == capacity;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Reads whatever data is in the buffer into `data`, returning the number of bytes read
 | 
			
		||||
		 * from the buffer.
 | 
			
		||||
		 */
 | 
			
		||||
		expected<usize, io_error> read(slice<u8> const & data) override {
 | 
			
		||||
			slice const readable_data{this->data, min(this->filled, data.length)};
 | 
			
		||||
 | 
			
		||||
			this->filled -= readable_data.length;
 | 
			
		||||
 | 
			
		||||
			for (usize index = 0; index < readable_data.length; index += 1) {
 | 
			
		||||
				data[index] = this->data[this->read_index];
 | 
			
		||||
				this->read_index = (this->read_index + 1) % capacity;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return readable_data.length;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Attempts to write `data` to the buffer, returning the number of bytes written or
 | 
			
		||||
		 * [io_error::unavailable] if it has been completely filled and no more bytes can be
 | 
			
		||||
		 * written.
 | 
			
		||||
		 */
 | 
			
		||||
		expected<usize, io_error> write(slice<u8 const> const & data) override {
 | 
			
		||||
			if (this->is_full()) return io_error::unavailable;
 | 
			
		||||
 | 
			
		||||
			slice const writable_data{data.sliced(0, min(data.length, this->filled))};
 | 
			
		||||
 | 
			
		||||
			this->filled += writable_data.length;
 | 
			
		||||
 | 
			
		||||
			for (usize index = 0; index < writable_data.length; index += 1) {
 | 
			
		||||
				this->data[this->write_index] = data[index];
 | 
			
		||||
				this->write_index = (this->write_index + 1) % capacity;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return writable_data.length;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
		usize filled = 0;
 | 
			
		||||
 | 
			
		||||
		usize read_index = 0;
 | 
			
		||||
 | 
			
		||||
		usize write_index = 0;
 | 
			
		||||
 | 
			
		||||
		u8 data[capacity];
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Streams the data from `input` to `output`, using `buffer` as temporary transfer space.
 | 
			
		||||
	 *
 | 
			
		||||
	 * The returned [expected] can be used to introspect if `input` or `output` encountered any
 | 
			
		||||
	 * issues during streaming, otherwise it will contain the number of bytes streamed.
 | 
			
		||||
	 *
 | 
			
		||||
	 * *Note*: if `buffer` has a length of `0`, no data will be streamed as there is nowhere to
 | 
			
		||||
	 * temporarily place data during streaming.
 | 
			
		||||
	 */
 | 
			
		||||
	expected<usize, io_error> stream(writer & output, reader & input, slice<u8> const & buffer) {
 | 
			
		||||
		usize total_bytes_written = 0;
 | 
			
		||||
		expected bytes_read = input.read(buffer);
 | 
			
		||||
 | 
			
		||||
		if (!bytes_read.is_ok()) return bytes_read.error();
 | 
			
		||||
 | 
			
		||||
		usize read = bytes_read.value();
 | 
			
		||||
 | 
			
		||||
		while (read != 0) {
 | 
			
		||||
			expected const bytes_written = output.write(buffer.sliced(0, read));
 | 
			
		||||
 | 
			
		||||
			if (!bytes_written.is_ok()) return bytes_read.error();
 | 
			
		||||
 | 
			
		||||
			total_bytes_written += bytes_written.value();
 | 
			
		||||
			bytes_read = input.read(buffer);
 | 
			
		||||
 | 
			
		||||
			if (!bytes_read.is_ok()) return bytes_read.error();
 | 
			
		||||
 | 
			
		||||
			read = bytes_read.value();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return total_bytes_written;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns a reference to a shared [allocator] which will always return `nullptr` on calls to
 | 
			
		||||
	 * [allocator::reallocate].
 | 
			
		||||
	 */
 | 
			
		||||
	allocator & null_allocator() {
 | 
			
		||||
		static struct : public allocator {
 | 
			
		||||
			u8 * reallocate(u8 * maybe_allocation, usize requested_size) override {
 | 
			
		||||
				if (maybe_allocation != nullptr) unreachable();
 | 
			
		||||
 | 
			
		||||
				return nullptr;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			void deallocate(void * allocation) override {
 | 
			
		||||
				if (allocation != nullptr) unreachable();
 | 
			
		||||
			}
 | 
			
		||||
		} a;
 | 
			
		||||
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Attempts to format and print `value` as an unsigned integer out to `output`.
 | 
			
		||||
	 *
 | 
			
		||||
	 * The returned [expected] can be used to introspect if `output` encountered any issues during
 | 
			
		||||
	 * printing, otherwise it will contain the number of characters used to print `value` as text.
 | 
			
		||||
	 */
 | 
			
		||||
	expected<usize, io_error> print_unsigned(writer & output, u64 value) {
 | 
			
		||||
		if (value == 0) return output.write(slice{"0"}.as_bytes());
 | 
			
		||||
 | 
			
		||||
		u8 buffer[20]{0};
 | 
			
		||||
		usize buffer_count{0};
 | 
			
		||||
 | 
			
		||||
		while (value != 0) {
 | 
			
		||||
			constexpr usize radix{10};
 | 
			
		||||
 | 
			
		||||
			buffer[buffer_count] = static_cast<u8>((value % radix) + '0');
 | 
			
		||||
			value = (value / radix);
 | 
			
		||||
			buffer_count += 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		usize const half_buffer_count{buffer_count / 2};
 | 
			
		||||
 | 
			
		||||
		for (usize i = 0; i < half_buffer_count; i += 1)
 | 
			
		||||
			swap(buffer[i], buffer[buffer_count - i - 1]);
 | 
			
		||||
 | 
			
		||||
		return output.write({buffer, buffer_count});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -44,21 +44,16 @@ export namespace coral {
 | 
			
		||||
	 * this, it is recommended to use larger `init_capacity` values for data which has a known or
 | 
			
		||||
	 * approximate upper bound at compile-time. Otherwise, the `init_capacity` value may be left at
 | 
			
		||||
	 * its default.
 | 
			
		||||
	 *
 | 
			
		||||
	 * *Note*: the [allocator] referenced in the stack must remain valid for the duration of the
 | 
			
		||||
	 * stack lifetime.
 | 
			
		||||
	 */
 | 
			
		||||
	template<typename element, usize init_capacity = 1> struct stack : public sequence<element> {
 | 
			
		||||
		stack(allocator * dynamic_allocator) {
 | 
			
		||||
		stack(allocator * dynamic_allocator) : local_buffer{0} {
 | 
			
		||||
			this->dynamic_allocator = dynamic_allocator;
 | 
			
		||||
			this->filled = 0;
 | 
			
		||||
			this->elements = this->local_buffer;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		~stack() override {
 | 
			
		||||
			if (this->is_dynamic()) {
 | 
			
		||||
				for (element & e : this->elements) e.~element();
 | 
			
		||||
 | 
			
		||||
				this->dynamic_allocator->deallocate(this->elements.pointer);
 | 
			
		||||
			}
 | 
			
		||||
			if (this->is_dynamic()) this->dynamic_allocator->deallocate(this->elements.pointer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
@ -120,7 +115,7 @@ export namespace coral {
 | 
			
		||||
		 * Returns `true` if the stack is backed by dynamic memory, otherwise `false`.
 | 
			
		||||
		 */
 | 
			
		||||
		bool is_dynamic() const {
 | 
			
		||||
			return this->elements.pointer != reinterpret_cast<element const *>(this->local_buffer);
 | 
			
		||||
			return this->elements.pointer != this->local_buffer;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
@ -162,6 +157,7 @@ export namespace coral {
 | 
			
		||||
			usize const requested_capacity = this->filled + capacity;
 | 
			
		||||
 | 
			
		||||
			if (this->is_dynamic()) {
 | 
			
		||||
				// Grow dynamic buffer (bailing out if failed).
 | 
			
		||||
				u8 * const buffer = this->dynamic_allocator->reallocate(
 | 
			
		||||
					reinterpret_cast<u8 *>(this->elements.pointer),
 | 
			
		||||
						sizeof(element) * requested_capacity);
 | 
			
		||||
@ -192,13 +188,13 @@ export namespace coral {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
		allocator * dynamic_allocator{nullptr};
 | 
			
		||||
		allocator * dynamic_allocator;
 | 
			
		||||
 | 
			
		||||
		usize filled{0};
 | 
			
		||||
		usize filled;
 | 
			
		||||
 | 
			
		||||
		slice<element> elements{reinterpret_cast<element *>(local_buffer), init_capacity};
 | 
			
		||||
		slice<element> elements;
 | 
			
		||||
 | 
			
		||||
		u8 local_buffer[init_capacity]{0};
 | 
			
		||||
		element local_buffer[init_capacity];
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,6 @@ import app;
 | 
			
		||||
 | 
			
		||||
import coral;
 | 
			
		||||
import coral.files;
 | 
			
		||||
import coral.io;
 | 
			
		||||
import coral.math;
 | 
			
		||||
import coral.sequence;
 | 
			
		||||
 | 
			
		||||
@ -30,6 +29,7 @@ extern "C" int main(int argc, char const * const * argv) {
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			coral::stack<coral::u8> script_source{allocator};
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				coral::u8 stream_buffer[1024]{0};
 | 
			
		||||
				coral::sequence_writer script_writer{&script_source};
 | 
			
		||||
@ -38,7 +38,7 @@ extern "C" int main(int argc, char const * const * argv) {
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			vm.with_object(vm.compile(coral::slice{script_source.begin(), script_source.end()}.as_chars()), [&](kym::bound_object & script) {
 | 
			
		||||
				vm.with_object(script.call({}), [&](kym::bound_object & config) {
 | 
			
		||||
				vm.with_object(script.call({}), [&](kym::bound_object config) {
 | 
			
		||||
					constexpr auto as_u16 = [](coral::i64 value) -> coral::optional<coral::i16> {
 | 
			
		||||
						if ((value >= 0) && (value <= coral::u16_max))
 | 
			
		||||
							return static_cast<coral::u16>(value);
 | 
			
		||||
@ -62,7 +62,16 @@ extern "C" int main(int argc, char const * const * argv) {
 | 
			
		||||
						return system.log(app::log_level::error, "failed to initialize window");
 | 
			
		||||
 | 
			
		||||
					vm.with_object(config.get_field("title"), [&](kym::bound_object & title) {
 | 
			
		||||
						// TODO: implement.
 | 
			
		||||
						coral::stack<coral::u8, 128> title_buffer{&system.thread_safe_allocator()};
 | 
			
		||||
						coral::sequence_writer title_writer{&title_buffer};
 | 
			
		||||
 | 
			
		||||
						if (!title.stringify(title_writer).is_ok()) {
 | 
			
		||||
							system.log(app::log_level::error,
 | 
			
		||||
								"failed to decode `title` property of config");
 | 
			
		||||
 | 
			
		||||
							return;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						is_config_loaded = true;
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
@ -71,6 +80,7 @@ extern "C" int main(int argc, char const * const * argv) {
 | 
			
		||||
 | 
			
		||||
		if (!is_config_loaded) {
 | 
			
		||||
			coral::stack<coral::u8> error_message{&system.thread_safe_allocator()};
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				coral::sequence_writer error_writer{&error_message};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user