diff --git a/assets/tiled/map.tmx b/assets/tiled/map.tmx index 6c925c0..bdd1c49 100644 --- a/assets/tiled/map.tmx +++ b/assets/tiled/map.tmx @@ -1,5 +1,5 @@ - + @@ -20,6 +20,24 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, +0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, +0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, +0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, +0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, +0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, +0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 @@ -42,6 +60,24 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,98,98,98,98,98,98,98,0,0,0,0,0, +0,0,0,0,98,0,0,0,0,0,98,0,0,0,0,0, +0,0,0,0,98,0,7,0,26,0,98,0,0,0,0,0, +0,0,0,0,98,0,0,0,0,0,98,0,0,0,0,0, +0,0,0,0,98,0,7,0,26,0,98,0,0,0,0,0, +0,0,0,0,98,0,0,0,0,0,98,0,0,0,0,0, +0,0,0,0,98,98,98,98,98,98,98,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 @@ -50,5 +86,16 @@ - + + + + + + + + + + + + diff --git a/libs/tiled/src/layer.zig b/libs/tiled/src/layer.zig index 9e34834..841a54d 100644 --- a/libs/tiled/src/layer.zig +++ b/libs/tiled/src/layer.zig @@ -212,7 +212,6 @@ variant: Variant, pub fn initFromXml( arena: std.mem.Allocator, - scratch: *std.heap.ArenaAllocator, doc: xml.Document, element_id: xml.Element.Id ) !Layer { @@ -279,33 +278,41 @@ pub fn initFromXml( var objects: std.ArrayList(Object) = .empty; var layers: std.ArrayList(Layer) = .empty; + if (variant == .object) { + try objects.ensureTotalCapacityPrecise(arena, doc.countChildren(element_id)); + } + + if (variant == .group) { + try layers.ensureTotalCapacityPrecise(arena, doc.countChildren(element_id)); + } + var iter = doc.iterChildren(element_id); while (iter.next()) |child_id| { const child = doc.getTag(child_id) orelse continue; const child_name = child.variant.tag.name; if (std.mem.eql(u8, child_name, "properties")) { - properties = try Property.List.initFromXml(arena, scratch, doc, child_id); + properties = try Property.List.initFromXml(arena, doc, child_id); } else if (variant == .image and std.mem.eql(u8, child_name, "image")) { variant.image.image = try ImageVariant.Image.initFromXml(arena, doc, child_id); } else if (variant == .object and std.mem.eql(u8, child_name, "object")) { - const object = try Object.initFromXml(arena, scratch, doc, child_id); - try objects.append(scratch.allocator(), object); + const object = try Object.initFromXml(arena, doc, child_id); + objects.appendAssumeCapacity(object); } else if (variant == .group and Layer.Type.name_map.has(child_name)) { - const layer = try initFromXml(arena, scratch, doc, child_id); - try layers.append(scratch.allocator(), layer); + const layer = try initFromXml(arena, doc, child_id); + layers.appendAssumeCapacity(layer); } } if (variant == .object) { - variant.object.items = try arena.dupe(Object, objects.items); + variant.object.items = objects.items; } if (variant == .group) { - variant.group.layers = try arena.dupe(Layer, layers.items); + variant.group.layers = layers.items; } return Layer{ diff --git a/libs/tiled/src/object.zig b/libs/tiled/src/object.zig index 47c276b..782fca0 100644 --- a/libs/tiled/src/object.zig +++ b/libs/tiled/src/object.zig @@ -116,7 +116,6 @@ shape: Shape, pub fn initFromXml( arena: std.mem.Allocator, - scratch: *std.heap.ArenaAllocator, doc: xml.Document, element_id: xml.Element.Id ) !Object { @@ -213,10 +212,12 @@ pub fn initFromXml( const points_str = child_attrs.get("points") orelse ""; var points: std.ArrayList(Position) = .empty; + try points.ensureTotalCapacityPrecise(arena, std.mem.countScalar(u8, points_str, ' ')+1); + var point_iter = std.mem.splitScalar(u8, points_str, ' '); while (point_iter.next()) |point_str| { const point = try Position.parseCommaDelimited(point_str); - try points.append(scratch.allocator(), point); + points.appendAssumeCapacity(point); } shape = .{ diff --git a/libs/tiled/src/property.zig b/libs/tiled/src/property.zig index 6eb121c..7531509 100644 --- a/libs/tiled/src/property.zig +++ b/libs/tiled/src/property.zig @@ -33,13 +33,13 @@ pub const List = struct { pub fn initFromXml( arena: std.mem.Allocator, - scratch: *std.heap.ArenaAllocator, doc: xml.Document, element_id: xml.Element.Id ) !Property.List { _ = try doc.getTagExpect(element_id, "properties"); - var temp_properties: std.ArrayList(Property) = .empty; + var properties: std.ArrayList(Property) = .empty; + try properties.ensureTotalCapacityPrecise(arena, doc.countChildren(element_id)); var iter = doc.iterChildren(element_id); while (iter.next()) |child_id| { @@ -48,14 +48,12 @@ pub const List = struct { if (std.mem.eql(u8, child_name, "property")) { const property = try Property.initFromXml(arena, doc, child_id); - try temp_properties.append(scratch.allocator(), property); + properties.appendAssumeCapacity(property); } } - const properties = try arena.dupe(Property, temp_properties.items); - return List{ - .items = properties + .items = properties.items }; } diff --git a/libs/tiled/src/tilemap.zig b/libs/tiled/src/tilemap.zig index def2cbb..9e0ca88 100644 --- a/libs/tiled/src/tilemap.zig +++ b/libs/tiled/src/tilemap.zig @@ -109,7 +109,6 @@ layers: []Layer, // https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#map pub fn initFromXml( gpa: std.mem.Allocator, - scratch: *std.heap.ArenaAllocator, doc: xml.Document, element_id: xml.Element.Id ) !Tilemap { @@ -145,8 +144,27 @@ pub fn initFromXml( // TODO: staggerindex } + var layer_count: usize = 0; + var tileset_count: usize = 0; + { + var iter = doc.iterChildren(element_id); + while (iter.next()) |child_id| { + const child = doc.getTag(child_id) orelse continue; + const child_name = child.variant.tag.name; + + if (std.mem.eql(u8, child_name, "tileset")) { + tileset_count += 1; + } else { + layer_count += 1; + } + } + } + var tileset_list: std.ArrayList(TilesetReference) = .empty; + try tileset_list.ensureTotalCapacityPrecise(arena, tileset_count); + var layer_list: std.ArrayList(Layer) = .empty; + try layer_list.ensureTotalCapacityPrecise(arena, layer_count); var iter = doc.iterChildren(element_id); while (iter.next()) |child_id| { @@ -154,11 +172,10 @@ pub fn initFromXml( const child_name = child.variant.tag.name; if (std.mem.eql(u8, child_name, "tileset")) { - try tileset_list.append(scratch.allocator(), try TilesetReference.initFromXml(arena, doc, child_id)); + tileset_list.appendAssumeCapacity(try TilesetReference.initFromXml(arena, doc, child_id)); } else { - try layer_list.append(scratch.allocator(), try Layer.initFromXml( + layer_list.appendAssumeCapacity(try Layer.initFromXml( arena, - scratch, doc, child_id )); diff --git a/libs/tiled/src/tileset.zig b/libs/tiled/src/tileset.zig index f105656..3c2094e 100644 --- a/libs/tiled/src/tileset.zig +++ b/libs/tiled/src/tileset.zig @@ -36,7 +36,6 @@ pub const Tile = struct { pub fn initFromXml( arena: std.mem.Allocator, - scratch: *std.heap.ArenaAllocator, doc: xml.Document, element_id: xml.Element.Id ) !Tile { @@ -53,7 +52,7 @@ pub const Tile = struct { const child_name = child.variant.tag.name; if (std.mem.eql(u8, child_name, "properties")) { - properties = try Property.List.initFromXml(arena, scratch, doc, child_id); + properties = try Property.List.initFromXml(arena, doc, child_id); } } @@ -124,7 +123,6 @@ tiles: []Tile, pub fn initFromXml( gpa: std.mem.Allocator, - scratch: *std.heap.ArenaAllocator, doc: xml.Document, element_id: xml.Element.Id ) !Tileset { @@ -144,6 +142,7 @@ pub fn initFromXml( var image: ?Image = null; var tiles_list: std.ArrayList(Tile) = .empty; + try tiles_list.ensureTotalCapacityPrecise(arena, doc.countChildren(element_id)); var iter = doc.iterChildren(element_id); while (iter.next()) |child_id| { @@ -153,8 +152,8 @@ pub fn initFromXml( if (std.mem.eql(u8, child_name, "image")) { image = try Image.intFromXml(arena, doc, child_id); } else if (std.mem.eql(u8, child_name, "tile")) { - const tile = try Tile.initFromXml(arena, scratch, doc, child_id); - try tiles_list.append(scratch.allocator(), tile); + const tile = try Tile.initFromXml(arena, doc, child_id); + tiles_list.appendAssumeCapacity(tile); } } diff --git a/src/app.zig b/src/app.zig index ba0ae8d..720bf0b 100644 --- a/src/app.zig +++ b/src/app.zig @@ -270,14 +270,11 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 { }; { - var scratch = std.heap.ArenaAllocator.init(plt.gpa); - defer scratch.deinit(); - var xml_parser = try Tiled.xml.Parser.initCapacity(plt.gpa, .{}); defer xml_parser.deinit(plt.gpa); const tilemap = try Tiled.Tilemap.initFromXml( - plt.gpa, &scratch, + plt.gpa, try xml_parser.parse(plt.assets.readFile("tiled/map.tmx")), .root ); @@ -287,7 +284,7 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 { defer tilesets.deinit(plt.gpa); try tilesets.add(plt.gpa, "tileset.tsx", try Tiled.Tileset.initFromXml( - plt.gpa, &scratch, + plt.gpa, try xml_parser.parse(plt.assets.readFile("tiled/tileset.tsx")), .root ));