I’ve been trying to find ways but none worked. I’m basically doing this:
@:hlNative("chart_file", "insertNotes") public static function insertNotes(values:hl.types.ArrayObj):Void {}
@:hlNative("chart_file", "removeNotes") public static function removeNotes(values:hl.types.ArrayObj):Void {}
HL_PRIM void HL_NAME(insertNotes)(varray* arr) {
int64_t* ptr = hl_aptr(arr, int64_t);
std::vector<int64_t> newNotes(ptr, ptr + arr->size);
if (newNotes.empty()) return;
int64_t oldLen = length;
int64_t insCount = newNotes.size();
int64_t newLen = oldLen + insCount;
if (!remap(newLen)) throw std::runtime_error("resize failed");
ensureScratch(oldLen + insCount);
int64_t* oldCopy = scratchBuf;
memcpy(oldCopy, data, oldLen * sizeof(int64_t));
int64_t* newCopy = scratchBuf + oldLen;
memcpy(newCopy, newNotes.data(), insCount * sizeof(int64_t));
int64_t i = 0, j = 0, k = 0;
while (i < oldLen && j < insCount) {
int64_t tTime = extractTime(oldCopy[i]);
int64_t dTime = extractTime(newCopy[j]);
data[k++] = (tTime <= dTime) ? oldCopy[i++] : newCopy[j++];
}
while (i < oldLen) data[k++] = oldCopy[i++];
while (j < insCount) data[k++] = newCopy[j++];
length = newLen;
}
HL_PRIM void HL_NAME(removeNotes)(varray* arr) {
int64_t* ptr = hl_aptr(arr, int64_t);
std::vector<int64_t> toRemove(ptr, ptr + arr->size);
if (toRemove.empty() || length == 0) return;
int64_t write = 0, j = 0;
for (int64_t i = 0; i < length; ++i) {
if (j < (int64_t)toRemove.size() && data[i] == toRemove[j]) {
++j; // skip
} else {
if (write != i) data[write] = data[i];
++write;
}
}
if (write != length) {
if (!remap(write)) throw std::runtime_error("shrink failed in removeNotes");
}
}
These extern functions are what I’m trying to pass a haxe array from.
Here’s the test sample (don’t mind the other things)
haxe.Timer.delay(function() {
// START CHART SAMPLE
var stamp = haxe.Timer.stamp();
trace("Insert 1,000,000 notes (array)");
Chart.load("assets/songs/god-eater");
var arr = new Array<MetaNote>();
for (i in 0...1000000) {
arr.push(new MetaNote(Tools.betterInt64FromFloat((50.0 + (50.0 * i)) * 100),
Math.floor(/*100*/0 * 0.2), // Equal to `note.duration / 5`.
i % 9,
0,
1));
//Sys.println(i);
}
Sys.println("Insert 1,000,000 notes (function)");
var stamp2 = haxe.Timer.stamp();
File.insertNotes(arr);
Sys.println('Done! Took ${(haxe.Timer.stamp() - stamp2) * 1000}ms');
// Remove notes
var stamp3 = haxe.Timer.stamp();
Sys.println("Remove 1,000,000 notes (function)");
Sys.println(arr.length);
File.removeNotes(arr);
Sys.println('Done! Took ${(haxe.Timer.stamp() - stamp3) * 1000}ms');
Sys.println('Inserting 1,000,000 notes fully done! Took ${(haxe.Timer.stamp() - stamp) * 1000}ms');
Chart.destroy();
}, 8000);