Refactor: Переместил модуль shape

Я переместил модуль shape в подкаталог shape/ для лучшей организации кода.

Изменил пути импорта в связанных файлах, чтобы соответствовать новому местоположению модуля.

Удалил возвраты null из `getLocalBounds` и заменил их на обработку ошибок для улучшения надежности.
This commit is contained in:
2026-02-24 20:34:14 +03:00
parent f1a0e84272
commit 4f386c981c
7 changed files with 46 additions and 42 deletions

View File

@@ -0,0 +1,95 @@
const std = @import("std");
const Object = @import("../Object.zig");
const Property = @import("../Property.zig").Property;
const PropertyData = @import("../Property.zig").Data;
const defaultCommonProperties = @import("../Property.zig").defaultCommonProperties;
const basic_models = @import("../basic_models.zig");
const line = @import("line.zig");
const ellipse = @import("ellipse.zig");
const broken = @import("broken.zig");
const arc = @import("arc.zig");
pub const Rect = basic_models.Rect;
/// Создаёт объект с общими свойствами по умолчанию и специфичными для типа фигуры.
pub fn createObject(allocator: std.mem.Allocator, shape_kind: Object.ShapeKind) !Object {
var obj = try createWithCommonProperties(allocator, shape_kind);
errdefer obj.deinit(allocator);
switch (shape_kind) {
.line => try line.appendDefaultShapeProperties(allocator, &obj),
.ellipse => try ellipse.appendDefaultShapeProperties(allocator, &obj),
.broken => try broken.appendDefaultShapeProperties(allocator, &obj),
.arc => try arc.appendDefaultShapeProperties(allocator, &obj),
}
return obj;
}
fn createWithCommonProperties(allocator: std.mem.Allocator, shape_kind: Object.ShapeKind) !Object {
var properties_list = std.ArrayList(Property).empty;
errdefer properties_list.deinit(allocator);
for (defaultCommonProperties) |prop| try properties_list.append(allocator, prop);
return .{
.shape = shape_kind,
.properties = properties_list,
.children = std.ArrayList(Object).empty,
};
}
/// Проверяет, что объект имеет ожидаемый тип и все требуемые для этого типа свойства.
pub fn ensure(obj: *const Object, expected_kind: Object.ShapeKind) !void {
if (obj.shape != expected_kind) return error.WrongShapeKind;
const tags = requiredTagsFor(expected_kind);
for (tags) |tag| {
if (obj.getProperty(tag) == null) return error.MissingRequiredProperty;
}
}
fn requiredTagsFor(kind: Object.ShapeKind) []const std.meta.Tag(PropertyData) {
return switch (kind) {
.line => line.getRequiredTags(),
.ellipse => ellipse.getRequiredTags(),
.broken => broken.getRequiredTags(),
.arc => arc.getRequiredTags(),
};
}
/// Локальные границы объекта (AABB в своих координатах).
pub fn getLocalBounds(obj: *const Object) !Rect {
return switch (obj.shape) {
.line => line.getLocalBounds(obj),
.ellipse => ellipse.getLocalBounds(obj),
.broken => broken.getLocalBounds(obj),
.arc => arc.getLocalBounds(obj),
};
}
test "getLocalBounds" {
const shape = @This();
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var line_obj = try shape.createObject(allocator, .line);
defer line_obj.deinit(allocator);
const line_bounds = try getLocalBounds(&line_obj);
try std.testing.expect(line_bounds.x == 0);
try std.testing.expect(line_bounds.y == 0);
try std.testing.expect(line_bounds.w == 100);
try std.testing.expect(line_bounds.h == 0);
var ellipse_obj = try shape.createObject(allocator, .ellipse);
defer ellipse_obj.deinit(allocator);
const ellipse_bounds = try getLocalBounds(&ellipse_obj);
try std.testing.expect(ellipse_bounds.x == -50);
try std.testing.expect(ellipse_bounds.y == -50);
try std.testing.expect(ellipse_bounds.w == 100);
try std.testing.expect(ellipse_bounds.h == 100);
var broken_obj = try shape.createObject(allocator, .broken);
defer broken_obj.deinit(allocator);
const broken_bounds = try getLocalBounds(&broken_obj);
try std.testing.expect(broken_bounds.x == 0);
try std.testing.expect(broken_bounds.y == 0);
try std.testing.expect(broken_bounds.w == 80);
try std.testing.expect(broken_bounds.h == 60);
}