From 0a5456feb9bc2a0e7f02b4b7cee34f0353e76b59 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Wed, 5 Aug 2020 11:47:41 -0400
Subject: [PATCH] vfs_vector: Make creation of array vfs files less verbose

We can add a helper function to make creation of these files nicer.
While we're at it, we can eliminate an unnecessary std::array copy in
the constructor. This makes the overhead on some of these functions way
less intensive, given some arrays were quite large.

e.g. The timezone location names are 9633 bytes in size.
---
 .../file_sys/system_archive/mii_model.cpp     | 18 +++-----
 src/core/file_sys/system_archive/ng_word.cpp  | 42 ++++++++-----------
 .../system_archive/time_zone_binary.cpp       |  9 ++--
 src/core/file_sys/vfs_vector.h                | 13 +++++-
 4 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/src/core/file_sys/system_archive/mii_model.cpp b/src/core/file_sys/system_archive/mii_model.cpp
index 61bb679459..d65c7d2344 100644
--- a/src/core/file_sys/system_archive/mii_model.cpp
+++ b/src/core/file_sys/system_archive/mii_model.cpp
@@ -27,18 +27,12 @@ VirtualDir MiiModel() {
     auto out = std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{},
                                                     std::vector<VirtualDir>{}, "data");
 
-    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::TEXTURE_LOW_LINEAR.size()>>(
-        MiiModelData::TEXTURE_LOW_LINEAR, "NXTextureLowLinear.dat"));
-    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::TEXTURE_LOW_SRGB.size()>>(
-        MiiModelData::TEXTURE_LOW_SRGB, "NXTextureLowSRGB.dat"));
-    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::TEXTURE_MID_LINEAR.size()>>(
-        MiiModelData::TEXTURE_MID_LINEAR, "NXTextureMidLinear.dat"));
-    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::TEXTURE_MID_SRGB.size()>>(
-        MiiModelData::TEXTURE_MID_SRGB, "NXTextureMidSRGB.dat"));
-    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::SHAPE_HIGH.size()>>(
-        MiiModelData::SHAPE_HIGH, "ShapeHigh.dat"));
-    out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::SHAPE_MID.size()>>(
-        MiiModelData::SHAPE_MID, "ShapeMid.dat"));
+    out->AddFile(MakeArrayFile(MiiModelData::TEXTURE_LOW_LINEAR, "NXTextureLowLinear.dat"));
+    out->AddFile(MakeArrayFile(MiiModelData::TEXTURE_LOW_SRGB, "NXTextureLowSRGB.dat"));
+    out->AddFile(MakeArrayFile(MiiModelData::TEXTURE_MID_LINEAR, "NXTextureMidLinear.dat"));
+    out->AddFile(MakeArrayFile(MiiModelData::TEXTURE_MID_SRGB, "NXTextureMidSRGB.dat"));
+    out->AddFile(MakeArrayFile(MiiModelData::SHAPE_HIGH, "ShapeHigh.dat"));
+    out->AddFile(MakeArrayFile(MiiModelData::SHAPE_MID, "ShapeMid.dat"));
 
     return out;
 }
diff --git a/src/core/file_sys/system_archive/ng_word.cpp b/src/core/file_sys/system_archive/ng_word.cpp
index f4443784db..100d3c5db9 100644
--- a/src/core/file_sys/system_archive/ng_word.cpp
+++ b/src/core/file_sys/system_archive/ng_word.cpp
@@ -24,19 +24,18 @@ constexpr std::array<u8, 30> WORD_TXT{
 } // namespace NgWord1Data
 
 VirtualDir NgWord1() {
-    std::vector<VirtualFile> files(NgWord1Data::NUMBER_WORD_TXT_FILES);
+    std::vector<VirtualFile> files;
+    files.reserve(NgWord1Data::NUMBER_WORD_TXT_FILES);
 
     for (std::size_t i = 0; i < files.size(); ++i) {
-        files[i] = std::make_shared<ArrayVfsFile<NgWord1Data::WORD_TXT.size()>>(
-            NgWord1Data::WORD_TXT, fmt::format("{}.txt", i));
+        files.push_back(MakeArrayFile(NgWord1Data::WORD_TXT, fmt::format("{}.txt", i)));
     }
 
-    files.push_back(std::make_shared<ArrayVfsFile<NgWord1Data::WORD_TXT.size()>>(
-        NgWord1Data::WORD_TXT, "common.txt"));
-    files.push_back(std::make_shared<ArrayVfsFile<NgWord1Data::VERSION_DAT.size()>>(
-        NgWord1Data::VERSION_DAT, "version.dat"));
+    files.push_back(MakeArrayFile(NgWord1Data::WORD_TXT, "common.txt"));
+    files.push_back(MakeArrayFile(NgWord1Data::VERSION_DAT, "version.dat"));
 
-    return std::make_shared<VectorVfsDirectory>(files, std::vector<VirtualDir>{}, "data");
+    return std::make_shared<VectorVfsDirectory>(std::move(files), std::vector<VirtualDir>{},
+                                                "data");
 }
 
 namespace NgWord2Data {
@@ -55,27 +54,22 @@ constexpr std::array<u8, 0x2C> AC_NX_DATA{
 } // namespace NgWord2Data
 
 VirtualDir NgWord2() {
-    std::vector<VirtualFile> files(NgWord2Data::NUMBER_AC_NX_FILES * 3);
+    std::vector<VirtualFile> files;
+    files.reserve(NgWord2Data::NUMBER_AC_NX_FILES * 3);
 
     for (std::size_t i = 0; i < NgWord2Data::NUMBER_AC_NX_FILES; ++i) {
-        files[3 * i] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
-            NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b1_nx", i));
-        files[3 * i + 1] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
-            NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b2_nx", i));
-        files[3 * i + 2] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
-            NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_not_b_nx", i));
+        files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b1_nx", i)));
+        files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b2_nx", i)));
+        files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_not_b_nx", i)));
     }
 
-    files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
-        NgWord2Data::AC_NX_DATA, "ac_common_b1_nx"));
-    files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
-        NgWord2Data::AC_NX_DATA, "ac_common_b2_nx"));
-    files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
-        NgWord2Data::AC_NX_DATA, "ac_common_not_b_nx"));
-    files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::VERSION_DAT.size()>>(
-        NgWord2Data::VERSION_DAT, "version.dat"));
+    files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, "ac_common_b1_nx"));
+    files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, "ac_common_b2_nx"));
+    files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, "ac_common_not_b_nx"));
+    files.push_back(MakeArrayFile(NgWord2Data::VERSION_DAT, "version.dat"));
 
-    return std::make_shared<VectorVfsDirectory>(files, std::vector<VirtualDir>{}, "data");
+    return std::make_shared<VectorVfsDirectory>(std::move(files), std::vector<VirtualDir>{},
+                                                "data");
 }
 
 } // namespace FileSys::SystemArchive
diff --git a/src/core/file_sys/system_archive/time_zone_binary.cpp b/src/core/file_sys/system_archive/time_zone_binary.cpp
index d1de63f20f..8fd0050128 100644
--- a/src/core/file_sys/system_archive/time_zone_binary.cpp
+++ b/src/core/file_sys/system_archive/time_zone_binary.cpp
@@ -654,12 +654,13 @@ static VirtualFile GenerateDefaultTimeZoneFile() {
 }
 
 VirtualDir TimeZoneBinary() {
-    const std::vector<VirtualDir> root_dirs{std::make_shared<VectorVfsDirectory>(
+    std::vector<VirtualDir> root_dirs{std::make_shared<VectorVfsDirectory>(
         std::vector<VirtualFile>{GenerateDefaultTimeZoneFile()}, std::vector<VirtualDir>{},
         "zoneinfo")};
-    const std::vector<VirtualFile> root_files{
-        std::make_shared<ArrayVfsFile<LOCATION_NAMES.size()>>(LOCATION_NAMES, "binaryList.txt")};
-    return std::make_shared<VectorVfsDirectory>(root_files, root_dirs, "data");
+    std::vector<VirtualFile> root_files{MakeArrayFile(LOCATION_NAMES, "binaryList.txt")};
+
+    return std::make_shared<VectorVfsDirectory>(std::move(root_files), std::move(root_dirs),
+                                                "data");
 }
 
 } // namespace FileSys::SystemArchive
diff --git a/src/core/file_sys/vfs_vector.h b/src/core/file_sys/vfs_vector.h
index ac36cb2ee7..95d3da2f21 100644
--- a/src/core/file_sys/vfs_vector.h
+++ b/src/core/file_sys/vfs_vector.h
@@ -4,7 +4,11 @@
 
 #pragma once
 
+#include <array>
 #include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
 #include "core/file_sys/vfs.h"
 
 namespace FileSys {
@@ -13,7 +17,8 @@ namespace FileSys {
 template <std::size_t size>
 class ArrayVfsFile : public VfsFile {
 public:
-    ArrayVfsFile(std::array<u8, size> data, std::string name = "", VirtualDir parent = nullptr)
+    explicit ArrayVfsFile(const std::array<u8, size>& data, std::string name = "",
+                          VirtualDir parent = nullptr)
         : data(data), name(std::move(name)), parent(std::move(parent)) {}
 
     std::string GetName() const override {
@@ -61,6 +66,12 @@ private:
     VirtualDir parent;
 };
 
+template <std::size_t Size, typename... Args>
+std::shared_ptr<ArrayVfsFile<Size>> MakeArrayFile(const std::array<u8, Size>& data,
+                                                  Args&&... args) {
+    return std::make_shared<ArrayVfsFile<Size>>(data, std::forward<Args>(args)...);
+}
+
 // An implementation of VfsFile that is backed by a vector optionally supplied upon construction
 class VectorVfsFile : public VfsFile {
 public: