Jump to content

rain_gloom

Members
  • Posts

    228
  • Joined

  • Last visited

Posts posted by rain_gloom

  1. Even if that works, what if you want a namespace.create() function that returns a new object. It won't work, I tried several things before, none worked.

    I guess metatables won't work, but I only use them for the OOP syntax in this particular case.

    Just think about it, all that the 'myObject:method' notation does is it inserts an implicit 'self' as the first argument.

    Yes, I won't have OOP methods, but I'll still be able to use the old MTA syntax, as in:

    classnameDoSomething(classObject) 
    

    Here is the relation in detail:

    class={} 
    class.__index=class 
    function class.new() 
    return setmetatable({num=0},class) 
    end 
    class_new=class.new 
      
    function class:setnum(x) 
    self.num=x 
    end 
    class_setnum=class.setnum 
    --the above function's formal description will actually become this: class.setnum(self,x) 
      
    

    An OOP call in Lua looks like 'obj:method(...)' which is shorthand for 'obj.method(obj,...)', but of course we know that the 'obj.' can go through __index, which allows the object to inherit its data from another table.

    If we sacrifice that kind of call syntax and all metamethods, the code can be exported without redundancy in the memory.

    I really hope the MTA team is going to fix this though, but since OOP in MTA is still relatively young, I think it is forgivable that they have not yet done it.

  2. Yup, I've tried that, but that's very redundant.

    I'm going to test exporting without the OOP format. As in:

    namespace={} 
    --OOP definition 
    function namespace.foo() return "bar" end 
    --May be exportable through this name? 
    namespace_foo=namespace.foo 
    

    and then:

    <export function="namespace_foo" type="shared"/> 
    

    Will edit with the results.

    Since I started working on implementing a pre-processor, I could add an automatic converter for exported OOP functions this way.

    Even if it works, it loses the whole point of OOP. Well, the syntax at least.

  3. Tested it right now. I printed all keys and the only one it had was __index, which is also the only one with a non-function value. :/

    *sigh* I guess I'll have to use the functional syntax.

    Or I could just load the script into every resource that needs it. But that would be a waste of good memory and inelegant. So not in the Lua way :/

  4. Since MTA does not always report the full error message, you are better off using this little trick, whenever you aren't sure what's wrong.

    Here is a very simple script we want to debug:

    error"I'm an error!" 
    

    (I couldn't find a better example. This gives a proper message, but more complex errors sometimes don't. If you can find a better error, please share.)

    Here is the same thing wrapped inside a pcall.

    outputDebugString(select(2,pcall(function() 
      
    error"I'm an error!" 
      
    end)) or "Everything went smooth.") 
    

    Here is what happens:

    We wrap the script into a function. This changes nothing in its behaviour. (except that it won't automatically run if we don't call it, but we will take care of that.)

    We call the new function using 'pcall'. 'Pcall' is a very useful function, which executes a function, then returns 'true' (and whatever the function returned) if it ran without errors and 'false' and the error message if it failed.

    We want to get that error message printed, so we use 'select'. This is a vararg function. Its first argument indicates how many of the following arguments should be discarded. Example:

    print(select(2,1,2,3)) 
    

    Will print:

    2,3 
    

    We use that to select the returned error message, which is then printed, but only if it exists.

    Since MTA scripts rarely return anything at the end of the file (which is used in normal Lua to create modules), if there was no error, then 'pcall' only return 'true'. Hence the second argument is 'nil'.

    We can leave it nil, we'll only get a warning that 'outputDebugString' was expecting a string, but let's make it a bit more correct with this simple trick.

    As you should already know, 'or' does not necessarily return a boolean, it returns whichever operand was not 'false' or 'nil'.

    If the first operand evaluates to false (only 'false' and 'nil' does) it returns the second one, in this case, the message telling us that everything went smooth.

    I hope I could help, writing this sure passed some time on networking class. :mrgreen:

    Note:

    this won't automatically work for functions called by event handlers, but the principle is the same

  5. I made an implementation of this pre-processor. Currently it just returns the processed file as a string.

    Example file:

      
    #debug=true 
    function power (x,n) 
        #if debug then 
        print(x,n) 
        #end 
        if n==0 return 1 else 
        return x*power(x,n-1) 
    end 
    powersOfTwo={ 
    #for i=0,10 do 
        $(2^i), 
    #end 
    } 
    

    Becomes:

      
    function power(x,n) 
        print(x,n) 
        return x*power(x,n-1) 
    end 
    powersOfTwo={ 
        1, 
        2, 
        4, 
        8, 
        16, 
        32, 
        64, 
        128, 
        256, 
        1024, 
    } 
      
    

    Useful if you want to build more optimized scripts, pre-initialize constants, make debug builds, make debug code easily removable.

    If there is demand for it, I'll try to implement the more sophisticated version

    I'm planning to use it for a server-side "build" system. It would pre-process the files, then send them to the compiler, save the compiled version as a luac file, then edit the meta.xml accordingly.

    Which files are pre-processed and which to compile should be controllable either in the Meta or a separate config file per-resource.

    If you have any suggestions, I'd be happy to hear them.

    ps.: don't ask for a GNU Make-style thingy, I have something that remotely resembles a life

  6. Since SA is apparently reasonably portable, could MTA be made portable too?

    I've tried this thingy called Cameyo inside a clean Windows 7 virtual machine, but when I start MTA, it just opens the splash screen, then pops up the "GTA:SA might not have started correctly" (or stg like that).

    Have anyone succeeded with this before?

  7. rain, this is because unpack is defined for indexed tables, not dictionary tables. You're essentially writing a "tutorial" to make unpack support the wrong syntax

    You're also using tables wrong. Tables don't have nil values. It might sound like it does. But it doesn't. When t[key] == nil, it denotes the absence of a value. t[key] = nil removes the value.

    Instead of nil use a value of eg -1 so you know that there is 'no value' in there.

    Sounds good actually.

    While we are at tables, here is how I know it:

    A table in Lua has two parts (implementation-wise): an array part and a hash (or dictionary or whatever you want to call it) part.

    The array part of table 't' is from t[1] to t[#t] and if the table only has an array part, it is called a sequence.

    Anyways, using a substitute value would actually be faster, but I'm not sure if that's true for decoding the substitute. I'll test it sometime. Maybe.

    Anyways, I preferred this method because the code reading the table does not need to know what the substitute value is, but maybe it would be bad for larger scale usage.

  8. Instead of using a timer (which would be a waste of resources), you could have a separate client-side script, that triggers the server-side part when the ped is streamed in. Not sure how that will affect anim-syncing though. Maybe you could keep track of time as well and set the anim progress accordingly.

    It's a bit more complicated, but I think it could even be used for multiple peds without too much overhead.

    Sry, no code.

  9. Could someone help with the math here?

    If I have a line of length 'a' and it is 'd' distance away from the camera, how do I calculate the perspectively correct size on screen? I checked existing 3d text resources, but the only method I found is incorrect and I don't know what to google. ._.

    (Part of what I'm trying to do is to replicate the "effect" system of the game "XIII", that's why I want it to be this way)

  10. Unpack uses the length of the array part by default, so if your table has a "hole" in it, the unpacking will stop before that hole.

    eg.:

    print(unpack{1,2,3,nil,5}) 
    

    will give you

    1,2,3 
    

    That is because 5 is not stored in the array part. If you do not know what that is, I recommend googling it. You could learn a few things about optimizing Lua code as well.

    Bottom line: unpack does not like nils. There are quite a few ways to deal with this (as there are to everything in Lua), but many of them implement metamethods and some placeholder for nil, which is not really flexible.

    Simplest solution: define an explicit 'n' field and use that with unpack. This is also how vararg functions work, they also define such a field i their 'arg' table.

    eg.:

    unpack(t,1,t.n) 
    

    This also means that you must store the table in some way, but that's not quite as big an overhead as calling through a metamethod. It is also portable through MTA calls and exportable to JSON and other common formats. (metatables are not)

  11. AFAIK, you can do this by using custom models in single-player, not sure if loading those would work in MTA though. There was a mod that added such points to the ends of trailers, letting the player create chains of trailers. (sry, I can't find it)

    I think you just add a dummy object with the appropriate name to the appropriate parent.

    But if this was possible from scripts, that would indeed be better. (no dff downloads)

  12. How can I add custom OOP methods to a custom element type?

    eg.:

    (getElementsByType("myElementType")[1]):someCustomMethod() 
    

    :arrowup: That should call a method on the element I created.

    It should also support exporting, if possible.

    What kind of constructor would I need?

    Does the new OOP support this?

  13. Az inventory nak valszeg lesz két változata, egy beépített (OOP) és egy export (hagyományos MTA) változata (ami lehet hogy csak az OOP-hez lesz egy interface).

    PL pont nem kell, egyelőre hagyom, de később jól jöhet.

    A self, ja. Hmm... képzeld el így:

    Van egy class base amin keresztül mennek az object-ek és a saját indexei is.

    Az object-ek pölö a method-jaikat a base-től öröklik egy sima __index-szel, de a base is örököl, mondjuk a table-ből.

    Angol: hagyjuk az egészet, angolul írni könnyebb. (legalábbis ilyen szöveget) Nem véletlenül nem magyarul kommentelem a kódot.

  14. nem saját dxgui -.- annyira azért nem unatkozok hogy abba belekezdjek

    oop-t amúgy meg lehetne oldani, például egy globális metatable tárral, nem mondom hogy túl egyszerű lenne, de megoldható.

    --automatikusan hozzárendel egy táblát a generált globális táblákhoz, teszteletlen, de elvileg működnie kell 
    ( esetleg a metódusokat exportolni kell és az exportokra hivatkozni a táblákban, de ha valaki ezeket figyelembe véve írja az egész kódot, akkor no problemo ) 
    setmetatable (_G,{ __newindex = function ( self, i, v ) 
    if type ( v ) == "table" then 
    rawset ( _G,i,v._meta and setmetatable(v,exports.gmeta:get(v._meta) or v ) 
    else 
    rawset(_G,i,v) 
    end 
    end 
    

    az if kinézhet úgy is, hogy az első fele a class funkcióit keresi (class inheritance indices), míg a második az object-ek számára keres az osztályon belül. (class root index)

    remélem értelmesen magyaráztam

    ha nem az se baj

    penlight: tiszta Lua kód, tehát csak az io meg os cuccokat kell helyettesíteni (és a require-t) és már működik is egy csomó része, ami meg nem, az nagy eséllyel úgyse kell.

    az inventory közben halad, már majdnem kész minden get/set alapja és a gui (mivel dxgui exportokra épül) azután már csak pár dxDrawImage meg dxCreateWindow

    --edit: valamelyik előző postban volt valami a metamethod-okról, íme az új módszer:

    t = setmetatable({},{ 
    __index = function ( self, i ) 
    if self ~= t then--ha nincs a class gyökerének inheritation-je 
    return rawget(t,i)--mivel a rawget nem invoke-ol metamethod-okat (komolyan irritál ha magyarul kell kódot kommentelnem, az összes rag hülyén hangzik az idegen szavakon, kiszótáraznom őket meg minek) 
    end 
    end 
    }) 
    

    ajánlom a Lua tanulmányozását az MTA-n kívül :)

×
×
  • Create New...