Skip to content

Commit d9750d1

Browse files
committed
Add basic implementation for ProjectDB buffers
Still need to port over the tiny buffer optimization from the C++ version and make them work with the undo/redo system.
1 parent f6c34cd commit d9750d1

File tree

1 file changed

+75
-4
lines changed

1 file changed

+75
-4
lines changed

src/App/Project/ProjectDB.bf

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,34 @@ namespace Nanoforge.App
1313
{
1414
///Project database. Tracks editor objects and changes made to them through transactions.
1515
///If you're comparing this to the C++ codebase this is really the Project + Registry classes combined. They only ever exist together so they were merged.
16-
///This implementation the more generic data model used by the C++ codebase for ease of use and type checks.
16+
///This implementation was exchanged was chosen over the more generic data model used by the C++ codebase for ease of use and comptime type checks.
1717
public static class ProjectDB
1818
{
1919
public static String ProjectFilePath { get; private set; } = new .() ~delete _; //Path of project file
2020
public static String ProjectFolderPath { get; private set; } = new .() ~delete _;
2121
public static bool Ready { get; private set; } = false;
2222

23-
static List<EditorObject> _objects = new .() ~DeleteContainerAndItems!(_);
24-
static Dictionary<EditorObject, String> _objectNames = new .() ~DeleteDictionaryAndValues!(_); //Names owned by Project so we don't add unnecessary bloat to unnamed objects
23+
static append List<EditorObject> _objects ~ClearAndDeleteItems!(_);
24+
static append Dictionary<EditorObject, String> _objectNames ~ClearDictionaryAndDeleteValues!(_); //Names owned by Project so we don't add unnecessary bloat to unnamed objects
2525
static append Monitor _objectNameDictionaryLock;
2626
static append Monitor _objectCreationLock;
27+
static append Monitor _bufferCreationLock;
2728
static append Monitor _commitLock;
2829

30+
static u64 _nextBufferUID = 0;
31+
static append Dictionary<u64, ProjectBuffer> _buffers ~ClearDictionaryAndDeleteValues!(_);
32+
2933
//Undo/redo stacks. Just using plain lists + Add() & PopBack() to handle pushing onto the stack and popping off it.
3034
//Eventually should replace with a Stack<T> class that inherits List<T> and hides non stack function. At the moment Beef doesn't have a standard stack class.
3135
public static List<Commit> UndoStack = new .() ~DeleteContainerAndItems!(_);
3236
public static List<Commit> RedoStack = new .() ~DeleteContainerAndItems!(_);
33-
37+
38+
public static this()
39+
{
40+
//Temporary hardcoded project folder while porting from C++. Will replace once I add project loading and saving
41+
ProjectFolderPath.Set(@"D:\_NFRewriteProjectDBTest\");
42+
}
43+
3444
public static T CreateObject<T>(StringView name = "") where T : EditorObject, new
3545
{
3646
ScopedLock!(_objectCreationLock);
@@ -41,6 +51,19 @@ namespace Nanoforge.App
4151
return obj;
4252
}
4353

54+
public static ProjectBuffer CreateBuffer(Span<u8> bytes = .Empty, StringView name = "")
55+
{
56+
_bufferCreationLock.Enter();
57+
u64 uid = _nextBufferUID++;
58+
ProjectBuffer buffer = new .(uid, bytes.Length, name);
59+
_buffers[uid] = buffer;
60+
_bufferCreationLock.Exit();
61+
62+
if (!bytes.IsEmpty)
63+
buffer.Save(bytes);
64+
return buffer;
65+
}
66+
4467
//Used to add objects created by DiffUtil when it commits changes. It creates its own objects so they can be destroyed on rollback and don't exist program wide until commit.
4568
public static void AddObject(EditorObject obj)
4669
{
@@ -149,4 +172,52 @@ namespace Nanoforge.App
149172
}
150173
}
151174
}
175+
176+
//Binary blob of data attached to the project. Useful for bulk binary data such as textures and meshes.
177+
public class ProjectBuffer
178+
{
179+
public const u64 NullUID = u64.MaxValue;
180+
181+
public readonly u64 UID = NullUID;
182+
public int Size { get; private set; };
183+
public append String Name;
184+
private append Monitor _lock;
185+
186+
public this(u64 uid, int size = 0, StringView name = "")
187+
{
188+
UID = uid;
189+
Size = size;
190+
Name.Set(name);
191+
}
192+
193+
public void GetPath(String path)
194+
{
195+
path.Set(scope $@"{ProjectDB.ProjectFolderPath}Buffers\{Name}.{UID}.buffer");
196+
}
197+
198+
//Read buffer from hard drive. Caller takes ownership of the result if it returns .Ok
199+
public Result<List<u8>> Load()
200+
{
201+
ScopedLock!(_lock);
202+
var bytes = new List<u8>();
203+
if (File.ReadAll(GetPath(.. scope .()), bytes) case .Ok)
204+
{
205+
return .Ok(bytes);
206+
}
207+
else
208+
{
209+
delete bytes;
210+
return .Err;
211+
}
212+
}
213+
214+
public Result<void> Save(Span<u8> data)
215+
{
216+
//TODO: Port tiny buffer merge optimization from the C++ version. Prevents having 1000s of 1KB or less files in the buffers folder since that causes performance issues.
217+
ScopedLock!(_lock);
218+
String path = GetPath(.. scope .());
219+
Directory.CreateDirectory(Path.GetDirectoryPath(path, .. scope .()));
220+
return File.WriteAll(path, data, false);
221+
}
222+
}
152223
}

0 commit comments

Comments
 (0)