Thread Tools Display Modes
10-20-16, 12:03 PM   #1
Tesser
A Deviate Faerie Dragon
Join Date: Oct 2016
Posts: 15
limits of execution environment??

this one has me stumped; my only thought is I don't have enough resources allocated to execute this. I'm writing this lua within Gryphonheart addon, which until now has never presented problems like this.

I can't get a few strings concatenated and returned to a higher variable.

I'm taking binary code and reassembling to english, so the final concatenation which won't work is located a few orders down:
Code:
local sentence = ""
function()
  for pairs in table(long binary strings) 
    for bytes in strings
      for bits in bytes
      return charcode
    return letter
  return word
return sentence *HERE*
end
Everything works except the final sentence concatenation! Can't even print() the sentence, or return it to a variable outside function.
The basic concat code works fine if I isolate it. I can print() the individual table values. So... !@?!?!
I can only imagine this is too much iteration?
doesn't throw a lua error, just returns an empty "sentence" variable.
I tried both ".." and table.concat method.

To be clear, here is the mysterious code block itself:
Code:
local sentence = "" 
for i=1, #word_table, 1 do
  print(word_table[i]) -- TABLE VALUES FILLED
  sentence = sentence .. word_table[i]
end
print(sentence) -- EMPTY STRING

Last edited by Tesser : 10-20-16 at 12:23 PM.
  Reply With Quote
10-20-16, 02:49 PM   #2
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
How long strings we talking here?

Can you post an actual example that we can try?
__________________
Grab your sword and fight the Horde!
  Reply With Quote
10-20-16, 09:49 PM   #3
Tesser
A Deviate Faerie Dragon
Join Date: Oct 2016
Posts: 15
Here is actually a *working* example, but notice there are 2 commented out conditional statements. With them commented, it works. With them in it doesn't. This leads me to think it may in fact be a performance issue because when I run the whole item (not copied here) with them commented out, it still doesn't run. So these 2 lines can break the item, but removing them doesn't necessarily fix it...

With the conditionals commented, this code will interpret any binary bytes it finds in the CHAT_MSG_SAY channel.

Apologies for my self-taught, brute-force approach here - and thanks in advance for any time and tips you have!

(note there is one conditional - GHI_CountBuffs - that requires GHI..)

Code:
local word_table = {}
if not binbrewFrame then
    binbrewFrame = CreateFrame("Frame");
end
binbrewFrame:RegisterEvent("CHAT_MSG_SAY");




local binBrewFunc = function (self, event, ...)
    local message, sender, language, channelString, target, flags, unknown, channelNumber, channelName, unknown, counter = ...  
    local msgSearch = string.find(message, "[bB]inary");
    
    
    -- if GHI_CountBuffs("Binary") > 0 then
    -- if msgSearch ~= nil then
    local array2 = {}
    local array3 = {}
    for wurd in message:gmatch("%S+") do table.insert(array3, wurd) end 
    
    for k,v in pairs(array3) do
        
        local incr = 1
        local array4 = {}
        local tByte = ""
        local altr = ""
        local actual_word = ""
        
        for w in string.gmatch(v, ".") do  
            tByte = tByte .. w
            local sum = 0
            if incr%7==0 then
                
                array4[incr/7] = tByte
                local bin = string.reverse(array4[incr/7])
                for i = 1, string.len(bin) do
                    num = string.sub(bin, i,i) == "1" and 1 or 0
                    sum = sum + num * math.pow(2, i-1)
                    
                end
                tByte=""
                altr = string.char(sum)
                actual_word = actual_word .. altr
            end
            incr = incr + 1
        end
        word_table[k] = actual_word
    end   
    local sentence = "" 
    for i=1, #word_table, 1 do
        sentence = sentence .. word_table[i]
    end
    print(sentence)
    -- end
    -- end
end

binbrewFrame:SetScript("OnEvent", binBrewFunc);

Last edited by Tesser : 10-20-16 at 10:04 PM.
  Reply With Quote
10-21-16, 05:42 AM   #4
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Well, I can't say I understand what all this stuff is meant to accomplish, but there's no reason those conditionals would break anything, as they don't alter the process in any way.

I tried it in an offline interpreter, and as far as I can tell it will ignore words shorter than seven characters? When entering sufficiently long words, it just seemed to print a string of one � (unknown character) per word. Not sure if that's intended? And if it is, maybe that comes out as an empty string when printed in game?

As for performance, well, if you're in combat there is a limit on how long a single script is allowed to run before it is terminated. Not sure what the limit is. I think a few tenths of a second. Other than that I don't believe there any restrictions.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
10-21-16, 01:21 PM   #5
Tesser
A Deviate Faerie Dragon
Join Date: Oct 2016
Posts: 15
*EDIT* I've now got it officially working! I *think* the problem was the location of the concatenation, but I changed a lot and am not sure. You can paste this full item code into an Advanced Item > Script widget in GHI and it will work (type /binary to speak)

It allows you to both speak and understand binary.

I don't think the runtime of lua was the problem, after all that. Thanks for looking it over!

Code:
function toBits(num,bits)
-- function toBits(bits)
    -- returns a table of bits, most significant first.
    bits = bits or select(2,math.frexp(num))
    local t={} -- will contain the bits        
    for b=bits,1,-1 do
        t[b]=math.fmod(num,2)
        num=(num-t[b])/2
    end
    return t
end


local binString = ""

function cmdSay(msg)
    -- local msg =  "how crazy can we get?!`1234567890~!@#$%^&*(" 
    local array1 = {}
    binString = ""
    
    for ltr in msg:gmatch(".") do table.insert(array1, ltr) end 
    
    for k,v in pairs(array1) do
        local binNum 
        if v == " " then 
            binNum = " "
        else
            binNum = table.concat(toBits(string.byte(v)))
        end
        binString = binString .. binNum
    end
    GHI_Say("[Binary]: "..binString)
end



local binary = GHI_SlashCmd("binary")

binary.SetDefaultFunc(function(x)    
        cmdSay(x)    
    end
)




function humanize(message)
    local word_table = {}
    local array2 = {}
    local array3 = {}
    local strip = 0
    for wurd in message:gmatch("%S+") do if strip>0 then table.insert(array3, wurd) else end strip = strip + 1 end 
    
    for k,v in pairs(array3) do
        -- print('beg of pairs', k, v)
        local incr = 1
        local array4 = {}
        local tByte = ""
        local altr = ""
        local actual_word = ""
        
        for w in string.gmatch(v, ".") do  
            tByte = tByte .. w
            local sum = 0
            if incr%7==0 then
                
                array4[incr/7] = tByte
                local bin = string.reverse(array4[incr/7])
                for i = 1, string.len(bin) do
                    num = string.sub(bin, i,i) == "1" and 1 or 0
                    sum = sum + num * math.pow(2, i-1)
                end
                tByte=""
                altr = string.char(sum)
                actual_word = actual_word .. altr
            end
            incr = incr + 1
        end
        word_table[k] = actual_word
        -- print('end of pairs', k, v)
        
    end
    local sentence = ""
    for ke,va in pairs(word_table) do   
            -- print(ke, va)
            sentence = sentence .. " " .. va

        end
        print(sentence)
end


if not binbrewFrame then
    binbrewFrame = CreateFrame("Frame");
end
binbrewFrame:RegisterEvent("CHAT_MSG_SAY");



local binBrewFunc = function (self, event, ...)
    local message, sender, language, channelString, target, flags, unknown, channelNumber, channelName, unknown, counter = ...  
    local msgSearch = string.find(message, "[bB]inary");

   -- if GHI_CountBuffs("Binary") > 0 then
        if msgSearch ~= nil then
            humanize(message)
        end
   -- end

end

binbrewFrame:SetScript("OnEvent", binBrewFunc);

Last edited by Tesser : 10-21-16 at 02:48 PM.
  Reply With Quote
10-21-16, 02:43 PM   #6
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Sounds like you need to double check how your keys are defined, then. I would start there. If you use pairs it will iterate over any keys in the table, and unless you have perfectly sequenced integer keys starting at 1 the order is undefined. ipairs will only iterate over perfectly sequenced integer keys starting at 1 and do so in order, but that doesn't help if your keys are broken in the first place.

# just returns the length of a table or a string. There shouldn't be anything unintuitive about it. Although for tables it once again requires sequenced integer keys starting at 1 to give the expected result.

Edit: Oh, okay. Glad to hear you got it sorted!
__________________
Grab your sword and fight the Horde!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » limits of execution environment??

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off