Pesquisa personalizada

2014/04/08

paslibvlc VLC Library interface - PasLibVlcUnit.pas - my 1/2 cents

I'm working using the library paslibvlc - a pascal interface for VideoLAN libvlc/libvlccore DLL. I'm happy to find it. It's better than libvlc.pas from Lazarus/FPC, is mature, works fine and it works on Lazarus and Delphi.

While implementing a class to handle VLM broadcast, I did three changes to paslibvlc:
1) I found that PasLibVlcUnit.pas missed libvlc_vlm_set_enabled - it isn't being (dynamically) bound to the DLL  function. So I added it to be initialized also:

  if not libvlc_dll_get_proc_addr(@libvlc_vlm_set_enabled,
    'libvlc_vlm_set_enabled') then exit;
2) Also, I changed that unit to clear all pointers/variables as needed.
3) Not really related to that good library, but the problem was very hard to understand and easy to fix, it a hardware float point exception (to be honest, the problem raises in MMX, but as MMX also uses registers from the float point coprocessor, the context is shared also) that VLM throws while playing some Windows Media Format. The fix is too easy, just set the float point mask before add each media to VLM - I did it before calling libvlc_vlm_add_broadcast.
The bug always happens after add a second stream. Anyway I have to handle several of them, including from unknown sources, without raising fatal exceptions to the application. So it is important to mitigate any exception before it can be propagated.
To fix it, just run the following statement before add the stream to the VLM:
SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,exOverflow, exUnderflow, exPrecision]);

The changed PasLibVlcUnit.pas unit can be downloaded here if you think it will be useful.

I implemented a class to handle VLM broadcasting, but my code is too far from that one clean and good code from PasLibVlcUnit. Said it, I can agree that it is working as expected (well, fine...). If anybody want it, just ask me. I implemented it because I didn't find any implementation to the VLM functions, like, eg.: libvlc_vlm_xxxxx

My thanks to Robert Jêdrzejczyk  for bring us its library and maintaining it.

2013/12/15

WoW Addon: PetBattle Teams: Adding Feature: Searching Team by Name

Taming the World

Looking at my Blizzard Armory profile, we can see that I have more than 500 unique battle pets. I really like to "wowkemon".. it's fun and easy than raiding the latest raid in heroic mode ;)
I have some World of Warcraft addons to help me build and choosing the right pet team as needed. One them is PetBattle Teams. It is pretty, easy to use and works - this last is a nice feature while talking about wow addons...
There is one feature, a most to have in my opinion, that is missing in PetBattle Teams:
- search for a team using its name.
It is obvious, useful and really wished, but missing.. Every time before a battle, while trying to find my team for the someone daily battle pet quest I wish to have a way to found my previous built team. I have thousands of teams... After seeing that others users also is requesting this feature, I decides to implement the mostly PetBattle Teams wished/missed feature.
I'm using Hack addon to test my Lua scripts. It is an in game Lua editor, like a mini-IDE. As a Hack user, I decides to implement the PetBattle Teams search by name feature using it.


The code to find the missed feature

I'm newbie while talking about Lua and Warcraft addons programming, so my code is a little fuzzy... my excuses for sharing this kind of mess, but it is working; maybe, someone also thinks it useful.

local tm = LibStub("AceAddon-3.0"):GetAddon("PetBattleTeams"):GetModule("TeamManager");

FixPetTeams = FixPetTeams or tm;

function FixPetTeams:GetPetInfoBySpeciesIDLevel(reqSpecieID, reqLevel)
   local numPets, _ = C_PetJournal.GetNumPets();
   for idxPet=1, numPets do
      local petID, speciesID, _, _, level, _, _, name = C_PetJournal.GetPetInfoByIndex(idxPet);
      if (reqSpecieID == speciesID) and (level == reqLevel) then
         return petID, name;
      end
   end      
end



function FixPetTeams:fixPetID()
   local PETS_PER_TEAM = 3;   
   local numTeams = self:GetNumTeams()
   
   for team=1,numTeams do
      for petIndex = 1, PETS_PER_TEAM do
         local petSlotInfo = self.teams[team][petIndex];
         local speciesID = petSlotInfo.speciesID;
         if speciesID then
            local petID, name = self:GetPetInfoBySpeciesIDLevel(speciesID, 25);
            if petID then
               petSlotInfo.petID = petID;
               petSlotInfo.name = name;
               print( name );               
            end
         end
      end   
   end
end



-- --------------------------------------------- --
--    Adds support to search teams by name.
--

local GUI = LibStub("AceAddon-3.0"):GetAddon("PetBattleTeams"):GetModule("GUI");
FixPetTeams.GUI = GUI;

local widget = PetBattleTeamFrame;

function FixPetTeams:findTeamByName(nameFilter)
   if (not nameFilter) then return end
   
   local numTeams = self:GetNumTeams();
   
   nameFilter = strlower( tostring(nameFilter) );
   
   if (strlen(nameFilter) < 1) then return end
   
   local result = {};
   
   for idxTeam=1,numTeams do
      local teamInfo = self.teams[idxTeam];
      local sName = teamInfo.name;
      if (sName) then 
         sName = strlower(sName);         
         local posName = strfind(sName, nameFilter, 1, true);
         if (posName) then
            --print( teamInfo.name );
            result[idxTeam] = teamInfo;
         end         
      end      
   end   
   
   return result;
end

--  To use, just call:
--      FixPetTeams.GUI:addSearchSupport()
--  Just for convenience (or lazy people like me - mwb):
--        
function GUI:addSearchSupport()
   local findTeamEdit = widget.findTeamEdit or CreateFrame("EditBox", "FindTeamEdit", widget, "InputBoxTemplate");
   widget.findTeamEdit = findTeamEdit;
   _G.findTeamEdit = findTeamEdit;
   findTeamEdit:SetPoint("TOP", widget, "BOTTOM");
   findTeamEdit:SetAutoFocus(false);
   --findTeamEdit:SetAllPoints();
   findTeamEdit:Show();      
   
   return widget;
end

local function findTeamEdit_OnTextChanged(self)
   local sNameFilter = self:GetText();
   
   local resultFound = FixPetTeams:findTeamByName(sNameFilter);
   if not resultFound then
      print("-----------------------------");
      return;
   end
   
   for idxTeam, teamInfo in ipairs(resultFound) do
      print( sNameFilter );
   end   
end

local function findTeamEdit_OnEnterPressed(self)
   local sNameFilter = self:GetText();
   
   print("");
   print("-----------------------------");
   
   local resultFound = FixPetTeams:findTeamByName(sNameFilter);
   if not resultFound then
      return;
   end   
   
   local idxCurTeam = FixPetTeams:GetSelected() or 0;
   local idxNewTeam = 0;   
   local idxFirstTeam = 0;
   
   for idxTeam, teamInfo in pairs(resultFound) do    
      print( "#" .. idxTeam .. " " .. teamInfo.name );      
      
      if (idxFirstTeam < 1) then 
         idxFirstTeam = idxTeam;
      end
            
      if (idxTeam > idxCurTeam) then
         if (idxNewTeam==0 or idxNewTeam>idxTeam) then
            idxNewTeam = idxTeam;
         end         
      end   
   end
   
   
   if (idxNewTeam < 1) then       
      idxNewTeam = idxFirstTeam; 
   end
   
   --GUI:ResetScrollBar();     
   --PetBattleTeamsScrollFrame:Hide();
   FixPetTeams:SetSelected(idxNewTeam);
   --PetBattleTeamsScrollFrame:Show();
   
   do
      local self = PetBattleTeamsRosterFrame;
      local teamFrames = self.scrollChild.teamFrames;
      local rowHeight = teamFrames[1]:GetHeight();
      
      local totalHeight = self.scrollFrame:GetVerticalScrollRange();
      local tot = totalHeight;
      local pos = tot / (rowHeight+64) * (idxNewTeam-1);      
      if (pos<0) then 
         pos = 0;
      elseif  (pos>tot) then
         pos = tot;
      end      
      self.scrollFrame:SetVerticalScroll(pos);            
   end   
   
   print( "TIME: " .. idxNewTeam);   
end

local FIND_EDIT_GAIN_FOCUS_ALPHA = 0.95;
local FIND_EDIT_LOST_FOCUS_ALPHA = 0.3;

GUI:addSearchSupport();

widget:Hide();
findTeamEdit:Hide();
findTeamEdit:SetFrameStrata("DIALOG");
findTeamEdit:SetAlpha(FIND_EDIT_LOST_FOCUS_ALPHA);
--findTeamEdit:ClearAllPoints();
findTeamEdit:SetAllPoints(widget.selectedTeamText);
--findTeamEdit:SetSize(60, 25);
--findTeamEdit:SetPoint("TOP", widget.selectedTeamText, "BOTTOM");
findTeamEdit:SetScript("OnTextChanged", findTeamEdit_OnTextChanged);
findTeamEdit:SetScript("OnEnterPressed", findTeamEdit_OnEnterPressed);
findTeamEdit:SetScript("OnEnter", function(self) 
      widget.selectedTeamText:SetAlpha(FIND_EDIT_LOST_FOCUS_ALPHA);
end);
findTeamEdit:SetScript("OnLeave", function(self) 
      if (strlen(self:GetText())==0) then
         widget.selectedTeamText:SetAlpha(FIND_EDIT_GAIN_FOCUS_ALPHA);
      end      
end);
findTeamEdit:SetScript("OnEditFocusGained", function(self) 
      self:SetAlpha(FIND_EDIT_GAIN_FOCUS_ALPHA);            
      widget.selectedTeamText:SetAlpha(FIND_EDIT_LOST_FOCUS_ALPHA);            
end);
findTeamEdit:SetScript("OnEditFocusLost", function(self) 
      self:SetAlpha(FIND_EDIT_LOST_FOCUS_ALPHA);      
      widget.selectedTeamText:SetAlpha(FIND_EDIT_GAIN_FOCUS_ALPHA);
end);
--findTeamEdit:SetScript("OnEscapePressed", function(self) self:SetText("" end);
findTeamEdit:Show();
widget:Show(); 

How it works

It adds a small, non intrusive EditBox in top of the label "Selected Team". Just move your mouse to it and you will see some fade effect. Click it, type your team name and hit ENTER. If there is any team matching its name with you typed, it will be selected. If you have more than one team matching, just hit ENTER again to select the next matched team.

Searching teams by its name

To install it

For you convenience, you can download this file from: fixPetBattleTeams.lua.
To run it, just copy/paste it into a new Hack page and check it to run every time that UI is loaded.

Cheers,
Doggod-Azralon - A mediocre lazy warlock, but also a very lazy programmer.

Labels: , , , ,