Testing out python bindings, needs refactor
A disgusting little race condition has appeared, running will result in a black screen 70% of the time >:( TODO: lambda functions referencing non static graphics methods instead of making graphics methods static state manager (everything is hodge podged into graphics and pycron objects) sort math functions into relevant places (trig, random etc)
This commit is contained in:
parent
d7966bdcae
commit
66ce48776a
@ -47,5 +47,6 @@ if(EMSCRIPTEN)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
file(COPY ${CMAKE_SOURCE_DIR}/resources DESTINATION ${CMAKE_BINARY_DIR})
|
file(COPY ${CMAKE_SOURCE_DIR}/resources DESTINATION ${CMAKE_BINARY_DIR})
|
||||||
|
file(COPY ${CMAKE_SOURCE_DIR}/python DESTINATION ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
17
python/main.py
Normal file
17
python/main.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
i = 0
|
||||||
|
def update():
|
||||||
|
global i
|
||||||
|
i += 1
|
||||||
|
clear(43)
|
||||||
|
x = sin(i * 0.071234) * 50 + 100
|
||||||
|
y = sin(i * 0.0236) * 20 + 80
|
||||||
|
circle(x + sin(i * 0.05) * 30, y + cos(i * 0.05) * 30, 5, 15)
|
||||||
|
circle(x + sin(i * 0.05) * 30, y + cos(i * 0.05) * 30, 3, 11)
|
||||||
|
circle(x + -sin(i * 0.05) * 30, y + -cos(i * 0.05) * 30, 5, 17)
|
||||||
|
circle(x + -sin(i * 0.05) * 30, y + -cos(i * 0.05) * 30, 3, 19)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
clear(44)
|
||||||
|
circle(20,30, 5, 17)
|
||||||
@ -6,6 +6,9 @@
|
|||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "../Utilities.h"
|
#include "../Utilities.h"
|
||||||
|
|
||||||
|
std::vector<Color> Graphics::palette;
|
||||||
|
|
||||||
|
|
||||||
Graphics::Graphics(int screenWidth, int screenHeight, int startupScale) : screenWidth(screenWidth), screenHeight(screenHeight){
|
Graphics::Graphics(int screenWidth, int screenHeight, int startupScale) : screenWidth(screenWidth), screenHeight(screenHeight){
|
||||||
startupScreenWidth = screenWidth * startupScale;
|
startupScreenWidth = screenWidth * startupScale;
|
||||||
startupScreenHeight = screenHeight * startupScale;
|
startupScreenHeight = screenHeight * startupScale;
|
||||||
@ -16,11 +19,19 @@ Graphics::Graphics(int screenWidth, int screenHeight, int startupScale) : screen
|
|||||||
InitWindow(startupScreenWidth, startupScreenHeight, "test");
|
InitWindow(startupScreenWidth, startupScreenHeight, "test");
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
virtualScreen = LoadRenderTexture(screenWidth, screenHeight);
|
virtualScreen = LoadRenderTexture(screenWidth, screenHeight);
|
||||||
|
|
||||||
virtualScreenLocalBounds = {0.0f, 0.0f, (float)virtualScreen.texture.width, -(float)virtualScreen.texture.height };
|
virtualScreenLocalBounds = {0.0f, 0.0f, (float)virtualScreen.texture.width, -(float)virtualScreen.texture.height };
|
||||||
|
updateFunction = nullptr;
|
||||||
calculateScreenPositionInWindow();
|
calculateScreenPositionInWindow();
|
||||||
|
|
||||||
|
std::cout << origin.x << " : " << origin.y << std::endl;
|
||||||
|
std::cout << virtualScreenLocalBounds.width << " : " << virtualScreenLocalBounds.height << std::endl;
|
||||||
|
std::cout << virtualScreenWindowBounds.width << " : " << virtualScreenWindowBounds.height << std::endl;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::draw() {
|
void Graphics::draw(pkpy::VM* vm) {
|
||||||
|
|
||||||
windowShouldClose = WindowShouldClose();
|
windowShouldClose = WindowShouldClose();
|
||||||
|
|
||||||
@ -32,18 +43,12 @@ void Graphics::draw() {
|
|||||||
|
|
||||||
BeginTextureMode(virtualScreen);
|
BeginTextureMode(virtualScreen);
|
||||||
//////////
|
//////////
|
||||||
ClearBackground(palette[1]);
|
try{
|
||||||
DrawText(("Hello World " + std::to_string(GetFPS()) + " FPS").c_str(), 5, 5, 5, RAYWHITE);
|
if(updateFunction != nullptr)
|
||||||
|
vm->call(updateFunction);
|
||||||
DrawRectangle(3, 19, 33, 33, BLACK);
|
} catch(pkpy::Exception e){
|
||||||
|
std::cout << e.summary() << std::endl;
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
for (int j = 0; j < 8; ++j) {
|
|
||||||
DrawRectangle(4 + i * 4, 20 + j * 4, 3, 3, palette[i + j * 8]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawCircleLines(mouseX(), mouseY(),3, palette[18]);
|
|
||||||
//////////
|
//////////
|
||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
|
|
||||||
@ -52,7 +57,7 @@ void Graphics::draw() {
|
|||||||
|
|
||||||
void Graphics::renderVirtualScreen() {
|
void Graphics::renderVirtualScreen() {
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(palette[0]);
|
//ClearBackground(palette[16]);
|
||||||
DrawTexturePro(virtualScreen.texture, virtualScreenLocalBounds, virtualScreenWindowBounds, origin, 0.0f, WHITE);
|
DrawTexturePro(virtualScreen.texture, virtualScreenLocalBounds, virtualScreenWindowBounds, origin, 0.0f, WHITE);
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
@ -114,6 +119,48 @@ void Graphics::toggleFullScreen() {
|
|||||||
calculateScreenPositionInWindow();
|
calculateScreenPositionInWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::bindMethods(pkpy::VM *vm) {
|
||||||
|
vm->bind(vm->builtins, "clear(color: int)", reinterpret_cast<pkpy::NativeFuncC>(Clear));
|
||||||
|
vm->bind(vm->builtins, "pixel(x: int, y: int, color: int)", reinterpret_cast<pkpy::NativeFuncC>(Pixel));
|
||||||
|
vm->bind(vm->builtins, "circle(x: int, y: int, radius: float, color: int)", reinterpret_cast<pkpy::NativeFuncC>(Circle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::Clear(pkpy::VM* vm, pkpy::ArgsView args) {
|
||||||
|
int paletteIndex = pkpy::py_cast<int>(vm, args[0]);
|
||||||
|
if(paletteIndex < 0 || paletteIndex >= palette.size()) paletteIndex = 0;
|
||||||
|
ClearBackground(palette[paletteIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::Pixel(pkpy::VM* vm, pkpy::ArgsView args) {
|
||||||
|
int x = pkpy::py_cast<int>(vm, args[0]);
|
||||||
|
int y = pkpy::py_cast<int>(vm, args[1]);
|
||||||
|
int paletteIndex = pkpy::py_cast<int>(vm, args[2]);
|
||||||
|
DrawPixel(x, y, palette[paletteIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::Circle(pkpy::VM* vm, pkpy::ArgsView args) {
|
||||||
|
float x = pkpy::py_cast<float>(vm, args[0]);
|
||||||
|
float y = pkpy::py_cast<float>(vm, args[1]);
|
||||||
|
float radius = pkpy::py_cast<float>(vm, args[2]);
|
||||||
|
int paletteIndex = pkpy::py_cast<int>(vm, args[3]);
|
||||||
|
DrawCircle(x, y, radius, palette[paletteIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::searchForDrawFunc(pkpy::VM* vm) {
|
||||||
|
updateFunction = vm->eval("update");
|
||||||
|
if(updateFunction == nullptr){
|
||||||
|
std::cout << "Can't find update function" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::beginDraw() {
|
||||||
|
BeginTextureMode(virtualScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::endDraw() {
|
||||||
|
EndTextureMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
#include "pocketpy/vm.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -18,7 +19,6 @@ private:
|
|||||||
Rectangle virtualScreenLocalBounds; // virtual screen bounds
|
Rectangle virtualScreenLocalBounds; // virtual screen bounds
|
||||||
RenderTexture2D virtualScreen; // actual pixel screen
|
RenderTexture2D virtualScreen; // actual pixel screen
|
||||||
|
|
||||||
std::vector<Color> palette;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void renderVirtualScreen();
|
void renderVirtualScreen();
|
||||||
@ -31,15 +31,32 @@ public:
|
|||||||
|
|
||||||
bool windowShouldClose;
|
bool windowShouldClose;
|
||||||
|
|
||||||
|
static std::vector<Color> palette;
|
||||||
|
|
||||||
|
pkpy::PyObject* updateFunction;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Graphics(int screenWidth, int screenHeight, int startupScale);
|
Graphics(int screenWidth, int screenHeight, int startupScale);
|
||||||
|
|
||||||
void draw();
|
void draw(pkpy::VM* vm);
|
||||||
|
|
||||||
|
void beginDraw();
|
||||||
|
void endDraw();
|
||||||
|
|
||||||
void loadPalette(std::string path);
|
void loadPalette(std::string path);
|
||||||
int mouseX();
|
int mouseX();
|
||||||
int mouseY();
|
int mouseY();
|
||||||
void toggleFullScreen();
|
void toggleFullScreen();
|
||||||
|
|
||||||
|
void bindMethods(pkpy::VM* vm);
|
||||||
|
|
||||||
|
void searchForDrawFunc(pkpy::VM* vm);
|
||||||
|
|
||||||
|
|
||||||
|
static void Clear(pkpy::VM* vm, pkpy::ArgsView args);
|
||||||
|
static void Pixel(pkpy::VM* vm, pkpy::ArgsView args);
|
||||||
|
static void Circle(pkpy::VM* vm, pkpy::ArgsView args);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,10 +1,27 @@
|
|||||||
//
|
//
|
||||||
// Created by Bobby Lucero on 4/20/24.
|
// Created by Bobby Lucero on 4/20/24.
|
||||||
//
|
//
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <random>
|
||||||
|
#include <cmath>
|
||||||
#include "Pycron.h"
|
#include "Pycron.h"
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
|
|
||||||
|
|
||||||
|
std::string loadFileToString(const std::string& filename) {
|
||||||
|
std::ifstream file(filename); // Open the file
|
||||||
|
std::stringstream buffer; // String stream to hold file content
|
||||||
|
if (file.is_open()) { // Check if file is open
|
||||||
|
buffer << file.rdbuf(); // Read the entire file into the buffer
|
||||||
|
file.close(); // Close the file
|
||||||
|
} else {
|
||||||
|
std::cerr << "Unable to open file: " << filename << std::endl;
|
||||||
|
}
|
||||||
|
return buffer.str(); // Return the content string
|
||||||
|
}
|
||||||
|
|
||||||
Pycron::Pycron() {
|
Pycron::Pycron() {
|
||||||
SetTraceLogLevel(LOG_ERROR);
|
SetTraceLogLevel(LOG_ERROR);
|
||||||
|
|
||||||
@ -13,14 +30,21 @@ Pycron::Pycron() {
|
|||||||
|
|
||||||
vm = new pkpy::VM();
|
vm = new pkpy::VM();
|
||||||
|
|
||||||
|
bindMethods(vm);
|
||||||
|
|
||||||
|
graphics->bindMethods(vm);
|
||||||
|
|
||||||
|
std::string python = loadFileToString("../python/main.py");
|
||||||
|
|
||||||
|
graphics->beginDraw();
|
||||||
try {
|
try {
|
||||||
pkpy::CodeObject_ code = vm->compile("return 'test'", "main.py", pkpy::EXEC_MODE, false);
|
pkpy::CodeObject_ code = vm->compile(python, "main.py", pkpy::EXEC_MODE, false);
|
||||||
pkpy::PyObject* obj = vm->_exec(code, vm->_main);
|
vm->_exec(code, vm->_main);
|
||||||
|
graphics->searchForDrawFunc(vm);
|
||||||
auto& str = pkpy::py_cast<pkpy::Str&>(vm, obj);
|
|
||||||
}catch (pkpy::Exception e) {
|
}catch (pkpy::Exception e) {
|
||||||
|
std::cout << e.summary() << std::endl;
|
||||||
}
|
}
|
||||||
|
graphics->endDraw();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,6 +61,38 @@ void Pycron::StartGameLoop() {
|
|||||||
if (IsKeyPressed(KEY_F)) {
|
if (IsKeyPressed(KEY_F)) {
|
||||||
graphics->toggleFullScreen();
|
graphics->toggleFullScreen();
|
||||||
}
|
}
|
||||||
graphics->draw();
|
graphics->draw(vm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pycron::bindMethods(pkpy::VM *vm) {
|
||||||
|
vm->bind(vm->builtins, "rnd(min: int, max: int) -> int", reinterpret_cast<pkpy::NativeFuncC>(getRandomNumber));
|
||||||
|
vm->bind(vm->builtins, "sin(num: float) -> float", reinterpret_cast<pkpy::NativeFuncC>(getSin));
|
||||||
|
vm->bind(vm->builtins, "cos(num: float) -> float", reinterpret_cast<pkpy::NativeFuncC>(getCos));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pkpy::PyObject* Pycron::getRandomNumber(pkpy::VM* vm, pkpy::ArgsView args) {
|
||||||
|
int min = pkpy::py_cast<int>(vm, args[0]);
|
||||||
|
int max = pkpy::py_cast<int>(vm, args[1]);
|
||||||
|
// Seed the random number generator with a random device
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 gen(rd());
|
||||||
|
|
||||||
|
// Define a uniform distribution for the range [min, max]
|
||||||
|
std::uniform_int_distribution<int> distribution(min, max);
|
||||||
|
|
||||||
|
// Generate a random number within the specified range
|
||||||
|
return pkpy::py_var(vm, distribution(gen));
|
||||||
|
}
|
||||||
|
|
||||||
|
pkpy::PyObject* Pycron::getSin(pkpy::VM* vm, pkpy::ArgsView args) {
|
||||||
|
auto num = pkpy::py_cast<double>(vm, args[0]);
|
||||||
|
return pkpy::py_var(vm, sin(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
pkpy::PyObject* Pycron::getCos(pkpy::VM* vm, pkpy::ArgsView args) {
|
||||||
|
auto num = pkpy::py_cast<double>(vm, args[0]);
|
||||||
|
return pkpy::py_var(vm, cos(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,11 @@ public:
|
|||||||
~Pycron();
|
~Pycron();
|
||||||
|
|
||||||
void StartGameLoop();
|
void StartGameLoop();
|
||||||
|
void bindMethods(pkpy::VM* vm);
|
||||||
|
|
||||||
|
static pkpy::PyObject* getRandomNumber(pkpy::VM* vm, pkpy::ArgsView args);
|
||||||
|
static pkpy::PyObject* getSin(pkpy::VM* vm, pkpy::ArgsView args);
|
||||||
|
static pkpy::PyObject* getCos(pkpy::VM* vm, pkpy::ArgsView args);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user