If path is blank, loads Core */
| 127 | |
| 128 | /** If path is blank, loads Core */ |
| 129 | static Plugin* loadPlugin(std::string path) { |
| 130 | if (path == "") |
| 131 | INFO("Loading Core plugin"); |
| 132 | else |
| 133 | INFO("Loading plugin from %s", path.c_str()); |
| 134 | |
| 135 | Plugin* plugin = new Plugin; |
| 136 | |
| 137 | try { |
| 138 | if (path == "") |
| 139 | plugin->version = APP_VERSION; |
| 140 | |
| 141 | // Set plugin path |
| 142 | plugin->path = (path == "") ? asset::systemDir : path; |
| 143 | |
| 144 | // Get modified timestamp |
| 145 | if (path != "") { |
| 146 | struct stat statbuf; |
| 147 | if (!stat(path.c_str(), &statbuf)) { |
| 148 | #if defined ARCH_MAC |
| 149 | plugin->modifiedTimestamp = (double) statbuf.st_mtimespec.tv_sec + statbuf.st_mtimespec.tv_nsec * 1e-9; |
| 150 | #elif defined ARCH_WIN |
| 151 | plugin->modifiedTimestamp = (double) statbuf.st_mtime; |
| 152 | #elif defined ARCH_LIN |
| 153 | plugin->modifiedTimestamp = (double) statbuf.st_mtim.tv_sec + statbuf.st_mtim.tv_nsec * 1e-9; |
| 154 | #endif |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | // Load plugin.json |
| 159 | std::string manifestFilename = (path == "") ? asset::system("Core.json") : system::join(path, "plugin.json"); |
| 160 | FILE* file = std::fopen(manifestFilename.c_str(), "r"); |
| 161 | if (!file) |
| 162 | throw Exception("Manifest file %s does not exist", manifestFilename.c_str()); |
| 163 | DEFER({std::fclose(file);}); |
| 164 | |
| 165 | json_error_t error; |
| 166 | json_t* rootJ = json_loadf(file, 0, &error); |
| 167 | if (!rootJ) |
| 168 | throw Exception("JSON parsing error at %s %d:%d %s", manifestFilename.c_str(), error.line, error.column, error.text); |
| 169 | DEFER({json_decref(rootJ);}); |
| 170 | |
| 171 | // Load manifest |
| 172 | plugin->fromJson(rootJ); |
| 173 | |
| 174 | // Reject plugin if slug already exists |
| 175 | Plugin* existingPlugin = getPlugin(plugin->slug); |
| 176 | if (existingPlugin) |
| 177 | throw Exception("Plugin %s is already loaded, not attempting to load it again", plugin->slug.c_str()); |
| 178 | |
| 179 | // Call init callback |
| 180 | InitCallback initCallback; |
| 181 | if (path == "") { |
| 182 | initCallback = core::init; |
| 183 | } |
| 184 | else { |
| 185 | initCallback = loadPluginCallback(plugin); |
| 186 | } |
no test coverage detected