2012-11-23 2 views
1

Я использую Lua и LuaBridge с Allegro 5. Я решил перенести все графические объекты в Lua, но я сталкиваюсь с некоторыми проблемами:Функция Lua OOP не называется?

класс символов, который вызывается один раз

Character = {sprite; AI} 

function Character:new() 
    o = o or {} -- works! 
    setmetatable(o, self) -- works! 
    self.__index = self -- works! 
    return o -- works! 
end 

function Character:LoadSprite(filename) 
    self.sprite = self.sprite or Bitmap() -- works! 
    self.sprite:LoadFile(filename) -- works! 
    self.sprite.x = 0 -- works! 
    self.sprite.y = 0 --works! 
end 

function Character:SetX(xx) 
    self.sprite.x = xx -- maybe? cannot tell if it works or not. 
end 

function Character:AddBehavior(fname, cname) 
    self.AI = self.AI or Pattern() 
    self.AI:AddBehavior(fname, cname) 
end 

function Character:Draw() 
    self.sprite:Draw() -- works! 
end 

Foo = Character:new() 

Lua скрипт чьи функции вызывается из основной программы:

function CoreInit() --called at initialization 
    Foo:LoadSprite("Image.png") -- works! 
end 

function CoreLogic() --called during logic cycle 
    Foo:SetX(50) -- does NOT work! 
end 

function CoreDraw() --called during drawing/rendering cycle 
    Foo:Draw() --works perfectly! 
end 

Так в основном, скрипт инициализирует символ с соответствующими координатами и изображениями, и рисует, но ни логика не вызывается (который находится в журнале ic loop) или что-то не так с функцией изменения координаты X.

Кроме того, диспетчер задач предполагает, что утечка памяти составляет ~ 30 КБ каждый цикл, чего не было, когда у меня были объекты изображения на C++.

Вот отрывок из Bitmap структуры, которая была экспортирована в Lua через LuaBridge в случае, если это было необходимо:

void Bitmap::Register(lua_State*lua) { 
    luabridge::getGlobalNamespace(lua) 
    .beginClass<Bitmap>("Bitmap") 
    .addConstructor <void (*) (void)>() 
    .addStaticData("scale", &Bitmap::scale) 
    .addFunction("LoadFile", &Bitmap::LoadFile) 
    .addFunction("Draw", &Bitmap::Draw) 
    .addData("x", &Bitmap::x) 
    .addData("y", &Bitmap::y) 
    .addData("w", &Bitmap::w) 
    .addData("h", &Bitmap::h) 
    .endClass(); 
} 


void Bitmap::LoadFile(string file) { 
    name = file; 
    bitmap = al_load_bitmap(file.c_str()); 
    w = al_get_bitmap_width(bitmap); 
    h = al_get_bitmap_height(bitmap); 
} 

void Bitmap::Draw() { 
    if (scale > 1) 
    al_draw_scaled_bitmap(bitmap, 0, 0, w, h, x * scale , y * scale, w * scale, h * scale, 0); 
    else 
    al_draw_bitmap(bitmap, x, y, 0); 
} 

Bitmap::Bitmap() : velocity(1) { 
    bitmap = NULL; 

} 
Bitmap::~Bitmap() { 
    name = ""; 
    if (!bitmap) 
    al_destroy_bitmap(bitmap); 
} 

UPDATE: Одна вещь, которую я был в состоянии выяснить, что утечка памяти от CoreLogic; Я прокомментировал вызов на C++, утечка памяти исчезла, но когда я оставил вызов неповрежденным, но прокомментировал содержимое CoreLogic, утечка сохранилась. Хммм ...

ВТОРАЯ UPDATE: Утечка памяти была сужена к чему-то с ИИ, который я не писал:

Pattern = {complete; timer; command; Files; Commands; itr; num} 

function Pattern:new() 
    o = o or {} 
    o.Files = {} 
    o.Commands = {} 
    o.complete = false 
    o.timer = 0 
    o.itr = 1 
    o.num = 1 
    setmetatable(o, self) 
    self.__index = self 
    return o 
end 

function Pattern:AddBehavior(filename, commandname) 
    self.Files[self.num] = filename 
    self.Commands[self.num] = commandname 
    self.num = self.num + 1 
end 

function Pattern:DoBehavior() 
    self.command = self.Commands[self.itr] 
    dofile(self.Files[self.itr]) 
end 

function Pattern:CheckBehavior() 
    if self.complete == true then 
    self.itr = self.itr + 1 
self.timer = 0 
self.complete = false 
    end 
    if itr >= num then 
    self.itr = 1 
self.timer = 0 
self.complete = false 
    end 
end 

function Pattern:Initialize() 
    self.itr = 1; self.timer = 0 
    self.complete = false 
    self.command = self.Commands[self.itr] 
end 

И в функции CoreLogic, было бы назвать Foo.AI:DoBehavior(), который ничего не сделал и вызвал утечку памяти.

+1

Что вы подразумеваете под утечкой памяти и циклом? Луа собирает мусор. В вашем случае каждый раз, когда вы вызываете «Bitmap()« объект », создается и не обязательно уничтожается. Если вы поместите свой объект в замыкания, ссылка будет сохранена, поэтому освобождение объекта, связанного с C++, будет задерживаться. –

+0

В принципе, каждый раз, когда вызывалась функция _CoreLogic_ (текущий FPS равен 30), объем памяти программы увеличивался на 30 КБ. Мне удалось прибить его к проблеме с таблицей AI. Я отправлю этот код на мгновение. – M89

ответ

0

После некоторой дополнительной смазки локтя, я смог решить проблему; по существу, он вернулся к конструктору таблицы и как объект AI был инициализирован в Персонаж.Я должен был изменить конструктор из:

Pattern = {complete; timer; command; Files; Commands; itr; num} 

function Pattern:new() 
    o = o or {} 
    o.Files = {} 
    o.Commands = {} 
    o.complete = false 
    o.timer = 0 
    o.itr = 1 
    o.num = 1 
    setmetatable(o, self) 
    self.__index = self 
    return o 
end 

к:

Pattern = {} 

function Pattern:new() 
    local o = {complete = false; timer = 0; command = ""; Files = {}; Commands = {}; itr = 1; num = 1} 
    setmetatable(o, self) 
    self.__index = self 
    return o 
end 

И это:

Character = {sprite; AI} 

function Character:new() 
    o = o or {} 
    setmetatable(o, self) 
    self.__index = self 
    return o 
end 

к:

Character = {} 

function Character:new() 
    local o = {sprite; AI = Pattern:new()} 
    setmetatable(o, self) 
    self.__index = self 
    return o 
end 

Теперь вызов к Foo. AI: DoBehavior() делает так, как предполагается, без использования дополнительной памяти. Этот код был моим первым попыткой реализовать ООП в Lua, и это, вероятно, так, как я собираюсь это сделать с этого момента.

1

Foo.AI:DoBehavior() читает фрагмент из файла, резервируя память для своего содержимого, свою переведенную форму байт-кода, функциональные среды и любые возможные временные значения, созданные на верхнем уровне этого файла. Ожидается, что здесь потеряется память, и это не утечка. Lua не освобождает память сразу. На самом деле он даже не возвращает его системе вообще.

Время от времени сборщик мусора запускает и находит строки/таблицы/функции/все остальное, что больше не используется. Lua отмечает эту память как бесплатную в своем собственном внутреннем индексе и будет использовать ее в следующий раз, когда ей нужна свободная память, но потребление памяти Lua, как видно из системы, никогда не сократится.

Если вы подозреваете, что какая-то часть вашей программы может создать слишком много ненужного мусора между автоматическими вызовами GC, вы можете захотеть принудительно выполнить шаг GC через collectgarbage или C API.

 Смежные вопросы

  • Нет связанных вопросов^_^