Better management of the lua element and other ==> garbage collector to down the number of malloc and free

This commit is contained in:
Edouard Dupin 2012-06-03 10:28:49 +02:00
parent 43ce5cf436
commit 0c1b391b19
7 changed files with 275 additions and 50 deletions

View File

@ -44,6 +44,8 @@ ewol::GameElement::GameElement(SceneElement & sceneElement, etk::UString& tmpNam
m_size = 64.0;
m_angle = 0.0;
m_gravity = 0.0;
m_fileNameConfig = tmpName;
m_canBeCibled = false;
}

View File

@ -49,6 +49,7 @@ namespace ewol {
etkFloat_t m_size;
etkFloat_t m_angle;
etkFloat_t m_gravity;
bool m_canBeCibled;
public:
/**
* @brief Constructor : here are requested all the needed sprite and effect that can be used in the game
@ -63,6 +64,9 @@ namespace ewol {
*/
virtual ~GameElement(void) { };
virtual void Init(void) { };
virtual void UnInit(void) { };
uint16_t GetUniqueId(void) { return m_uniqueId; };
bool HasName(etk::UString tmpName) { return (tmpName == m_fileNameConfig); };
@ -82,6 +86,8 @@ namespace ewol {
void GravitySet(etkFloat_t state) { m_gravity = state; };
int32_t PowerGet(void) { return m_power; };
void PowerSet(int32_t state) { m_power = state; };
bool CanBeCibledGet(void) { return m_canBeCibled; };
void CanBeCibledSet(bool state) { m_canBeCibled = state; };
int32_t GetType(void) { return m_type; }; // DEPRECATED ...
int32_t TypeGet(void) { return m_type; };

View File

@ -267,14 +267,45 @@ LUAMOD_API int lua_SetSize(lua_State *L)
if (NULL==tmpObj) {
EWOL_ERROR("NULL obj...");
lua_pushnumber(L, 0 );
return 1;
return 0;
}
etkFloat_t value = luaL_checknumber(L, 1);
tmpObj->SizeSet(value);
// return number of parameters
return 0;
}
LUAMOD_API int lua_GetCanBeCibled(lua_State *L)
{
if (NULL==tmpObj) {
EWOL_ERROR("NULL obj...");
lua_pushboolean(L, false );
return 1;
}
etkFloat_t value = tmpObj->CanBeCibledGet();
lua_pushboolean(L, value );
// return number of parameters
return 1;
}
LUAMOD_API int lua_SetCanBeCibled(lua_State *L)
{
if (NULL==tmpObj) {
EWOL_ERROR("NULL obj...");
return 0;
}
bool value = false;
if ( lua_isboolean( L, 1 ) ) {
value = lua_toboolean( L, 1 );
}
tmpObj->CanBeCibledSet(value);
// return number of parameters
return 0;
}
LUAMOD_API int lua_SpriteLoad(lua_State *L)
{
//LUA : int SpriteLoad("fileName", maxSize); => -1 in error ...
@ -457,9 +488,6 @@ LUAMOD_API int lua_GetNearestEnemy(lua_State *L)
return 1;
}
uint32_t elementId = tmpScene->GetNearestEnemy(tmpObj->PositionGet(), tmpObj->GroupGet());
if (0==elementId) {
EWOL_ERROR("Error getting enemy ...");
}
lua_pushinteger(L, elementId );
// return number of parameters
return 1;
@ -553,6 +581,8 @@ static const luaL_Reg functionsTable[] = {
{ "SetSize", lua_SetSize },
{ "GetPower", lua_GetPower },
{ "SetPower", lua_SetPower },
{ "GetCanBeCibled", lua_GetCanBeCibled },
{ "SetCanBeCibled", lua_SetCanBeCibled },
// other element section
{ "ElementAdd", lua_ElementAdd },
{ "ElementExisted", lua_ElmentExisted },
@ -644,28 +674,49 @@ ewol::GameElementLua::GameElementLua(ewol::SceneElement & sceneElement, etk::USt
EWOL_ERROR("LUA: " << lua_tostring(m_luaState, -1));
return;
}
// call the init function
lua_getglobal(m_luaState, "Init");
if(!lua_isfunction(m_luaState,-1)) {
EWOL_WARNING("LUA: Not Find Init function ");
lua_pop(m_luaState,1);
} else {
// do the call (0 arguments, 0 result)
if (lua_pcall(m_luaState, 0, 0, 0) != 0) {
EWOL_ERROR("LUA: error running function 'Init':" << lua_tostring(m_luaState, -1));
return;
}
}
/*
EWOL_INFO("retreave element : " << *myValue << " and : " << *myBool);
*/
tmpObj = NULL;
tmpScene = NULL;
Init();
}
ewol::GameElementLua::~GameElementLua(void)
{
UnInit();
if (NULL != m_luaState) {
lua_close(m_luaState);
m_luaState = NULL;
}
}
void ewol::GameElementLua::Init(void)
{
tmpObj = this;
tmpScene = &m_sceneElement;
if (NULL != m_luaState) {
// call the init function
lua_getglobal(m_luaState, "Init");
if(!lua_isfunction(m_luaState,-1)) {
EWOL_WARNING("LUA: Not Find Init function ");
lua_pop(m_luaState,1);
} else {
// do the call (0 arguments, 0 result)
if (lua_pcall(m_luaState, 0, 0, 0) != 0) {
EWOL_ERROR("LUA: error running function 'Init':" << lua_tostring(m_luaState, -1));
return;
}
}
}
tmpObj = NULL;
tmpScene = NULL;
}
void ewol::GameElementLua::UnInit(void)
{
tmpObj = this;
tmpScene = &m_sceneElement;
@ -681,8 +732,6 @@ ewol::GameElementLua::~GameElementLua(void)
EWOL_ERROR("LUA: error running function 'UnInit':" << lua_tostring(m_luaState, -1));
}
}
lua_close(m_luaState);
m_luaState = NULL;
}
tmpObj = NULL;
tmpScene = NULL;
@ -845,4 +894,35 @@ void ewol::GameElementLua::Message(etk::UString control, etk::UString message)
tmpObj = NULL;
}
static ewol::GameElement* LoadSceneElement_lua(ewol::SceneElement & sceneElement, etk::UString& elementName, etk::UString& userString)
{
// try to find the file :
etk::UString tmpName = userString;
tmpName += elementName;
tmpName += ".lua";
// added a new element :
etk::File fileElement(tmpName, etk::FILE_TYPE_DATA);
if (false == fileElement.Exist()) {
EWOL_ERROR("Can not find Game element : " << elementName << " ==> " << tmpName);
return NULL;
}
EWOL_VERBOSE("We find Game element : " << elementName << " ==> " << tmpName);
ewol::GameElementLua * tmpElement = new ewol::GameElementLua(sceneElement, tmpName);
if (NULL == tmpElement) {
EWOL_ERROR("Can not Allocat : " << elementName);
return NULL;
}
return tmpElement;
}
void ewol::RegisterLuaElementInFolder(ewol::SceneElement & sceneElement, etk::UString folder)
{
// TODO : parsing the folder ...
sceneElement.RegisterElementType("??????", &LoadSceneElement_lua, folder);
}
void ewol::RegisterLuaElementSpecify(ewol::SceneElement & sceneElement, etk::UString folder, etk::UString name)
{
sceneElement.RegisterElementType(name, &LoadSceneElement_lua, folder);
}

View File

@ -40,14 +40,19 @@ namespace ewol {
private:
lua_State *m_luaState; // internal Lua state
public:
GameElementLua(ewol::SceneElement & sceneElement, etk::UString& tmpName, int32_t group);
GameElementLua(ewol::SceneElement & sceneElement, etk::UString& tmpName, int32_t group = 0);
~GameElementLua(void);
virtual void Init(void);
virtual void UnInit(void);
virtual bool Process(int64_t time, int32_t deltaTime, ewol::SceneElement & sceneElement);
virtual void Draw(etk::VectorType<ewol::Sprite*> & listOfSprite, etk::VectorType<ewol::Sprite*> & listOfEffects);
virtual bool HaveImpact(int32_t group, int32_t type, coord2D_ts position, etkFloat_t size);
virtual void Explosion(int32_t group, int32_t type, coord2D_ts position, etkFloat_t pxAtenuation, etkFloat_t power);
virtual void Message(etk::UString control, etk::UString message);
};
void RegisterLuaElementInFolder(ewol::SceneElement & sceneElement, etk::UString folder);
void RegisterLuaElementSpecify(ewol::SceneElement & sceneElement, etk::UString folder, etk::UString name);
};
#endif

View File

@ -42,7 +42,108 @@ ewol::SceneElement::SceneElement(void)
groupEnemy[iii][jjj] = -1;
}
}
};
retreviveElement = 0;
allocatedElements = 0;
}
ewol::SceneElement::~SceneElement(void)
{
EWOL_DEBUG("Remove sceane, allocated element : " << allocatedElements << " and retreive : " << retreviveElement);
// clean all element allocated :
for (int32_t jjj=0; jjj<listGarbage.Size(); jjj++) {
if (NULL != listGarbage[jjj]) {
delete(listGarbage[jjj]);
listGarbage[jjj] = NULL;
}
}
listGarbage.Clear();
for (int32_t jjj=0; jjj<listCreatorElement.Size(); jjj++) {
if (NULL != listCreatorElement[jjj]) {
delete(listCreatorElement[jjj]);
listCreatorElement[jjj] = NULL;
}
}
listCreatorElement.Clear();
for (int32_t iii=0; iii<MAX_GROUP_NUMBER; iii++) {
for (int32_t jjj=0; jjj<listAnimatedElements[iii].Size(); jjj++) {
if (NULL != listAnimatedElements[iii][jjj]) {
delete(listAnimatedElements[iii][jjj]);
listAnimatedElements[iii][jjj] = NULL;
}
}
listAnimatedElements[iii].Clear();
}
for (int32_t iii=0; iii<NB_BOUBLE_BUFFER; iii++) {
for (int32_t jjj=0; jjj<backgroundElements[iii].Size(); jjj++) {
if (NULL != backgroundElements[iii][jjj]) {
delete(backgroundElements[iii][jjj]);
backgroundElements[iii][jjj] = NULL;
}
}
backgroundElements[iii].Clear();
}
for (int32_t iii=0; iii<NB_BOUBLE_BUFFER; iii++) {
for (int32_t jjj=0; jjj<animated[iii].Size(); jjj++) {
if (NULL != animated[iii][jjj]) {
delete(animated[iii][jjj]);
animated[iii][jjj] = NULL;
}
}
animated[iii].Clear();
}
for (int32_t iii=0; iii<NB_BOUBLE_BUFFER; iii++) {
for (int32_t jjj=0; jjj<effects[iii].Size(); jjj++) {
if (NULL != effects[iii][jjj]) {
delete(effects[iii][jjj]);
effects[iii][jjj] = NULL;
}
}
effects[iii].Clear();
}
}
void ewol::SceneElement::RegisterElementType(etk::UString name, creatorElement_tf * loadElement, etk::UString userString)
{
// TODO : Check if the element already existed
ewol::listRegisteElement * tmpElement = new listRegisteElement();
if (NULL == tmpElement) {
EWOL_ERROR("Memory error in allocation registered element");
return;
}
tmpElement->name = name;
tmpElement->userString = userString;
tmpElement->loadElement = loadElement;
listCreatorElement.PushBack(tmpElement);
}
void ewol::SceneElement::RmElement(int32_t group, int32_t idElement)
{
if (group < 0 || group >= MAX_GROUP_NUMBER) {
EWOL_ERROR("group is wrong " << group << "!=[0," << MAX_GROUP_NUMBER << "]==> not rm at the system ...");
return;
}
if (idElement < 0 || idElement >= listAnimatedElements[group].Size()) {
EWOL_ERROR("idElement is wrong " << idElement << "!=[0," << listAnimatedElements[group].Size() << "]==> not rm at the system ...");
return;
}
if (NULL == listAnimatedElements[group][idElement]) {
return;
}
// try to find an empty slot :
for (int32_t iii=0; iii<listGarbage.Size(); iii++) {
if (NULL == listGarbage[iii]) {
// find an empty slot ...
listGarbage[iii] = listAnimatedElements[group][idElement];
listAnimatedElements[group][idElement] = NULL;
return;
}
}
listAnimatedElements[group][idElement]->UnInit();
listGarbage.PushBack(listAnimatedElements[group][idElement]);
listAnimatedElements[group][idElement] = NULL;
return;
}
uint32_t ewol::SceneElement::AddElement(int32_t group, ewol::GameElement* newElement)
{
@ -54,6 +155,9 @@ uint32_t ewol::SceneElement::AddElement(int32_t group, ewol::GameElement* newEle
EWOL_ERROR("group is wrong " << group << "!=[0," << MAX_GROUP_NUMBER << "]==> not added at the system ...");
return 0;
}
// for statistic
newElement->GroupSet(group);
newElement->Init();
for (int32_t iii=0; iii<listAnimatedElements[group].Size(); iii++) {
if (NULL == listAnimatedElements[group][iii]) {
// find an empty slot ...
@ -72,22 +176,34 @@ uint32_t ewol::SceneElement::AddElement(int32_t group, ewol::GameElement* newEle
uint32_t ewol::SceneElement::AddElementNamed(int32_t group, etk::UString &elementName)
{
// try to find the file :
etk::UString tmpName = "elementGame/";
tmpName += elementName;
tmpName += ".lua";
etk::File fileElement(tmpName, etk::FILE_TYPE_DATA);
if (false == fileElement.Exist()) {
EWOL_ERROR("Can not find Game element : " << elementName << " ==> " << tmpName);
return 0;
// try to fined it in the garbase :
for (int32_t iii=0; iii<listGarbage.Size(); iii++) {
if (NULL != listGarbage[iii]) {
// check his name :
if (true == listGarbage[iii]->HasName(elementName)) {
// we find a previous element loaded ==> retreve it
int32_t idElementBackAdded = AddElement(group, listGarbage[iii]);
listGarbage[iii] = NULL;
retreviveElement++;
return idElementBackAdded;
}
}
}
EWOL_VERBOSE("We find Game element : " << elementName << " ==> " << tmpName);
ewol::GameElementLua * tmpElement = new ewol::GameElementLua(*this, tmpName, group);
if (NULL == tmpElement) {
EWOL_ERROR("Can not Allocat : " << elementName);
return 0;
ewol::GameElement* newElement=NULL;
// find in registered element
for (int32_t iii=0; iii<listCreatorElement.Size(); iii++) {
if (NULL != listCreatorElement[iii]) {
// check his name :
if (listCreatorElement[iii]->name == elementName) {
// create a new element :
newElement = (*listCreatorElement[iii]->loadElement)(*this, elementName, listCreatorElement[iii]->userString);
// we find a previous element loaded ==> retreve it
return AddElement(group, newElement);
}
}
}
return AddElement(group, tmpElement);
allocatedElements++;
return AddElement(group, newElement);
}
@ -121,11 +237,13 @@ uint32_t ewol::SceneElement::GetNearestEnemy(coord2D_ts position, int32_t groupI
while (groupEnemy[groupId][jjj] != -1) {
for (int32_t iii=0; iii<listAnimatedElements[groupEnemy[groupId][jjj]].Size(); iii++) {
if (NULL != listAnimatedElements[groupEnemy[groupId][jjj]][iii]) {
coord2D_ts tmpPos = listAnimatedElements[groupEnemy[groupId][jjj]][iii]->PositionGet();
etkFloat_t distance = quadDist(position, tmpPos);
if (distance <= lastQuadDistance) {
lastQuadDistance = distance;
result = createUniqueId(listAnimatedElements[groupEnemy[groupId][jjj]][iii]->GetUniqueId(), iii);
if (true == listAnimatedElements[groupEnemy[groupId][jjj]][iii]->CanBeCibledGet()) {
coord2D_ts tmpPos = listAnimatedElements[groupEnemy[groupId][jjj]][iii]->PositionGet();
etkFloat_t distance = quadDist(position, tmpPos);
if (distance <= lastQuadDistance) {
lastQuadDistance = distance;
result = createUniqueId(listAnimatedElements[groupEnemy[groupId][jjj]][iii]->GetUniqueId(), iii);
}
}
}
}

View File

@ -31,6 +31,7 @@
namespace ewol {
class GameElement;
class SceneElement;
typedef struct {
uint32_t id; //!< unique id of the element
@ -42,22 +43,36 @@ namespace ewol {
etkFloat_t angle; //!< element angle
} gameElementGenericProperty_ts;
typedef ewol::GameElement* (creatorElement_tf)(SceneElement & sceneElement, etk::UString& tmpName, etk::UString& userString);
class listRegisteElement {
public:
etk::UString name; //!< name of an element
etk::UString userString; //!< additionnal sting defined by the user
creatorElement_tf * loadElement; //!< callback function to create it
};
#define MAX_GROUP_NUMBER (32)
class SceneElement {
private:
int16_t m_id; //!< Unique element ID ==> to reference the element unicly
int32_t retreviveElement;
int32_t allocatedElements;
public:
SceneElement(void);
~SceneElement(void) { };
int32_t numberOfGroup; //!< curent scene number of group
etk::UString groupDescription[MAX_GROUP_NUMBER]; //!< name of all the groups
int32_t groupEnemy[MAX_GROUP_NUMBER][MAX_GROUP_NUMBER]; //!< list of the ennemy
etk::VectorType<ewol::OObject*> backgroundElements[NB_BOUBLE_BUFFER]; //!< element that must be display the first
etk::VectorType<ewol::Sprite*> animated[NB_BOUBLE_BUFFER]; //!< element that must be display the second
etk::VectorType<ewol::Sprite*> effects[NB_BOUBLE_BUFFER]; //!< element that must be display the third
etk::VectorType<ewol::GameElement*> listAnimatedElements[MAX_GROUP_NUMBER]; //!< generic element to display order in the diffferent group
~SceneElement(void);
int32_t numberOfGroup; //!< curent scene number of group
etk::UString groupDescription[MAX_GROUP_NUMBER]; //!< name of all the groups
int32_t groupEnemy[MAX_GROUP_NUMBER][MAX_GROUP_NUMBER]; //!< list of the ennemy
etk::VectorType<ewol::OObject*> backgroundElements[NB_BOUBLE_BUFFER]; //!< element that must be display the first
etk::VectorType<ewol::Sprite*> animated[NB_BOUBLE_BUFFER]; //!< element that must be display the second
etk::VectorType<ewol::Sprite*> effects[NB_BOUBLE_BUFFER]; //!< element that must be display the third
etk::VectorType<ewol::GameElement*> listAnimatedElements[MAX_GROUP_NUMBER]; //!< generic element to display order in the diffferent group
etk::VectorType<ewol::GameElement*> listGarbage; //!< garbage of the old element allocated ==> prevent multiple alloc and free
etk::VectorType<listRegisteElement*> listCreatorElement; //!< list of all creatable elements
int16_t GetUniqueId(void) { int16_t iddd = m_id; m_id++; return iddd; };
void RegisterElementType(etk::UString name, creatorElement_tf * loadElement, etk::UString userString);
void RmElement(int32_t group, int32_t idElement);
uint32_t AddElement(int32_t group, ewol::GameElement* newElement);
uint32_t AddElementNamed(int32_t group, etk::UString &elementName);
ewol::GameElement* GetElement(uint32_t idElement);

View File

@ -180,8 +180,7 @@ void ewol::Scene::PeriodicCall(int64_t localTime)
if (NULL != m_sceneElement.listAnimatedElements[jjj][iii]) {
// check if the element request an auto Kill ...
if (true == m_sceneElement.listAnimatedElements[jjj][iii]->Process(m_lastCallTime, CYCLIC_CALL_PERIODE_US, m_sceneElement) ) {
delete(m_sceneElement.listAnimatedElements[jjj][iii]);
m_sceneElement.listAnimatedElements[jjj][iii] = NULL;
m_sceneElement.RmElement(jjj, iii);
}
}
}