From 0c1b391b193897bce5c9df38f84f3d61ee800ce6 Mon Sep 17 00:00:00 2001 From: Edouard Dupin Date: Sun, 3 Jun 2012 10:28:49 +0200 Subject: [PATCH] Better management of the lua element and other ==> garbage collector to down the number of malloc and free --- Sources/libewol/ewol/Game/GameElement.cpp | 2 + Sources/libewol/ewol/Game/GameElement.h | 6 + Sources/libewol/ewol/Game/GameElementLua.cpp | 118 +++++++++++--- Sources/libewol/ewol/Game/GameElementLua.h | 7 +- Sources/libewol/ewol/Game/SceneElement.cpp | 158 ++++++++++++++++--- Sources/libewol/ewol/Game/SceneElement.h | 31 +++- Sources/libewol/ewol/widget/Scene.cpp | 3 +- 7 files changed, 275 insertions(+), 50 deletions(-) diff --git a/Sources/libewol/ewol/Game/GameElement.cpp b/Sources/libewol/ewol/Game/GameElement.cpp index 031e633f..483f7b31 100644 --- a/Sources/libewol/ewol/Game/GameElement.cpp +++ b/Sources/libewol/ewol/Game/GameElement.cpp @@ -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; } diff --git a/Sources/libewol/ewol/Game/GameElement.h b/Sources/libewol/ewol/Game/GameElement.h index 7ae511f7..4727bcc3 100644 --- a/Sources/libewol/ewol/Game/GameElement.h +++ b/Sources/libewol/ewol/Game/GameElement.h @@ -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; }; diff --git a/Sources/libewol/ewol/Game/GameElementLua.cpp b/Sources/libewol/ewol/Game/GameElementLua.cpp index a7eb40bc..88591fd8 100644 --- a/Sources/libewol/ewol/Game/GameElementLua.cpp +++ b/Sources/libewol/ewol/Game/GameElementLua.cpp @@ -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); +} diff --git a/Sources/libewol/ewol/Game/GameElementLua.h b/Sources/libewol/ewol/Game/GameElementLua.h index 604bd64d..79745930 100644 --- a/Sources/libewol/ewol/Game/GameElementLua.h +++ b/Sources/libewol/ewol/Game/GameElementLua.h @@ -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 & listOfSprite, etk::VectorType & 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 diff --git a/Sources/libewol/ewol/Game/SceneElement.cpp b/Sources/libewol/ewol/Game/SceneElement.cpp index ec777bfd..ff2c1c01 100644 --- a/Sources/libewol/ewol/Game/SceneElement.cpp +++ b/Sources/libewol/ewol/Game/SceneElement.cpp @@ -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; jjjname = 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; iiiUnInit(); + 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 " << tmpName); - return 0; + // try to fined it in the garbase : + for (int32_t iii=0; iiiHasName(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; iiiname == 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; iiiPositionGet(); - 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); + } } } } diff --git a/Sources/libewol/ewol/Game/SceneElement.h b/Sources/libewol/ewol/Game/SceneElement.h index e894663d..2d0da9a1 100644 --- a/Sources/libewol/ewol/Game/SceneElement.h +++ b/Sources/libewol/ewol/Game/SceneElement.h @@ -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 backgroundElements[NB_BOUBLE_BUFFER]; //!< element that must be display the first - etk::VectorType animated[NB_BOUBLE_BUFFER]; //!< element that must be display the second - etk::VectorType effects[NB_BOUBLE_BUFFER]; //!< element that must be display the third - etk::VectorType 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 backgroundElements[NB_BOUBLE_BUFFER]; //!< element that must be display the first + etk::VectorType animated[NB_BOUBLE_BUFFER]; //!< element that must be display the second + etk::VectorType effects[NB_BOUBLE_BUFFER]; //!< element that must be display the third + etk::VectorType listAnimatedElements[MAX_GROUP_NUMBER]; //!< generic element to display order in the diffferent group + etk::VectorType listGarbage; //!< garbage of the old element allocated ==> prevent multiple alloc and free + etk::VectorType 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); diff --git a/Sources/libewol/ewol/widget/Scene.cpp b/Sources/libewol/ewol/widget/Scene.cpp index 231b9fbc..417a0484 100644 --- a/Sources/libewol/ewol/widget/Scene.cpp +++ b/Sources/libewol/ewol/widget/Scene.cpp @@ -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); } } }