Jump to content


Photo

Help condensing code

luacodehelp

    12 replies to this topic

    #1 allibear17

    allibear17

      Newbie

    • Members
    • Pip
    • 9 posts

      Posted 27 November 2016 - 02:22 AM

      I've been working on this addon off and on when I have been able to play XI.  I know only the basics in programming, but I feel like I should be able to condense some of my code.  I feel like the tparty addons does something similar, but in the condensed fashion.

      I have a block like this, for each party member where the only things changing are the number in the varaible name, and a multiplier for step.x (which will be identical to the number alongside 'p'.

      p1_settings = {}	
      p1_settings.pos = {}
      p1_settings.pos.x = nondefault.pos.x + nondefault.step.x
      p1_settings.pos.y = nondefault.pos.y
      p1_settings.text = {}
      p1_settings.text.size = nondefault.font_size
      

      Is there some way to condense this, using a for loop, so that inside the loop it creates the variable using the i value? 

       

      Here's my lua on github, if you want to see the entire thing.

       

      Thanks.
       



      #2 Iryoku

      Iryoku

        Advanced Member

      • Windower Staff
      • 488 posts

        Posted 27 November 2016 - 03:29 AM

        This is equivalent:

        p1_settings = {pos = {x = nondefault.pos.x + nondefault.step.x, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
        

        The two forms generate identical, or nearly identical bytecode, so performance is the same. Use which ever form you think is easiest to read.
         
        If you don't need to keep the p1_settings variable name you can do this:

        settings = {}
        for i = 1, 6 do
            settings[i] = {pos = {x = nondefault.pos.x + nondefault.step.x * i, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
        end
        

        If you really need to keep that variable name this should work:

        for i = 1, 6 do
            _G['p' .. i .. '_settings'] = {pos = {x = nondefault.pos.x + nondefault.step.x * i, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
        end
        

        • allibear17 likes this

        #3 sdahlka

        sdahlka

          Advanced Member

        • Members
        • PipPipPip
        • 324 posts

          Posted 27 November 2016 - 04:53 AM

          Iryoku got to it before me not to mention he is probably better then me at lua



          #4 allibear17

          allibear17

            Newbie

          • Members
          • Pip
          • 9 posts

            Posted 28 November 2016 - 02:00 AM

            Thanks so much, you completely answered my question, and gave me alternatives as well.



            #5 allibear17

            allibear17

              Newbie

            • Members
            • Pip
            • 9 posts

              Posted 28 November 2016 - 09:34 PM

              Using what I learned from the above, I was able to add in MP, and then condense 230+ lines down to 150 lines.

              I'm sure I could further condense the Update function, but I don't quite understand the third example from Iryoku, which I think is how I would be able to condense it.  I feel a lot better about my code now though, Thanks again.

              Here's a screenshot of how it is working, in case you wanted to see the result



              #6 sdahlka

              sdahlka

                Advanced Member

              • Members
              • PipPipPip
              • 324 posts

                Posted 29 November 2016 - 08:08 PM

                Using what I learned from the above, I was able to add in MP, and then condense 230+ lines down to 150 lines.

                I'm sure I could further condense the Update function, but I don't quite understand the third example from Iryoku, which I think is how I would be able to condense it.  I feel a lot better about my code now though, Thanks again.

                Here's a screenshot of how it is working, in case you wanted to see the result

                for i = 1, 6 do
                    _G['p' .. i .. '_settings'] = {pos = {x = nondefault.pos.x + nondefault.step.x * i, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
                end
                

                is the same as this

                p1_settings = {pos = {x = nondefault.pos.x + nondefault.step.x * 1, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
                p2_settings = {pos = {x = nondefault.pos.x + nondefault.step.x * 2, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
                p3_settings = {pos = {x = nondefault.pos.x + nondefault.step.x * 3, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
                p4_settings = {pos = {x = nondefault.pos.x + nondefault.step.x * 4, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
                p5_settings = {pos = {x = nondefault.pos.x + nondefault.step.x * 5, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
                p6_settings = {pos = {x = nondefault.pos.x + nondefault.step.x * 6, y = nondefault.pos.y}, text = {size = nondefault.font_size}}
                

                _G stands for the global table
                when you create a table or function
                examples:

                function a()
                a = function()
                a = {}
                

                the full name would actually be

                _G.a
                

                because _G is the global table
                tho _G is only needed if you need to call a variable with a dynamic name (use the above code fore an example) because _G is implied
                also _G is useful if you have a local and global variable with the same name
                example:

                a = {]
                function b()
                    local a = {}
                end
                

                you can call the local table with a and the global table with _G.a
                 
                in programing implied is something that is put in even if you do not use it
                 
                 
                also using the above code in your code does not make the running memory smaller only your code smaller in fact the running memory will be bigger
                --running memory is the running code in memory
                 
                so if your table will never be changed by your code is best to write it out manually for memory size reasons
                but if your going to build and rebuild your table dynamically based on data its best to use the above code
                --if you look at the code i created for my gearswap display you might understand
                ---my display code is 29KB how ever if i wrote everything out it would be around 90KB+
                ---however my code in memory is 100KB+ because of all the tables i build for it
                 
                however if you want to do both your code and memory size condensing
                you cant at lest not in lua as far as i am aware
                 
                here is your code minimized as far as i can make it (running memory size may actually be larger then what you had)

                _addon.name = 'PartyP'
                _addon.author = 'Allison Jane'
                _addon.version = '0.2'
                _addon.language = 'english'
                
                texts = require('texts')
                config = require('config')
                
                defaults = {pos = {x = 200,y = 100},step = {x = 90,y = 20},pet = {x = 840,y = 440},font_size = 12}
                
                settings = config.load(defaults)
                config.save(settings)
                
                config.register(settings, function(settings_table)
                    local nondefault = defaults
                    if settings_table.pos.x ~= nil then
                        nondefault = settings_table
                    end
                    
                    hp_settings,hp_display,mp_settings,mp_display = {},{},{},{}
                    
                    for i = 0, 5 do
                        hp_settings[i] = {pos = {x = nondefault.pos.x + (nondefault.step.x * i), y = nondefault.pos.y}, text = {size = nondefault.font_size}}
                        hp_display[i] = texts.new('HP: ${hpp|---}%', hp_settings[i])
                        mp_settings[i] = {pos = {x = nondefault.pos.x + (nondefault.step.x * i), y = nondefault.pos.y + nondefault.step.y}, text = {size = nondefault.font_size}}
                        mp_display[i] = texts.new('MP: ${mpp|---}%', mp_settings[i])
                    end
                    
                    pet_settings = {pos = {x = nondefault.pet.x, y = nondefault.pet.y}, text = {size = nondefault.font_size}}
                    p0pet = texts.new(' Pet: ${hpp|---}%', pet_settings)
                end)
                
                windower.register_event('prerender', function()
                    local party = windower.ffxi.get_party()
                    local mypet = windower.ffxi.get_mob_by_target('pet')
                    
                    for i = 0, 5 do
                        if party["p"..i] ~= nil then
                            hp_display[i].hpp = party['p'..i].hpp
                            mp_display[i].mpp = party['p'..i].mpp
                            hp_display[i]:show()
                            mp_display[i]:show()
                        else
                            hp_display[i]:hide()
                            mp_display[i]:hide()
                        end
                    end
                
                    if mypet ~= nil then
                        p0pet.hpp = mypet.hpp
                        p0pet:show()
                    else
                        p0pet:hide()
                    end
                end)
                

                i dont recommend using prerender like this because it will be triggered 30+ times a second

                 

                i recommend

                function Update()
                    local party = windower.ffxi.get_party()
                    local mypet = windower.ffxi.get_mob_by_target('pet')
                    
                    for i = 0, 5 do
                        if party["p"..i] ~= nil then
                            hp_display[i].hpp = party['p'..i].hpp
                            mp_display[i].mpp = party['p'..i].mpp
                            hp_display[i]:show()
                            mp_display[i]:show()
                        else
                            hp_display[i]:hide()
                            mp_display[i]:hide()
                        end
                    end
                
                    if mypet ~= nil then
                        p0pet.hpp = mypet.hpp
                        p0pet:show()
                    else
                        p0pet:hide()
                    end
                end
                
                frame_count = 0
                windower.register_event('prerender',function()
                    if not windower.ffxi.get_info().logged_in then -- stops prerender if not logged in yet
                        return
                    end
                    if frame_count%30 == 0 and windower.ffxi.get_info().logged_in then
                        Update()
                    end
                    frame_count = frame_count + 1
                end)
                

                • allibear17 likes this

                #7 allibear17

                allibear17

                  Newbie

                • Members
                • Pip
                • 9 posts

                  Posted 29 November 2016 - 11:44 PM

                  I didn't expect such a lengthy and informative post.  There's a lot of information int there to digest.  I'm grateful Sdahlka.  I will go over this and hopefully absorb it all.



                  #8 sdahlka

                  sdahlka

                    Advanced Member

                  • Members
                  • PipPipPip
                  • 324 posts

                    Posted 30 November 2016 - 02:27 AM

                    sorry for the long post i just did not want to leave anything out



                    #9 Iryoku

                    Iryoku

                      Advanced Member

                    • Windower Staff
                    • 488 posts

                      Posted 05 December 2016 - 07:18 PM

                      Iryoku got to it before me not to mention he is probably better then me at lua

                       

                      Probably not, lol. I write C++ and C#, I learned Lua because I had to for Windower. What I do have is a very good understanding of how Lua works internally and how it interacts with native code through the Lua/C API. I know a lot more about really obscure parts of Lua like weak tables, upvalue captures, metatables, etc., because those are the parts that are important for the parts of Windower that I work on. For example, you can't even create a function from the C side of Lua without explicitly telling Lua how many upvalues to capture, which is something that is completely transparent from the other side.

                       

                      Some of that knowledge does transfer over, but I would not say I'm good at Lua.



                      #10 sdahlka

                      sdahlka

                        Advanced Member

                      • Members
                      • PipPipPip
                      • 324 posts

                        Posted 05 December 2016 - 09:43 PM

                        Probably not, lol. I write C++ and C#, I learned Lua because I had to for Windower. What I do have is a very good understanding of how Lua works internally and how it interacts with native code through the Lua/C API. I know a lot more about really obscure parts of Lua like weak tables, upvalue captures, metatables, etc., because those are the parts that are important for the parts of Windower that I work on. For example, you can't even create a function from the C side of Lua without explicitly telling Lua how many upvalues to capture, which is something that is completely transparent from the other side.

                         

                        Some of that knowledge does transfer over, but I would not say I'm good at Lua.

                        trust me you know more about lua then i do

                        because if i cant figure out how to do something in my code i turn to the windower chat room

                        then its usually you or Byrth that figures it out for me (there are a few others but mostly the listed ones)

                         

                        and i can write in these C#,C++,FORTRAN(this is really hard),QBasic,LUA



                        #11 allibear17

                        allibear17

                          Newbie

                        • Members
                        • Pip
                        • 9 posts

                          Posted 06 December 2016 - 05:04 AM

                          I've been reading a bit about lua, and the great info posted above.  Is there a relatively easy way to determine how much running memory my code uses?  Do I simply check task manager, and load/unload it checking each time?  I realize the differences at best/worst will be hardly worthwhile, even if I'm the only person ever using my own addon, but this stuff highly interests me.  It's why I have taught myself coding basics and the like.



                          #12 Kenshi

                          Kenshi

                            Advanced Member

                          • Members
                          • PipPipPip
                          • 334 posts

                            Posted 06 December 2016 - 11:27 AM

                            //lua memory



                            #13 allibear17

                            allibear17

                              Newbie

                            • Members
                            • Pip
                            • 9 posts

                              Posted 06 December 2016 - 04:46 PM

                              Thank you







                              Also tagged with one or more of these keywords: lua, code, help

                              1 user(s) are reading this topic

                              0 members, 1 guests, 0 anonymous users