Lua support fully working and efficient except for sliders

pull/170/head
James Ball 2023-07-01 15:29:53 +01:00
rodzic a4ee966f50
commit 91aa11ddcc
6 zmienionych plików z 103 dodań i 61 usunięć

Wyświetl plik

@ -300,7 +300,9 @@ void OscirenderAudioProcessor::updateFrame() {
frameLength = Shape::totalLength(frame);
}
}
} else {
DBG("frame not ready!");
}
}
void OscirenderAudioProcessor::updateLengthIncrement() {
@ -345,7 +347,11 @@ void OscirenderAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, j
double y = 0.0;
double length = 0.0;
if (currentShape < frame.size()) {
bool renderingSample = currentFile >= 0 && parsers[currentFile]->isSample();
if (renderingSample) {
channels = parsers[currentFile]->nextSample();
} else if (currentShape < frame.size()) {
auto& shape = frame[currentShape];
length = shape->length();
double drawingProgress = length == 0.0 ? 1 : shapeDrawn / length;
@ -360,6 +366,7 @@ void OscirenderAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, j
x = channels.x;
y = channels.y;
if (totalNumOutputChannels >= 2) {
channelData[0][sample] = x;
@ -368,29 +375,31 @@ void OscirenderAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, j
channelData[0][sample] = x;
}
// hard cap on how many times it can be over the length to
// prevent audio stuttering
frameDrawn += std::min(lengthIncrement, 20 * length);
shapeDrawn += std::min(lengthIncrement, 20 * length);
if (!renderingSample) {
// hard cap on how many times it can be over the length to
// prevent audio stuttering
frameDrawn += std::min(lengthIncrement, 20 * length);
shapeDrawn += std::min(lengthIncrement, 20 * length);
// Need to skip all shapes that the lengthIncrement draws over.
// This is especially an issue when there are lots of small lines being
// drawn.
while (shapeDrawn > length) {
shapeDrawn -= length;
currentShape++;
if (currentShape >= frame.size()) {
currentShape = 0;
break;
}
// POTENTIAL TODO: Think of a way to make this more efficient when iterating
// this loop many times
length = frame[currentShape]->len;
}
// Need to skip all shapes that the lengthIncrement draws over.
// This is especially an issue when there are lots of small lines being
// drawn.
while (shapeDrawn > length) {
shapeDrawn -= length;
currentShape++;
if (currentShape >= frame.size()) {
currentShape = 0;
break;
}
// POTENTIAL TODO: Think of a way to make this more efficient when iterating
// this loop many times
length = frame[currentShape]->len;
}
}
if (frameDrawn >= frameLength) {
updateFrame();
}
if (!renderingSample && frameDrawn >= frameLength) {
updateFrame();
}
}
juce::MidiBuffer processedMidi;

Wyświetl plik

@ -8,45 +8,61 @@ LuaParser::LuaParser(juce::String script) {
luaL_openlibs(L);
this->script = script;
parse();
}
LuaParser::~LuaParser() {
lua_close(L);
}
std::vector<std::unique_ptr<Shape>> LuaParser::draw() {
std::vector<std::unique_ptr<Shape>> shapes;
for (int i = 0; i < 100; i++) {
lua_pushnumber(L, step);
lua_setglobal(L, "step");
const int ret = luaL_dostring(L, script.toUTF8());
if (ret != 0) {
const char* error = lua_tostring(L, -1);
DBG(error);
lua_pop(L, 1);
} else if (lua_istable(L, -1)) {
// get the first element of the table
lua_pushinteger(L, 1);
lua_gettable(L, -2);
float x = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
// get the second element of the table
lua_pushinteger(L, 2);
lua_gettable(L, -2);
float y = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
shapes.push_back(std::make_unique<Vector2>(x, y));
}
// pop the table
lua_pop(L, 1);
step++;
void LuaParser::parse() {
const int ret = luaL_loadstring(L, script.toUTF8());
if (ret != 0) {
const char* error = lua_tostring(L, -1);
DBG(error);
lua_pop(L, 1);
functionRef = -1;
} else {
functionRef = luaL_ref(L, LUA_REGISTRYINDEX);
}
return shapes;
}
Vector2 LuaParser::draw() {
Vector2 sample;
if (functionRef == -1) {
return sample;
}
lua_pushnumber(L, step);
lua_setglobal(L, "step");
lua_geti(L, LUA_REGISTRYINDEX, functionRef);
const int ret = lua_pcall(L, 0, LUA_MULTRET, 0);
if (ret != 0) {
const char* error = lua_tostring(L, -1);
DBG(error);
functionRef = -1;
} else if (lua_istable(L, -1)) {
// get the first element of the table
lua_pushinteger(L, 1);
lua_gettable(L, -2);
float x = lua_tonumber(L, -1);
lua_pop(L, 1);
// get the second element of the table
lua_pushinteger(L, 2);
lua_gettable(L, -2);
float y = lua_tonumber(L, -1);
lua_pop(L, 1);
sample = Vector2(x, y);
}
lua_pop(L, 1);
step++;
return sample;
}

Wyświetl plik

@ -9,8 +9,10 @@ public:
LuaParser(juce::String script);
~LuaParser();
std::vector<std::unique_ptr<Shape>> draw();
Vector2 draw();
private:
void parse();
int functionRef = -1;
long step = 1;
lua_State* L;
juce::String script;

Wyświetl plik

@ -23,6 +23,8 @@ void FileParser::parse(juce::String extension, std::unique_ptr<juce::InputStream
} else if (extension == ".lua") {
lua = std::make_shared<LuaParser>(stream->readEntireStreamAsString());
}
sampleSource = lua != nullptr;
}
std::vector<std::unique_ptr<Shape>> FileParser::nextFrame() {
@ -30,7 +32,6 @@ std::vector<std::unique_ptr<Shape>> FileParser::nextFrame() {
auto tempCamera = camera;
auto tempSvg = svg;
auto tempText = text;
auto tempLua = lua;
if (tempObject != nullptr && tempCamera != nullptr) {
return tempCamera->draw(*tempObject);
@ -38,14 +39,23 @@ std::vector<std::unique_ptr<Shape>> FileParser::nextFrame() {
return tempSvg->draw();
} else if (tempText != nullptr) {
return tempText->draw();
} else if (tempLua != nullptr) {
return tempLua->draw();
}
auto tempShapes = std::vector<std::unique_ptr<Shape>>();
tempShapes.push_back(std::make_unique<CircleArc>(0, 0, 0.5, 0.5, std::numbers::pi / 4.0, 2 * std::numbers::pi));
return tempShapes;
}
Vector2 FileParser::nextSample() {
auto tempLua = lua;
if (tempLua != nullptr) {
return tempLua->draw();
}
}
bool FileParser::isSample() {
return sampleSource;
}
bool FileParser::isActive() {
return active;
}

Wyświetl plik

@ -14,12 +14,15 @@ public:
void parse(juce::String extension, std::unique_ptr<juce::InputStream>) override;
std::vector<std::unique_ptr<Shape>> nextFrame() override;
Vector2 nextSample() override;
bool isSample() override;
bool isActive() override;
void disable() override;
void enable() override;
private:
bool active = true;
bool sampleSource = false;
std::shared_ptr<WorldObject> object;
std::shared_ptr<Camera> camera;

Wyświetl plik

@ -9,6 +9,8 @@ class FrameSource {
public:
virtual void parse(juce::String extension, std::unique_ptr<juce::InputStream>) = 0;
virtual std::vector<std::unique_ptr<Shape>> nextFrame() = 0;
virtual Vector2 nextSample() = 0;
virtual bool isSample() = 0;
virtual bool isActive() = 0;
virtual void disable() = 0;
virtual void enable() = 0;