mirror of
https://github.com/love2d/love-android.git
synced 2026-08-20 04:31:26 +02:00
Using latest android branch of LÖVE (6d14516b05c9) that now syncs with default (woooo!)
This commit is contained in:
@@ -18,8 +18,8 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include "Exception.h"
|
||||
#include "common/config.h"
|
||||
#include "Exception.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -60,4 +60,8 @@ Exception::Exception(const char *fmt, ...)
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
Exception::~Exception() throw()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
* @param fmt The format string (see printf).
|
||||
**/
|
||||
Exception(const char *fmt, ...);
|
||||
virtual ~Exception() throw() {}
|
||||
virtual ~Exception() throw();
|
||||
|
||||
/**
|
||||
* Returns a string containing reason for the exception.
|
||||
|
||||
+121
-47
@@ -32,17 +32,17 @@ namespace love
|
||||
// | e2 e6 e10 e14 |
|
||||
// | e3 e7 e11 e15 |
|
||||
|
||||
Matrix::Matrix()
|
||||
Matrix4::Matrix4()
|
||||
{
|
||||
setIdentity();
|
||||
}
|
||||
|
||||
Matrix::Matrix(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
Matrix4::Matrix4(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
{
|
||||
setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
}
|
||||
|
||||
Matrix::~Matrix()
|
||||
Matrix4::~Matrix4()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ Matrix::~Matrix()
|
||||
// | e2 e6 e10 e14 |
|
||||
// | e3 e7 e11 e15 |
|
||||
|
||||
Matrix Matrix::operator * (const Matrix &m) const
|
||||
Matrix4 Matrix4::operator * (const Matrix4 &m) const
|
||||
{
|
||||
Matrix t;
|
||||
Matrix4 t;
|
||||
|
||||
t.e[0] = (e[0]*m.e[0]) + (e[4]*m.e[1]) + (e[8]*m.e[2]) + (e[12]*m.e[3]);
|
||||
t.e[4] = (e[0]*m.e[4]) + (e[4]*m.e[5]) + (e[8]*m.e[6]) + (e[12]*m.e[7]);
|
||||
@@ -82,31 +82,31 @@ Matrix Matrix::operator * (const Matrix &m) const
|
||||
return t;
|
||||
}
|
||||
|
||||
void Matrix::operator *= (const Matrix &m)
|
||||
void Matrix4::operator *= (const Matrix4 &m)
|
||||
{
|
||||
Matrix t = (*this) * m;
|
||||
memcpy((void *)this->e, (void *)t.e, sizeof(float)*16);
|
||||
Matrix4 t = (*this) * m;
|
||||
memcpy(this->e, t.e, sizeof(float)*16);
|
||||
}
|
||||
|
||||
const float *Matrix::getElements() const
|
||||
const float *Matrix4::getElements() const
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
void Matrix::setIdentity()
|
||||
void Matrix4::setIdentity()
|
||||
{
|
||||
memset(e, 0, sizeof(float)*16);
|
||||
e[0] = e[5] = e[10] = e[15] = 1;
|
||||
}
|
||||
|
||||
void Matrix::setTranslation(float x, float y)
|
||||
void Matrix4::setTranslation(float x, float y)
|
||||
{
|
||||
setIdentity();
|
||||
e[12] = x;
|
||||
e[13] = y;
|
||||
}
|
||||
|
||||
void Matrix::setRotation(float rad)
|
||||
void Matrix4::setRotation(float rad)
|
||||
{
|
||||
setIdentity();
|
||||
float c = cosf(rad), s = sinf(rad);
|
||||
@@ -116,21 +116,21 @@ void Matrix::setRotation(float rad)
|
||||
e[5] = c;
|
||||
}
|
||||
|
||||
void Matrix::setScale(float sx, float sy)
|
||||
void Matrix4::setScale(float sx, float sy)
|
||||
{
|
||||
setIdentity();
|
||||
e[0] = sx;
|
||||
e[5] = sy;
|
||||
}
|
||||
|
||||
void Matrix::setShear(float kx, float ky)
|
||||
void Matrix4::setShear(float kx, float ky)
|
||||
{
|
||||
setIdentity();
|
||||
e[1] = ky;
|
||||
e[4] = kx;
|
||||
}
|
||||
|
||||
void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
void Matrix4::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
{
|
||||
memset(e, 0, sizeof(float)*16); // zero out matrix
|
||||
float c = cosf(angle), s = sinf(angle);
|
||||
@@ -149,59 +149,37 @@ void Matrix::setTransformation(float x, float y, float angle, float sx, float sy
|
||||
e[13] = y - ox * e[1] - oy * e[5];
|
||||
}
|
||||
|
||||
void Matrix::translate(float x, float y)
|
||||
void Matrix4::translate(float x, float y)
|
||||
{
|
||||
Matrix t;
|
||||
Matrix4 t;
|
||||
t.setTranslation(x, y);
|
||||
this->operator *=(t);
|
||||
}
|
||||
|
||||
void Matrix::rotate(float rad)
|
||||
void Matrix4::rotate(float rad)
|
||||
{
|
||||
Matrix t;
|
||||
Matrix4 t;
|
||||
t.setRotation(rad);
|
||||
this->operator *=(t);
|
||||
}
|
||||
|
||||
void Matrix::scale(float sx, float sy)
|
||||
void Matrix4::scale(float sx, float sy)
|
||||
{
|
||||
Matrix t;
|
||||
Matrix4 t;
|
||||
t.setScale(sx, sy);
|
||||
this->operator *=(t);
|
||||
}
|
||||
|
||||
void Matrix::shear(float kx, float ky)
|
||||
void Matrix4::shear(float kx, float ky)
|
||||
{
|
||||
Matrix t;
|
||||
Matrix4 t;
|
||||
t.setShear(kx,ky);
|
||||
this->operator *=(t);
|
||||
}
|
||||
|
||||
// | x |
|
||||
// | y |
|
||||
// | 0 |
|
||||
// | 1 |
|
||||
// | e0 e4 e8 e12 |
|
||||
// | e1 e5 e9 e13 |
|
||||
// | e2 e6 e10 e14 |
|
||||
// | e3 e7 e11 e15 |
|
||||
|
||||
void Matrix::transform(Vertex *dst, const Vertex *src, int size) const
|
||||
Matrix4 Matrix4::ortho(float left, float right, float bottom, float top)
|
||||
{
|
||||
for (int i = 0; i<size; i++)
|
||||
{
|
||||
// Store in temp variables in case src = dst
|
||||
float x = (e[0]*src[i].x) + (e[4]*src[i].y) + (0) + (e[12]);
|
||||
float y = (e[1]*src[i].x) + (e[5]*src[i].y) + (0) + (e[13]);
|
||||
|
||||
dst[i].x = x;
|
||||
dst[i].y = y;
|
||||
}
|
||||
}
|
||||
|
||||
Matrix Matrix::ortho(float left, float right, float bottom, float top)
|
||||
{
|
||||
Matrix m;
|
||||
Matrix4 m;
|
||||
|
||||
m.e[0] = 2.0f / (right - left);
|
||||
m.e[5] = 2.0f / (top - bottom);
|
||||
@@ -213,5 +191,101 @@ Matrix Matrix::ortho(float left, float right, float bottom, float top)
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* | e0 e3 e6 |
|
||||
* | e1 e4 e7 |
|
||||
* | e2 e5 e8 |
|
||||
**/
|
||||
Matrix3::Matrix3()
|
||||
{
|
||||
setIdentity();
|
||||
}
|
||||
|
||||
Matrix3::Matrix3(const Matrix4 &mat4)
|
||||
{
|
||||
const float *mat4elems = mat4.getElements();
|
||||
|
||||
// Column 0.
|
||||
e[0] = mat4elems[0];
|
||||
e[1] = mat4elems[1];
|
||||
e[2] = mat4elems[2];
|
||||
|
||||
// Column 1.
|
||||
e[3] = mat4elems[4];
|
||||
e[4] = mat4elems[5];
|
||||
e[5] = mat4elems[6];
|
||||
|
||||
// Column 2.
|
||||
e[6] = mat4elems[8];
|
||||
e[7] = mat4elems[9];
|
||||
e[8] = mat4elems[10];
|
||||
}
|
||||
|
||||
Matrix3::~Matrix3()
|
||||
{
|
||||
}
|
||||
|
||||
void Matrix3::setIdentity()
|
||||
{
|
||||
memset(e, 0, sizeof(float) * 9);
|
||||
e[8] = e[4] = e[0] = 1.0f;
|
||||
}
|
||||
|
||||
Matrix3 Matrix3::operator * (const love::Matrix3 &m) const
|
||||
{
|
||||
Matrix3 t;
|
||||
|
||||
t.e[0] = (e[0]*m.e[0]) + (e[3]*m.e[1]) + (e[6]*m.e[2]);
|
||||
t.e[3] = (e[0]*m.e[3]) + (e[3]*m.e[4]) + (e[6]*m.e[5]);
|
||||
t.e[6] = (e[0]*m.e[6]) + (e[3]*m.e[7]) + (e[6]*m.e[8]);
|
||||
|
||||
t.e[1] = (e[1]*m.e[0]) + (e[4]*m.e[1]) + (e[7]*m.e[2]);
|
||||
t.e[4] = (e[1]*m.e[3]) + (e[4]*m.e[4]) + (e[7]*m.e[5]);
|
||||
t.e[7] = (e[1]*m.e[6]) + (e[4]*m.e[7]) + (e[7]*m.e[8]);
|
||||
|
||||
t.e[2] = (e[2]*m.e[0]) + (e[5]*m.e[1]) + (e[8]*m.e[2]);
|
||||
t.e[5] = (e[2]*m.e[3]) + (e[5]*m.e[4]) + (e[8]*m.e[5]);
|
||||
t.e[8] = (e[2]*m.e[6]) + (e[5]*m.e[7]) + (e[8]*m.e[8]);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void Matrix3::operator *= (const Matrix3 &m)
|
||||
{
|
||||
Matrix3 t = (*this) * m;
|
||||
memcpy(e, t.e, sizeof(float) * 9);
|
||||
}
|
||||
|
||||
const float *Matrix3::getElements() const
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
Matrix3 Matrix3::transposedInverse() const
|
||||
{
|
||||
// e0 e3 e6
|
||||
// e1 e4 e7
|
||||
// e2 e5 e8
|
||||
|
||||
float det = e[0] * (e[4]*e[8] - e[7]*e[5])
|
||||
- e[1] * (e[3]*e[8] - e[5]*e[6])
|
||||
+ e[2] * (e[3]*e[7] - e[4]*e[6]);
|
||||
|
||||
float invdet = 1.0f / det;
|
||||
|
||||
Matrix3 m;
|
||||
|
||||
m.e[0] = invdet * (e[4]*e[8] - e[7]*e[5]);
|
||||
m.e[3] = -invdet * (e[1]*e[8] - e[2]*e[7]);
|
||||
m.e[6] = invdet * (e[1]*e[5] - e[2]*e[4]);
|
||||
m.e[1] = -invdet * (e[3]*e[8] - e[5]*e[6]);
|
||||
m.e[4] = invdet * (e[0]*e[8] - e[2]*e[6]);
|
||||
m.e[7] = -invdet * (e[0]*e[5] - e[3]*e[2]);
|
||||
m.e[2] = invdet * (e[3]*e[7] - e[6]*e[4]);
|
||||
m.e[5] = -invdet * (e[0]*e[7] - e[6]*e[1]);
|
||||
m.e[8] = invdet * (e[0]*e[4] - e[3]*e[1]);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
} // love
|
||||
|
||||
+103
-12
@@ -28,41 +28,41 @@ namespace love
|
||||
{
|
||||
|
||||
/**
|
||||
* This class is the basis for all transformations in LOVE. Althought not
|
||||
* really needed for 2D, it contains 4x4 elements to be compatible with
|
||||
* OpenGL without conversions.
|
||||
* This class is the basis for all transformations in LOVE. Although not really
|
||||
* needed for 2D, it contains 4x4 elements to be compatible with OpenGL without
|
||||
* conversions.
|
||||
**/
|
||||
class Matrix
|
||||
class Matrix4
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new identity matrix.
|
||||
**/
|
||||
Matrix();
|
||||
Matrix4();
|
||||
|
||||
/**
|
||||
* Creates a new matrix set to a transformation.
|
||||
**/
|
||||
Matrix(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||
Matrix4(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
**/
|
||||
~Matrix();
|
||||
~Matrix4();
|
||||
|
||||
/**
|
||||
* Multiplies this Matrix with another Matrix, changing neither.
|
||||
* @param m The Matrix to multiply with this Matrix.
|
||||
* @return The combined matrix.
|
||||
**/
|
||||
Matrix operator * (const Matrix &m) const;
|
||||
Matrix4 operator * (const Matrix4 &m) const;
|
||||
|
||||
/**
|
||||
* Multiplies a Matrix into this Matrix.
|
||||
* @param m The Matrix to combine into this Matrix.
|
||||
**/
|
||||
void operator *= (const Matrix &m);
|
||||
void operator *= (const Matrix4 &m);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the 16 array elements.
|
||||
@@ -153,13 +153,14 @@ public:
|
||||
* @param src The source vertices.
|
||||
* @param size The number of vertices.
|
||||
**/
|
||||
void transform(Vertex *dst, const Vertex *src, int size) const;
|
||||
template <typename V>
|
||||
void transform(V *dst, const V *src, int size) const;
|
||||
|
||||
/**
|
||||
* Creates a new orthographic projection matrix with depth in the range of
|
||||
* [-1, 1].
|
||||
**/
|
||||
static Matrix ortho(float left, float right, float bottom, float top);
|
||||
static Matrix4 ortho(float left, float right, float bottom, float top);
|
||||
|
||||
private:
|
||||
|
||||
@@ -171,7 +172,97 @@ private:
|
||||
**/
|
||||
float e[16];
|
||||
|
||||
}; // Matrix
|
||||
}; // Matrix4
|
||||
|
||||
class Matrix3
|
||||
{
|
||||
public:
|
||||
|
||||
Matrix3();
|
||||
|
||||
/**
|
||||
* Constructs a 3x3 matrix from the upper left section of a 4x4 matrix.
|
||||
**/
|
||||
Matrix3(const Matrix4 &mat4);
|
||||
|
||||
~Matrix3();
|
||||
|
||||
/**
|
||||
* Resets this matrix to the identity matrix.
|
||||
**/
|
||||
void setIdentity();
|
||||
|
||||
Matrix3 operator * (const Matrix3 &m) const;
|
||||
void operator *= (const Matrix3 &m);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the 9 array elements.
|
||||
**/
|
||||
const float *getElements() const;
|
||||
|
||||
/**
|
||||
* Calculates the inverse of the transpose of this matrix.
|
||||
**/
|
||||
Matrix3 transposedInverse() const;
|
||||
|
||||
/**
|
||||
* Transforms an array of vertices by this matrix.
|
||||
**/
|
||||
template <typename V>
|
||||
void transform(V *dst, const V *src, int size) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* | e0 e3 e6
|
||||
* | e1 e4 e7
|
||||
* | e2 e5 e8
|
||||
**/
|
||||
float e[9];
|
||||
|
||||
}; // Matrix3
|
||||
|
||||
// | x |
|
||||
// | y |
|
||||
// | 0 |
|
||||
// | 1 |
|
||||
// | e0 e4 e8 e12 |
|
||||
// | e1 e5 e9 e13 |
|
||||
// | e2 e6 e10 e14 |
|
||||
// | e3 e7 e11 e15 |
|
||||
|
||||
template <typename V>
|
||||
void Matrix4::transform(V *dst, const V *src, int size) const
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
// Store in temp variables in case src = dst
|
||||
float x = (e[0]*src[i].x) + (e[4]*src[i].y) + (0) + (e[12]);
|
||||
float y = (e[1]*src[i].x) + (e[5]*src[i].y) + (0) + (e[13]);
|
||||
|
||||
dst[i].x = x;
|
||||
dst[i].y = y;
|
||||
}
|
||||
}
|
||||
|
||||
// | x |
|
||||
// | y |
|
||||
// | 1 |
|
||||
// | e0 e3 e6 |
|
||||
// | e1 e4 e7 |
|
||||
// | e2 e5 e8 |
|
||||
template <typename V>
|
||||
void Matrix3::transform(V *dst, const V *src, int size) const
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
float x = (e[0]*src[i].x) + (e[3]*src[i].y) + (e[6]);
|
||||
float y = (e[1]*src[i].x) + (e[4]*src[i].y) + (e[7]);
|
||||
|
||||
dst[i].x = x;
|
||||
dst[i].y = y;
|
||||
}
|
||||
}
|
||||
|
||||
} //love
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#ifndef LOVE_OSX_H
|
||||
#define LOVE_OSX_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef LOVE_MACOSX
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace osx
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the filepath of the first detected love file in the Resources folder
|
||||
* in the main bundle (love.app.)
|
||||
* Returns an empty string if no love file is found.
|
||||
**/
|
||||
std::string getLoveInResources();
|
||||
|
||||
/**
|
||||
* Checks for drop-file events. Returns the filepath if an event occurred, or
|
||||
* an empty string otherwise.
|
||||
**/
|
||||
std::string checkDropEvents();
|
||||
|
||||
/**
|
||||
* Returns the full path to the executable.
|
||||
**/
|
||||
std::string getExecutablePath();
|
||||
|
||||
/**
|
||||
* Bounce the dock icon, if the app isn't in the foreground.
|
||||
**/
|
||||
void requestAttention(bool continuous);
|
||||
|
||||
} // osx
|
||||
} // love
|
||||
|
||||
#endif // LOVE_MACOSX
|
||||
|
||||
#endif // LOVE_OSX_H
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include "OSX.h"
|
||||
|
||||
#ifdef LOVE_MACOSX
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace osx
|
||||
{
|
||||
|
||||
std::string getLoveInResources()
|
||||
{
|
||||
std::string path;
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
// Check to see if there are any .love files in Resources.
|
||||
NSString *lovepath = [[NSBundle mainBundle] pathForResource:nil ofType:@"love"];
|
||||
|
||||
if (lovepath != nil)
|
||||
path = lovepath.UTF8String;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string checkDropEvents()
|
||||
{
|
||||
std::string dropstr;
|
||||
SDL_Event event;
|
||||
|
||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
||||
|
||||
SDL_PumpEvents();
|
||||
if (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_DROPFILE, SDL_DROPFILE) > 0)
|
||||
{
|
||||
if (event.type == SDL_DROPFILE)
|
||||
{
|
||||
dropstr = std::string(event.drop.file);
|
||||
SDL_free(event.drop.file);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
|
||||
return dropstr;
|
||||
}
|
||||
|
||||
std::string getExecutablePath()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
return std::string([NSBundle mainBundle].executablePath.UTF8String);
|
||||
}
|
||||
}
|
||||
|
||||
void requestAttention(bool continuous)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
if (continuous)
|
||||
[NSApp requestUserAttention:NSCriticalRequest];
|
||||
else
|
||||
[NSApp requestUserAttention:NSInformationalRequest];
|
||||
}
|
||||
}
|
||||
|
||||
} // osx
|
||||
} // love
|
||||
|
||||
#endif // LOVE_MACOSX
|
||||
@@ -25,28 +25,37 @@ namespace love
|
||||
{
|
||||
|
||||
Object::Object()
|
||||
: count(1)
|
||||
{
|
||||
}
|
||||
|
||||
Object::Object(const Object & /*other*/)
|
||||
: count(1) // Always start with a reference count of 1.
|
||||
{
|
||||
count.value = 1;
|
||||
}
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
}
|
||||
|
||||
int Object::getReferenceCount()
|
||||
int Object::getReferenceCount() const
|
||||
{
|
||||
return SDL_AtomicGet(&count);
|
||||
return count;
|
||||
}
|
||||
|
||||
void Object::retain()
|
||||
{
|
||||
SDL_AtomicIncRef(&count);
|
||||
count.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void Object::release()
|
||||
{
|
||||
if (SDL_AtomicDecRef(&count))
|
||||
// http://www.boost.org/doc/libs/1_56_0/doc/html/atomic/usage_examples.html
|
||||
if (count.fetch_sub(1, std::memory_order_release) == 1)
|
||||
{
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
} // love
|
||||
|
||||
@@ -21,12 +21,7 @@
|
||||
#ifndef LOVE_OBJECT_H
|
||||
#define LOVE_OBJECT_H
|
||||
|
||||
/**
|
||||
* NOTE: the fact that an SDL header is included in such a widely used header
|
||||
* file is only temporary - in the LOVE 0.10+ codebase we use atomics from
|
||||
* C++11's standard library.
|
||||
**/
|
||||
#include <SDL_atomic.h>
|
||||
#include <atomic>
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -47,6 +42,7 @@ public:
|
||||
* Constructor. Sets reference count to one.
|
||||
**/
|
||||
Object();
|
||||
Object(const Object &other);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -57,7 +53,7 @@ public:
|
||||
* Gets the reference count of this Object.
|
||||
* @returns The reference count.
|
||||
**/
|
||||
int getReferenceCount();
|
||||
int getReferenceCount() const;
|
||||
|
||||
/**
|
||||
* Retains the Object, i.e. increases the
|
||||
@@ -75,7 +71,7 @@ public:
|
||||
private:
|
||||
|
||||
// The reference count.
|
||||
SDL_atomic_t count;
|
||||
std::atomic<int> count;
|
||||
|
||||
}; // Object
|
||||
|
||||
@@ -136,7 +132,7 @@ public:
|
||||
private:
|
||||
|
||||
T *object;
|
||||
|
||||
|
||||
}; // StrongRef
|
||||
|
||||
} // love
|
||||
|
||||
@@ -101,9 +101,8 @@ Variant::Variant(love::Type udatatype, void *userdata)
|
||||
if (udatatype != INVALID_ID)
|
||||
{
|
||||
Proxy *p = (Proxy *) userdata;
|
||||
flags = p->flags;
|
||||
data.userdata = p->data;
|
||||
((love::Object *) data.userdata)->retain();
|
||||
data.userdata = p->object;
|
||||
p->object->retain();
|
||||
}
|
||||
else
|
||||
data.userdata = userdata;
|
||||
@@ -223,11 +222,7 @@ void Variant::toLua(lua_State *L)
|
||||
break;
|
||||
case FUSERDATA:
|
||||
if (udatatype != INVALID_ID)
|
||||
{
|
||||
const char *name = NULL;
|
||||
love::types.find(udatatype, name);
|
||||
luax_pushtype(L, name, flags, (love::Object *) data.userdata);
|
||||
}
|
||||
luax_pushtype(L, udatatype, (love::Object *) data.userdata);
|
||||
else
|
||||
lua_pushlightuserdata(L, data.userdata);
|
||||
// I know this is not the same
|
||||
|
||||
@@ -76,7 +76,6 @@ public:
|
||||
|
||||
private:
|
||||
love::Type udatatype;
|
||||
bits flags;
|
||||
|
||||
}; // Variant
|
||||
} // love
|
||||
|
||||
@@ -216,15 +216,15 @@ inline float Vector::normalize(float length)
|
||||
**/
|
||||
|
||||
inline Vector::Vector()
|
||||
: x(0.0f)
|
||||
, y(0.0f)
|
||||
{
|
||||
x = 1;
|
||||
y = 1;
|
||||
}
|
||||
|
||||
inline Vector::Vector(float x, float y)
|
||||
: x(x)
|
||||
, y(y)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
inline Vector Vector::operator + (const Vector &v) const
|
||||
|
||||
@@ -32,16 +32,23 @@
|
||||
# define LOVE_ANDROID 1
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
# define LOVE_MACOSX 1
|
||||
# include <AvailabilityMacros.h>
|
||||
# include <TargetConditionals.h>
|
||||
# if TARGET_OS_IPHONE
|
||||
# define LOVE_IOS 1
|
||||
# elif TARGET_OS_MAC
|
||||
# define LOVE_MACOSX 1
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
// I know it's not linux, but it seems most "linux-only" code is bsd-compatible
|
||||
# define LOVE_LINUX 1
|
||||
#endif
|
||||
|
||||
// Endianness.
|
||||
#if defined(__i386__) || defined(__i386)
|
||||
# define LOVE_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
#if defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(__powerpc)
|
||||
# define LOVE_BIG_ENDIAN 1
|
||||
#else
|
||||
# define LOVE_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
||||
// Warnings.
|
||||
@@ -74,7 +81,7 @@
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#if defined(LOVE_MACOSX)
|
||||
#if defined(LOVE_MACOSX) || defined(LOVE_IOS)
|
||||
# define LOVE_LEGENDARY_APP_ARGV_HACK
|
||||
#endif
|
||||
|
||||
@@ -139,4 +146,12 @@
|
||||
# define LOVE_ENABLE_WUFF
|
||||
#endif
|
||||
|
||||
// Check we have a sane configuration
|
||||
#if !defined(LOVE_WINDOWS) && !defined(LOVE_LINUX) && !defined(LOVE_IOS) && !defined(LOVE_MACOSX)
|
||||
# error Could not detect target platform
|
||||
#endif
|
||||
#if !defined(LOVE_LITTLE_ENDIAN) && !defined(LOVE_BIG_ENDIAN)
|
||||
# error Could not detect endianness
|
||||
#endif
|
||||
|
||||
#endif // LOVE_CONFIG_H
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#ifndef LOVE_IOS_H
|
||||
#define LOVE_IOS_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef LOVE_IOS
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace ios
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the filepath of the first detected love file. The main .app Bundle is
|
||||
* searched first, and then the app's Documents folder.
|
||||
**/
|
||||
std::string getLoveInResources(bool &fused);
|
||||
|
||||
/**
|
||||
* Gets the directory path where files should be stored.
|
||||
**/
|
||||
std::string getAppdataDirectory();
|
||||
|
||||
/**
|
||||
* Get the home directory (on iOS, this really means the app's sandbox dir.)
|
||||
**/
|
||||
std::string getHomeDirectory();
|
||||
|
||||
/**
|
||||
* Opens the specified URL with the default program associated with the URL's
|
||||
* scheme.
|
||||
**/
|
||||
bool openURL(const std::string &url);
|
||||
|
||||
/**
|
||||
* Returns the full path to the executable.
|
||||
**/
|
||||
std::string getExecutablePath();
|
||||
|
||||
} // ios
|
||||
} // love
|
||||
|
||||
#endif // LOVE_IOS
|
||||
#endif // LOVE_IOS_H
|
||||
@@ -0,0 +1,327 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include "iOS.h"
|
||||
|
||||
#ifdef LOVE_IOS
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
static NSArray *getLovesInDocuments();
|
||||
static bool deleteFileInDocuments(NSString *filename);
|
||||
|
||||
@interface LOVETableViewController : UITableViewController
|
||||
|
||||
- (instancetype)initWithGameList:(NSArray *)list;
|
||||
|
||||
@property (nonatomic) NSMutableArray *gameList;
|
||||
@property (nonatomic, readonly, copy) NSString *selectedGame;
|
||||
|
||||
@end
|
||||
|
||||
@implementation LOVETableViewController
|
||||
|
||||
- (instancetype)initWithGameList:(NSArray *)list
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
_gameList = [[NSMutableArray alloc] initWithArray:list copyItems:YES];
|
||||
|
||||
self.title = @"LÖVE Games";
|
||||
self.navigationItem.rightBarButtonItem = self.editButtonItem;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
#pragma unused(tableView)
|
||||
#pragma unused(section)
|
||||
// We want to list all games plus the no-game screen.
|
||||
return self.gameList.count + 1;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
static NSString *cellIdentifier = @"LOVETableCell";
|
||||
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
|
||||
if (cell == nil)
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
|
||||
|
||||
if (indexPath.row < (NSInteger) self.gameList.count)
|
||||
cell.textLabel.text = self.gameList[indexPath.row];
|
||||
else
|
||||
cell.textLabel.text = @"No-game screen";
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
#pragma unused(tableView)
|
||||
if (indexPath.row < (NSInteger) self.gameList.count)
|
||||
_selectedGame = [(NSString *)(self.gameList[indexPath.row]) copy];
|
||||
else
|
||||
{
|
||||
// We test against nil to check if a game has been selected, so we'll
|
||||
// just use an empty string instead to represent the no-game screen.
|
||||
_selectedGame = @"";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (editingStyle != UITableViewCellEditingStyleDelete)
|
||||
return;
|
||||
|
||||
if (indexPath.row >= (NSInteger) self.gameList.count)
|
||||
return;
|
||||
|
||||
NSString *filename = self.gameList[indexPath.row];
|
||||
|
||||
// Delete the file.
|
||||
if (deleteFileInDocuments(filename))
|
||||
{
|
||||
[self.gameList removeObjectAtIndex:indexPath.row];
|
||||
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
|
||||
{
|
||||
#pragma unused(tableView)
|
||||
// The no-game screen isn't removable.
|
||||
return indexPath.row < (NSInteger) self.gameList.count;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static NSString *getDocumentsDirectory()
|
||||
{
|
||||
NSArray *docdirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
return docdirs[0];
|
||||
}
|
||||
|
||||
static NSArray *getLovesInDocuments()
|
||||
{
|
||||
NSString *documents = getDocumentsDirectory();
|
||||
NSArray *filepaths = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documents error:nil];
|
||||
return [filepaths pathsMatchingExtensions:@[@"love"]];
|
||||
}
|
||||
|
||||
static bool deleteFileInDocuments(NSString *filename)
|
||||
{
|
||||
NSString *documents = getDocumentsDirectory();
|
||||
|
||||
NSString *file = [documents stringByAppendingPathComponent:filename];
|
||||
bool success = [[NSFileManager defaultManager] removeItemAtPath:file error:nil];
|
||||
|
||||
if (success)
|
||||
NSLog(@"Deleted file %@ in Documents folder.", filename);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static int dropFileEventFilter(void *userdata, SDL_Event *event)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
if (event->type != SDL_DROPFILE)
|
||||
return 1;
|
||||
|
||||
NSString *fname = @(event->drop.file);
|
||||
NSFileManager *fmanager = [NSFileManager defaultManager];
|
||||
|
||||
if ([fmanager fileExistsAtPath:fname] && [fname.pathExtension isEqual:@"love"])
|
||||
{
|
||||
NSString *documents = getDocumentsDirectory();
|
||||
|
||||
documents = documents.stringByStandardizingPath.stringByResolvingSymlinksInPath;
|
||||
fname = fname.stringByStandardizingPath.stringByResolvingSymlinksInPath;
|
||||
|
||||
// Is the file inside the Documents directory?
|
||||
if ([fname hasPrefix:documents])
|
||||
{
|
||||
LOVETableViewController *vc = (__bridge LOVETableViewController *) userdata;
|
||||
|
||||
// Update the game list.
|
||||
NSArray *games = getLovesInDocuments();
|
||||
vc.gameList = [[NSMutableArray alloc] initWithArray:games copyItems:YES];
|
||||
[vc.tableView reloadData];
|
||||
|
||||
SDL_free(event->drop.file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace ios
|
||||
{
|
||||
|
||||
/**
|
||||
* Displays a full-screen list of available LOVE games for the user to choose.
|
||||
* Returns the index of the selected game from the list. The list of games
|
||||
* includes the no-game screen, and the function will return an index outside
|
||||
* of the array's range if that is selected.
|
||||
**/
|
||||
static NSString *showGameList(NSArray *filenames)
|
||||
{
|
||||
// Game list view controller.
|
||||
LOVETableViewController *tablecontroller = [[LOVETableViewController alloc] initWithGameList:filenames];
|
||||
|
||||
// Navigation view controller (only used for the header bar right now.)
|
||||
// Contains the game list view/controller.
|
||||
UINavigationController *navcontroller = [[UINavigationController alloc] initWithRootViewController:tablecontroller];
|
||||
|
||||
UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
window.rootViewController = navcontroller;
|
||||
|
||||
SDL_EventFilter oldfilter = nullptr;
|
||||
void *oldudata = nullptr;
|
||||
SDL_GetEventFilter(&oldfilter, &oldudata);
|
||||
|
||||
// Manually retain the table VC and use it for the event filter userdata.
|
||||
// We need to set a custom event filter to update the table when .love files
|
||||
// are opened by the user.
|
||||
void *tableudata = (void *) CFBridgingRetain(tablecontroller);
|
||||
SDL_SetEventFilter(dropFileEventFilter, tableudata);
|
||||
|
||||
[window makeKeyAndVisible];
|
||||
|
||||
// Process events until a game in the list is selected.
|
||||
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
|
||||
while (tablecontroller.selectedGame == nil)
|
||||
{
|
||||
[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
|
||||
[runloop runMode:UITrackingRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0/60.0]];
|
||||
}
|
||||
|
||||
// The window will get released and cleaned up once we go out of scope.
|
||||
window.hidden = YES;
|
||||
|
||||
SDL_SetEventFilter(oldfilter, oldudata);
|
||||
CFBridgingRelease(tableudata);
|
||||
|
||||
return tablecontroller.selectedGame;
|
||||
}
|
||||
|
||||
std::string getLoveInResources(bool &fused)
|
||||
{
|
||||
fused = false;
|
||||
std::string path;
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
// Start by looking in the main bundle (.app) folder for .love files.
|
||||
NSArray *bundlepaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"love" inDirectory:nil];
|
||||
|
||||
if (bundlepaths.count > 0)
|
||||
{
|
||||
// The game should be fused if we have something here.
|
||||
fused = true;
|
||||
return [bundlepaths[0] UTF8String];
|
||||
}
|
||||
|
||||
// Otherwise look in the app's Documents directory. The game won't be
|
||||
// fused.
|
||||
NSArray *filepaths = getLovesInDocuments();
|
||||
|
||||
// Let the user select a game from the un-fused list.
|
||||
NSString *selectedfile = showGameList(filepaths);
|
||||
|
||||
// The string length might be 0 if the no-game screen was selected.
|
||||
if (selectedfile != nil && selectedfile.length > 0)
|
||||
{
|
||||
NSString *documents = getDocumentsDirectory();
|
||||
path = [documents stringByAppendingPathComponent:selectedfile].UTF8String;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string getAppdataDirectory()
|
||||
{
|
||||
NSSearchPathDirectory searchdir = NSApplicationSupportDirectory;
|
||||
std::string path;
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
NSArray *dirs = NSSearchPathForDirectoriesInDomains(searchdir, NSUserDomainMask, YES);
|
||||
|
||||
if (dirs.count > 0)
|
||||
path = [dirs[0] UTF8String];
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string getHomeDirectory()
|
||||
{
|
||||
std::string path;
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
path = [NSHomeDirectory() UTF8String];
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
bool openURL(const std::string &url)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
UIApplication *app = [UIApplication sharedApplication];
|
||||
NSURL *nsurl = [NSURL URLWithString:@(url.c_str())];
|
||||
|
||||
if ([app canOpenURL:nsurl])
|
||||
success = [app openURL:nsurl];
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
std::string getExecutablePath()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
return std::string([NSBundle mainBundle].executablePath.UTF8String);
|
||||
}
|
||||
}
|
||||
|
||||
} // ios
|
||||
} // love
|
||||
|
||||
#endif // LOVE_IOS
|
||||
@@ -31,8 +31,6 @@
|
||||
#endif
|
||||
|
||||
// C standard sized integer types.
|
||||
// This header was added to Visual studio in VS 2012, which is LOVE's current
|
||||
// minimum supported VS version (as of this comment's commit date.)
|
||||
#include <stdint.h>
|
||||
|
||||
#define LOVE_INT8_MAX 0x7F
|
||||
|
||||
+87
-147
@@ -26,7 +26,6 @@
|
||||
#include "Object.h"
|
||||
#include "Reference.h"
|
||||
#include "StringMap.h"
|
||||
#include <thread/threads.h>
|
||||
|
||||
// C++
|
||||
#include <algorithm>
|
||||
@@ -36,24 +35,14 @@
|
||||
namespace love
|
||||
{
|
||||
|
||||
static thread::Mutex *gcmutex = nullptr;
|
||||
|
||||
/**
|
||||
* Called when an object is collected. The object is released
|
||||
* once in this function, possibly deleting it.
|
||||
**/
|
||||
static int w__gc(lua_State *L)
|
||||
{
|
||||
if (!gcmutex)
|
||||
gcmutex = thread::newMutex();
|
||||
|
||||
Proxy *p = (Proxy *) lua_touserdata(L, 1);
|
||||
Object *object = (Object *) p->data;
|
||||
|
||||
thread::Lock lock(gcmutex);
|
||||
|
||||
object->release();
|
||||
|
||||
p->object->release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -67,7 +56,7 @@ static int w__typeOf(lua_State *L)
|
||||
{
|
||||
Proxy *p = (Proxy *)lua_touserdata(L, 1);
|
||||
Type t = luax_type(L, 2);
|
||||
luax_pushboolean(L, p->flags[t]);
|
||||
luax_pushboolean(L, typeFlags[p->type][t]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -75,13 +64,13 @@ static int w__eq(lua_State *L)
|
||||
{
|
||||
Proxy *p1 = (Proxy *)lua_touserdata(L, 1);
|
||||
Proxy *p2 = (Proxy *)lua_touserdata(L, 2);
|
||||
luax_pushboolean(L, p1->data == p2->data);
|
||||
luax_pushboolean(L, p1->object == p2->object);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference *luax_refif(lua_State *L, int type)
|
||||
{
|
||||
Reference *r = 0;
|
||||
Reference *r = nullptr;
|
||||
|
||||
// Create a reference only if the test succeeds.
|
||||
if (lua_type(L, -1) == type)
|
||||
@@ -95,9 +84,7 @@ Reference *luax_refif(lua_State *L, int type)
|
||||
void luax_printstack(lua_State *L)
|
||||
{
|
||||
for (int i = 1; i<=lua_gettop(L); i++)
|
||||
{
|
||||
std::cout << i << " - " << luaL_typename(L, i) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool luax_toboolean(lua_State *L, int idx)
|
||||
@@ -144,7 +131,7 @@ bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultV
|
||||
if (lua_isnoneornil(L, -1))
|
||||
retval = defaultValue;
|
||||
else
|
||||
retval = lua_toboolean(L, -1);
|
||||
retval = lua_toboolean(L, -1) != 0;
|
||||
|
||||
lua_pop(L, 1);
|
||||
return retval;
|
||||
@@ -201,24 +188,32 @@ int luax_assert_nilerror(lua_State *L, int idx)
|
||||
|
||||
void luax_setfuncs(lua_State *L, const luaL_Reg *l)
|
||||
{
|
||||
if (l == 0)
|
||||
if (l == nullptr)
|
||||
return;
|
||||
|
||||
for (; l->name != 0; l++)
|
||||
for (; l->name != nullptr; l++)
|
||||
{
|
||||
lua_pushcfunction(L, l->func);
|
||||
lua_setfield(L, -2, l->name);
|
||||
}
|
||||
}
|
||||
|
||||
int luax_require(lua_State *L, const char *name)
|
||||
{
|
||||
lua_getglobal(L, "require");
|
||||
lua_pushstring(L, name);
|
||||
lua_call(L, 1, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int luax_register_module(lua_State *L, const WrappedModule &m)
|
||||
{
|
||||
// Put a reference to the C++ module in Lua.
|
||||
luax_insistregistry(L, REGISTRY_MODULES);
|
||||
|
||||
Proxy *p = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
|
||||
p->data = m.module;
|
||||
p->flags = m.flags;
|
||||
p->object = m.module;
|
||||
p->type = m.type;
|
||||
|
||||
luaL_newmetatable(L, m.module->getName());
|
||||
lua_pushvalue(L, -1);
|
||||
@@ -237,13 +232,15 @@ int luax_register_module(lua_State *L, const WrappedModule &m)
|
||||
lua_newtable(L);
|
||||
|
||||
// Register all the functions.
|
||||
if (m.functions != 0)
|
||||
if (m.functions != nullptr)
|
||||
luax_setfuncs(L, m.functions);
|
||||
|
||||
// Register types.
|
||||
if (m.types != 0)
|
||||
for (const lua_CFunction *t = m.types; *t != 0; t++)
|
||||
if (m.types != nullptr)
|
||||
{
|
||||
for (const lua_CFunction *t = m.types; *t != nullptr; t++)
|
||||
(*t)(L);
|
||||
}
|
||||
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, m.name); // love.graphics = table
|
||||
@@ -265,17 +262,17 @@ int luax_preload(lua_State *L, lua_CFunction f, const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f)
|
||||
int luax_register_type(lua_State *L, love::Type type, const luaL_Reg *f, bool pushmetatable)
|
||||
{
|
||||
// Verify that this type name has a matching Type ID and type name mapping.
|
||||
love::Type ltype;
|
||||
if (!love::getType(tname, ltype))
|
||||
printf("Missing type entry for type name: %s\n", tname);
|
||||
const char *tname = "Invalid";
|
||||
if (!love::getType(type, tname))
|
||||
printf("Missing type name entry for type ID %d\n", type);
|
||||
|
||||
// Get the place for storing and re-using instantiated love types.
|
||||
luax_getregistry(L, REGISTRY_TYPES);
|
||||
luax_getregistry(L, REGISTRY_OBJECTS);
|
||||
|
||||
// Create registry._lovetypes if it doesn't exist yet.
|
||||
// Create registry._loveobjects if it doesn't exist yet.
|
||||
if (!lua_istable(L, -1))
|
||||
{
|
||||
lua_newtable(L);
|
||||
@@ -291,8 +288,8 @@ int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f)
|
||||
// setmetatable(newtable, metatable)
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// registry._lovetypes = newtable
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "_lovetypes");
|
||||
// registry._loveobjects = newtable
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "_loveobjects");
|
||||
}
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
@@ -325,9 +322,12 @@ int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f)
|
||||
lua_pushcfunction(L, w__typeOf);
|
||||
lua_setfield(L, -2, "typeOf");
|
||||
|
||||
if (f != 0)
|
||||
if (f != nullptr)
|
||||
luax_setfuncs(L, f);
|
||||
|
||||
if (pushmetatable)
|
||||
return 1; // leave the metatable on the stack.
|
||||
|
||||
lua_pop(L, 1); // Pops metatable.
|
||||
return 0;
|
||||
}
|
||||
@@ -338,19 +338,22 @@ int luax_table_insert(lua_State *L, int tindex, int vindex, int pos)
|
||||
tindex = lua_gettop(L)+1+tindex;
|
||||
if (vindex < 0)
|
||||
vindex = lua_gettop(L)+1+vindex;
|
||||
|
||||
if (pos == -1)
|
||||
{
|
||||
lua_pushvalue(L, vindex);
|
||||
lua_rawseti(L, tindex, lua_objlen(L, tindex)+1);
|
||||
lua_rawseti(L, tindex, (int) luax_objlen(L, tindex)+1);
|
||||
return 0;
|
||||
}
|
||||
else if (pos < 0)
|
||||
pos = lua_objlen(L, tindex)+1+pos;
|
||||
for (int i = lua_objlen(L, tindex)+1; i > pos; i--)
|
||||
pos = (int) luax_objlen(L, tindex)+1+pos;
|
||||
|
||||
for (int i = (int) luax_objlen(L, tindex)+1; i > pos; i--)
|
||||
{
|
||||
lua_rawgeti(L, tindex, i-1);
|
||||
lua_rawseti(L, tindex, i);
|
||||
}
|
||||
|
||||
lua_pushvalue(L, vindex);
|
||||
lua_rawseti(L, tindex, pos);
|
||||
return 0;
|
||||
@@ -382,20 +385,23 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *object)
|
||||
void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object)
|
||||
{
|
||||
Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
|
||||
|
||||
object->retain();
|
||||
|
||||
u->data = (void *) object;
|
||||
u->flags = flags;
|
||||
u->object = object;
|
||||
u->type = type;
|
||||
|
||||
const char *name = "Invalid";
|
||||
getType(type, name);
|
||||
|
||||
luaL_newmetatable(L, name);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *object)
|
||||
void luax_pushtype(lua_State *L, love::Type type, love::Object *object)
|
||||
{
|
||||
if (object == nullptr)
|
||||
{
|
||||
@@ -403,18 +409,18 @@ void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *obj
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the registry table of instantiated types.
|
||||
luax_getregistry(L, REGISTRY_TYPES);
|
||||
// Fetch the registry table of instantiated objects.
|
||||
luax_getregistry(L, REGISTRY_OBJECTS);
|
||||
|
||||
// The table might not exist - it should be insisted in luax_register_type.
|
||||
if (!lua_istable(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
return luax_rawnewtype(L, name, flags, object);
|
||||
return luax_rawnewtype(L, type, object);
|
||||
}
|
||||
|
||||
// Get the value of lovetypes[object] on the stack.
|
||||
lua_pushlightuserdata(L, (void *) object);
|
||||
// Get the value of loveobjects[object] on the stack.
|
||||
lua_pushlightuserdata(L, object);
|
||||
lua_gettable(L, -2);
|
||||
|
||||
// If the Proxy userdata isn't in the instantiated types table yet, add it.
|
||||
@@ -422,27 +428,28 @@ void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *obj
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
|
||||
luax_rawnewtype(L, name, flags, object);
|
||||
luax_rawnewtype(L, type, object);
|
||||
|
||||
lua_pushlightuserdata(L, (void *) object);
|
||||
lua_pushlightuserdata(L, object);
|
||||
lua_pushvalue(L, -2);
|
||||
|
||||
// lovetypes[object] = Proxy.
|
||||
// loveobjects[object] = Proxy.
|
||||
lua_settable(L, -4);
|
||||
}
|
||||
|
||||
// Remove the lovetypes table from the stack.
|
||||
// Remove the loveobjects table from the stack.
|
||||
lua_remove(L, -2);
|
||||
|
||||
// Keep the Proxy userdata on the stack.
|
||||
}
|
||||
|
||||
bool luax_istype(lua_State *L, int idx, love::bits type)
|
||||
bool luax_istype(lua_State *L, int idx, love::Type type)
|
||||
{
|
||||
if (lua_type(L, idx) != LUA_TUSERDATA)
|
||||
return false;
|
||||
|
||||
return ((((Proxy *)lua_touserdata(L, idx))->flags & type) == type);
|
||||
Proxy *p = (Proxy *) lua_touserdata(L, idx);
|
||||
return typeFlags[p->type][type];
|
||||
}
|
||||
|
||||
int luax_getfunction(lua_State *L, const char *mod, const char *fn)
|
||||
@@ -485,7 +492,8 @@ int luax_convobj(lua_State *L, int idxs[], int n, const char *mod, const char *f
|
||||
lua_call(L, n, 2); // Call the function, n args, one return value (plus optional errstring.)
|
||||
luax_assert_nilerror(L, -2); // Make sure the function returned something.
|
||||
lua_pop(L, 1); // Pop the second return value now that we don't need it.
|
||||
lua_replace(L, idxs[0]); // Replace the initial argument with the new object.
|
||||
if (n > 0)
|
||||
lua_replace(L, idxs[0]); // Replace the initial argument with the new object.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -548,6 +556,11 @@ int luax_insistglobal(lua_State *L, const char *k)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int luax_c_insistglobal(lua_State *L, const char *k)
|
||||
{
|
||||
return luax_insistglobal(L, k);
|
||||
}
|
||||
|
||||
int luax_insistlove(lua_State *L, const char *k)
|
||||
{
|
||||
luax_insistglobal(L, "love");
|
||||
@@ -581,8 +594,8 @@ int luax_insistregistry(lua_State *L, Registry r)
|
||||
return luax_insistlove(L, "_gc");
|
||||
case REGISTRY_MODULES:
|
||||
return luax_insistlove(L, "_modules");
|
||||
case REGISTRY_TYPES:
|
||||
return luax_insist(L, LUA_REGISTRYINDEX, "_lovetypes");
|
||||
case REGISTRY_OBJECTS:
|
||||
return luax_insist(L, LUA_REGISTRYINDEX, "_loveobjects");
|
||||
default:
|
||||
return luaL_error(L, "Attempted to use invalid registry.");
|
||||
}
|
||||
@@ -596,8 +609,8 @@ int luax_getregistry(lua_State *L, Registry r)
|
||||
return luax_getlove(L, "_gc");
|
||||
case REGISTRY_MODULES:
|
||||
return luax_getlove(L, "_modules");
|
||||
case REGISTRY_TYPES:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "_lovetypes");
|
||||
case REGISTRY_OBJECTS:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "_loveobjects");
|
||||
return 1;
|
||||
default:
|
||||
return luaL_error(L, "Attempted to use invalid registry.");
|
||||
@@ -632,105 +645,32 @@ extern "C" int luax_typerror(lua_State *L, int narg, const char *tname)
|
||||
return luaL_argerror(L, narg, msg);
|
||||
}
|
||||
|
||||
StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
|
||||
size_t luax_objlen(lua_State *L, int ndx)
|
||||
{
|
||||
{"Invalid", INVALID_ID},
|
||||
|
||||
{"Object", OBJECT_ID},
|
||||
{"Data", DATA_ID},
|
||||
{"Module", MODULE_ID},
|
||||
|
||||
// Filesystem
|
||||
{"File", FILESYSTEM_FILE_ID},
|
||||
{"FileData", FILESYSTEM_FILE_DATA_ID},
|
||||
|
||||
// Font
|
||||
{"GlyphData", FONT_GLYPH_DATA_ID},
|
||||
{"Rasterizer", FONT_RASTERIZER_ID},
|
||||
|
||||
// Graphics
|
||||
{"Drawable", GRAPHICS_DRAWABLE_ID},
|
||||
{"Texture", GRAPHICS_TEXTURE_ID},
|
||||
{"Image", GRAPHICS_IMAGE_ID},
|
||||
{"Quad", GRAPHICS_QUAD_ID},
|
||||
{"Font", GRAPHICS_FONT_ID},
|
||||
{"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID},
|
||||
{"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID},
|
||||
{"Canvas", GRAPHICS_CANVAS_ID},
|
||||
{"Shader", GRAPHICS_SHADER_ID},
|
||||
{"Mesh", GRAPHICS_MESH_ID},
|
||||
|
||||
// Image
|
||||
{"ImageData", IMAGE_IMAGE_DATA_ID},
|
||||
{"CompressedData", IMAGE_COMPRESSED_DATA_ID},
|
||||
|
||||
// Joystick
|
||||
{"Joystick", JOYSTICK_JOYSTICK_ID},
|
||||
|
||||
// Math
|
||||
{"RandomGenerator", MATH_RANDOM_GENERATOR_ID},
|
||||
{"BezierCurve", MATH_BEZIER_CURVE_ID},
|
||||
|
||||
// Audio
|
||||
{"Source", AUDIO_SOURCE_ID},
|
||||
|
||||
// Sound
|
||||
{"SoundData", SOUND_SOUND_DATA_ID},
|
||||
{"Decoder", SOUND_DECODER_ID},
|
||||
|
||||
// Mouse
|
||||
{"Cursor", MOUSE_CURSOR_ID},
|
||||
|
||||
// Physics
|
||||
{"World", PHYSICS_WORLD_ID},
|
||||
{"Contact", PHYSICS_CONTACT_ID},
|
||||
{"Body", PHYSICS_BODY_ID},
|
||||
{"Fixture", PHYSICS_FIXTURE_ID},
|
||||
{"Shape", PHYSICS_SHAPE_ID},
|
||||
{"CircleShape", PHYSICS_CIRCLE_SHAPE_ID},
|
||||
{"PolygonShape", PHYSICS_POLYGON_SHAPE_ID},
|
||||
{"EdgeShape", PHYSICS_EDGE_SHAPE_ID},
|
||||
{"ChainShape", PHYSICS_CHAIN_SHAPE_ID},
|
||||
{"Joint", PHYSICS_JOINT_ID},
|
||||
{"MouseJoint", PHYSICS_MOUSE_JOINT_ID},
|
||||
{"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID},
|
||||
{"PrismaticJoint", PHYSICS_PRISMATIC_JOINT_ID},
|
||||
{"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID},
|
||||
{"PulleyJoint", PHYSICS_PULLEY_JOINT_ID},
|
||||
{"GearJoint", PHYSICS_GEAR_JOINT_ID},
|
||||
{"FrictionJoint", PHYSICS_FRICTION_JOINT_ID},
|
||||
{"WeldJoint", PHYSICS_WELD_JOINT_ID},
|
||||
{"RopeJoint", PHYSICS_ROPE_JOINT_ID},
|
||||
{"WheelJoint", PHYSICS_WHEEL_JOINT_ID},
|
||||
{"MotorJoint", PHYSICS_MOTOR_JOINT_ID},
|
||||
|
||||
// Thread
|
||||
{"Thread", THREAD_THREAD_ID},
|
||||
{"Channel", THREAD_CHANNEL_ID},
|
||||
|
||||
// The modules themselves. Only add abstracted modules here.
|
||||
{"filesystem", MODULE_FILESYSTEM_ID},
|
||||
{"graphics", MODULE_GRAPHICS_ID},
|
||||
{"image", MODULE_IMAGE_ID},
|
||||
{"sound", MODULE_SOUND_ID},
|
||||
};
|
||||
|
||||
StringMap<Type, TYPE_MAX_ENUM> types(typeEntries, sizeof(typeEntries));
|
||||
|
||||
bool getType(const char *in, love::Type &out)
|
||||
{
|
||||
return types.find(in, out);
|
||||
#if LUA_VERSION_NUM == 501
|
||||
return lua_objlen(L, ndx);
|
||||
#else
|
||||
return lua_rawlen(L, ndx);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool getType(love::Type in, const char *&out)
|
||||
void luax_register(lua_State *L, const char *name, const luaL_Reg *l)
|
||||
{
|
||||
return types.find(in, out);
|
||||
if (name)
|
||||
lua_newtable(L);
|
||||
|
||||
luax_setfuncs(L, l);
|
||||
if (name)
|
||||
{
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, name);
|
||||
}
|
||||
}
|
||||
|
||||
Type luax_type(lua_State *L, int idx)
|
||||
{
|
||||
Type t = INVALID_ID;
|
||||
types.find(luaL_checkstring(L, idx), t);
|
||||
getType(luaL_checkstring(L, idx), t);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ enum Registry
|
||||
{
|
||||
REGISTRY_GC,
|
||||
REGISTRY_MODULES,
|
||||
REGISTRY_TYPES
|
||||
REGISTRY_OBJECTS
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -63,10 +63,10 @@ enum Registry
|
||||
struct Proxy
|
||||
{
|
||||
// Holds type information (see types.h).
|
||||
bits flags;
|
||||
Type type;
|
||||
|
||||
// The light userdata (pointer to the love::Object).
|
||||
void *data;
|
||||
// Pointer to the actual object.
|
||||
Object *object;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -80,15 +80,14 @@ struct WrappedModule
|
||||
// The name for the table to put the functions in, without the 'love'-prefix.
|
||||
const char *name;
|
||||
|
||||
// The type flags of this module.
|
||||
love::bits flags;
|
||||
// The type of this module.
|
||||
love::Type type;
|
||||
|
||||
// The functions of the module (last element {0,0}).
|
||||
const luaL_Reg *functions;
|
||||
|
||||
// A list of functions which expose the types of the modules (last element 0).
|
||||
const lua_CFunction *types;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -223,6 +222,13 @@ int luax_assert_nilerror(lua_State *L, int idx);
|
||||
**/
|
||||
void luax_setfuncs(lua_State *L, const luaL_Reg *l);
|
||||
|
||||
/**
|
||||
* Loads a Lua module using the 'require' function. Leaves the return result on
|
||||
* the stack.
|
||||
* @param name The name of the module to require.
|
||||
**/
|
||||
int luax_require(lua_State *L, const char *name);
|
||||
|
||||
/**
|
||||
* Register a module in the love table. The love table will be created if it does not exist.
|
||||
* NOTE: The module-object is expected to have a +1 reference count before calling
|
||||
@@ -241,11 +247,11 @@ int luax_preload(lua_State *L, lua_CFunction f, const char *name);
|
||||
|
||||
/**
|
||||
* Register a new type.
|
||||
* @param tname The name of the type. This must not conflict with other type names,
|
||||
* even from other modules.
|
||||
* @param type The type.
|
||||
* @param f The list of member functions for the type.
|
||||
* @param pushmetatable Whether to push the type's metatable to the stack.
|
||||
**/
|
||||
int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f = 0);
|
||||
int luax_register_type(lua_State *L, love::Type type, const luaL_Reg *f = nullptr, bool pushmetatable = false);
|
||||
|
||||
/**
|
||||
* Do a table.insert from C
|
||||
@@ -270,11 +276,10 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1);
|
||||
* storing the Lua representation in a weak table if it doesn't exist yet.
|
||||
* NOTE: The object will be retained by Lua and released upon garbage collection.
|
||||
* @param L The Lua state.
|
||||
* @param name The name of the type. This must match the name used with luax_register_type.
|
||||
* @param flags The type information of the object.
|
||||
* @param type The type information of the object.
|
||||
* @param object The pointer to the actual object.
|
||||
**/
|
||||
void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *object);
|
||||
void luax_pushtype(lua_State *L, const love::Type type, love::Object *object);
|
||||
|
||||
/**
|
||||
* Creates a new Lua representation of the given object *without* checking if it
|
||||
@@ -284,11 +289,10 @@ void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *obj
|
||||
* Lua-side objects from working in some cases when used as keys in tables.
|
||||
* NOTE: The object will be retained by Lua and released upon garbage collection.
|
||||
* @param L The Lua state.
|
||||
* @param name The name of the type. This must match the name used with luax_register_type.
|
||||
* @param flags The type information of the object.
|
||||
* @param type The type information of the object.
|
||||
* @param object The pointer to the actual object.
|
||||
**/
|
||||
void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *object);
|
||||
void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object);
|
||||
|
||||
/**
|
||||
* Checks whether the value at idx is a certain type.
|
||||
@@ -297,7 +301,7 @@ void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *o
|
||||
* @param type The type to check for.
|
||||
* @return True if the value is Proxy of the specified type, false otherwise.
|
||||
**/
|
||||
bool luax_istype(lua_State *L, int idx, love::bits type);
|
||||
bool luax_istype(lua_State *L, int idx, love::Type type);
|
||||
|
||||
/**
|
||||
* Gets the function love.module.function and puts it on top of the stack (alone). If the
|
||||
@@ -390,52 +394,75 @@ extern "C" { // Also called from luasocket
|
||||
int luax_typerror(lua_State *L, int narg, const char *tname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls luax_objlen/lua_rawlen depending on version
|
||||
**/
|
||||
size_t luax_objlen(lua_State *L, int ndx);
|
||||
|
||||
extern "C" { // Called by enet and luasocket
|
||||
void luax_register(lua_State *L, const char *name, const luaL_Reg *l);
|
||||
int luax_c_insistglobal(lua_State *L, const char *k);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like luax_totype, but causes an error if the value at idx is not Proxy,
|
||||
* or is not the specified type.
|
||||
* @param L The Lua state.
|
||||
* @param idx The index on the stack.
|
||||
* @param name The name of the type.
|
||||
* @param type The type bit.
|
||||
**/
|
||||
template <typename T>
|
||||
T *luax_checktype(lua_State *L, int idx, const char *name, love::bits type)
|
||||
T *luax_checktype(lua_State *L, int idx, love::Type type)
|
||||
{
|
||||
if (lua_type(L, idx) != LUA_TUSERDATA)
|
||||
{
|
||||
const char *name = "Invalid";
|
||||
getType(type, name);
|
||||
luax_typerror(L, idx, name);
|
||||
}
|
||||
|
||||
Proxy *u = (Proxy *)lua_touserdata(L, idx);
|
||||
|
||||
if ((u->flags & type) != type)
|
||||
if (!typeFlags[u->type][type])
|
||||
{
|
||||
const char *name = "Invalid";
|
||||
getType(type, name);
|
||||
luax_typerror(L, idx, name);
|
||||
}
|
||||
|
||||
return (T *)u->data;
|
||||
return (T *)u->object;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *luax_getmodule(lua_State *L, const char *k, love::bits type)
|
||||
T *luax_getmodule(lua_State *L, love::Type type)
|
||||
{
|
||||
const char *name = "Invalid";
|
||||
getType(type, name);
|
||||
|
||||
luax_insistregistry(L, REGISTRY_MODULES);
|
||||
lua_getfield(L, -1, k);
|
||||
lua_getfield(L, -1, name);
|
||||
|
||||
if (!lua_isuserdata(L, -1))
|
||||
luaL_error(L, "Tried to get nonexistant module %s.", k);
|
||||
luaL_error(L, "Tried to get nonexistant module %s.", name);
|
||||
|
||||
Proxy *u = (Proxy *)lua_touserdata(L, -1);
|
||||
|
||||
if ((u->flags & type) != type)
|
||||
luaL_error(L, "Incorrect module %s", k);
|
||||
if (!typeFlags[u->type][type])
|
||||
luaL_error(L, "Incorrect module %s", name);
|
||||
|
||||
lua_pop(L, 2);
|
||||
|
||||
return (T *)u->data;
|
||||
return (T *)u->object;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *luax_optmodule(lua_State *L, const char *k, love::bits type)
|
||||
T *luax_optmodule(lua_State *L, love::Type type)
|
||||
{
|
||||
const char *name = "Invalid";
|
||||
getType(type, name);
|
||||
|
||||
luax_insistregistry(L, REGISTRY_MODULES);
|
||||
lua_getfield(L, -1, k);
|
||||
lua_getfield(L, -1, name);
|
||||
|
||||
if (!lua_isuserdata(L, -1))
|
||||
{
|
||||
@@ -445,12 +472,12 @@ T *luax_optmodule(lua_State *L, const char *k, love::bits type)
|
||||
|
||||
Proxy *u = (Proxy *)lua_touserdata(L, -1);
|
||||
|
||||
if ((u->flags & type) != type)
|
||||
luaL_error(L, "Incorrect module %s", k);
|
||||
|
||||
if (!typeFlags[u->type][type])
|
||||
luaL_error(L, "Incorrect module %s", name);
|
||||
|
||||
lua_pop(L, 2);
|
||||
|
||||
return (T *) u->data;
|
||||
|
||||
return (T *) u->object;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -459,13 +486,12 @@ T *luax_optmodule(lua_State *L, const char *k, love::bits type)
|
||||
* luax_istype, then this can be safely used. Otherwise, use luax_checktype.
|
||||
* @param L The Lua state.
|
||||
* @param idx The index on the stack.
|
||||
* @param name The name of the type.
|
||||
* @param type The type bit.
|
||||
* @param type The type of the object.
|
||||
**/
|
||||
template <typename T>
|
||||
T *luax_totype(lua_State *L, int idx, const char * /* name */, love::bits /* type */)
|
||||
T *luax_totype(lua_State *L, int idx, love::Type /*type*/)
|
||||
{
|
||||
return (T *)(((Proxy *)lua_touserdata(L, idx))->data);
|
||||
return (T *)(((Proxy *)lua_touserdata(L, idx))->object);
|
||||
}
|
||||
|
||||
Type luax_type(lua_State *L, int idx);
|
||||
@@ -495,7 +521,6 @@ int luax_catchexcept(lua_State *L, const T& func)
|
||||
return luaL_error(L, "%s", lua_tostring(L, -1));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
template <typename T, typename F>
|
||||
@@ -513,13 +538,12 @@ int luax_catchexcept(lua_State *L, const T& func, const F& finallyfunc)
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
|
||||
finallyfunc();
|
||||
finallyfunc(should_error);
|
||||
|
||||
if (should_error)
|
||||
return luaL_error(L, "%s", lua_tostring(L, -1));
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
} // love
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2015 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include "types.h"
|
||||
#include "StringMap.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
|
||||
static const TypeBits *createTypeFlags()
|
||||
{
|
||||
static TypeBits b[TYPE_MAX_ENUM];
|
||||
TypeBits one = TypeBits(1);
|
||||
|
||||
b[INVALID_ID] = one << INVALID_ID;
|
||||
|
||||
b[OBJECT_ID] = one << OBJECT_ID;
|
||||
b[DATA_ID] = (one << DATA_ID) | b[OBJECT_ID];
|
||||
b[MODULE_ID] = (one << MODULE_ID) | b[OBJECT_ID];
|
||||
|
||||
// Filesystem.
|
||||
b[FILESYSTEM_FILE_ID] = (one << FILESYSTEM_FILE_ID) | b[OBJECT_ID];
|
||||
b[FILESYSTEM_DROPPED_FILE_ID] = (one << FILESYSTEM_DROPPED_FILE_ID) | b[FILESYSTEM_FILE_ID];
|
||||
b[FILESYSTEM_FILE_DATA_ID] = (one << FILESYSTEM_FILE_DATA_ID) | b[DATA_ID];
|
||||
|
||||
b[FONT_GLYPH_DATA_ID] = (one << FONT_GLYPH_DATA_ID) | b[DATA_ID];
|
||||
b[FONT_RASTERIZER_ID] = (one << FONT_RASTERIZER_ID) | b[OBJECT_ID];
|
||||
|
||||
// Graphics.
|
||||
b[GRAPHICS_DRAWABLE_ID] = (one << GRAPHICS_DRAWABLE_ID) | b[OBJECT_ID];
|
||||
b[GRAPHICS_TEXTURE_ID] = (one << GRAPHICS_TEXTURE_ID) | b[GRAPHICS_DRAWABLE_ID];
|
||||
b[GRAPHICS_IMAGE_ID] = (one << GRAPHICS_IMAGE_ID) | b[GRAPHICS_TEXTURE_ID];
|
||||
b[GRAPHICS_QUAD_ID] = (one << GRAPHICS_QUAD_ID) | b[OBJECT_ID];
|
||||
b[GRAPHICS_FONT_ID] = (one << GRAPHICS_FONT_ID) | b[OBJECT_ID];
|
||||
b[GRAPHICS_PARTICLE_SYSTEM_ID] = (one << GRAPHICS_PARTICLE_SYSTEM_ID) | b[GRAPHICS_DRAWABLE_ID];
|
||||
b[GRAPHICS_SPRITE_BATCH_ID] = (one << GRAPHICS_SPRITE_BATCH_ID) | b[GRAPHICS_DRAWABLE_ID];
|
||||
b[GRAPHICS_CANVAS_ID] = (one << GRAPHICS_CANVAS_ID) | b[GRAPHICS_TEXTURE_ID];
|
||||
b[GRAPHICS_SHADER_ID] = (one << GRAPHICS_SHADER_ID) | b[OBJECT_ID];
|
||||
b[GRAPHICS_MESH_ID] = (one << GRAPHICS_MESH_ID) | b[GRAPHICS_DRAWABLE_ID];
|
||||
b[GRAPHICS_TEXT_ID] = (one << GRAPHICS_TEXT_ID) | b[GRAPHICS_DRAWABLE_ID];
|
||||
|
||||
// Image.
|
||||
b[IMAGE_IMAGE_DATA_ID] = (one << IMAGE_IMAGE_DATA_ID) | b[DATA_ID];
|
||||
b[IMAGE_COMPRESSED_IMAGE_DATA_ID] = (one << IMAGE_COMPRESSED_IMAGE_DATA_ID) | b[DATA_ID];
|
||||
|
||||
// Joystick.
|
||||
b[JOYSTICK_JOYSTICK_ID] = (one << JOYSTICK_JOYSTICK_ID) | b[OBJECT_ID];
|
||||
|
||||
// Math.
|
||||
b[MATH_RANDOM_GENERATOR_ID] = (one << MATH_RANDOM_GENERATOR_ID) | b[OBJECT_ID];
|
||||
b[MATH_BEZIER_CURVE_ID] = (one << MATH_BEZIER_CURVE_ID) | b[OBJECT_ID];
|
||||
b[MATH_COMPRESSED_DATA_ID] = (one <<MATH_COMPRESSED_DATA_ID) | b[DATA_ID];
|
||||
|
||||
// Audio.
|
||||
b[AUDIO_SOURCE_ID] = (one << AUDIO_SOURCE_ID) | b[OBJECT_ID];
|
||||
|
||||
// Sound.
|
||||
b[SOUND_SOUND_DATA_ID] = (one << SOUND_SOUND_DATA_ID) | b[DATA_ID];
|
||||
b[SOUND_DECODER_ID] = one << SOUND_DECODER_ID;
|
||||
|
||||
// Mouse.
|
||||
b[MOUSE_CURSOR_ID] = (one << MOUSE_CURSOR_ID) | b[OBJECT_ID];
|
||||
|
||||
// Physics.
|
||||
b[PHYSICS_WORLD_ID] = (one << PHYSICS_WORLD_ID) | b[OBJECT_ID];
|
||||
b[PHYSICS_CONTACT_ID] = (one << PHYSICS_CONTACT_ID) | b[OBJECT_ID];
|
||||
b[PHYSICS_BODY_ID] = (one << PHYSICS_BODY_ID) | b[OBJECT_ID];
|
||||
b[PHYSICS_FIXTURE_ID] = (one << PHYSICS_FIXTURE_ID) | b[OBJECT_ID];
|
||||
b[PHYSICS_SHAPE_ID] = (one << PHYSICS_SHAPE_ID) | b[OBJECT_ID];
|
||||
b[PHYSICS_CIRCLE_SHAPE_ID] = (one << PHYSICS_CIRCLE_SHAPE_ID) | b[PHYSICS_SHAPE_ID];
|
||||
b[PHYSICS_POLYGON_SHAPE_ID] = (one << PHYSICS_POLYGON_SHAPE_ID) | b[PHYSICS_SHAPE_ID];
|
||||
b[PHYSICS_EDGE_SHAPE_ID] = (one << PHYSICS_EDGE_SHAPE_ID) | b[PHYSICS_SHAPE_ID];
|
||||
b[PHYSICS_CHAIN_SHAPE_ID] = (one << PHYSICS_CHAIN_SHAPE_ID) | b[PHYSICS_SHAPE_ID];
|
||||
b[PHYSICS_JOINT_ID] = (one << PHYSICS_JOINT_ID) | b[OBJECT_ID];
|
||||
b[PHYSICS_MOUSE_JOINT_ID] = (one << PHYSICS_MOUSE_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_DISTANCE_JOINT_ID] = (one << PHYSICS_DISTANCE_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_PRISMATIC_JOINT_ID] = (one << PHYSICS_PRISMATIC_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_REVOLUTE_JOINT_ID] = (one << PHYSICS_REVOLUTE_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_PULLEY_JOINT_ID] = (one << PHYSICS_PULLEY_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_GEAR_JOINT_ID] = (one << PHYSICS_GEAR_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_FRICTION_JOINT_ID] = (one << PHYSICS_FRICTION_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_WELD_JOINT_ID] = (one << PHYSICS_WELD_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_ROPE_JOINT_ID] = (one << PHYSICS_ROPE_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_WHEEL_JOINT_ID] = (one << PHYSICS_WHEEL_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
b[PHYSICS_MOTOR_JOINT_ID] = (one << PHYSICS_MOTOR_JOINT_ID) | b[PHYSICS_JOINT_ID];
|
||||
|
||||
// Thread.
|
||||
b[THREAD_THREAD_ID] = (one << THREAD_THREAD_ID) | b[OBJECT_ID];
|
||||
b[THREAD_CHANNEL_ID] = (one << THREAD_CHANNEL_ID) | b[OBJECT_ID];
|
||||
|
||||
// Modules.
|
||||
b[MODULE_FILESYSTEM_ID] = (one << MODULE_FILESYSTEM_ID) | b[MODULE_ID];
|
||||
b[MODULE_GRAPHICS_ID] = (one << MODULE_GRAPHICS_ID) | b[MODULE_ID];
|
||||
b[MODULE_IMAGE_ID] = (one << MODULE_IMAGE_ID) | b[MODULE_ID];
|
||||
b[MODULE_SOUND_ID] = (one << MODULE_SOUND_ID) | b[MODULE_ID];
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
const TypeBits *typeFlags = createTypeFlags();
|
||||
|
||||
StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
|
||||
{
|
||||
{"Invalid", INVALID_ID},
|
||||
|
||||
{"Object", OBJECT_ID},
|
||||
{"Data", DATA_ID},
|
||||
{"Module", MODULE_ID},
|
||||
|
||||
// Filesystem
|
||||
{"File", FILESYSTEM_FILE_ID},
|
||||
{"DroppedFile", FILESYSTEM_DROPPED_FILE_ID},
|
||||
{"FileData", FILESYSTEM_FILE_DATA_ID},
|
||||
|
||||
// Font
|
||||
{"GlyphData", FONT_GLYPH_DATA_ID},
|
||||
{"Rasterizer", FONT_RASTERIZER_ID},
|
||||
|
||||
// Graphics
|
||||
{"Drawable", GRAPHICS_DRAWABLE_ID},
|
||||
{"Texture", GRAPHICS_TEXTURE_ID},
|
||||
{"Image", GRAPHICS_IMAGE_ID},
|
||||
{"Quad", GRAPHICS_QUAD_ID},
|
||||
{"Font", GRAPHICS_FONT_ID},
|
||||
{"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID},
|
||||
{"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID},
|
||||
{"Canvas", GRAPHICS_CANVAS_ID},
|
||||
{"Shader", GRAPHICS_SHADER_ID},
|
||||
{"Mesh", GRAPHICS_MESH_ID},
|
||||
{"Text", GRAPHICS_TEXT_ID},
|
||||
|
||||
// Image
|
||||
{"ImageData", IMAGE_IMAGE_DATA_ID},
|
||||
{"CompressedImageData", IMAGE_COMPRESSED_IMAGE_DATA_ID},
|
||||
|
||||
// Joystick
|
||||
{"Joystick", JOYSTICK_JOYSTICK_ID},
|
||||
|
||||
// Math
|
||||
{"RandomGenerator", MATH_RANDOM_GENERATOR_ID},
|
||||
{"BezierCurve", MATH_BEZIER_CURVE_ID},
|
||||
{"CompressedData", MATH_COMPRESSED_DATA_ID},
|
||||
|
||||
// Audio
|
||||
{"Source", AUDIO_SOURCE_ID},
|
||||
|
||||
// Sound
|
||||
{"SoundData", SOUND_SOUND_DATA_ID},
|
||||
{"Decoder", SOUND_DECODER_ID},
|
||||
|
||||
// Mouse
|
||||
{"Cursor", MOUSE_CURSOR_ID},
|
||||
|
||||
// Physics
|
||||
{"World", PHYSICS_WORLD_ID},
|
||||
{"Contact", PHYSICS_CONTACT_ID},
|
||||
{"Body", PHYSICS_BODY_ID},
|
||||
{"Fixture", PHYSICS_FIXTURE_ID},
|
||||
{"Shape", PHYSICS_SHAPE_ID},
|
||||
{"CircleShape", PHYSICS_CIRCLE_SHAPE_ID},
|
||||
{"PolygonShape", PHYSICS_POLYGON_SHAPE_ID},
|
||||
{"EdgeShape", PHYSICS_EDGE_SHAPE_ID},
|
||||
{"ChainShape", PHYSICS_CHAIN_SHAPE_ID},
|
||||
{"Joint", PHYSICS_JOINT_ID},
|
||||
{"MouseJoint", PHYSICS_MOUSE_JOINT_ID},
|
||||
{"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID},
|
||||
{"PrismaticJoint", PHYSICS_PRISMATIC_JOINT_ID},
|
||||
{"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID},
|
||||
{"PulleyJoint", PHYSICS_PULLEY_JOINT_ID},
|
||||
{"GearJoint", PHYSICS_GEAR_JOINT_ID},
|
||||
{"FrictionJoint", PHYSICS_FRICTION_JOINT_ID},
|
||||
{"WeldJoint", PHYSICS_WELD_JOINT_ID},
|
||||
{"RopeJoint", PHYSICS_ROPE_JOINT_ID},
|
||||
{"WheelJoint", PHYSICS_WHEEL_JOINT_ID},
|
||||
{"MotorJoint", PHYSICS_MOTOR_JOINT_ID},
|
||||
|
||||
// Thread
|
||||
{"Thread", THREAD_THREAD_ID},
|
||||
{"Channel", THREAD_CHANNEL_ID},
|
||||
|
||||
// The modules themselves. Only add abstracted modules here.
|
||||
{"filesystem", MODULE_FILESYSTEM_ID},
|
||||
{"graphics", MODULE_GRAPHICS_ID},
|
||||
{"image", MODULE_IMAGE_ID},
|
||||
{"sound", MODULE_SOUND_ID},
|
||||
};
|
||||
|
||||
StringMap<Type, TYPE_MAX_ENUM> types(typeEntries, sizeof(typeEntries));
|
||||
|
||||
static_assert((sizeof(typeEntries) / sizeof(typeEntries[0])) == TYPE_MAX_ENUM, "Type name array size doesn't match the total number of type IDs!");
|
||||
|
||||
bool getType(const char *in, love::Type &out)
|
||||
{
|
||||
return types.find(in, out);
|
||||
}
|
||||
|
||||
bool getType(love::Type in, const char *&out)
|
||||
{
|
||||
return types.find(in, out);
|
||||
}
|
||||
|
||||
} // love
|
||||
+10
-81
@@ -37,6 +37,7 @@ enum Type
|
||||
|
||||
// Filesystem.
|
||||
FILESYSTEM_FILE_ID,
|
||||
FILESYSTEM_DROPPED_FILE_ID,
|
||||
FILESYSTEM_FILE_DATA_ID,
|
||||
|
||||
// Font
|
||||
@@ -54,10 +55,11 @@ enum Type
|
||||
GRAPHICS_CANVAS_ID,
|
||||
GRAPHICS_SHADER_ID,
|
||||
GRAPHICS_MESH_ID,
|
||||
GRAPHICS_TEXT_ID,
|
||||
|
||||
// Image
|
||||
IMAGE_IMAGE_DATA_ID,
|
||||
IMAGE_COMPRESSED_DATA_ID,
|
||||
IMAGE_COMPRESSED_IMAGE_DATA_ID,
|
||||
|
||||
// Joystick
|
||||
JOYSTICK_JOYSTICK_ID,
|
||||
@@ -65,6 +67,7 @@ enum Type
|
||||
// Math
|
||||
MATH_RANDOM_GENERATOR_ID,
|
||||
MATH_BEZIER_CURVE_ID,
|
||||
MATH_COMPRESSED_DATA_ID,
|
||||
|
||||
// Audio
|
||||
AUDIO_SOURCE_ID,
|
||||
@@ -113,89 +116,15 @@ enum Type
|
||||
TYPE_MAX_ENUM
|
||||
};
|
||||
|
||||
typedef std::bitset<TYPE_MAX_ENUM> bits;
|
||||
typedef std::bitset<TYPE_MAX_ENUM> TypeBits;
|
||||
|
||||
const bits INVALID_T = bits(1) << INVALID_ID;
|
||||
|
||||
const bits OBJECT_T = bits(1) << OBJECT_ID;
|
||||
const bits DATA_T = (bits(1) << DATA_ID) | OBJECT_T;
|
||||
const bits MODULE_T = (bits(1) << MODULE_ID) | OBJECT_T;
|
||||
|
||||
// Filesystem.
|
||||
const bits FILESYSTEM_FILE_T = (bits(1) << FILESYSTEM_FILE_ID) | OBJECT_T;
|
||||
const bits FILESYSTEM_FILE_DATA_T = (bits(1) << FILESYSTEM_FILE_DATA_ID) | DATA_T;
|
||||
|
||||
const bits FONT_GLYPH_DATA_T = (bits(1) << FONT_GLYPH_DATA_ID) | DATA_T;
|
||||
const bits FONT_RASTERIZER_T = (bits(1) << FONT_RASTERIZER_ID) | OBJECT_T;
|
||||
|
||||
// Graphics.
|
||||
const bits GRAPHICS_DRAWABLE_T = (bits(1) << GRAPHICS_DRAWABLE_ID) | OBJECT_T;
|
||||
const bits GRAPHICS_TEXTURE_T = (bits(1) << GRAPHICS_TEXTURE_ID) | GRAPHICS_DRAWABLE_T;
|
||||
const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_TEXTURE_T;
|
||||
const bits GRAPHICS_QUAD_T = (bits(1) << GRAPHICS_QUAD_ID) | OBJECT_T;
|
||||
const bits GRAPHICS_FONT_T = (bits(1) << GRAPHICS_FONT_ID) | OBJECT_T;
|
||||
const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T;
|
||||
const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T;
|
||||
const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_TEXTURE_T;
|
||||
const bits GRAPHICS_SHADER_T = (bits(1) << GRAPHICS_SHADER_ID) | OBJECT_T;
|
||||
const bits GRAPHICS_MESH_T = (bits(1) << GRAPHICS_MESH_ID) | GRAPHICS_DRAWABLE_T;
|
||||
|
||||
// Image.
|
||||
const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;
|
||||
const bits IMAGE_COMPRESSED_DATA_T = (bits(1) << IMAGE_COMPRESSED_DATA_ID) | DATA_T;
|
||||
|
||||
// Joystick.
|
||||
const bits JOYSTICK_JOYSTICK_T = (bits(1) << JOYSTICK_JOYSTICK_ID) | OBJECT_T;
|
||||
|
||||
// Math.
|
||||
const bits MATH_RANDOM_GENERATOR_T = (bits(1) << MATH_RANDOM_GENERATOR_ID) | OBJECT_T;
|
||||
const bits MATH_BEZIER_CURVE_T = (bits(1) << MATH_BEZIER_CURVE_ID) | OBJECT_T;
|
||||
|
||||
// Audio.
|
||||
const bits AUDIO_SOURCE_T = (bits(1) << AUDIO_SOURCE_ID) | OBJECT_T;
|
||||
|
||||
// Sound.
|
||||
const bits SOUND_SOUND_DATA_T = (bits(1) << SOUND_SOUND_DATA_ID) | DATA_T;
|
||||
const bits SOUND_DECODER_T = bits(1) << SOUND_DECODER_ID;
|
||||
|
||||
// Mouse.
|
||||
const bits MOUSE_CURSOR_T = (bits(1) << MOUSE_CURSOR_ID) | OBJECT_T;
|
||||
|
||||
// Physics.
|
||||
const bits PHYSICS_WORLD_T = (bits(1) << PHYSICS_WORLD_ID) | OBJECT_T;
|
||||
const bits PHYSICS_CONTACT_T = (bits(1) << PHYSICS_CONTACT_ID) | OBJECT_T;
|
||||
const bits PHYSICS_BODY_T = (bits(1) << PHYSICS_BODY_ID) | OBJECT_T;
|
||||
const bits PHYSICS_FIXTURE_T = (bits(1) << PHYSICS_FIXTURE_ID) | OBJECT_T;
|
||||
const bits PHYSICS_SHAPE_T = (bits(1) << PHYSICS_SHAPE_ID) | OBJECT_T;
|
||||
const bits PHYSICS_CIRCLE_SHAPE_T = (bits(1) << PHYSICS_CIRCLE_SHAPE_ID) | PHYSICS_SHAPE_T;
|
||||
const bits PHYSICS_POLYGON_SHAPE_T = (bits(1) << PHYSICS_POLYGON_SHAPE_ID) | PHYSICS_SHAPE_T;
|
||||
const bits PHYSICS_EDGE_SHAPE_T = (bits(1) << PHYSICS_EDGE_SHAPE_ID) | PHYSICS_SHAPE_T;
|
||||
const bits PHYSICS_CHAIN_SHAPE_T = (bits(1) << PHYSICS_CHAIN_SHAPE_ID) | PHYSICS_SHAPE_T;
|
||||
const bits PHYSICS_JOINT_T = (bits(1) << PHYSICS_JOINT_ID) | OBJECT_T;
|
||||
const bits PHYSICS_MOUSE_JOINT_T = (bits(1) << PHYSICS_MOUSE_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_DISTANCE_JOINT_T = (bits(1) << PHYSICS_DISTANCE_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_PRISMATIC_JOINT_T = (bits(1) << PHYSICS_PRISMATIC_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_REVOLUTE_JOINT_T = (bits(1) << PHYSICS_REVOLUTE_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_PULLEY_JOINT_T = (bits(1) << PHYSICS_PULLEY_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_GEAR_JOINT_T = (bits(1) << PHYSICS_GEAR_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_FRICTION_JOINT_T = (bits(1) << PHYSICS_FRICTION_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_WELD_JOINT_T = (bits(1) << PHYSICS_WELD_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_ROPE_JOINT_T = (bits(1) << PHYSICS_ROPE_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_WHEEL_JOINT_T = (bits(1) << PHYSICS_WHEEL_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
const bits PHYSICS_MOTOR_JOINT_T = (bits(1) << PHYSICS_MOTOR_JOINT_ID) | PHYSICS_JOINT_T;
|
||||
|
||||
// Thread.
|
||||
const bits THREAD_THREAD_T = (bits(1) << THREAD_THREAD_ID) | OBJECT_T;
|
||||
const bits THREAD_CHANNEL_T = (bits(1) << THREAD_CHANNEL_ID) | OBJECT_T;
|
||||
|
||||
// Modules.
|
||||
const bits MODULE_FILESYSTEM_T = (bits(1) << MODULE_FILESYSTEM_ID) | MODULE_T;
|
||||
const bits MODULE_GRAPHICS_T = (bits(1) << MODULE_GRAPHICS_ID) | MODULE_T;
|
||||
const bits MODULE_IMAGE_T = (bits(1) << MODULE_IMAGE_ID) | MODULE_T;
|
||||
const bits MODULE_SOUND_T = (bits(1) << MODULE_SOUND_ID) | MODULE_T;
|
||||
/**
|
||||
* Array of length TYPE_MAX_ENUM containing the flags for each love Type.
|
||||
**/
|
||||
extern const TypeBits *typeFlags;
|
||||
|
||||
bool getType(const char *in, Type &out);
|
||||
bool getType(Type in, const char *&out);
|
||||
bool getType(Type in, const char *&out);
|
||||
|
||||
} // love
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ namespace love
|
||||
{
|
||||
|
||||
// Version stuff.
|
||||
#define LOVE_VERSION_STRING "0.9.2"
|
||||
const int VERSION_MAJOR = 0;
|
||||
const int VERSION_MINOR = 9;
|
||||
const int VERSION_REV = 2;
|
||||
const char *VERSION = LOVE_VERSION_STRING;
|
||||
const char *VERSION_COMPATIBILITY[] = { VERSION, "0.9.1", "0.9.0", 0 };
|
||||
const char *VERSION_CODENAME = "Baby Inspector";
|
||||
#define LOVE_VERSION_STRING "0.10.0"
|
||||
static const int VERSION_MAJOR = 0;
|
||||
static const int VERSION_MINOR = 10;
|
||||
static const int VERSION_REV = 0;
|
||||
static const char *VERSION = LOVE_VERSION_STRING;
|
||||
static const char *VERSION_COMPATIBILITY[] = { VERSION, 0 };
|
||||
static const char *VERSION_CODENAME = "";
|
||||
|
||||
} // love
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace love
|
||||
|
||||
Data *luax_checkdata(lua_State *L, int idx)
|
||||
{
|
||||
return luax_checktype<Data>(L, idx, "Data", DATA_T);
|
||||
return luax_checktype<Data>(L, idx, DATA_ID);
|
||||
}
|
||||
|
||||
int w_Data_getString(lua_State *L)
|
||||
@@ -59,7 +59,7 @@ const luaL_Reg w_Data_functions[] =
|
||||
|
||||
int w_Data_open(lua_State *L)
|
||||
{
|
||||
luax_register_type(L, "Data", w_Data_functions);
|
||||
luax_register_type(L, DATA_ID, w_Data_functions);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user