Удалил слои, добавил древовидность объектов
Удалил структуру слоев. Теперь объекты хранятся непосредственно в документе, а вложенность реализуется через поле children структуры Object. Это упростило структуру документа и позволило создавать иерархические объекты.
This commit is contained in:
@@ -7,44 +7,27 @@ const Document = @This();
|
|||||||
|
|
||||||
size: Size,
|
size: Size,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
layers: std.ArrayList(Layer),
|
/// Корневые объекты документа (вложенность через Object.children).
|
||||||
|
objects: std.ArrayList(Object),
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, size: Size) Document {
|
pub fn init(allocator: std.mem.Allocator, size: Size) Document {
|
||||||
return .{
|
return .{
|
||||||
.size = size,
|
.size = size,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.layers = std.ArrayList(Layer).empty,
|
.objects = std.ArrayList(Object).empty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Document) void {
|
pub fn deinit(self: *Document) void {
|
||||||
for (self.layers.items) |*layer| layer.deinit();
|
|
||||||
self.layers.deinit(self.allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Layer = struct {
|
|
||||||
name: [64:0]u8 = .{0} ** 64,
|
|
||||||
allocator: std.mem.Allocator,
|
|
||||||
objects: std.ArrayList(Object),
|
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) Layer {
|
|
||||||
return .{
|
|
||||||
.allocator = allocator,
|
|
||||||
.objects = std.ArrayList(Object).empty,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *Layer) void {
|
|
||||||
for (self.objects.items) |*obj| obj.deinit(self.allocator);
|
for (self.objects.items) |*obj| obj.deinit(self.allocator);
|
||||||
self.objects.deinit(self.allocator);
|
self.objects.deinit(self.allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Добавить объект в слой (клонирует свойства в allocator слоя).
|
/// Добавить корневой объект в документ (клонирует в allocator документа).
|
||||||
pub fn addObject(self: *Layer, template: Object) !void {
|
pub fn addObject(self: *Document, template: Object) !void {
|
||||||
const obj = try template.clone(self.allocator);
|
const obj = try template.clone(self.allocator);
|
||||||
try self.objects.append(self.allocator, obj);
|
try self.objects.append(self.allocator, obj);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/// Тип фигуры: определяет, как RenderEngine интерпретирует свойства и рисует объект.
|
/// Тип фигуры: определяет, как RenderEngine интерпретирует свойства и рисует объект.
|
||||||
pub const ShapeKind = enum {
|
pub const ShapeKind = enum {
|
||||||
@@ -54,12 +37,13 @@ pub const ShapeKind = enum {
|
|||||||
path,
|
path,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Объект на слое: тип фигуры + список полиморфных свойств.
|
/// Объект документа: тип фигуры, свойства и вложенные дочерние объекты.
|
||||||
/// Типы объектов (прямоугольник, эллипс, линия) задаются конструкторами,
|
/// Типы объектов задаются конструкторами; UI и RenderEngine работают с union Property.
|
||||||
/// которые создают нужный набор свойств; UI и RenderEngine работают с union Property.
|
|
||||||
pub const Object = struct {
|
pub const Object = struct {
|
||||||
shape: ShapeKind,
|
shape: ShapeKind,
|
||||||
properties: std.ArrayList(Property),
|
properties: std.ArrayList(Property),
|
||||||
|
/// Вложенные объекты (дерево).
|
||||||
|
children: std.ArrayList(Object),
|
||||||
|
|
||||||
/// Найти свойство по тегу и вернуть вариант union (caller делает switch).
|
/// Найти свойство по тегу и вернуть вариант union (caller делает switch).
|
||||||
pub fn getProperty(self: Object, tag: std.meta.Tag(Property)) ?Property {
|
pub fn getProperty(self: Object, tag: std.meta.Tag(Property)) ?Property {
|
||||||
@@ -80,15 +64,34 @@ pub const Object = struct {
|
|||||||
try self.properties.append(allocator, prop);
|
try self.properties.append(allocator, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Клонировать объект (в т.ч. список свойств) для вставки в другой слой/документ.
|
/// Добавить дочерний объект (клонирует в переданный allocator).
|
||||||
|
pub fn addChild(self: *Object, allocator: std.mem.Allocator, template: Object) !void {
|
||||||
|
const obj = try template.clone(allocator);
|
||||||
|
try self.children.append(allocator, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Клонировать объект рекурсивно (свойства и дети).
|
||||||
pub fn clone(self: Object, allocator: std.mem.Allocator) !Object {
|
pub fn clone(self: Object, allocator: std.mem.Allocator) !Object {
|
||||||
var list = std.ArrayList(Property).empty;
|
var properties_list = std.ArrayList(Property).empty;
|
||||||
errdefer list.deinit(allocator);
|
errdefer properties_list.deinit(allocator);
|
||||||
try list.appendSlice(allocator, self.properties.items);
|
try properties_list.appendSlice(allocator, self.properties.items);
|
||||||
return .{ .shape = self.shape, .properties = list };
|
|
||||||
|
var children_list = std.ArrayList(Object).empty;
|
||||||
|
errdefer children_list.deinit(allocator);
|
||||||
|
for (self.children.items) |child| {
|
||||||
|
try children_list.append(allocator, try child.clone(allocator));
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.shape = self.shape,
|
||||||
|
.properties = properties_list,
|
||||||
|
.children = children_list,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Object, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: *Object, allocator: std.mem.Allocator) void {
|
||||||
|
for (self.children.items) |*child| child.deinit(allocator);
|
||||||
|
self.children.deinit(allocator);
|
||||||
self.properties.deinit(allocator);
|
self.properties.deinit(allocator);
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
@@ -99,7 +102,11 @@ pub const Object = struct {
|
|||||||
var properties_list = std.ArrayList(Property).empty;
|
var properties_list = std.ArrayList(Property).empty;
|
||||||
errdefer properties_list.deinit(allocator);
|
errdefer properties_list.deinit(allocator);
|
||||||
try properties_list.appendSlice(allocator, &common);
|
try properties_list.appendSlice(allocator, &common);
|
||||||
return .{ .shape = shape, .properties = properties_list };
|
return .{
|
||||||
|
.shape = shape,
|
||||||
|
.properties = properties_list,
|
||||||
|
.children = std.ArrayList(Object).empty,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Публичные конструкторы: базовый объект + одно свойство фигуры ---
|
// --- Публичные конструкторы: базовый объект + одно свойство фигуры ---
|
||||||
|
|||||||
Reference in New Issue
Block a user