Graphics and drawing now work, but there is a HUGE memory leak, probably from creating a new object every frame or something

This commit is contained in:
sam-astro 2022-01-12 17:02:56 -05:00
parent ee147bd78a
commit 79ec9f6cd7
7 changed files with 323 additions and 215 deletions

View File

@ -24,28 +24,35 @@ unordered_map<string, vector<vector<string>>> functionValues;
boost::any GetVariableValue(const string& varName, const unordered_map<string, boost::any>& variableValues) boost::any GetVariableValue(const string& varName, const unordered_map<string, boost::any>& variableValues)
{ {
auto iA = variableValues.find(varName); string classSubComponent;
string baseName = varName;
if (count(varName, '.') > 0)
{
classSubComponent = rangeInStr(varName, indexInStr(varName, '.')+1, -1);
baseName = split(varName, '.')[0];
}
boost::any outputValue = nullType;
auto iA = variableValues.find(baseName);
auto iB = globalVariableValues.find(baseName);
if (iA != variableValues.end()) if (iA != variableValues.end())
{ outputValue = iA->second;
return iA->second; else if (iB != globalVariableValues.end())
} outputValue = iB->second;
else else
{ outputValue = varName;
auto iB = globalVariableValues.find(varName);
if (iB != globalVariableValues.end()) if (count(varName, '.') > 0 && !outputValue.empty())
{ return GetClassSubComponent(outputValue, classSubComponent);
return iB->second;
}
else else
{ return outputValue;
return varName;
}
}
} }
bool IsVar(const string& varName, const unordered_map<string, boost::any>& variableValues) bool IsVar(const string& varName, const unordered_map<string, boost::any>& variableValues)
{ {
if (variableValues.find(varName) != variableValues.end()) if (variableValues.find(split(varName, '.')[0]) != variableValues.end() && split(varName, '.')[0] != "CPP")
return true; return true;
else else
return false; return false;
@ -58,7 +65,6 @@ vector<boost::any> VarValues(const vector<string>& varNames, const unordered_map
for (int varIndex = 0; varIndex < varNames.size(); varIndex++) for (int varIndex = 0; varIndex < varNames.size(); varIndex++)
{ {
string varName = trim(varNames[varIndex]); string varName = trim(varNames[varIndex]);
//cout << varName << endl;
auto iA = variableValues.find(varName); auto iA = variableValues.find(varName);
if (iA != variableValues.end()) if (iA != variableValues.end())
@ -98,10 +104,10 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
string expression = trim(ex); string expression = trim(ex);
bool inQuotes = false; bool inQuotes = false;
//CompilerLog("OLDEXPRESSION: |" + expression + "|"); //InterpreterLog("OLDEXPRESSION: |" + expression + "|");
// If no operations are applied, then return self // If no operations are applied, then return self
if ((count(expression, '+') == 0 && count(expression, '-') == 0 && count(expression, '*') == 0 && count(expression, '/') == 0 && count(expression, '(') == 0 && count(expression, '^') == 0) || split(expression, '.')[0] == "CPP") if ((count(expression, '+') == 0 && count(expression, '-') == 0 && count(expression, '*') == 0 && count(expression, '/') == 0 && count(expression, '^') == 0) || split(expression, '.')[0] == "CPP")
{ {
bool isFunc = IsFunction(split(expression, '(')[0]); bool isFunc = IsFunction(split(expression, '(')[0]);
if (isFunc && !inQuotes) if (isFunc && !inQuotes)
@ -115,7 +121,7 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
y++; y++;
} }
//CompilerLog(split(expression, '(')[0] + " " + AnyAsString(GetVariableValue(split(argContents, ',')[0], variableValues))); //InterpreterLog(split(expression, '(')[0] + " " + AnyAsString(GetVariableValue(split(argContents, ',')[0], variableValues)));
return ExecuteFunction(split(expression, '(')[0], VarValues(split(argContents, ','), variableValues)); return ExecuteFunction(split(expression, '(')[0], VarValues(split(argContents, ','), variableValues));
} }
else if (split(expression, '.')[0] == "CPP" && !inQuotes) else if (split(expression, '.')[0] == "CPP" && !inQuotes)
@ -128,7 +134,7 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
y++; y++;
} }
//CompilerLog(split(expression, '(')[0] + " " + argContents); //InterpreterLog(split(expression, '(')[0] + " " + argContents);
return CPPFunction(split(expression, '(')[0], VarValues(split(argContents, ','), variableValues)); return CPPFunction(split(expression, '(')[0], VarValues(split(argContents, ','), variableValues));
} }
else else
@ -165,7 +171,7 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
i++; i++;
} }
//CompilerLog(split(expression, '(')[0] + " " + AnyAsString(GetVariableValue(split(argContents, ',')[0], variableValues))); //InterpreterLog(split(expression, '(')[0] + " " + AnyAsString(GetVariableValue(split(argContents, ',')[0], variableValues)));
string returnVal = AnyAsString(ExecuteFunction(name, VarValues(split(argContents, ','), variableValues))); string returnVal = AnyAsString(ExecuteFunction(name, VarValues(split(argContents, ','), variableValues)));
newExpression += returnVal; newExpression += returnVal;
//cout << newExpression << endl; //cout << newExpression << endl;
@ -199,7 +205,7 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
newExpression += expression[i]; newExpression += expression[i];
} }
} }
//CompilerLog("NEW EXPRESSION: |" + newExpression + "|"); //InterpreterLog("NEW EXPRESSION: |" + newExpression + "|");
bool addStrings = false; bool addStrings = false;
for (int i = 0; i < (int)newExpression.size(); i++) for (int i = 0; i < (int)newExpression.size(); i++)
@ -297,8 +303,8 @@ int varOperation(const vector<string>& str, unordered_map<string, boost::any>& v
boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unordered_map<string, boost::any>& variableValues) boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unordered_map<string, boost::any>& variableValues)
{ {
//CompilerLog(unWrapVec(words[lineNum])); //InterpreterLog(unWrapVec(words[lineNum]));
//CompilerLog(AnyAsString(GetVariableValue("out", variableValues))); //InterpreterLog(AnyAsString(GetVariableValue("out", variableValues)));
if (words[lineNum][0][0] == '/' && words[lineNum][0][1] == '/') if (words[lineNum][0][0] == '/' && words[lineNum][0][1] == '/')
return nullType; return nullType;
@ -325,12 +331,18 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
return nullType; return nullType;
} }
// Check if global variable declaration
else if (trim(words[lineNum][0]) == "global")
{
globalVariableValues[words[lineNum][2]] = EvalExpression(unWrapVec(slice(words[lineNum], 4, -1)), variableValues);
return nullType;
}
// Iterate through all types to see if line inits or // Iterate through all types to see if line inits or
// re-inits a variable then store it with it's value // re-inits a variable then store it with it's value
else if (countInVector(types, trim(words[lineNum][0])) > 0) else if (countInVector(types, trim(words[lineNum][0])) > 0)
{ {
variableValues[words[lineNum][1]] = EvalExpression(unWrapVec(slice(words[lineNum], 3, -1)), variableValues); variableValues[words[lineNum][1]] = EvalExpression(unWrapVec(slice(words[lineNum], 3, -1)), variableValues);
//CompilerLog("new var :: " + words[lineNum][1] + " = " + AnyAsString(variableValues[words[lineNum][1]]));
return nullType; return nullType;
} }
@ -524,7 +536,7 @@ int parseSlang(string script)
} }
args = replace(args, functName + " ", ""); args = replace(args, functName + " ", "");
//CompilerLog(args); //InterpreterLog(args);
functionContents.push_back(split(args, ',')); functionContents.push_back(split(args, ','));
int numOfBrackets = 1; int numOfBrackets = 1;

View File

@ -10,9 +10,17 @@ using namespace std;
int LogWarning(const string& warningText); int LogWarning(const string& warningText);
// Gets if any is NullType
bool any_null(const boost::any& val)
{
return val.empty();
}
// Will convert type 'any' val to a bool // Will convert type 'any' val to a bool
bool AnyAsBool(const boost::any& val) bool AnyAsBool(const boost::any& val)
{ {
if (any_null(val))
return false;
try // Try converting to bool try // Try converting to bool
{ {
return any_cast<bool>(val); return any_cast<bool>(val);
@ -48,6 +56,8 @@ bool AnyAsBool(const boost::any& val)
// Will convert type 'any' val to a string // Will convert type 'any' val to a string
string AnyAsString(const boost::any& val) string AnyAsString(const boost::any& val)
{ {
if (any_null(val))
return "";
try // Try converting to string try // Try converting to string
{ {
return any_cast<string>(val); return any_cast<string>(val);
@ -85,6 +95,8 @@ string AnyAsString(const boost::any& val)
// Will convert type 'any' val to a float // Will convert type 'any' val to a float
float AnyAsFloat(const boost::any& val) float AnyAsFloat(const boost::any& val)
{ {
if (any_null(val))
return 0.0f;
try // Try converting to float try // Try converting to float
{ {
return any_cast<float>(val); return any_cast<float>(val);
@ -105,11 +117,11 @@ float AnyAsFloat(const boost::any& val)
{ {
try try
{ {
float i = 0; float i = 0.0f;
if (any_cast<bool>(val) == true) i = 1; if (any_cast<bool>(val) == true) i = 1.0f;
return i; return i;
} }
catch (boost::bad_any_cast) // Does not convert, return catch (boost::bad_any_cast e) // Does not convert, return
{ {
LogWarning("invalid conversion to type \'float\'"); LogWarning("invalid conversion to type \'float\'");
return 0; return 0;
@ -122,6 +134,8 @@ float AnyAsFloat(const boost::any& val)
// Will convert type 'any' val to an integer // Will convert type 'any' val to an integer
int AnyAsInt(const boost::any& val) int AnyAsInt(const boost::any& val)
{ {
if (any_null(val))
return 0;
try // Try converting to int try // Try converting to int
{ {
return any_cast<int>(val); return any_cast<int>(val);
@ -157,7 +171,7 @@ int AnyAsInt(const boost::any& val)
} }
// Gets type of 'any' val // Gets type of 'any' val
// 0 -> int; 1 -> float; 2 -> bool; 3 -> string; // 0 -> int; 1 -> float; 2 -> bool; 3 -> string; 4 -> Sprite; 5 -> Vec2;
int any_type(const boost::any& val) int any_type(const boost::any& val)
{ {
try // Try converting to int try // Try converting to int
@ -186,6 +200,20 @@ int any_type(const boost::any& val)
string s = any_cast<string>(val); string s = any_cast<string>(val);
return 3; return 3;
} }
catch (boost::bad_any_cast) // Try converting to sprite
{
try
{
Sprite s = any_cast<Sprite>(val);
return 4;
}
catch (boost::bad_any_cast) // Try converting to Vec2
{
try
{
Vec2 v = any_cast<Vec2>(val);
return 5;
}
catch (boost::bad_any_cast) // Does not convert, return catch (boost::bad_any_cast) // Does not convert, return
{ {
LogWarning("variable has no type"); LogWarning("variable has no type");
@ -195,22 +223,7 @@ int any_type(const boost::any& val)
} }
} }
} }
}
// Gets if any is NullType
bool any_null(const boost::any& val)
{
/*if (val.type() == typeid(NullType))
return true;*/
return false;
//try // Try converting to Null
//{
// NullType n = any_cast<NullType>(val);
// return true;
//}
//catch (boost::bad_any_cast)
//{
// return false;
//}
} }
#endif #endif

View File

@ -13,6 +13,7 @@
#include "anyops.h" #include "anyops.h"
#include <boost/any.hpp> #include <boost/any.hpp>
#include <SDL.h> #include <SDL.h>
#include <ctime>
using namespace std; using namespace std;
using namespace boost; using namespace boost;
@ -35,19 +36,63 @@ int LogWarning(const string& warningText)
return 1; return 1;
} }
int CompilerLog(const string& logText) int InterpreterLog(const string& logText)
{ {
cerr << "\x1B[32mclog: " << logText << "\033[0m\t\t" << endl; time_t timer = time(0);
tm bt{};
#if defined(__unix__)
localtime_r(&timer, &bt);
#elif defined(_MSC_VER)
localtime_s(&bt, &timer);
#else
static mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
bt = *localtime(&timer);
#endif
int Hour = bt.tm_hour;
int Min = bt.tm_min;
int Sec = bt.tm_sec;
cout << "\x1B[34m[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] \x1B[33mSlang: \x1B[32m" << logText << "\033[0m\t\t" << endl;
return 1; return 1;
} }
int LogCriticalError(const string& errorText) int LogCriticalError(const string& errorText)
{ {
cerr << "\x1B[31mERROR: " << errorText << "\033[0m\t\t" << endl; time_t timer = time(0);
tm bt{};
#if defined(__unix__)
localtime_r(&timer, &bt);
#elif defined(_MSC_VER)
localtime_s(&bt, &timer);
#else
static mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
bt = *localtime(&timer);
#endif
int Hour = bt.tm_hour;
int Min = bt.tm_min;
int Sec = bt.tm_sec;
cerr << "\x1B[34m[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] \x1B[33mSlang: \x1B[31mERROR: " << errorText << "\033[0m\t\t" << endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
return 2; return 2;
} }
boost::any GetClassSubComponent(boost::any value, string subComponentName)
{
// If a Vec2 Class
if (any_type(value) == 5)
{
return any_cast<Vec2>(value).SubComponent(subComponentName);
}
return nullType;
}
// Initial script processing, which loads variables and functions from builtin // Initial script processing, which loads variables and functions from builtin
int GetBuiltins(const string& s) int GetBuiltins(const string& s)
{ {
@ -71,6 +116,8 @@ int GetBuiltins(const string& s)
string functName = split(words[lineNum][1], '(')[0]; string functName = split(words[lineNum][1], '(')[0];
InterpreterLog("Load builtin function " + functName);
string args = ""; string args = "";
for (int w = 1; w < (int)words[lineNum].size(); w++) // Get all words from the instantiation line: these are the args for (int w = 1; w < (int)words[lineNum].size(); w++) // Get all words from the instantiation line: these are the args
{ {
@ -78,7 +125,6 @@ int GetBuiltins(const string& s)
} }
args = replace(args, functName + " ", ""); args = replace(args, functName + " ", "");
CompilerLog(args);
functionContents.push_back(split(args, ',')); functionContents.push_back(split(args, ','));
int numOfBrackets = 1; int numOfBrackets = 1;
@ -95,13 +141,25 @@ int GetBuiltins(const string& s)
else else
{ {
if (words[lineNum][0] == "string") if (words[lineNum][0] == "string")
{
builtinVarVals[words[lineNum][1]] = StringRaw(words[lineNum][3]); builtinVarVals[words[lineNum][1]] = StringRaw(words[lineNum][3]);
InterpreterLog("Load builtin variable " + words[lineNum][1]);
}
else if (words[lineNum][0] == "int") else if (words[lineNum][0] == "int")
{
builtinVarVals[words[lineNum][1]] = stoi(words[lineNum][3]); builtinVarVals[words[lineNum][1]] = stoi(words[lineNum][3]);
InterpreterLog("Load builtin variable " + words[lineNum][1]);
}
else if (words[lineNum][0] == "float") else if (words[lineNum][0] == "float")
{
builtinVarVals[words[lineNum][1]] = stof(words[lineNum][3]); builtinVarVals[words[lineNum][1]] = stof(words[lineNum][3]);
InterpreterLog("Load builtin variable " + words[lineNum][1]);
}
else if (words[lineNum][0] == "bool") else if (words[lineNum][0] == "bool")
{
builtinVarVals[words[lineNum][1]] = stob(words[lineNum][3]); builtinVarVals[words[lineNum][1]] = stob(words[lineNum][3]);
InterpreterLog("Load builtin variable " + words[lineNum][1]);
}
//else //else
// LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum)); // LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum));
} }
@ -123,13 +181,13 @@ boost::any CPPFunction(const string& name, const vector<boost::any>& args)
return AnyAsInt(args[0]); return AnyAsInt(args[0]);
else if (name == "CPP.Graphics.Init") else if (name == "CPP.Graphics.Init")
{ {
cout << "\x1B[32mInit graphics\033[0m\t\t" << endl; InterpreterLog("Init graphics");
initGraphics(AnyAsString(args[0]), AnyAsInt(args[1]), AnyAsInt(args[2])); initGraphics(StringRaw(AnyAsString(args[0])), AnyAsInt(args[1]), AnyAsInt(args[2]));
} }
else if (name == "CPP.Graphics.Sprite") else if (name == "CPP.Graphics.Sprite")
{ {
Sprite s(AnyAsString(args[0]), any_cast<Vec2>(args[1]), any_cast<Vec2>(args[2]), AnyAsFloat(args[3])); Sprite s(StringRaw(AnyAsString(args[0])), any_cast<Vec2>(args[1]), any_cast<Vec2>(args[2]), AnyAsFloat(args[3]));
Sprite d = any_cast<Sprite>(a); return s;
} }
else if (name == "CPP.Graphics.Draw") else if (name == "CPP.Graphics.Draw")
{ {

View File

@ -86,7 +86,7 @@ func NSprite(path, x, y, r)
} }
// Creates new Vector2 class // Creates new Vector2 class
func Vec2(x, y) func NVec2(x, y)
{ {
Vec2 v = CPP.System.Vec2(x, y) Vec2 v = CPP.System.Vec2(x, y)
return v return v

View File

@ -184,12 +184,20 @@ public:
return Vec2(x * rhs, y * rhs); return Vec2(x * rhs, y * rhs);
} }
boost::any SubComponent(std::string componentName)
{
if (componentName == "x")
return x;
if (componentName == "y")
return y;
}
float x, y; float x, y;
}; };
struct _RotRect { struct _RotRect {
_Vector2D C; Vec2 C;
_Vector2D S; Vec2 S;
float ang; float ang;
}; };
@ -221,7 +229,7 @@ int RotRectsCollision(_RotRect * rr1, _RotRect * rr2)
C -= rr1->C; C -= rr1->C;
// rotate rr2 clockwise by rr2->ang to make rr2 axis-aligned // rotate rr2 clockwise by rr2->ang to make rr2 axis-aligned
RotateVector2DClockwise(&C, rr2->ang); RotateVec2Clockwise(&C, rr2->ang);
// calculate vertices of (moved and axis-aligned := 'ma') rr2 // calculate vertices of (moved and axis-aligned := 'ma') rr2
BL = TR = C; BL = TR = C;
@ -288,30 +296,45 @@ class Sprite
{ {
public: public:
Sprite(std::string path, Vec2 position, Vec2 scale, double angle) Sprite(std::string path, Vec2 position, Vec2 scale, double angle)
: position(position), angle(angle) : position(position), angle(angle), path(path)
{ {
rect.x = static_cast<int>(position.x); rect.x = static_cast<int>(position.x);
rect.y = static_cast<int>(position.y); rect.y = static_cast<int>(position.y);
rect.w = scale.x; rect.w = scale.x;
rect.h = scale.y; rect.h = scale.y;
}
void Load()
{
SDL_Surface* surface = loadSurface(path); SDL_Surface* surface = loadSurface(path);
texture = SDL_CreateTextureFromSurface(gRenderer, surface); texture = SDL_CreateTextureFromSurface(gRenderer, surface);
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
isLoaded = true;
} }
void Draw() void Draw()
{ {
if (texture == NULL)
Load();
rect.y = static_cast<int>(position.y); rect.y = static_cast<int>(position.y);
SDL_RenderCopy(gRenderer, texture, NULL, &rect); SDL_RenderCopy(gRenderer, texture, NULL, &rect);
} }
boost::any SubComponent(std::string componentName)
{
if (componentName == "position")
return position;
}
Vec2 position; Vec2 position;
double angle; double angle;
std::string path; std::string path;
SDL_Rect rect{}; SDL_Rect rect{};
SDL_Texture* texture; SDL_Texture* texture = NULL;
bool isLoaded = false;
};/* };/*
class PlayerScore class PlayerScore
@ -653,12 +676,12 @@ int updateLoop()
//paddleOne.Update(dt); //paddleOne.Update(dt);
//paddleTwo.Update(dt); //paddleTwo.Update(dt);
// Clear the window to black //// Clear the window to black
SDL_SetRenderDrawColor(gRenderer, 0x0, 0x0, 0x0, 0xFF); //SDL_SetRenderDrawColor(gRenderer, 0x0, 0x0, 0x0, 0xFF);
SDL_RenderClear(gRenderer); SDL_RenderClear(gRenderer);
// Set the draw color to be white //// Set the draw color to be white
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); //SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
//// Draw the net //// Draw the net
//for (int y = 0; y < WINDOW_HEIGHT; ++y) //for (int y = 0; y < WINDOW_HEIGHT; ++y)
@ -691,8 +714,8 @@ int updateLoop()
auto stopTime = std::chrono::high_resolution_clock::now(); auto stopTime = std::chrono::high_resolution_clock::now();
dt = std::chrono::duration<float, std::chrono::milliseconds::period>(stopTime - startTime).count(); dt = std::chrono::duration<float, std::chrono::milliseconds::period>(stopTime - startTime).count();
return 0;
} }
return 0;
} }
int initGraphics(std::string windowTitle, int width, int height) int initGraphics(std::string windowTitle, int width, int height)
@ -704,7 +727,7 @@ int initGraphics(std::string windowTitle, int width, int height)
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
TTF_Init(); TTF_Init();
gWindow = SDL_CreateWindow(windowTitle.c_str(), 40, 40, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN || SDL_WINDOW_RESIZABLE); gWindow = SDL_CreateWindow(windowTitle.c_str(), 40, 40, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
gRenderer = SDL_CreateRenderer(gWindow, -1, 0); gRenderer = SDL_CreateRenderer(gWindow, -1, 0);
//Get window surface //Get window surface

View File

@ -4,7 +4,7 @@ func Main(input, in)
{ {
print "PI is: " + PI print "PI is: " + PI
int x = 1 int x = 1
print x print "xis" + x
float k = 0 float k = 0
print k print k
while x < 5 while x < 5
@ -17,9 +17,10 @@ func Main(input, in)
x += 1 x += 1
} }
Vec2 aa = Vec2(0, 0) Vec2 aa = NVec2(6, 8)
Sprite thisisasprite = CPP.Graphics.Sprite("circle.png", aa, aa, 0) print aa.x + " " + aa.y
//CPP.Graphics.Init("This is a pong game", 64, 64) global Sprite thisisasprite = CPP.Graphics.Sprite("./circle.png", aa, aa, 0)
CPP.Graphics.Init("This is a pong game", 500, 500)
} }
func Update(input) func Update(input)
@ -36,5 +37,6 @@ func Update(input)
// y = 0 // y = 0
// x += 1 // x += 1
//} //}
CPP.Graphics.Draw(thisisasprite)
print "updating" print "updating"
} }

View File

@ -41,7 +41,7 @@ vector<string> rangeInVec(const vector<string>& str, const int& min, const int&
vector<string> slice(vector<string> const& v, int min, int max); vector<string> slice(vector<string> const& v, int min, int max);
string rangeInStr(const string& str, const int& min, const int& max); string rangeInStr(const string& str, const int& min, int max);
string unWrapVec(const vector<string>& vec); string unWrapVec(const vector<string>& vec);