From 6ae927c4b76f8d0ad2805af225be1c91685e7812 Mon Sep 17 00:00:00 2001 From: Roman Pytkov Date: Mon, 23 Feb 2026 19:33:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20=D1=81?= =?UTF-8?q?=D0=BB=D0=BE=D0=B8,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B4=D1=80=D0=B5=D0=B2=D0=BE=D0=B2=D0=B8=D0=B4=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Удалил структуру слоев. Теперь объекты хранятся непосредственно в документе, а вложенность реализуется через поле children структуры Object. Это упростило структуру документа и позволило создавать иерархические объекты. --- src/models/Document.zig | 79 ++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/src/models/Document.zig b/src/models/Document.zig index a0582b7..69d258b 100644 --- a/src/models/Document.zig +++ b/src/models/Document.zig @@ -7,44 +7,27 @@ const Document = @This(); size: Size, allocator: std.mem.Allocator, -layers: std.ArrayList(Layer), +/// Корневые объекты документа (вложенность через Object.children). +objects: std.ArrayList(Object), pub fn init(allocator: std.mem.Allocator, size: Size) Document { return .{ .size = size, .allocator = allocator, - .layers = std.ArrayList(Layer).empty, + .objects = std.ArrayList(Object).empty, }; } pub fn deinit(self: *Document) void { - for (self.layers.items) |*layer| layer.deinit(); - self.layers.deinit(self.allocator); + for (self.objects.items) |*obj| obj.deinit(self.allocator); + self.objects.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); - self.objects.deinit(self.allocator); - } - - /// Добавить объект в слой (клонирует свойства в allocator слоя). - pub fn addObject(self: *Layer, template: Object) !void { - const obj = try template.clone(self.allocator); - try self.objects.append(self.allocator, obj); - } -}; +/// Добавить корневой объект в документ (клонирует в allocator документа). +pub fn addObject(self: *Document, template: Object) !void { + const obj = try template.clone(self.allocator); + try self.objects.append(self.allocator, obj); +} /// Тип фигуры: определяет, как RenderEngine интерпретирует свойства и рисует объект. pub const ShapeKind = enum { @@ -54,12 +37,13 @@ pub const ShapeKind = enum { path, }; -/// Объект на слое: тип фигуры + список полиморфных свойств. -/// Типы объектов (прямоугольник, эллипс, линия) задаются конструкторами, -/// которые создают нужный набор свойств; UI и RenderEngine работают с union Property. +/// Объект документа: тип фигуры, свойства и вложенные дочерние объекты. +/// Типы объектов задаются конструкторами; UI и RenderEngine работают с union Property. pub const Object = struct { shape: ShapeKind, properties: std.ArrayList(Property), + /// Вложенные объекты (дерево). + children: std.ArrayList(Object), /// Найти свойство по тегу и вернуть вариант union (caller делает switch). 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); } - /// Клонировать объект (в т.ч. список свойств) для вставки в другой слой/документ. + /// Добавить дочерний объект (клонирует в переданный 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 { - var list = std.ArrayList(Property).empty; - errdefer list.deinit(allocator); - try list.appendSlice(allocator, self.properties.items); - return .{ .shape = self.shape, .properties = list }; + var properties_list = std.ArrayList(Property).empty; + errdefer properties_list.deinit(allocator); + try properties_list.appendSlice(allocator, self.properties.items); + + 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 { + for (self.children.items) |*child| child.deinit(allocator); + self.children.deinit(allocator); self.properties.deinit(allocator); self.* = undefined; } @@ -99,7 +102,11 @@ pub const Object = struct { var properties_list = std.ArrayList(Property).empty; errdefer properties_list.deinit(allocator); try properties_list.appendSlice(allocator, &common); - return .{ .shape = shape, .properties = properties_list }; + return .{ + .shape = shape, + .properties = properties_list, + .children = std.ArrayList(Object).empty, + }; } // --- Публичные конструкторы: базовый объект + одно свойство фигуры ---