mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-11 22:11:51 +00:00
refactor descriptors_manager
This commit is contained in:
parent
4cc6a83872
commit
07702f9e57
6 changed files with 166 additions and 166 deletions
|
|
@ -9,10 +9,19 @@ local lib = {
|
||||||
close = file.__close_descriptor
|
close = file.__close_descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local __open_descriptor = file.__open_descriptor
|
||||||
|
file.__open_descriptor = nil
|
||||||
|
file.__read_descriptor = nil
|
||||||
|
file.__write_descriptor = nil
|
||||||
|
file.__seek_descriptor = nil
|
||||||
|
file.__flush_descriptor = nil
|
||||||
|
file.__has_descriptor = nil
|
||||||
|
file.__close_descriptor = nil
|
||||||
|
|
||||||
return function(path, mode)
|
return function(path, mode)
|
||||||
return io_stream.new(
|
return io_stream.new(
|
||||||
file.__open_descriptor(path, mode),
|
__open_descriptor(path, mode),
|
||||||
mode:find('b') ~= nil,
|
mode:find('b') ~= nil,
|
||||||
lib
|
lib
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
#include "logic/scripting/descriptors_manager.hpp"
|
|
||||||
|
|
||||||
#include "debug/Logger.hpp"
|
|
||||||
|
|
||||||
static debug::Logger logger("descriptors-manager");
|
|
||||||
|
|
||||||
namespace scripting {
|
|
||||||
|
|
||||||
std::vector<std::optional<StreamDescriptor>> descriptors_manager::descriptors;
|
|
||||||
|
|
||||||
std::istream* descriptors_manager::get_input(int descriptor) {
|
|
||||||
if (!is_readable(descriptor))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return descriptors[descriptor]->in.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream* descriptors_manager::get_output(int descriptor) {
|
|
||||||
if (!is_writeable(descriptor))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return descriptors[descriptor]->out.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void descriptors_manager::flush(int descriptor) {
|
|
||||||
if (is_writeable(descriptor)) {
|
|
||||||
descriptors[descriptor]->out->flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool descriptors_manager::has_descriptor(int descriptor) {
|
|
||||||
return is_readable(descriptor) || is_writeable(descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool descriptors_manager::is_readable(int descriptor) {
|
|
||||||
return descriptor >= 0 && descriptor < static_cast<int>(descriptors.size())
|
|
||||||
&& descriptors[descriptor].has_value()
|
|
||||||
&& descriptors[descriptor]->in != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool descriptors_manager::is_writeable(int descriptor) {
|
|
||||||
return descriptor >= 0 && descriptor < static_cast<int>(descriptors.size())
|
|
||||||
&& descriptors[descriptor].has_value()
|
|
||||||
&& descriptors[descriptor]->out != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void descriptors_manager::close(int descriptor) {
|
|
||||||
if (descriptor >= 0 && descriptor < static_cast<int>(descriptors.size())) {
|
|
||||||
if (descriptors[descriptor].has_value()) {
|
|
||||||
auto& desc = descriptors[descriptor].value();
|
|
||||||
|
|
||||||
if (desc.out)
|
|
||||||
desc.out->flush();
|
|
||||||
|
|
||||||
desc.in.reset();
|
|
||||||
desc.out.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptors[descriptor].reset();
|
|
||||||
|
|
||||||
descriptors[descriptor] = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int descriptors_manager::open_descriptor(const io::path& path, bool write, bool read) {
|
|
||||||
std::unique_ptr<std::istream> in;
|
|
||||||
std::unique_ptr<std::ostream> out;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (read)
|
|
||||||
in = io::read(path);
|
|
||||||
|
|
||||||
if (write)
|
|
||||||
out = io::write(path);
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
logger.error() << "failed to open descriptor for " << path.string()
|
|
||||||
<< ": " << e.what();
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < static_cast<int>(descriptors.size()); ++i) {
|
|
||||||
if (!descriptors[i].has_value()) {
|
|
||||||
descriptors[i] = StreamDescriptor{ std::move(in), std::move(out) };
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptors.emplace_back(StreamDescriptor{ std::move(in), std::move(out) });
|
|
||||||
|
|
||||||
return static_cast<int>(descriptors.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void descriptors_manager::close_all_descriptors() {
|
|
||||||
for (int i = 0; i < static_cast<int>(descriptors.size()); ++i) {
|
|
||||||
if (descriptors[i].has_value()) {
|
|
||||||
close(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptors.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
|
||||||
#include <istream>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
#include "io/io.hpp"
|
|
||||||
|
|
||||||
namespace scripting {
|
|
||||||
|
|
||||||
struct StreamDescriptor {
|
|
||||||
std::unique_ptr<std::istream> in;
|
|
||||||
std::unique_ptr<std::ostream> out;
|
|
||||||
};
|
|
||||||
|
|
||||||
class descriptors_manager {
|
|
||||||
private:
|
|
||||||
static std::vector<std::optional<StreamDescriptor>> descriptors;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static std::istream* get_input(int descriptor);
|
|
||||||
static std::ostream* get_output(int descriptor);
|
|
||||||
|
|
||||||
static void flush(int descriptor);
|
|
||||||
|
|
||||||
static bool has_descriptor(int descriptor);
|
|
||||||
|
|
||||||
static bool is_readable(int descriptor);
|
|
||||||
static bool is_writeable(int descriptor);
|
|
||||||
|
|
||||||
static void close(int descriptor);
|
|
||||||
static int open_descriptor(const io::path& path, bool write, bool read);
|
|
||||||
|
|
||||||
static void close_all_descriptors();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
111
src/logic/scripting/io_descriptors.cpp
Normal file
111
src/logic/scripting/io_descriptors.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
#include "logic/scripting/io_descriptors.hpp"
|
||||||
|
|
||||||
|
#include "debug/Logger.hpp"
|
||||||
|
#include "io/io.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
static debug::Logger logger("descriptors-manager");
|
||||||
|
|
||||||
|
using namespace scripting;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct StreamDescriptor {
|
||||||
|
std::unique_ptr<std::istream> in;
|
||||||
|
std::unique_ptr<std::ostream> out;
|
||||||
|
};
|
||||||
|
std::vector<std::optional<StreamDescriptor>> descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream* io_descriptors::get_input(int id) {
|
||||||
|
if (!is_readable(id)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return ::descriptors[id]->in.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream* io_descriptors::get_output(int id) {
|
||||||
|
if (!is_writeable(id)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return ::descriptors[id]->out.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_descriptors::flush(int id) {
|
||||||
|
if (is_writeable(id)) {
|
||||||
|
::descriptors[id]->out->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool io_descriptors::has_descriptor(int id) {
|
||||||
|
return id >= 0 && id < static_cast<int>(::descriptors.size()) &&
|
||||||
|
::descriptors[id].has_value() &&
|
||||||
|
(::descriptors[id]->in != nullptr ||
|
||||||
|
::descriptors[id]->out != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool io_descriptors::is_readable(int id) {
|
||||||
|
return id >= 0 && id < static_cast<int>(::descriptors.size())
|
||||||
|
&& ::descriptors[id].has_value()
|
||||||
|
&& ::descriptors[id]->in != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool io_descriptors::is_writeable(int id) {
|
||||||
|
return id >= 0 && id < static_cast<int>(::descriptors.size())
|
||||||
|
&& ::descriptors[id].has_value()
|
||||||
|
&& ::descriptors[id]->out != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_descriptors::close(int id) {
|
||||||
|
if (!has_descriptor(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& desc = ::descriptors[id].value();
|
||||||
|
if (desc.out) {
|
||||||
|
desc.out->flush();
|
||||||
|
}
|
||||||
|
desc.in.reset();
|
||||||
|
desc.out.reset();
|
||||||
|
::descriptors[id] = std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int io_descriptors::open_descriptor(const io::path& path, bool write, bool read) {
|
||||||
|
std::unique_ptr<std::istream> in;
|
||||||
|
std::unique_ptr<std::ostream> out;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (read) {
|
||||||
|
in = io::read(path);
|
||||||
|
}
|
||||||
|
if (write) {
|
||||||
|
out = io::write(path);
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
logger.error() << "failed to open descriptor for " << path.string()
|
||||||
|
<< ": " << e.what();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < static_cast<int>(descriptors.size()); ++i) {
|
||||||
|
if (!descriptors[i].has_value()) {
|
||||||
|
descriptors[i] = StreamDescriptor{ std::move(in), std::move(out) };
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::descriptors.emplace_back(StreamDescriptor{ std::move(in), std::move(out) });
|
||||||
|
return static_cast<int>(::descriptors.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void io_descriptors::close_all_descriptors() {
|
||||||
|
for (int i = 0; i < static_cast<int>(::descriptors.size()); ++i) {
|
||||||
|
if (::descriptors[i].has_value()) {
|
||||||
|
close(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::descriptors.clear();
|
||||||
|
}
|
||||||
23
src/logic/scripting/io_descriptors.hpp
Normal file
23
src/logic/scripting/io_descriptors.hpp
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <istream>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
#include "io/fwd.hpp"
|
||||||
|
|
||||||
|
namespace scripting::io_descriptors {
|
||||||
|
std::istream* get_input(int id);
|
||||||
|
std::ostream* get_output(int id);
|
||||||
|
|
||||||
|
void flush(int id);
|
||||||
|
|
||||||
|
bool has_descriptor(int id);
|
||||||
|
|
||||||
|
bool is_readable(int id);
|
||||||
|
bool is_writeable(int id);
|
||||||
|
|
||||||
|
void close(int id);
|
||||||
|
int open_descriptor(const io::path& path, bool write, bool read);
|
||||||
|
|
||||||
|
void close_all_descriptors();
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
#include "api_lua.hpp"
|
#include "api_lua.hpp"
|
||||||
#include "../lua_engine.hpp"
|
#include "../lua_engine.hpp"
|
||||||
#include "logic/scripting/descriptors_manager.hpp"
|
#include "logic/scripting/io_descriptors.hpp"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
using namespace scripting;
|
using namespace scripting;
|
||||||
|
|
@ -263,13 +263,13 @@ static int l_open_descriptor(lua::State* L) {
|
||||||
std::vector<char> buffer;
|
std::vector<char> buffer;
|
||||||
|
|
||||||
if(wplusMode) {
|
if(wplusMode) {
|
||||||
int temp_descriptor = scripting::descriptors_manager::open_descriptor(path, false, true);
|
int temp_descriptor = io_descriptors::open_descriptor(path, false, true);
|
||||||
|
|
||||||
if (temp_descriptor == -1) {
|
if (temp_descriptor == -1) {
|
||||||
throw std::runtime_error("failed to open descriptor for initial reading");
|
throw std::runtime_error("failed to open descriptor for initial reading");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* in_stream = scripting::descriptors_manager::get_input(temp_descriptor);
|
auto* in_stream = io_descriptors::get_input(temp_descriptor);
|
||||||
|
|
||||||
in_stream->seekg(0, std::ios::end);
|
in_stream->seekg(0, std::ios::end);
|
||||||
std::streamsize size = in_stream->tellg();
|
std::streamsize size = in_stream->tellg();
|
||||||
|
|
@ -278,17 +278,17 @@ static int l_open_descriptor(lua::State* L) {
|
||||||
buffer.resize(size);
|
buffer.resize(size);
|
||||||
in_stream->read(buffer.data(), size);
|
in_stream->read(buffer.data(), size);
|
||||||
|
|
||||||
scripting::descriptors_manager::close(temp_descriptor);
|
io_descriptors::close(temp_descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
int descriptor = scripting::descriptors_manager::open_descriptor(path, write, read);
|
int descriptor = io_descriptors::open_descriptor(path, write, read);
|
||||||
|
|
||||||
if(descriptor == -1) {
|
if(descriptor == -1) {
|
||||||
throw std::runtime_error("failed to open descriptor");
|
throw std::runtime_error("failed to open descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wplusMode) {
|
if(wplusMode) {
|
||||||
auto* out_stream = scripting::descriptors_manager::get_output(descriptor);
|
auto* out_stream = io_descriptors::get_output(descriptor);
|
||||||
out_stream->write(buffer.data(), buffer.size());
|
out_stream->write(buffer.data(), buffer.size());
|
||||||
out_stream->flush();
|
out_stream->flush();
|
||||||
}
|
}
|
||||||
|
|
@ -297,23 +297,23 @@ static int l_open_descriptor(lua::State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_has_descriptor(lua::State* L) {
|
static int l_has_descriptor(lua::State* L) {
|
||||||
return lua::pushboolean(L, scripting::descriptors_manager::has_descriptor(lua::tointeger(L, 1)));
|
return lua::pushboolean(L, io_descriptors::has_descriptor(lua::tointeger(L, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_read_descriptor(lua::State* L) {
|
static int l_read_descriptor(lua::State* L) {
|
||||||
int descriptor = lua::tointeger(L, 1);
|
int descriptor = lua::tointeger(L, 1);
|
||||||
|
|
||||||
if (!scripting::descriptors_manager::has_descriptor(descriptor)) {
|
if (!io_descriptors::has_descriptor(descriptor)) {
|
||||||
throw std::runtime_error("unknown descriptor");
|
throw std::runtime_error("unknown descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scripting::descriptors_manager::is_readable(descriptor)) {
|
if (!io_descriptors::is_readable(descriptor)) {
|
||||||
throw std::runtime_error("descriptor is not readable");
|
throw std::runtime_error("descriptor is not readable");
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxlen = lua::tointeger(L, 2);
|
int maxlen = lua::tointeger(L, 2);
|
||||||
|
|
||||||
auto* stream = scripting::descriptors_manager::get_input(descriptor);
|
auto* stream = io_descriptors::get_input(descriptor);
|
||||||
|
|
||||||
util::Buffer<char> buffer(maxlen);
|
util::Buffer<char> buffer(maxlen);
|
||||||
|
|
||||||
|
|
@ -327,17 +327,17 @@ static int l_read_descriptor(lua::State* L) {
|
||||||
static int l_write_descriptor(lua::State* L) {
|
static int l_write_descriptor(lua::State* L) {
|
||||||
int descriptor = lua::tointeger(L, 1);
|
int descriptor = lua::tointeger(L, 1);
|
||||||
|
|
||||||
if (!scripting::descriptors_manager::has_descriptor(descriptor)) {
|
if (!io_descriptors::has_descriptor(descriptor)) {
|
||||||
throw std::runtime_error("unknown descriptor");
|
throw std::runtime_error("unknown descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scripting::descriptors_manager::is_writeable(descriptor)) {
|
if (!io_descriptors::is_writeable(descriptor)) {
|
||||||
throw std::runtime_error("descriptor is not writeable");
|
throw std::runtime_error("descriptor is not writeable");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = lua::bytearray_as_string(L, 2);
|
auto data = lua::bytearray_as_string(L, 2);
|
||||||
|
|
||||||
auto* stream = scripting::descriptors_manager::get_output(descriptor);
|
auto* stream = io_descriptors::get_output(descriptor);
|
||||||
|
|
||||||
stream->write(data.data(), static_cast<std::streamsize>(data.size()));
|
stream->write(data.data(), static_cast<std::streamsize>(data.size()));
|
||||||
|
|
||||||
|
|
@ -350,7 +350,7 @@ static int l_write_descriptor(lua::State* L) {
|
||||||
static int l_seek_descriptor(lua::State* L) {
|
static int l_seek_descriptor(lua::State* L) {
|
||||||
int descriptor = lua::tointeger(L, 1);
|
int descriptor = lua::tointeger(L, 1);
|
||||||
|
|
||||||
if (!scripting::descriptors_manager::has_descriptor(descriptor)) {
|
if (!io_descriptors::has_descriptor(descriptor)) {
|
||||||
throw std::runtime_error("unknown descriptor");
|
throw std::runtime_error("unknown descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -371,7 +371,7 @@ static int l_seek_descriptor(lua::State* L) {
|
||||||
throw std::runtime_error("invalid seek mode");
|
throw std::runtime_error("invalid seek mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* stream = scripting::descriptors_manager::get_output(descriptor);
|
auto* stream = io_descriptors::get_output(descriptor);
|
||||||
|
|
||||||
stream->seekp(lua::tointeger(L, 3), dir);
|
stream->seekp(lua::tointeger(L, 3), dir);
|
||||||
|
|
||||||
|
|
@ -385,31 +385,31 @@ static int l_seek_descriptor(lua::State* L) {
|
||||||
static int l_flush_descriptor(lua::State* L) {
|
static int l_flush_descriptor(lua::State* L) {
|
||||||
int descriptor = lua::tointeger(L, 1);
|
int descriptor = lua::tointeger(L, 1);
|
||||||
|
|
||||||
if (!scripting::descriptors_manager::has_descriptor(descriptor)) {
|
if (!io_descriptors::has_descriptor(descriptor)) {
|
||||||
throw std::runtime_error("unknown descriptor");
|
throw std::runtime_error("unknown descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scripting::descriptors_manager::is_writeable(descriptor)) {
|
if (!io_descriptors::is_writeable(descriptor)) {
|
||||||
throw std::runtime_error("descriptor is not writeable");
|
throw std::runtime_error("descriptor is not writeable");
|
||||||
}
|
}
|
||||||
|
|
||||||
scripting::descriptors_manager::flush(descriptor);
|
io_descriptors::flush(descriptor);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_close_descriptor(lua::State* L) {
|
static int l_close_descriptor(lua::State* L) {
|
||||||
int descriptor = lua::tointeger(L, 1);
|
int descriptor = lua::tointeger(L, 1);
|
||||||
|
|
||||||
if (!scripting::descriptors_manager::has_descriptor(descriptor)) {
|
if (!io_descriptors::has_descriptor(descriptor)) {
|
||||||
throw std::runtime_error("unknown descriptor");
|
throw std::runtime_error("unknown descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
scripting::descriptors_manager::close(descriptor);
|
io_descriptors::close(descriptor);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_close_all_descriptors(lua::State* L) {
|
static int l_close_all_descriptors(lua::State* L) {
|
||||||
scripting::descriptors_manager::close_all_descriptors();
|
io_descriptors::close_all_descriptors();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue