Announcement

Collapse
No announcement yet.

LuaEx

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • LuaEx

    If you haven't used it yet, the LuaEx module is packed full of great stuff. Check it out on my github.

    I just added an enum type to LuaEx. I've been needing an enum object for a long while so I decided to build it. I've included common enum features such as immutability, an iterator, ordinal positioning, optional user-set string or number values for each enum item, type checking and more.

    For a detailed description and usage examples, check out the gihub page https://github.com/CentauriSoldier/LuaEx.
    https://github.com/CentauriSoldier

  • #2
    Hi Centauri
    can I just do "require ()" to get LuaEx?

    David

    Comment


    • #3
      Hey Daviz,

      If you're using LuaEx with Autoplay Media Studio, drop the LuaEx folder into your Scripts folder. In your Globals, use this code to make all the LuaEx code available to the rest of your project.
      PHP Code:
      require("LuaEx.init"
      https://github.com/CentauriSoldier

      Comment


      • #4
        I just did a major update to the project making real, working constants and enums. These values, once set, cannot be changed or deleted even from the global scope (even using _G). Now, you could break this feature intentionally if you went far out of your way to do it (by altering the _G.__LUAEX_PROTECTED__ table using rawset/rawget) but not by accident or by normal use.
        https://github.com/CentauriSoldier

        Comment


        • #5
          In response to David's query, I've provided an example (the same one on the github modified for AMS) for anyone who'd like to see enums in action.

          PHP Code:
          --init all LuaEx modules
          require("LuaEx.init");

          local sText "";

          --
          rewrite print for AMS
          function print(sInput)
              
          sText sText..sInput.."\r\n";
          end

          --create a few of enums
          enum
          ("CREATURE",{"HUMAN""MONSTER""FROG""DRAGON"});
          enum("AUTO", {"CAR""TRUCK""BIKE"});
          enum("ANIMAL", {"DOG""FROG""MONKEY""GIANT_SNAKE"});
          --
          create one with custom values
          enum
          ("TOOL", {"HAMMER""DRILL""TAPE"}, {"Framing""Mega Drill"50});

          local maDrill TOOL.DRILL;

          --print 
          every item in an enum
          print("Printing All Items in the "..ANIMAL.__name.." enum:\r\n");
          for 
          nIDoItem in ANIMAL() do
          print(
          tostring(oItem).." ("..oItem.name..") is an "..tostring(oItem.enum)..".");
          end

          --print some test cases
          print("\r\n");
          print(
          "Fact-check: A "..AUTO.CAR.name.." is an "..tostring(ANIMAL).." - "..tostring(AUTO.CAR:isA(ANIMAL)));
          print(
          "Fact-check: A "..tostring(TOOL).." has a "..tostring(maDrill).." - "..tostring(TOOL.__hasA(maDrill)));
          print(
          "Fact-check: A "..AUTO.TRUCK.name.." is an "..tostring(AUTO).." - "..tostring(AUTO.TRUCK:isA(AUTO)));
          print(
          "Fact-check: An "..tostring(AUTO.TRUCK.enum).." is an "..tostring(AUTO).." - "..tostring(AUTO.TRUCK.enum == AUTO));
          print(
          "Fact-check: A "..ANIMAL.FROG.name.." and "..ANIMAL.MONKEY.name.." are in the same enum - "..tostring(ANIMAL.FROG.enum == ANIMAL.MONKEY.enum));
          print(
          "Fact-check: A "..AUTO.BIKE.name.." and "..TOOL.HAMMER.name.." are in the same enum - "..tostring(AUTO.BIKE.enum == TOOL.HAMMER.enum));
          print(
          "Fact-check: A (Creature) "..CREATURE.FROG.name.." and (Animal) "..ANIMAL.FROG.name.." are in the same enum - "..tostring(CREATURE.FROG.enum == ANIMAL.FROG.enum));
          print(
          "Fact-check: A (Creature) "..CREATURE.FROG.name.." and (Creature) "..CREATURE.DRAGON.name.." are siblings (in the same enum)- "..tostring(CREATURE.FROG:isSibling(CREATURE.DRAGO N)));
          print(
          "Get a "..CREATURE.FROG.name.." by name ("..CREATURE.FROG.name..") and by ordinal ("..CREATURE[3].id..")");
          print(
          "Get the first ("..AUTO[1].name..") and last ("..AUTO[AUTO.__count].name..") items in "..AUTO.__name..".");

          --
          you can also create non-global enums
          local tMyTable 
          = {
          MY_COOL_ENUM enum("MU_ENUM", {"STUFF""THINGS""ITEMS"}, niltrue),
          MY_OTHER_COOL_ENUM enum("MU__OTHER_ENUM", {"STUFF""THINGS""ITEMS"}, {1799}, true),
          };

          Dialog.Message("Enum Test"sText); 
          https://github.com/CentauriSoldier

          Comment


          • #6
            If you put the enum and constant code in the same Lua script, you don need _G.__LUAEX_PROTECTED__. Instead, you can use a local variable in the outer scope and access it from the (i.e.) constant function as an upvalue.
            Bas Groothedde
            Imagine Programming :: Blog

            AMS8 Plugins
            IMXLH Compiler

            Comment


            • #7
              What do you mean by "outer scope"? Do you mean the scope in the init.lua file?

              I placed them in the _G.__LUAEX_PROTECTED__ table so they could be, both, globally accessible and protected from accidental overwrites. Do you think I could keep those features if I imlpemented what you're suggesting? If I'm not mistaken, your method would make access much faster and, as such, interests me very much :P.
              https://github.com/CentauriSoldier

              Comment


              • #8
                Originally posted by Centauri Soldier View Post
                What do you mean by "outer scope"? Do you mean the scope in the init.lua file?

                I placed them in the _G.__LUAEX_PROTECTED__ table so they could be, both, globally accessible and protected from accidental overwrites. Do you think I could keep those features if I imlpemented what you're suggesting? If I'm not mistaken, your method would make access much faster and, as such, interests me very much :P.
                Putting an __index and __newindex operator on _G might slow things down quite a bit, as you're invoking a Lua function for each GETGLOBAL and SETGLOBAL, but also for each lua_getglobal and lua_getglobal done from any C-api. The latter might not matter too much. I do now realize that you're trying to prevent developers from overwriting/redefining global values, so I guess you're stuck with your own strategy haha!

                I used to implement something called 'enum classes` in Lua. Basically, you define a type and the constants in the enum are member of the type. The caveat is that you don't have the enumeration values as global variables, the advantage is that you have named enumerations. For example;

                Code:
                enum "connection_types" {
                  "unix",
                  "tcp",
                  "udp",
                  "serial"
                };
                Which would create a variable "connection_types" in _G (or _ENV for later version) that is a userdatum with its own __index and __newindex. For constants this idea doesn't work though, if you want to protect a variable in the global scope you are doing the only thing possible in 5.1. So sad that AMS is stuck at 5.1, 5.4 has <const>:
                Code:
                local my_var <const> = "This is a constant variable, its value may not change.";
                Bas Groothedde
                Imagine Programming :: Blog

                AMS8 Plugins
                IMXLH Compiler

                Comment


                • #9
                  The latter might not matter too much. I do now realize that you're trying to prevent developers from overwriting/redefining global values, so I guess you're stuck with your own strategy haha!
                  Heh heh, perhaps a victim of my own strategy then.

                  So sad that AMS is stuck at 5.1, 5.4 has <const>:
                  Ikr! I really wish IR would spend the little time it would take to move to 5.4. Despite all the concern about there being "not enough interest", it seems like it wouldn't be that much trouble to update lua in AMS. Besides the <const> directive and the awesome metamethod additions, 5.4 benchmarks much higher that 5.1. At the least, they could open the source of AMS so we could change it.

                  Do you think the procesing cost of my strategy is prohibitive? Is there a way to benchmark it? I also don't want to commit the cardinal programming sin of pre-optimization.

                  Edit: Wouldn't the overhead of the added call(s) be negated by localizing globals within scripts?
                  https://github.com/CentauriSoldier

                  Comment


                  • #10
                    Originally posted by Centauri Soldier View Post
                    Ikr! I really wish IR would spend the little time it would take to move to 5.4. Despite all the concern about there being "not enough interest", it seems like it wouldn't be that much trouble to update lua in AMS. Besides the <const> directive and the awesome metamethod additions, 5.4 benchmarks much higher that 5.1. At the least, they could open the source of AMS so we could change it.

                    Do you think the procesing cost of my strategy is prohibitive? Is there a way to benchmark it? I also don't want to commit the cardinal programming sin of pre-optimization.

                    Edit: Wouldn't the overhead of the added call(s) be negated by localizing globals within scripts?
                    Upgrading the AMS engine to Lua 5.4 would not be too much trouble in the engine itself, probably; however every single plugin for AMS 8 would have to be upgraded to link with Lua 5.4 as well. That would be a hassle. Nevertheless, I'd love to see IR open source it so someone could just make a branch with 5.4 support.

                    Your strategy is fine functionally, pre-emptive optimiziation is bad. What you could do is mention in the examples that localizing a constant or enum value (i.e. local val = enum_value) before loops would solve all performance problems. You could benchmark it by using os.clock, which is an accurate aproximation of the time used on the CPU by the process:

                    Code:
                    function time_it(name, func)
                      local t = os.clock();
                      func();
                      local d = os.clock() - t;
                      print(("time %s: %0.5f seconds"):format(name, d - t));
                    end
                    
                    time_it("all in _G 1000 times", function()
                      for r = 1, 1000 do
                        for i, v in pairs(_G) do
                          print(i, v);
                        end
                      end
                    end);
                    But for the functionality you're going for there is not too much you can do, except for having the _G __index and __newindex as a C function.
                    Bas Groothedde
                    Imagine Programming :: Blog

                    AMS8 Plugins
                    IMXLH Compiler

                    Comment


                    • #11
                      my response is flagged as potential spam for some reason.... waiting for moderator approval
                      Bas Groothedde
                      Imagine Programming :: Blog

                      AMS8 Plugins
                      IMXLH Compiler

                      Comment


                      • #12
                        Nice to see you never stopped playing with Lua, I really do with there was a nice replacement to AMS I have looked at other tools but none fit the bill I haven't made anything in the last year last project I made I got help with from IP and then the thing I made it for well ended up putting all the options I made in to there tool so ya that hurt but same time it was a good thing to see them get there things sorted but I just hand no over ideas to convert the app to lol

                        I will be taking a closer look at this later for sure CS nice work.

                        P.S I vote for Lua update or open source also ;p
                        Plugins or Sources MokoX
                        BunnyHop 2021 Here

                        Comment


                        • #13
                          Originally posted by Imagine Programming View Post
                          my response is flagged as potential spam for some reason.... waiting for moderator approval
                          That happens to me all the time. It seems to occur if you edit a new post too many times in a certain timespan.

                          Originally posted by kingzooly View Post
                          I will be taking a closer look at this later for sure CS nice work.

                          P.S I vote for Lua update or open source also ;p
                          I should note, that this project (LusEx) is relied upon by my CoG project which, in turn, is relied upon by Sim2D. That is, if you use Sim2D (when it gets to a useable alpha stage), you'll have accesss to CoG and LuaEx functionality.
                          https://github.com/CentauriSoldier

                          Comment


                          • #14
                            Originally posted by Imagine Programming View Post

                            Upgrading the AMS engine to Lua 5.4 would not be too much trouble in the engine itself, probably; however every single plugin for AMS 8 would have to be upgraded to link with Lua 5.4 as well. That would be a hassle. Nevertheless, I'd love to see IR open source it so someone could just make a branch with 5.4 support.

                            Your strategy is fine functionally, pre-emptive optimiziation is bad. What you could do is mention in the examples that localizing a constant or enum value (i.e. local val = enum_value) before loops would solve all performance problems. You could benchmark it by using os.clock, which is an accurate aproximation of the time used on the CPU by the process:

                            Code:
                            function time_it(name, func)
                            local t = os.clock();
                            func();
                            local d = os.clock() - t;
                            print(("time %s: %0.5f seconds"):format(name, d - t));
                            end
                            
                            time_it("all in _G 1000 times", function()
                            for r = 1, 1000 do
                            for i, v in pairs(_G) do
                            print(i, v);
                            end
                            end
                            end);
                            But for the functionality you're going for there is not too much you can do, except for having the _G __index and __newindex as a C function.
                            Thanks for the detailed info. I'll warn users on the github page and then run some benchmarks and see how it performs.

                            Hey, maybe you can talk IR into doing just that :P. I'd put a star on your fork of AMS lol.
                            https://github.com/CentauriSoldier

                            Comment


                            • #15
                              Originally posted by Centauri Soldier View Post

                              Thanks for the detailed info. I'll warn users on the github page and then run some benchmarks and see how it performs.

                              Hey, maybe you can talk IR into doing just that :P. I'd put a star on your fork of AMS lol.
                              If IR would open-source AMS I would contribute, but I don't think they ever will. :(
                              Bas Groothedde
                              Imagine Programming :: Blog

                              AMS8 Plugins
                              IMXLH Compiler

                              Comment

                              Working...
                              X