diff options
Diffstat (limited to 'Source/modules/asura-base/FileSystem')
22 files changed, 2102 insertions, 0 deletions
diff --git a/Source/modules/asura-base/FileSystem/Binding/_compressor.cpp b/Source/modules/asura-base/FileSystem/Binding/_compressor.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Binding/_compressor.cpp diff --git a/Source/modules/asura-base/FileSystem/Binding/_data_buffer.cpp b/Source/modules/asura-base/FileSystem/Binding/_data_buffer.cpp new file mode 100644 index 0000000..ff1f0dc --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Binding/_data_buffer.cpp @@ -0,0 +1,132 @@ +#include "../DataBuffer.h" + +using namespace Luax; + +namespace AsuraEngine +{ + namespace FileSystem + { + + LUAX_REGISTRY(DataBuffer) + { + LUAX_REGISTER_METHODS(state, + { "New", _New }, + { "GetData", _GetData }, + { "GetSize", _GetSize }, + { "GetCapacity", _GetCapacity }, + { "Refactor", _Refactor }, + { "Load", _Load }, + { "Clear", _Clear } + ); + } + + LUAX_POSTPROCESS(DataBuffer) + { + } + + // databuffer = DataBuffer.New(lstring) + // databuffer = DataBuffer.New(capacity) + LUAX_IMPL_METHOD(DataBuffer, _New) + { + LUAX_STATE(L); + + if (state.IsType(1, LUA_TSTRING)) + { + size_t size; + const byte* bytes = lua_tolstring(L, 1, &size); + DataBuffer* buffer = new DataBuffer(bytes, size); + buffer->PushLuaxUserdata(state); + return 1; + } + else if (state.IsType(1, LUA_TNUMBER)) + { + size_t capacity = lua_tonumber(L, 1); + DataBuffer* buffer = new DataBuffer(capacity); + buffer->PushLuaxUserdata(state); + return 1; + } + else + { + return state.ErrorType(1, "number or string"); + } + } + + // lsting, len = databuffer:GetData() + LUAX_IMPL_METHOD(DataBuffer, _GetData) + { + LUAX_SETUP(L, "U"); + + DataBuffer* self = state.GetUserdata<DataBuffer>(1); + lua_pushlstring(L, self->GetData(), self->GetSize()); + return 1; + } + + // length = databuffer:GetSize() + LUAX_IMPL_METHOD(DataBuffer, _GetSize) + { + LUAX_SETUP(L, "U"); + + DataBuffer* self = state.GetUserdata<DataBuffer>(1); + lua_pushinteger(L, self->GetSize()); + return 1; + } + + // capacity = databuffer:GetCapacity() + LUAX_IMPL_METHOD(DataBuffer, _GetCapacity) + { + LUAX_SETUP(L, "U"); + + DataBuffer* self = state.GetUserdata<DataBuffer>(1); + lua_pushinteger(L, self->GetCapacity()); + return 1; + } + + // databuffer:Refactor(capacity) + LUAX_IMPL_METHOD(DataBuffer, _Refactor) + { + LUAX_PREPARE(L, DataBuffer); + + size_t capacity = state.CheckValue<int>(2); + self->Refactor(capacity); + return 0; + } + + // size = databuffer:Load(lstring) + // size = databuffer:Load(src) + LUAX_IMPL_METHOD(DataBuffer, _Load) + { + LUAX_STATE(L); + + DataBuffer* buffer = state.GetUserdata<DataBuffer>(1); + const byte* data; + size_t size; + if (state.IsType(2, LUA_TSTRING)) + { + data = lua_tolstring(L, 2, &size); + buffer->Load(data, size); + return 0; + } + else if(state.IsType(2, LUA_TUSERDATA)) + { + DataBuffer* src = state.CheckUserdata<DataBuffer>(2); + buffer->Load(*src); + return 0; + } + else + { + return state.ErrorType(1, "lstring or DataBuffer"); + } + } + + // databuffer:Clear() + LUAX_IMPL_METHOD(DataBuffer, _Clear) + { + LUAX_SETUP(L, "U"); + + DataBuffer* self = state.GetUserdata<DataBuffer>(1); + self->Clear(); + return 0; + } + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/Binding/_file.cpp b/Source/modules/asura-base/FileSystem/Binding/_file.cpp new file mode 100644 index 0000000..d19c02a --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Binding/_file.cpp @@ -0,0 +1,223 @@ +#include "../file.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + LUAX_REGISTRY(File) + { + LUAX_REGISTER_METHODS(state, + { "New", _New }, + { "Open", _Open }, + { "Close", _Close }, + { "IsOpen", _IsOpen }, + { "GetMode", _GetMode }, + { "GetSize", _GetSize }, + { "Read", _Read }, + { "IsEOF", _IsEOF }, + { "Write", _Write }, + { "Flush", _Flush }, + { "Tell", _Tell }, + { "Seek", _Seek }, + { "SetBuffer", _SetBuffer }, + { "GetBuffer", _GetBuffer }, + { "GetFileName", _GetFileName }, + { "GetExtension", _GetExtension }, + { "GetName", _GetName } + ); + } + + LUAX_POSTPROCESS(File) + { + LUAX_REGISTER_ENUM(state, "EFileMode", + { "CLOSED", FILE_MODE_CLOSED }, + { "READ", FILE_MODE_READ }, + { "WRITE", FILE_MODE_WRITE }, + { "APPEND", FILE_MODE_APPEND } + ); + + LUAX_REGISTER_ENUM(state, "EBufferMode", + { "NONE", BUFFER_MODE_NONE}, + { "LINE", BUFFER_MODE_LINE}, + { "FULL", BUFFER_MODE_FULL} + ); + } + + // file = File.New(name) + LUAX_IMPL_METHOD(File, _New) + { + LUAX_STATE(L); + + cc8* name = state.CheckValue<cc8*>(1); + File* file = new File(name); + file->PushLuaxUserdata(state); + return 1; + } + + // successsed = file:Open(mode) + LUAX_IMPL_METHOD(File, _Open) + { + LUAX_PREPARE(L, File); + + File::FileMode mode = (File::FileMode)state.CheckValue<int>(2); + state.Push(self->Open(mode)); + return 1; + } + + // successed = file:Close() + LUAX_IMPL_METHOD(File, _Close) + { + LUAX_PREPARE(L, File); + + state.Push(self->Close()); + return 1; + } + + // opened = file:IsOpen() + LUAX_IMPL_METHOD(File, _IsOpen) + { + LUAX_PREPARE(L, File); + + state.Push(self->IsOpen()); + return 1; + } + + // mode = file:GetMode() + LUAX_IMPL_METHOD(File, _GetMode) + { + LUAX_PREPARE(L, File); + + File::FileMode mode = self->GetMode(); + state.Push((int)mode); + return 1; + } + + // size = file:GetSize() + LUAX_IMPL_METHOD(File, _GetSize) + { + LUAX_PREPARE(L, File); + + state.Push(self->GetSize()); + return 1; + } + + // size = file:Read(dst, len) + // returns: + // size ʵʶĴС + // params: + // self ļ + // dst Ŀ껺 + // len ĴС + LUAX_IMPL_METHOD(File, _Read) + { + LUAX_PREPARE(L, File); + + DataBuffer* db = state.CheckUserdata<DataBuffer>(2); + if (!db) return state.ErrorType(2, "DataBuffer"); + int len = state.CheckValue<int>(3); + int size = self->Read(db, len); + state.Push(size); + return 1; + } + + // isEOF = file:IsEOF() + LUAX_IMPL_METHOD(File, _IsEOF) + { + LUAX_PREPARE(L, File); + + state.Push(self->IsEOF()); + return 1; + } + + // isWrite = file:Write(data buffer[, size]) + LUAX_IMPL_METHOD(File, _Write) + { + LUAX_PREPARE(L, File); + + DataBuffer* db = state.CheckUserdata<DataBuffer>(2); + if (!db) return state.ErrorType(2, "DataBuffer"); + state.Push(self->Write(db)); + return 1; + } + + // isFlushed = file:Flush() + LUAX_IMPL_METHOD(File, _Flush) + { + LUAX_PREPARE(L, File); + + state.Push(self->Flush()); + return 1; + } + + // pos = file:Tell() + LUAX_IMPL_METHOD(File, _Tell) + { + LUAX_PREPARE(L, File); + + state.Push(self->Tell()); + return 1; + } + + // isSeek = file:Seek(pos) + LUAX_IMPL_METHOD(File, _Seek) + { + LUAX_PREPARE(L, File); + + int pos = state.CheckValue<int>(2); + state.Push(self->Seek(pos)); + return 1; + } + + // isSetted = file:SetBuffer(mode, size) + LUAX_IMPL_METHOD(File, _SetBuffer) + { + LUAX_PREPARE(L, File); + + BufferMode mode = (BufferMode)state.CheckValue<int>(2); + int size = state.CheckValue<int>(3); + state.Push(self->SetBuffer(mode, size)); + return 1; + } + + // size, mode = file:GetBuffer() + LUAX_IMPL_METHOD(File, _GetBuffer) + { + LUAX_PREPARE(L, File); + + size_t size = 0; + BufferMode mode = self->GetBuffer(ASURA_OUT size); + state.Push((int)size); + state.Push((int)mode); + return 2; + } + + // name = file:GetFileName() + LUAX_IMPL_METHOD(File, _GetFileName) + { + LUAX_PREPARE(L, File); + + state.Push(self->GetFileName()); + return 1; + } + + // name = file:GetExtension() + LUAX_IMPL_METHOD(File, _GetExtension) + { + LUAX_PREPARE(L, File); + + state.Push(self->GetExtension()); + return 1; + } + + // name = file:GetName() + LUAX_IMPL_METHOD(File, _GetName) + { + LUAX_PREPARE(L, File); + + state.Push(self->GetName()); + return 1; + } + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/Binding/_file_data.cpp b/Source/modules/asura-base/FileSystem/Binding/_file_data.cpp new file mode 100644 index 0000000..ca872d2 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Binding/_file_data.cpp @@ -0,0 +1,60 @@ +#include "../FileData.h" + +using namespace std; + +namespace AsuraEngine +{ + namespace FileSystem + { + + LUAX_REGISTRY(FileData) + { + LUAX_REGISTER_METHODS(state, + { "GetFileName", _GetFileName }, + { "GetExtension", _GetExtension }, + { "GetName", _GetName }, + { "GetDataBuffer", _GetDataBuffer } + ); + } + + LUAX_POSTPROCESS(FileData) + { + } + + // filename = filedata:GetFileName() + LUAX_IMPL_METHOD(FileData, _GetFileName) + { + LUAX_PREPARE(L, FileData); + string filename = self->GetFileName(); + state.Push(filename); + return 1; + } + + // extension = filedata:GetExtension() + LUAX_IMPL_METHOD(FileData, _GetExtension) + { + LUAX_PREPARE(L, FileData); + string extension = self->GetExtension(); + state.Push(extension); + return 1; + } + + // name = filedata:GetName() + LUAX_IMPL_METHOD(FileData, _GetName) + { + LUAX_PREPARE(L, FileData); + string extension = self->GetName(); + state.Push(extension); + return 1; + } + + // databuffer = filedata:GetDataBuffer() + LUAX_IMPL_METHOD(FileData, _GetDataBuffer) + { + LUAX_PREPARE(L, FileData); + self->PushLuaxMemberRef(state, self->m_DataRef); + return 1; + } + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/Binding/_file_manager.cpp b/Source/modules/asura-base/FileSystem/Binding/_file_manager.cpp new file mode 100644 index 0000000..7781d99 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Binding/_file_manager.cpp @@ -0,0 +1,265 @@ +#include "../FileManager.h" + +using namespace Luax; + +namespace AsuraEngine +{ + namespace FileSystem + { + +#define PREPARE(l) \ + LUAX_STATE(l); \ + FileManager* fs = FileManager::Get(); + + LUAX_REGISTRY(FileManager) + { + LUAX_REGISTER_METHODS(state, + { "Init", _Init }, + { "Mount", _Mount }, + { "Unmount", _Unmount }, + { "GetMountPoint", _GetMountPoint }, + { "SetWriteDirectory", _SetWriteDirectory }, + { "GetWriteDirectory", _GetWriteDirectory }, + { "CreateFile", _CreateFile }, + { "CreateDirectory", _CreateDirectory }, + { "Write", _Write }, + { "Append", _Append }, + { "Remove", _Remove }, + { "Read", _Read }, + { "GetFileInfo", _GetFileInfo }, + { "GetDirectoryItems", _GetDirectoryItems } + ); + } + + LUAX_POSTPROCESS(FileManager) + { + LUAX_REGISTER_ENUM(state, "EFileType", + { "FILE", FILE_TYPE_FILE }, + { "DIRECTORY", FILE_TYPE_DIRECTORY }, + { "SYMLINK", FILE_TYPE_SYMLINK }, + { "OTHER", FILE_TYPE_OTHER } + ); + } + + // FileManager.Init(arg0) + LUAX_IMPL_METHOD(FileManager, _Init) + { + PREPARE(L); + + const char* arg0 = state.CheckValue<const char*>(1); + fs->Init(arg0); + return 0; + } + + // successed = FileManager.Mount(path, mountpoint[, prepend = false]) + // successed = FileManager.Mount(data buffer, archievename, mountpoint[, prepend = false]) + LUAX_IMPL_METHOD(FileManager, _Mount) + { + PREPARE(L); + bool mounted = false; + + if (state.IsType(1, LUA_TSTRING)) + { + cc8* path = state.GetValue<cc8*>(1, ""); + cc8* moutpoint = state.GetValue<cc8*>(2, "/"); + bool prepend = state.GetValue<bool>(3, false); + mounted = fs->Mount(path, moutpoint, prepend); + } + else if (state.IsType(1, LUA_TUSERDATA)) + { + DataBuffer* db = state.CheckUserdata<DataBuffer>(1); + if (!db) + return state.ErrorType(1, "Data Buffer"); + cc8* arcname = state.GetValue<cc8*>(2, ""); + cc8* mountpoint = state.GetValue<cc8*>(3, "/"); + bool prepend = state.GetValue<bool>(4, false); + mounted = fs->Mount(db, arcname, mountpoint, prepend); + // retain + fs->LuaxRetain<DataBuffer>(state, db); + } + state.Push(mounted); + return 1; + } + + // successed = FileManager.Unmount(path) + // successed = FileManager.Unmount(data buffer) + LUAX_IMPL_METHOD(FileManager, _Unmount) + { + PREPARE(L); + bool unmounted = false; + + if (state.IsType(1, LUA_TSTRING)) + { + cc8* path = state.GetValue<cc8*>(1, ""); + unmounted = fs->Unmount(path); + } + else if (state.IsType(1, LUA_TUSERDATA)) + { + DataBuffer* db = state.CheckUserdata<DataBuffer>(1); + if (!db) + return state.ErrorType(1, "Data Buffer"); + unmounted = fs->Unmount(db); + if (unmounted) + fs->LuaxRelease<DataBuffer>(state, db); + } + state.Push(unmounted); + return 1; + } + + // moutpoint = FileManager.GetMountPoint(path) + LUAX_IMPL_METHOD(FileManager, _GetMountPoint) + { + PREPARE(L); + + cc8* path = state.CheckValue<cc8*>(1); + std::string mp; + if (fs->GetMountPoint(path, ASURA_OUT mp)) + state.Push(mp); + else + state.PushNil(); + + return 1; + } + + // FileManager.SetWriteDirectory(dir) + LUAX_IMPL_METHOD(FileManager, _SetWriteDirectory) + { + PREPARE(L); + + cc8* dir = state.CheckValue<cc8*>(1); + fs->SetWriteDirectory(dir); + return 0; + } + + // dir = FileManager.GetWriteDirectory() + LUAX_IMPL_METHOD(FileManager, _GetWriteDirectory) + { + PREPARE(L); + + std::string dir = fs->GetWriteDirectory(); + state.Push(dir); + return 1; + } + + // file = FileManager.CreateFile(name) + LUAX_IMPL_METHOD(FileManager, _CreateFile) + { + PREPARE(L); + + cc8* name = state.CheckValue<cc8*>(1); + File* file = fs->NewFile(name); + if (file) + file->PushLuaxUserdata(state); + else + state.PushNil(); + return 1; + } + + // successed = FileManager.CreateDirectory(name) + LUAX_IMPL_METHOD(FileManager, _CreateDirectory) + { + PREPARE(L); + + cc8* path = state.CheckValue<cc8*>(1); + state.Push(fs->NewDirectory(path)); + return 1; + } + + // successed = FileManager.Write(path, data buffer) + LUAX_IMPL_METHOD(FileManager, _Write) + { + PREPARE(L); + + cc8* path = state.CheckValue<cc8*>(1); + DataBuffer* db = state.CheckUserdata<DataBuffer>(2); + state.Push(fs->Write(path, db)); + return 1; + } + + // successed = FileManager.Append(path, data buffer) + LUAX_IMPL_METHOD(FileManager, _Append) + { + PREPARE(L); + + cc8* path = state.CheckValue<cc8*>(1); + DataBuffer* db = state.CheckUserdata<DataBuffer>(2); + state.Push(fs->Append(path, db)); + return 1; + } + + // successed = FileManager.Remove(path) + LUAX_IMPL_METHOD(FileManager, _Remove) + { + PREPARE(L); + + cc8* path = state.CheckValue<cc8*>(1); + state.Push(fs->Remove(path)); + return 1; + } + + // filedata = FileManager.Read(path) + LUAX_IMPL_METHOD(FileManager, _Read) + { + PREPARE(L); + + cc8* path = state.CheckValue<cc8*>(1); + FileData* fd = fs->Read(path); + if (fd) + { + fd->m_Data->PushLuaxUserdata(state); + fd->SetLuaxMemberRef(state, fd->m_DataRef, -1); // fd->m_DataRef = data buffer + state.Pop(1); // data buffer + fd->PushLuaxUserdata(state); + } + else + { + state.PushNil(); + } + return 1; + } + + // fileinfo = FileManager.GetFileInfo(path) + LUAX_IMPL_METHOD(FileManager, _GetFileInfo) + { + PREPARE(L); + + cc8* path = state.CheckValue<cc8*>(1); + FileInfo info; + if (fs->GetFileInfo(path, &info)) + { + lua_newtable(L); // info table + state.SetField(-1, "size", info.size); + state.SetField(-1, "modtime", info.modtime); + state.SetField(-1, "type", info.type); + } + else + { + state.PushNil(); + } + return 1; + } + + // items = FileManager.GetDirectoryItems(path) + LUAX_IMPL_METHOD(FileManager, _GetDirectoryItems) + { + PREPARE(L); + + cc8* path = state.CheckValue<cc8*>(1); + std::vector<std::string> items; + if(fs->GetDirectoryItems(path, ASURA_OUT items)) + { + lua_newtable(L); // item list + for (int i = 0; i < items.size(); ++i) + { + state.SetFieldByIndex(-1, i + 1, items[i]); + } + } + else + { + state.PushNil(); + } + return 1; + } + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/Binding/_io_task.cpp b/Source/modules/asura-base/FileSystem/Binding/_io_task.cpp new file mode 100644 index 0000000..a3d82d5 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Binding/_io_task.cpp @@ -0,0 +1,46 @@ +#include "../IOTask.h" + +using namespace std; + +namespace AsuraEngine +{ + namespace FileSystem + { + + LUAX_REGISTRY(IOTask) + { + LUAX_REGISTER_METHODS(state, + { "New", _New } + ); + } + + LUAX_POSTPROCESS(IOTask) + { + LUAX_REGISTER_ENUM(state, "EIOTaskType", + { "READ", IOTASK_TYPE_READ }, + { "WRITE", IOTASK_TYPE_WRITE }, + { "APPEND", IOTASK_TYPE_APPEND } + ); + + } + + // task = IOTask.New(path, buffer, type, callback) + LUAX_IMPL_METHOD(IOTask, _New) + { + LUAX_STATE(L); + + cc8* path = state.CheckValue<cc8*>(1); + DataBuffer* db = state.CheckUserdata<DataBuffer>(2); + IOTaskType type = (IOTaskType)state.CheckValue<int>(3); + bool cbk = state.GetTop() >= 4 && state.IsType(4, LUA_TFUNCTION); + + IOTask* task = new IOTask(path, db, type); + task->SetLuaxMemberRef(state, task->m_BufferRef, 2); + if(cbk) + task->SetLuaxMemberRef(state, task->m_Callback, 4); + task->PushLuaxUserdata(state); + return 1; + } + + } +} diff --git a/Source/modules/asura-base/FileSystem/Compressor.cpp b/Source/modules/asura-base/FileSystem/Compressor.cpp new file mode 100644 index 0000000..eaa59a2 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Compressor.cpp @@ -0,0 +1,11 @@ +#include "Compressor.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/Compressor.h b/Source/modules/asura-base/FileSystem/Compressor.h new file mode 100644 index 0000000..9fd0808 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Compressor.h @@ -0,0 +1,28 @@ +#ifndef _ASURA_COMPRESSOR_H_ +#define _ASURA_COMPRESSOR_H_ + +#include "../Scripting/Scripting.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + class Compressor ASURA_FINAL + : public AEScripting::Portable<Compressor> + { + public: + + LUAX_DECL_SINGLETON(Compressor); + + private: + + LUAX_DECL_METHOD(_Compress); + LUAX_DECL_METHOD(_Decompress); + + }; + + } +} + +#endif
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/DataBuffer.cpp b/Source/modules/asura-base/FileSystem/DataBuffer.cpp new file mode 100644 index 0000000..71431e1 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/DataBuffer.cpp @@ -0,0 +1,156 @@ +#include <cstdlib> +#include <cstring> +#include "DataBuffer.h" + +using namespace AEThreading; + +namespace AsuraEngine +{ + namespace FileSystem + { + + DataBuffer::DataBuffer(DataBuffer& src) + : m_Size(0) + , m_Capacity(0) + , m_Bytes(nullptr) + { + // ʼ + lock(m_Mutex) + { + m_Capacity = src.m_Size; + m_Bytes = new byte[m_Capacity]; + Clear(); + + Load(src); + } + } + + DataBuffer::DataBuffer(std::size_t capacity) + : m_Size(0) + , m_Capacity(0) + , m_Bytes(nullptr) + { + lock(m_Mutex) + { + m_Capacity = capacity; + m_Bytes = new byte[m_Capacity]; + Clear(); + } + } + + DataBuffer::DataBuffer(const void* data, std::size_t size) + : m_Capacity(0) + , m_Size(0) + , m_Bytes(nullptr) + { + lock(m_Mutex) + { + m_Capacity = size; + m_Bytes = new byte[m_Capacity]; + Clear(); + + Load(data, size); + } + } + + DataBuffer::~DataBuffer() + { + lock(m_Mutex) + { + delete[] m_Bytes; + } + } + + void DataBuffer::Refactor(size_t capacity) + { + lock(m_Mutex) + { + if (!m_Bytes || m_Capacity != capacity) + { + if(m_Bytes) + delete[] m_Bytes; + m_Capacity = capacity; + m_Bytes = new byte[m_Capacity]; + m_Size = 0; + } + Clear(); + } + } + + void DataBuffer::Load(DataBuffer& db) + { + lock(m_Mutex) + { + Load(db.GetData(), db.GetSize()); + } + } + + void DataBuffer::Load(const void* data, std::size_t size) + { + lock(m_Mutex) + { + ASSERT(m_Capacity >= size); + memcpy(m_Bytes, data, size); + m_Size = size; + } + } + + void DataBuffer::Move(void* bytes, std::size_t size) + { + lock(m_Mutex) + { + if (m_Bytes == bytes) + { + // sizeֵڶļʱ + m_Size = size; + } + else + { + if (m_Bytes) + delete[] m_Bytes; + m_Bytes = (byte*)bytes; + m_Size = size; + m_Capacity = size; + } + } + } + + byte* DataBuffer::GetData() + { + return m_Bytes; + } + + void DataBuffer::Clear() + { + lock(m_Mutex) + { + if (m_Bytes) + { + memset(m_Bytes, 0, m_Size); + m_Size = 0; + } + } + } + + std::size_t DataBuffer::GetSize() + { + return m_Size; + } + + std::size_t DataBuffer::GetCapacity() + { + return m_Capacity; + } + + void DataBuffer::Lock() + { + m_Mutex.Lock(); + } + + void DataBuffer::Unlock() + { + m_Mutex.Unlock(); + } + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/DataBuffer.h b/Source/modules/asura-base/FileSystem/DataBuffer.h new file mode 100644 index 0000000..ace372e --- /dev/null +++ b/Source/modules/asura-base/FileSystem/DataBuffer.h @@ -0,0 +1,87 @@ +#ifndef _ASURA_ENGINE_DATABUFFER_H_ +#define _ASURA_ENGINE_DATABUFFER_H_ + +#include <cstdlib> + +#include "../Scripting/Scripting.h" +#include "../Threads/Mutex.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + /// + /// ڴݵķװеʹData bufferװֱʹconst void*ͨresource managerȡ + /// + class DataBuffer ASURA_FINAL + : public AEScripting::Portable<DataBuffer> + { + public: + + LUAX_DECL_FACTORY(DataBuffer); + + DataBuffer(DataBuffer& src); + DataBuffer(std::size_t capacity); + DataBuffer(const void* bytes, std::size_t size); + ~DataBuffer(); + + byte* GetData(); + size_t GetSize(); + size_t GetCapacity(); + + /// + /// + /// + void Refactor(size_t capacity); + + /// + /// Դ˻ + /// + void Load(DataBuffer& db); + void Load(const void* bytes, std::size_t size); + + /// + /// bytesӵȨcapacityΪsize + /// + void Move(void* bytes, std::size_t size); + + /// + /// + /// + void Clear(); + + void Lock(); + void Unlock(); + + private: + + LUAX_DECL_METHOD(_New); + LUAX_DECL_METHOD(_GetData); + LUAX_DECL_METHOD(_GetSize); + LUAX_DECL_METHOD(_GetCapacity); + LUAX_DECL_METHOD(_Refactor); + LUAX_DECL_METHOD(_Load); + LUAX_DECL_METHOD(_Clear); + + /// + /// Bufferַݵij + /// + byte* m_Bytes; + size_t m_Size; + + /// + /// Buffer + /// + size_t m_Capacity; + + AEThreading::Mutex m_Mutex; + + }; + + } +} + +namespace AEFileSystem = AsuraEngine::FileSystem; + +#endif
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/DecodedData.h b/Source/modules/asura-base/FileSystem/DecodedData.h new file mode 100644 index 0000000..1744233 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/DecodedData.h @@ -0,0 +1,41 @@ +#ifndef _ASURA_ENGINE_DATA_H_ +#define _ASURA_ENGINE_DATA_H_ + +#include <cstdlib> + +#include <asura-base/Threads/Thread.h> + +#include "../Scripting/Scripting.h" + +#include "DataBuffer.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + /// + /// һ̹߳data̳дࡣͼƬݡƵݵȣһ߳нԭ + /// ļڲݸʽصȡ + /// + ASURA_ABSTRACT class DecodedData + { + public: + + /// + /// ڴйdataԷһ߳棬Դϵͳء + /// + DecodedData() {}; + virtual ~DecodedData() {}; + + /// + /// ڴеݲijָʽ档 + /// + virtual void Decode(DataBuffer& buffer) = 0; + + }; + + } +} + +#endif
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/File.cpp b/Source/modules/asura-base/FileSystem/File.cpp new file mode 100644 index 0000000..ec8a9bf --- /dev/null +++ b/Source/modules/asura-base/FileSystem/File.cpp @@ -0,0 +1,294 @@ +#include <physfs/physfs.h> + +#include <asura-base/Exception.h> + +#include "File.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + File::File(const std::string& filename) + : m_FileName(filename) + , m_FileHandle(nullptr) + , m_Mode(FILE_MODE_CLOSED) + , m_BufferMode(BUFFER_MODE_NONE) + , m_BufferSize(0) + { + size_t dot = filename.rfind('.'); + if (dot != std::string::npos) + { + m_Extension = filename.substr(dot + 1); + m_Name = filename.substr(0, dot); + } + else + m_Name = filename; + } + + File::~File() + { + if (m_Mode != FILE_MODE_CLOSED) + Close(); + } + + bool File::Open(FileMode mode) + { + if (!PHYSFS_isInit()) + throw Exception("Physfs is NOT initialized."); + + if (mode == FILE_MODE_CLOSED) + return false; + + if (mode == FILE_MODE_READ && !PHYSFS_exists(m_FileName.c_str())) + throw Exception("Could NOT open file %s. Does not exist.", m_FileName.c_str()); + + if (mode == FILE_MODE_APPEND || mode == FILE_MODE_WRITE) + { + if (!PHYSFS_getWriteDir()) + { + throw Exception("Could NOT set write directory."); + } + } + + // Ѿ֮ǰͲٴµhandle + if (m_FileHandle != nullptr) + return true; + + PHYSFS_getLastErrorCode(); + + PHYSFS_File* handle = nullptr; + + switch (mode) + { + case FILE_MODE_READ: + handle = PHYSFS_openRead(m_FileName.c_str()); + break; + case FILE_MODE_APPEND: + handle = PHYSFS_openAppend(m_FileName.c_str()); + break; + case FILE_MODE_WRITE: + handle = PHYSFS_openWrite(m_FileName.c_str()); + break; + } + + if (handle == nullptr) + { + const char *err = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); + if (err == nullptr) + err = "unknown error"; + throw Exception("Could not open file %s (%s)", m_FileName.c_str(), err); + } + + m_FileHandle = handle; + m_Mode = mode; + + if (m_FileHandle && !SetBuffer(m_BufferMode,m_BufferSize)) + { + m_BufferMode = BUFFER_MODE_NONE; + m_BufferSize = 0; + } + + return m_FileHandle != nullptr; + } + + bool File::Close() + { + if (m_FileHandle == nullptr || !PHYSFS_close(m_FileHandle)) + return false; + m_Mode = FILE_MODE_CLOSED; + m_FileHandle = nullptr; + return true; + } + + bool File::IsOpen() + { + return m_Mode != FILE_MODE_CLOSED && m_FileHandle != nullptr; + } + + size_t File::GetSize() + { + if (m_FileHandle == nullptr) + { + Open(FILE_MODE_READ); + size_t size = PHYSFS_fileLength(m_FileHandle); + Close(); + return size; + } + return PHYSFS_fileLength(m_FileHandle); + } + + size_t File::Read(ASURA_OUT DataBuffer* dst, size_t length) + { + ASSERT(dst); + + if (dst->GetCapacity() < length) + throw Exception("Data buffer is too small compares to read length."); + + if (!m_FileHandle || m_Mode != FILE_MODE_READ) + throw Exception("File \"%s\" is not opened for reading", m_FileName); + + size_t max = PHYSFS_fileLength(m_FileHandle); + length = (length > max) ? max : length; + + if (length < 0) + throw Exception("Invalid read size."); + + dst->Lock(); + size_t size = PHYSFS_readBytes(m_FileHandle, dst->GetData(), length); + dst->Unlock(); + return size; + } + + size_t File::ReadAll(ASURA_OUT DataBuffer* dst) + { + ASSERT(dst); + + if (!m_FileHandle || m_Mode != FILE_MODE_READ) + throw Exception("File \"%s\" is not opened for reading", m_FileName); + + size_t length = PHYSFS_fileLength(m_FileHandle); + + if (dst->GetCapacity() < length) + throw Exception("Data buffer is too small compares to file length."); + + dst->Lock(); + byte* data = dst->GetData(); + size_t size = PHYSFS_readBytes(m_FileHandle, data, length); + dst->Move(data, length); + dst->Unlock(); + return size; + } + +#ifdef ASURA_WINDOWS + inline bool test_eof(File *that, PHYSFS_File *) + { + int64 pos = that->Tell(); + int64 size = that->GetSize(); + return pos == -1 || size == -1 || pos >= size; + } +#else + inline bool test_eof(File *, PHYSFS_File *file) + { + return PHYSFS_eof(file); + } +#endif + + bool File::IsEOF() + { + return m_FileHandle == nullptr || test_eof(this, m_FileHandle); + } + + size_t File::Tell() + { + if (!m_FileHandle) + return - 1; + + return PHYSFS_tell(m_FileHandle); + } + + bool File::Seek(size_t pos) + { + return m_FileHandle != nullptr && PHYSFS_seek(m_FileHandle, pos) != 0; + } + + bool File::Write(ASURA_REF DataBuffer* src) + { + if (!m_FileHandle || (m_Mode != FILE_MODE_APPEND && m_Mode != FILE_MODE_WRITE)) + throw Exception("File is not opened for writing."); + + byte* data = src->GetData(); + int size = src->GetSize(); + + if (size < 0) + throw Exception("Invalid write size."); + + size_t written = PHYSFS_writeBytes(m_FileHandle, data, size); + + if (written != src->GetSize()) + return false; + + // л + if (m_BufferSize == BUFFER_MODE_LINE && m_BufferSize > size) + { + if (memchr(data, '\n', size) != nullptr) + Flush(); + } + + return true; + } + + bool File::Flush() + { + if (!m_FileHandle || (m_Mode != FILE_MODE_WRITE && m_Mode != FILE_MODE_APPEND)) + throw Exception("File is not opened for writing."); + + return PHYSFS_flush(m_FileHandle) != 0; + } + + bool File::SetBuffer(BufferMode mode, size_t size) + { + if (size < 0) + return false; + + // If the file isn't open, we'll make sure the buffer values are set in + // File::open. + if (!IsOpen()) + { + m_BufferMode = mode; + m_BufferSize = size; + return true; + } + + int ret = 1; + + switch (mode) + { + case BUFFER_MODE_NONE: + default: + ret = PHYSFS_setBuffer(m_FileHandle, 0); + size = 0; + break; + case BUFFER_MODE_LINE: + case BUFFER_MODE_FULL: + ret = PHYSFS_setBuffer(m_FileHandle, size); + break; + } + + if (ret == 0) + return false; + + m_BufferMode = mode; + m_BufferSize = size; + + return true; + } + + File::BufferMode File::GetBuffer(ASURA_OUT size_t& size) + { + size = m_BufferSize; + return m_BufferMode; + } + + const std::string& File::GetFileName() + { + return m_FileName; + } + + const std::string& File::GetName() + { + return m_Name; + } + + const std::string& File::GetExtension() + { + return m_Extension; + } + + File::FileMode File::GetMode() + { + return m_Mode; + } + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/File.h b/Source/modules/asura-base/FileSystem/File.h new file mode 100644 index 0000000..be772e0 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/File.h @@ -0,0 +1,146 @@ +#ifndef _ASURA_ENGINE_FILE_H_ +#define _ASURA_ENGINE_FILE_H_ + +#include "physfs/physfs.h" + +#include "../Scripting/Scripting.h" +#include "../Threads/Thread.h" + +#include "FileData.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + /// + /// ʽļָд㡢Сʹȡʱʹñ࣬ʹFilesystem.read()ֱӶȡļȫ + /// ݣһFileData + /// + class File ASURA_FINAL + : public AEScripting::Portable<File> + { + public: + + LUAX_DECL_FACTORY(File); + + /// + /// ļдģʽ + /// + enum FileMode + { + FILE_MODE_CLOSED, + FILE_MODE_READ, + FILE_MODE_WRITE, + FILE_MODE_APPEND, + }; + + /// + /// ļдʱΪ + /// + enum BufferMode + { + BUFFER_MODE_NONE, ///< ʹû壬дļ + BUFFER_MODE_LINE, ///< л壬зߴﵽСʱдļ + BUFFER_MODE_FULL, ///< ȫ壬ʱдļ + }; + + File(const std::string& filename); + ~File(); + + bool Open(FileMode mode); + bool Close(); + bool IsOpen(); + FileMode GetMode(); + size_t GetSize(); + + /// + /// ȡdata bufferض + /// + size_t Read(ASURA_OUT DataBuffer* dst, size_t length); + size_t ReadAll(ASURA_OUT DataBuffer* dst); + size_t ReadAsync(ASURA_OUT DataBuffer* dst); + + /// + /// Ƿļβ + /// + bool IsEOF(); + + /// + /// data bufferед룬Ƿɹ + /// + bool Write(ASURA_REF DataBuffer* src); + + /// + /// 첽дļдļtaskthreadĶС + /// + bool WriteAsync(ASURA_REF DataBuffer* src, AEThreading::Thread* thread); + + /// + /// ˻壬ǿջдļ + /// + bool Flush(); + + /// + /// صǰдλ + /// + size_t Tell(); + + /// + /// Ӧλ + /// + bool Seek(size_t pos); + + /// + /// ûСģʽ + /// + bool SetBuffer(BufferMode mode, size_t size); + + /// + /// ȡСģʽ + /// + BufferMode GetBuffer(ASURA_OUT size_t& size); + + const std::string& GetFileName(); + const std::string& GetName(); + const std::string& GetExtension(); + + private: + + PHYSFS_File* m_FileHandle; ///< physfs ļ + std::string m_FileName; ///< ļ + std::string m_Extension; ///< չ + std::string m_Name; ///< չļ + FileMode m_Mode; ///< ļģʽ + BufferMode m_BufferMode; ///< д뻺ģʽ + size_t m_BufferSize; ///< д뻺С + + LUAX_DECL_ENUM(FileMode); + LUAX_DECL_ENUM(BufferMode); + + LUAX_DECL_METHOD(_New); + LUAX_DECL_METHOD(_Open); + LUAX_DECL_METHOD(_Close); + LUAX_DECL_METHOD(_IsOpen); + LUAX_DECL_METHOD(_GetMode); + LUAX_DECL_METHOD(_GetSize); + LUAX_DECL_METHOD(_Read); + LUAX_DECL_METHOD(_Write); + LUAX_DECL_METHOD(_ReadAsync); + LUAX_DECL_METHOD(_WriteAsync); + LUAX_DECL_METHOD(_IsEOF); + LUAX_DECL_METHOD(_Flush); + LUAX_DECL_METHOD(_Tell); + LUAX_DECL_METHOD(_Seek); + LUAX_DECL_METHOD(_SetBuffer); + LUAX_DECL_METHOD(_GetBuffer); + LUAX_DECL_METHOD(_GetFileName); + LUAX_DECL_METHOD(_GetExtension); + LUAX_DECL_METHOD(_GetName); + + }; + + } +} + +#endif
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/FileData.cpp b/Source/modules/asura-base/FileSystem/FileData.cpp new file mode 100644 index 0000000..b29a95b --- /dev/null +++ b/Source/modules/asura-base/FileSystem/FileData.cpp @@ -0,0 +1,59 @@ +#include "FileData.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + FileData::FileData(const std::string& filename) + : m_Data(nullptr) + , m_FileName(filename) + { + size_t dot = filename.rfind('.'); + if (dot != std::string::npos) + { + m_Extension = filename.substr(dot + 1); + m_Name = filename.substr(0, dot); + } + else + m_Name = filename; + } + + FileData::~FileData() + { + if (m_Data) + m_Data->Release(); + } + + const std::string& FileData::GetFileName() + { + return m_FileName; + } + + const std::string& FileData::GetExtension() + { + return m_Extension; + } + + const std::string& FileData::GetName() + { + return m_Name; + } + + void FileData::BindData(ASURA_MOVE DataBuffer* buffer) + { + if (!buffer) + return; + if (m_Data) + m_Data->Release(); + m_Data = buffer; + m_Data->Retain(); + } + + DataBuffer* FileData::GetDataBuffer() + { + return m_Data; + } + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/FileData.h b/Source/modules/asura-base/FileSystem/FileData.h new file mode 100644 index 0000000..d0acd26 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/FileData.h @@ -0,0 +1,69 @@ +#ifndef _ASURA_ENGINE_FILE_DATA_H_ +#define _ASURA_ENGINE_FILE_DATA_H_ + +#include <string> + +#include <asura-base/Scripting/Scripting.h> + +#include "DataBuffer.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + class Filesystem; + + /// + /// filesystemֱӶȡļʱFileDataļݺϢFilesystem + /// + class FileData ASURA_FINAL + : public AEScripting::Portable<FileData> + { + public: + + LUAX_DECL_FACTORY(FileData); + + ~FileData(); + + /// + /// ļݣͨDatabufferݺʹСڲӿڶData bufferΪҲdata buffer + /// + DataBuffer* GetDataBuffer(); + + const std::string& GetFileName(); + const std::string& GetExtension(); + const std::string& GetName(); + + private: + + friend class FileManager; + + FileData(const std::string& name); + + /// + /// data buffer + /// + void BindData(ASURA_MOVE DataBuffer* buffer); + + /// + /// Data bufferfiledataʱ٣luaüΪ0ʱluaGC١mDataʱһԱá + /// + ASURA_REF DataBuffer* m_Data; + Luax::LuaxMemberRef m_DataRef; + + std::string m_FileName; ///< չļ + std::string m_Extension; ///< չ + std::string m_Name; ///< ͺļ + + LUAX_DECL_METHOD(_GetDataBuffer); + LUAX_DECL_METHOD(_GetFileName); + LUAX_DECL_METHOD(_GetExtension); + LUAX_DECL_METHOD(_GetName); + + }; + + } +} + +#endif
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/FileManager.cpp b/Source/modules/asura-base/FileSystem/FileManager.cpp new file mode 100644 index 0000000..bdb4069 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/FileManager.cpp @@ -0,0 +1,198 @@ +#include <physfs/physfs.h> + +#include "../Exception.h" + +#include "File.h" +#include "FileData.h" +#include "FileManager.h" + +using namespace std; + +namespace AsuraEngine +{ + namespace FileSystem + { + +#ifdef ASURA_WINDOWS + #include <windows.h> + #include <direct.h> +#else + #include <sys/param.h> + #include <unistd.h> +#endif + + FileManager::~FileManager() + { + if (m_Inited) //PHYSFS_isInit + PHYSFS_deinit(); + } + + void FileManager::Init(const char* arg0) + { + if (!PHYSFS_init(arg0)) + throw Exception("Failed to initialize filesystem: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); + + m_Inited = true; + } + + bool FileManager::Mount(const std::string& locpath, const std::string& montpoint/* = "/"*/, bool prepend /*= false*/) + { + if (!m_Inited) + return false; + + return PHYSFS_mount(locpath.c_str(), montpoint.c_str(), !prepend); + } + + bool FileManager::Mount(DataBuffer* db, const std::string& archivename, const std::string& mountpoint /*= "/"*/, bool prepend /*= false*/) + { + if (!m_Inited) + return false; + if (PHYSFS_mountMemory(db->GetData(), db->GetSize(), nullptr, archivename.c_str(), mountpoint.c_str(), !prepend)) + { + m_MountData[archivename] = db; + return true; + } + return false; + } + + bool FileManager::Unmount(const std::string& locpath) + { + if (!m_Inited) + return false; + + // ǹ鵵ӳɾ + auto datait = m_MountData.find(locpath); + if (datait != m_MountData.end() && PHYSFS_unmount(locpath.c_str()) != 0) + { + m_MountData.erase(datait); + return true; + } + + return PHYSFS_unmount(locpath.c_str()); + } + + bool FileManager::Unmount(DataBuffer* db) + { + for (const auto& dp : m_MountData) + { + if (dp.second == db) + { + std::string archive = dp.first; + return Unmount(archive); + } + } + } + + bool FileManager::GetMountPoint(const std::string& locpath, ASURA_OUT std::string& mountpoint) + { + if (!m_Inited) + return false; + const char* point = PHYSFS_getMountPoint(locpath.c_str()); + if (point != nullptr) + { + mountpoint = point; + return true; + } + return false; + } + + void FileManager::SetWriteDirectory(const std::string locpath) + { + if (!m_Inited) + return; + if (!PHYSFS_setWriteDir(locpath.c_str())) + throw Exception("Failed to set write directory %s", locpath.c_str()); + } + + std::string FileManager::GetWriteDirectory() + { + return PHYSFS_getWriteDir(); + } + + File* FileManager::NewFile(const std::string& name) + { + return new File(name); + } + + bool FileManager::NewDirectory(const std::string& path) + { + if (!m_Inited) + return false; + if (!PHYSFS_getWriteDir()) + return false; + if (!PHYSFS_mkdir(path.c_str())) + return false; + return true; + } + + bool FileManager::Write(const std::string& name, ASURA_REF DataBuffer* buffer) + { + File file(name); + file.Open(File::FILE_MODE_WRITE); + if (!file.Write(buffer)) + throw Exception("Data could not be written."); + } + + bool FileManager::Append(const std::string& name, ASURA_REF DataBuffer* buffer) + { + File file(name); + file.Open(File::FILE_MODE_APPEND); + if (!file.Write(buffer)) + throw Exception("Data could not be append."); + } + + FileData* FileManager::Read(const std::string& name) + { + File file = File(name); + file.Open(File::FILE_MODE_READ); + int size = file.GetSize(); + DataBuffer* db = new DataBuffer(size); + if (db) + { + file.ReadAll(db); + FileData* fd = new FileData(name); + fd->BindData(db); + return fd; + } + return nullptr; + } + + bool FileManager::Remove(const std::string& path) + { + if (!m_Inited) + return false; + if (PHYSFS_getWriteDir() == 0) + return false; + + if (!PHYSFS_delete(path.c_str())) + return false; + + return true; + } + + bool FileManager::GetFileInfo(const std::string& filepath, ASURA_OUT FileInfo* info) + { + if (!m_Inited) + return false; + + PHYSFS_Stat stat = {}; + if (!PHYSFS_stat(filepath.c_str(), &stat)) + return false; + + info->size = (int64)stat.filesize; + info->modtime = (int64)stat.modtime; + + if (stat.filetype == PHYSFS_FILETYPE_REGULAR) + info->type = FILE_TYPE_FILE; + else if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY) + info->type = FILE_TYPE_DIRECTORY; + else if (stat.filetype == PHYSFS_FILETYPE_SYMLINK) + info->type = FILE_TYPE_SYMLINK; + else + info->type = FILE_TYPE_OTHER; + + return true; + } + + } +}
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/FileManager.h b/Source/modules/asura-base/FileSystem/FileManager.h new file mode 100644 index 0000000..ac97da3 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/FileManager.h @@ -0,0 +1,112 @@ +#ifndef _ASURA_ENGINE_FILESYSTEM_H_ +#define _ASURA_ENGINE_FILESYSTEM_H_ + +#include <map> +#include <string> + +#include "../Scripting/Scripting.h" +#include "../Singleton.hpp" +#include "../Type.h" + +#include "FileData.h" +#include "File.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + enum FileType + { + FILE_TYPE_FILE, ///< ļ + FILE_TYPE_DIRECTORY, ///< ļ + FILE_TYPE_SYMLINK, ///< + FILE_TYPE_OTHER, ///< + }; + + struct FileInfo + { + int64 size; + int64 modtime; + FileType type; + }; + + /// + /// Դء洢ԴָĿ¼ȡ۱༭ʱҪƷʵĻƣûIJϷĿ¼ + /// £file systemµġFileManagerʱͱ༭õ࣬AssetDatabaseԴ࣬framework + /// ʵ֣дFileManagerʵ֣AssetDatabaseṩļݴӦԴķ + /// + class FileManager ASURA_FINAL + : public Singleton<FileManager> + , public AEScripting::Portable<FileManager> + { + public: + + LUAX_DECL_SINGLETON(FileManager); + + ~FileManager(); + + void Init(const char* arg0); + + /// + /// ǰִļļ + /// + std::string GetWorkingDirectory(); + + bool Mount(const std::string& locpath, const std::string& montpoint = "/", bool prepend = false); + bool Mount(DataBuffer* db, const std::string& archivename, const std::string& mountpoint = "/", bool prepend = false); + + bool Unmount(const std::string& locpath); + bool Unmount(DataBuffer* db); + + bool GetMountPoint(const std::string& locpath, ASURA_OUT std::string& mountpoint); + + void SetWriteDirectory(const std::string locpath); + std::string GetWriteDirectory(); + File* NewFile(const std::string& name); + bool NewDirectory(const std::string& path); + bool Write(const std::string& path, ASURA_REF DataBuffer* buffer); + bool Append(const std::string& path, ASURA_REF DataBuffer* buffer); + bool Remove(const std::string& path); + + FileData* Read(const std::string& path); + bool GetFileInfo(const std::string& path, ASURA_OUT FileInfo* info); + + bool GetDirectoryItems(const std::string& path, ASURA_OUT std::vector<std::string>& items) { return false; }; + + private: + + typedef std::map<std::string, DataBuffer*> MountDataMap; + + bool m_Inited; ///< Ƿʼɹ + std::string m_Cwd; ///< ǰִļĹĿ¼ + MountDataMap m_MountData; ///< ·ѹĵӳ + + LUAX_DECL_METHOD(_Init); + LUAX_DECL_METHOD(_Mount); + LUAX_DECL_METHOD(_Unmount); + LUAX_DECL_METHOD(_GetMountPoint); + + LUAX_DECL_METHOD(_SetWriteDirectory); + LUAX_DECL_METHOD(_GetWriteDirectory); + LUAX_DECL_METHOD(_CreateFile); + LUAX_DECL_METHOD(_CreateDirectory); + + LUAX_DECL_METHOD(_Write); + LUAX_DECL_METHOD(_Append); + LUAX_DECL_METHOD(_Remove); + + LUAX_DECL_METHOD(_Read); + + LUAX_DECL_METHOD(_GetFileInfo); + + LUAX_DECL_METHOD(_GetDirectoryItems); + + }; + + } +} + +namespace AEFileSystem = AsuraEngine::FileSystem; + +#endif
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/IOBatchTask.cpp b/Source/modules/asura-base/FileSystem/IOBatchTask.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/IOBatchTask.cpp diff --git a/Source/modules/asura-base/FileSystem/IOBatchTask.h b/Source/modules/asura-base/FileSystem/IOBatchTask.h new file mode 100644 index 0000000..8d73e93 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/IOBatchTask.h @@ -0,0 +1,31 @@ +#ifndef _ASURA_IO_BATCH_TASK_H_ +#define _ASURA_IO_BATCH_TASK_H_ + +#include "IOTask.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + /// + /// дһύһtableδؽ + /// + class IOBatchTask ASURA_FINAL : public AEThreading::Task + { + public: + + private: + + /// + /// ÿһĽṹ£ + /// { path = "", } + /// + Luax::LuaxMemberRef m_Tasks; + + }; + + } +} + +#endif
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/IOTask.cpp b/Source/modules/asura-base/FileSystem/IOTask.cpp new file mode 100644 index 0000000..9152a6e --- /dev/null +++ b/Source/modules/asura-base/FileSystem/IOTask.cpp @@ -0,0 +1,61 @@ +#include "FileManager.h" +#include "IOTask.h" + +#include <iostream> + +using namespace AEScripting; +using namespace Luax; + +namespace AsuraEngine +{ + namespace FileSystem + { + + IOTask::IOTask(const std::string& path, DataBuffer* buffer, IOTaskType type) + : m_Path(path) + , m_Buffer(buffer) + { + if (buffer) + buffer->Retain(); + } + + IOTask::~IOTask() + { + if (m_Buffer) + m_Buffer->Release(); + } + + bool IOTask::Execute() + { + File file(m_Path); + if (m_Type == IOTASK_TYPE_WRITE) + { + + } + // pathȡݱmBuffer + else if (m_Type == IOTASK_TYPE_READ) + { + if (!m_Buffer) + return false; + file.Open(File::FILE_MODE_READ); + file.ReadAll(m_Buffer); + file.Close(); + } + return true; + } + + void IOTask::Invoke(lua_State* invokeThreaad) + { + if (m_Callback) + { + LuaxScopedState state(invokeThreaad); + if (this->PushLuaxMemberRef(state, m_Callback)) + { + this->PushLuaxMemberRef(state, m_BufferRef); + state.Call(1, 0); + } + } + } + + } +} diff --git a/Source/modules/asura-base/FileSystem/IOTask.h b/Source/modules/asura-base/FileSystem/IOTask.h new file mode 100644 index 0000000..da54fdc --- /dev/null +++ b/Source/modules/asura-base/FileSystem/IOTask.h @@ -0,0 +1,56 @@ +#ifndef _ASURA_IO_TASK_H_ +#define _ASURA_IO_TASK_H_ + +#include <string> + +#include "../Scripting/Scripting.h" +#include "../Threads/Task.h" + +#include "DataBuffer.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + enum IOTaskType + { + IOTASK_TYPE_READ, + IOTASK_TYPE_WRITE, + IOTASK_TYPE_APPEND, + }; + + /// + /// ȡļ + /// + class IOTask ASURA_FINAL + : public AEScripting::Portable<IOTask, AEThreading::Task> + { + public: + + LUAX_DECL_FACTORY(IOTask); + + IOTask(const std::string& path, DataBuffer* buffer, IOTaskType type); + ~IOTask(); + + bool Execute() override ; + void Invoke(lua_State* invokeThreaad) override; + + private: + + LUAX_DECL_ENUM(IOTaskType); + + LUAX_DECL_METHOD(_New); + + std::string m_Path; + IOTaskType m_Type; + + DataBuffer* m_Buffer; + Luax::LuaxMemberRef m_BufferRef; + + }; + + } +} + +#endif
\ No newline at end of file diff --git a/Source/modules/asura-base/FileSystem/Renewable.h b/Source/modules/asura-base/FileSystem/Renewable.h new file mode 100644 index 0000000..ff44303 --- /dev/null +++ b/Source/modules/asura-base/FileSystem/Renewable.h @@ -0,0 +1,27 @@ +#ifndef __ASURA_ENGINE_RENEWABLE_H__ +#define __ASURA_ENGINE_RENEWABLE_H__ + +#include "DecodedData.h" + +namespace AsuraEngine +{ + namespace FileSystem + { + + /// + /// ¹ݽṹͼƬƵ֣ӽݿֱӹڱ༭ + /// ¹handleֵı䲻߱ƻԣڲıhandleԴ + /// + ASURA_ABSTRACT class Renewable + { + public: + Renewable() {}; + virtual ~Renewable() {}; + }; + + } +} + +namespace AEFileSystem = AsuraEngine::FileSystem; + +#endif
\ No newline at end of file |