@rel-packages/osu-beatmap-parser 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export declare function get_property(location: string, key: OsuKey): string;
3
3
  export declare function get_properties(input: string | OsuInput, keys: OsuKey[]): Record<OsuKey, string> & {
4
4
  id?: string;
5
5
  };
6
- export declare function process_beatmaps(inputs: (string | OsuInput)[], keys: OsuKey[]): Promise<(Record<OsuKey, string> & {
6
+ export declare function process_beatmaps(inputs: (string | OsuInput)[], keys: OsuKey[], update_fn?: (index: number) => void): Promise<(Record<OsuKey, string> & {
7
7
  id?: string;
8
8
  })[]>;
9
9
  export declare function get_duration(location: string): number;
package/dist/index.js CHANGED
@@ -24,9 +24,9 @@ function get_properties(input, keys) {
24
24
  return result;
25
25
  }
26
26
  ;
27
- async function process_beatmaps(inputs, keys) {
27
+ async function process_beatmaps(inputs, keys, update_fn) {
28
28
  const locations = inputs.map(i => typeof i === "string" ? i : i.path);
29
- const results = await native.process_beatmaps(locations, keys);
29
+ const results = await native.process_beatmaps(locations, keys, update_fn);
30
30
  return results.map((res, i) => {
31
31
  const input = inputs[i];
32
32
  if (typeof input !== "string" && input.id) {
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@ export interface OsuInput {
6
6
  export interface INativeExporter {
7
7
  get_property(location: string, key: string): string;
8
8
  get_properties(location: string, keys: string[]): Record<string, string>;
9
- process_beatmaps(locations: string[], keys: string[]): Promise<Record<string, string>[]>;
9
+ process_beatmaps(locations: string[], keys: string[], callback?: (index: number) => void): Promise<Record<string, string>[]>;
10
10
  get_duration(location: string): number;
11
11
  get_audio_duration(location: string): number;
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rel-packages/osu-beatmap-parser",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": ".osu parser for nodejs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -92,7 +92,14 @@ Napi::Value ParserAddon::get_properties(const Napi::CallbackInfo& info) {
92
92
  }
93
93
 
94
94
  return obj;
95
- }
95
+ };
96
+
97
+ struct CallbackContext {
98
+ Napi::ThreadSafeFunction tsfn;
99
+ std::atomic<size_t> current_index = 0;
100
+
101
+ CallbackContext() {}
102
+ };
96
103
 
97
104
  struct BatchContext {
98
105
  std::vector<std::string> paths;
@@ -100,6 +107,7 @@ struct BatchContext {
100
107
  std::vector<std::unordered_map<std::string, std::string>> results;
101
108
  std::atomic<size_t> completed_count{0};
102
109
  Napi::ThreadSafeFunction tsfn;
110
+ CallbackContext *callback_ctx;
103
111
  Napi::Promise::Deferred deferred;
104
112
  bool needs_duration = false;
105
113
 
@@ -107,6 +115,8 @@ struct BatchContext {
107
115
  };
108
116
 
109
117
  void process_chunk(BatchContext* context, size_t start, size_t end) {
118
+ auto callback_ctx = context->callback_ctx;
119
+
110
120
  for (size_t i = start; i < end; i++) {
111
121
  std::string content = read_file(context->paths[i]);
112
122
  if (!content.empty()) {
@@ -120,13 +130,30 @@ void process_chunk(BatchContext* context, size_t start, size_t end) {
120
130
  context->results[i]["Duration"] = std::to_string(duration);
121
131
  }
122
132
  }
133
+
134
+ // only increment and call if file was actually processed
135
+ if (callback_ctx != nullptr) {
136
+ size_t current = callback_ctx->current_index.fetch_add(1) + 1;
137
+ callback_ctx->tsfn.NonBlockingCall([current](Napi::Env env, Napi::Function js_callback) {
138
+ js_callback.Call({
139
+ Napi::Number::New(env, static_cast<double>(current))
140
+ });
141
+ });
142
+ }
123
143
  }
124
144
  }
125
145
 
126
146
  size_t completed = context->completed_count.fetch_add(end - start) + (end - start);
127
147
 
148
+ // last thread to finish resolves
128
149
  if (completed == context->paths.size()) {
129
- auto callback = [context](Napi::Env env, Napi::Function jsCallback) {
150
+ // release callback
151
+ if (context->callback_ctx != nullptr) {
152
+ context->callback_ctx->tsfn.Release();
153
+ }
154
+
155
+ // then resolve the promise
156
+ context->tsfn.BlockingCall([context](Napi::Env env, Napi::Function) {
130
157
  Napi::Array result_array = Napi::Array::New(env, context->results.size());
131
158
 
132
159
  for (size_t i = 0; i < context->results.size(); i++) {
@@ -138,9 +165,8 @@ void process_chunk(BatchContext* context, size_t start, size_t end) {
138
165
  }
139
166
 
140
167
  context->deferred.Resolve(result_array);
141
- };
168
+ });
142
169
 
143
- context->tsfn.BlockingCall(callback);
144
170
  context->tsfn.Release();
145
171
  }
146
172
  }
@@ -171,8 +197,27 @@ Napi::Value ParserAddon::process_beatmaps(const Napi::CallbackInfo& info) {
171
197
  }
172
198
  }
173
199
 
200
+ if (info[2].IsFunction()) {
201
+ Napi::Function callback_fn = info[2].As<Napi::Function>();
202
+ auto callback_ctx = new CallbackContext();
203
+
204
+ callback_ctx = new CallbackContext();
205
+ callback_ctx->tsfn = Napi::ThreadSafeFunction::New(
206
+ callback_fn.Env(),
207
+ callback_fn,
208
+ "ProcessBeatmapsUpdate",
209
+ 0,
210
+ 1,
211
+ [callback_ctx](Napi::Env) {
212
+ delete callback_ctx;
213
+ }
214
+ );
215
+
216
+ context->callback_ctx = callback_ctx;
217
+ }
218
+
174
219
  context->results.resize(context->paths.size());
175
-
220
+
176
221
  context->tsfn = Napi::ThreadSafeFunction::New(
177
222
  env,
178
223
  NOOP_FUNC(env),
package/src/types.ts CHANGED
@@ -42,7 +42,7 @@ export interface OsuInput {
42
42
  export interface INativeExporter {
43
43
  get_property(location: string, key: string): string;
44
44
  get_properties(location: string, keys: string[]): Record<string, string>;
45
- process_beatmaps(locations: string[], keys: string[]): Promise<Record<string, string>[]>;
45
+ process_beatmaps(locations: string[], keys: string[], callback?: (index: number) => void): Promise<Record<string, string>[]>;
46
46
  get_duration(location: string): number;
47
47
  get_audio_duration(location: string): number;
48
48
  }