[Sammelthema] Objektorientierte Programmierung (OOP)

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • hey Hey Jetzt bin ich während des Programmieren meines Haussystems doch noch auf ein Problem gestossen

      Gibt es eine Möglichkeit ein "object" auch zwischen server und client zu triggern?

      Denn ich bekomme wenn ichs mit triggerClientEvent(thePlayer,"irgendeinevent",thePlayer, dasHausObject) nur Fehler wenn ich auf die Funktionen zugreifen will
      Meine Beiträge beinhalten keine Rechtschreibe- oder Gramatikfehler, sie beinhalten nur Easter-Eggs für besonders gebildete Menschen :)
    • die frage ist wie ich es kompakt ihr schicke ^^ ist ziehmlich groß inzwischen

      im großen und ganzen sieht es so aus:

      Quellcode

      1. Haus = {}
      2. Haus.__index = Haus
      3. function Haus:constructor( ID, hx, hy, hz, irid, preis, miete, kasse, city, qm, stockwerke, wert )
      4. self.coords={ tonumber(hx), tonumber(hy), tonumber(hz)}
      5. self.irid=tonumber(irid)
      6. self.preis=tonumber(preis)
      7. self.miete=tonumber(miete)
      8. self.kasse=tonumber(kasse)
      9. self.city=city
      10. self.qm=tonumber(qm)
      11. self.stockwerke=tonumber(stockwerke)
      12. self.wert=tonumber(wert)
      13. self.ID=tonumber(ID)
      14. end
      15. function Haus:getIRID()
      16. return self.irid
      17. end
      18. .. viele weitere funktionen
      Alles anzeigen


      und an einer anderen stelle sowas wie

      Quellcode

      1. haus[laufendeNr]=new(Haus, die argumente dazu)


      und an einer ganz anderen Stelle

      Quellcode

      1. triggerClientEvent(thePlayer,"triggerValidHouses",thePlayer,haus)


      so solange ich Serverseitig damit arbeite (Objecte sind Serverseitig) geht das alles Problem los. Also auch die Funktion haus[nr]:getIRID()

      wenn ich aber nun nach dem trigger durch das Event triggerValidHouses die funktion Clientseitig aufrufe etwa so:

      Quellcode

      1. addEvent("triggerValidHouses",true)
      2. function triggerValidHouses_func(houses)
      3. houses[nr]:getIRID()
      4. end
      5. addEventHandler("triggerValidHouses",getRootElement(),triggerValidHouses_func)


      erhalte ich clientseitig diesen netten Fehler:
      [2014-05-15 20:45:50] ERROR: SYSTEM\haussys\haussystem_neu\iraum_kauf_client.lua:76: attempt to call method 'getIRID' (a nil value)
      Meine Beiträge beinhalten keine Rechtschreibe- oder Gramatikfehler, sie beinhalten nur Easter-Eggs für besonders gebildete Menschen :)
    • geramy schrieb:

      hey Hey Jetzt bin ich während des Programmieren meines Haussystems doch noch auf ein Problem gestossen

      Gibt es eine Möglichkeit ein "object" auch zwischen server und client zu triggern?

      Denn ich bekomme wenn ichs mit triggerClientEvent(thePlayer,"irgendeinevent",thePlayer, dasHausObject) nur Fehler wenn ich auf die Funktionen zugreifen will


      Ne das macht auch keinen Sinn. Da ein Objekt im Prinzip nichts anderes als eine Tabelle ist, wird sie zwar übertragen. Informationen über gespeicherte Funktionen gehen dabei allerdings verloren. Meistens macht es ja auch keinen Sinn Serverlogik auf dem Clienten auszuführen. Dieser dient im Idealfall nur dem visuellen Teil und nicht der relevanten Datenverarbeitung. Zeug wie Wegfindung kann man z.B. super Clientseitig implementieren. Du könntest natürlich eine Clientseitige Klasse erstellen und die Objekte, die du gerade benötigst vom Server synchronisieren. Im iLife Script nutzen wir dabei mehrere Methoden. Statische Spieldaten aus der Datenbank, wie z.B. Items werden beim Resourcestart vom Clienten angefragt und dann vom Server gesendet. Manche Daten werden für alle Spieler synchron gehalten, manche Daten werden nur für einzelne Spieler synchron gehalten. Man muss halt immer vorher wissen, was man Clientseitig benötigt.

      Bevor ich es vergesse: [Release] MTA Class Library
      Super, das Teil ;)

      MfG
      Ich bin nicht mehr in MTA aktiv!

      rewrite.hacksand.win
    • @rewrite: die klassen library nutze ich schon xD

      Neija in anderen Sprachen bzw. Logiken geht es ja (ich hab durch aus auch schon so manchen Sync mit PHP oder Java geschrieben die auf gleiche Klassen und Objecten bestanden) ... Schade eigentlich, denn in meinem Haussystem das ich jetzt geschrieben habe, würde das einiges erleichtern... Egal dann wirds eben oldschool gemacht xD
      Meine Beiträge beinhalten keine Rechtschreibe- oder Gramatikfehler, sie beinhalten nur Easter-Eggs für besonders gebildete Menschen :)
    • geramy schrieb:

      @rewrite: die klassen library nutze ich schon xD

      Neija in anderen Sprachen bzw. Logiken geht es ja (ich hab durch aus auch schon so manchen Sync mit PHP oder Java geschrieben die auf gleiche Klassen und Objecten bestanden) ... Schade eigentlich, denn in meinem Haussystem das ich jetzt geschrieben habe, würde das einiges erleichtern... Egal dann wirds eben oldschool gemacht xD


      Serialisierung funktioniert bei Java z.B. auch nur bei gleichen Klassen. Da werden auch keine Funktionen angerührt ^^.
      Und PHP ist eine rein serverseitige Scriptsprache. Ist alles schlecht vergleichbar.

      Alleine aus Sicherheitsgründen würde ich keine Funktionen vom Server an den Clienten übertragen.

      Musst du nicht melde dich bei mir mal in Skype.

      Super. Ich liebe Leute wie dich!
      Lass keinen Menschen an deinen Lösungsansatz teilhaben.
      Ich bin nicht mehr in MTA aktiv!

      rewrite.hacksand.win
    • rewrite ich rede im falle von php von einer server <> server verbindung mit 2 unterschiedlichen Servern (zB via REST API)
      einer von beiden server wird in dem falle dann zum client. Unterschied ist ja nur, dass ichs dort via json oder Serialisierung mache ... Ist auch wayne wenns hier nicht geht ....

      achso und mit selben klassen ^^: das object wäre client und server ja von der selben klasse abgeleitet ^^
      und hier geht es ja eigentlich nur um berechnungsfunktionen etc :( bzw abfrage funktionen bin halt eigentlich kein Freund von klasse.attribute direkt ansprechen aber ist auch wayne habs wie gesagt jetzt clientseitig über oldschool tabledingens gelöst ^^
      Meine Beiträge beinhalten keine Rechtschreibe- oder Gramatikfehler, sie beinhalten nur Easter-Eggs für besonders gebildete Menschen :)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von geramy ()

    • Und zwar habe ich zwei Fragen:
      Die erste: Wenn ich z.B. eine Funktion namens dx:dxGetText mache und ich dann aufeinmal zwei dx Editbox habe und ich dann abfrage was in self.text steht, wird dann z.B. das funktionieren:

      LUA-Quellcode

      1. dxEdit1 = dx:EditboxNew(x,y,w,h)
      2. dxEdit2 = dx:EditboxNew(x,y,w,h)


      und wenn ich dann dx:GetEditText eingebe z.B.

      LUA-Quellcode

      1. function dx:GetEditText ()
      2. if not self.activ then return end
      3. return self.text
      4. end


      Nicht wundern das ist nicht der volle Code ich wollte jetzt nurmal Fragen ob das möglich ist, oder sich dann dxEdit1 und dxEdit2 irgendwie überschneiden oder für jede eigene Editbox eine Instanz erstellt wird?

      Meine zweite Frage ist folgende: Wenn ich eine dxKlasse mache für einen Button wie z.B. mache ich es das dann eine Funktion ausgeführt wird, aber die dann immer anders ist.

      z.B. bei dxEdit 1 führe einen output aus und bei dxEdit 2 führe eine Positionsänderung durch

      Mfg Iven
    • Iven schrieb:

      Meine zweite Frage ist folgende: Wenn ich eine dxKlasse mache für einen Button wie z.B. mache ich es das dann eine Funktion ausgeführt wird, aber die dann immer anders ist.

      z.B. bei dxEdit 1 führe einen output aus und bei dxEdit 2 führe eine Positionsänderung durch

      Die Funktion als Argument mit übergeben.

      LUA-Quellcode

      1. function text6()
      2. outputChatBox("Hallo ich bin text 6")
      3. end
      4. function text69()
      5. outputChatBox("Hallo ich bin text 69")
      6. end
      7. function callFunction(attachedFunction, ...)
      8. attachedFunction(...)
      9. end
      10. callFunction(text69)
      11. --> "Hallo ich bin text 69"
      12. callFunction(text6)
      13. --> "Hallo ich bin text 6"
      14. callFunction(outputChatBox, "Hallo ich bin kein text", root, 255, 0, 0, true)
      15. --> "*ROT*Hallo ich bin kein text*ROT*"
      Alles anzeigen

      Ist zwar keine OOP aber ist ein ähnlicher bzw. der gleiche Aufbau.
    • LUA-Quellcode

      1. Klasse = {}
      2. function Klasse:new(...)
      3. local o = setmetatable({}, {__index = self}) -- o(Objekt) erstellen und metatable setzen
      4. -- Methoden aufrufen
      5. o:constructor(...) -- constructor aufrufen
      6. addEventHandler("onPlayerJoin", getRootElement(), bind(self.registerPlayerElement, self)) -- ( benötigt classlib wegen bind-Funktion )
      7. return o -- o(Objekt) zurückgeben
      8. end
      9. function Klasse:constructor(...)
      10. self.m_Data = {} -- Datentabelle für bspw. Spieler erstellen
      11. end
      12. function Klasse:registerPlayerElement()
      13. self.m_Data[source] = {} -- Beim joinen eines Spielers (source) eine weitere Tabelle erstellen, welche in der Datentabelle liegt.
      14. print(tostring(source).." has been registered")
      15. end
      16. Klasse:new() -- Klasse aufrufen
      17. --//--
      18. Personen = {}
      19. setmetatable(Personen, { -- Metatable auf Personen setzen.
      20. __call = function(_, name, age, adress) -- Metamethode __call nutzen
      21. local o = setmetatable({ -- o = eine neue Person - metatable setzen worin daten gespeichert sind
      22. Name = name,
      23. Age = age,
      24. Adress = adress
      25. }, {__index = Personen})
      26. return o
      27. end
      28. })
      29. function Personen:getName()
      30. return self.Name
      31. end
      32. function Personen:setName(name)
      33. self.Name = name
      34. end
      35. -- Diese Methoden sollten selbsterklärend sein
      36. Person1 = Personen("Max Mustermann", 35, "Musterstraße 35") -- Neue Person in Variable erstellen
      37. local Person1_Name = Person1:getName() -- Namen abfragen mit VARIABLE_NAME:METHODE also bspw. Person1:getName()
      38. print(Person1_Name)
      39. Person1:setName("Erika Mustermann")
      40. local Person1_Name = Person1:getName()
      41. print(Person1_Name)
      Alles anzeigen


      Ist eine etwas ältere Übung meinerseits. Vielleicht kann es ja jemand gebrauchen.
      Es sind zwei verschiedene Klassen wie man sehen kann. Unterteilt durch "--//--".

      mfg
    • Ist soetwas Objekt orientierte Pogrammierung(bin grad am lernen)

      LUA-Quellcode

      1. mainsystem = {}
      2. mainsystem.__index = mainsystem
      3. function mainsystem:onPlayerJoin ()
      4. local init = {}
      5. init.join = function() init:onJoin() end
      6. addEventHandler("onPlayerJoin",getRootElement(),init.join)
      7. setmetatable(init,self)
      8. return init
      9. end
      10. mainsystem:onPlayerJoin()
      11. function mainsystem:onJoin()
      12. source:setCameraMatrix(0,0,20,0,0,20)
      13. source:fadeCamera(true)
      14. outputChatBox(source:getName().." hat den Server betreten!",source,math.random(1,255),math.random(1,255),math.random(1,255))
      15. setElementData(source,"Lobbyname","Main-Lobby")
      16. setElementData(source,"Lobby",0)
      17. end
      Alles anzeigen


      LUA-Quellcode

      1. dbfunctions = {}
      2. dbfunctions.__index = dbfunctions
      3. function dbfunctions:connect ()
      4. dbfunctions.connector = dbConnect("mysql","dbname=multimode;host=127.0.0.1","root","")
      5. if dbfunctions.connector then
      6. outputDebugString("Datenbank Verbindung erfolgreich!")
      7. else
      8. outputDebugString("Datenbank Verbindung fehlgeschlagen!")
      9. end
      10. end
      11. dbfunctions:connect()
      12. function dbfunctions:setUserData(element,tabledata,value)
      13. local sql = dbExec(dbfunctions.connector,"UPDATE userdata SET `"..tabledata.."` = '"..value.."' WHERE Benutzername = '"..element:getName().."'")
      14. if sql then
      15. return true
      16. else
      17. return nil
      18. end
      19. end
      20. function dbfunctions:getUserData(element,tabledata)
      21. local sql = dbQuery(dbfunctions.connector,"SELECT * FROM userdata WHERE Benutzername = '"..element:getName().."'")
      22. if sql then
      23. local result = dbPoll(sql,-1)
      24. return result[1][tabledata]
      25. else
      26. outputDebugString("Es gab ein Problem mit der Methode getUserData!")
      27. return nil
      28. end
      29. end
      Alles anzeigen


      Es funktioniert alles nur ist das OOP? Und ist es so richtig gestaltet?
    • Also, das was wir "OOP in MTA" nennen, ist eigentlich garkein richtiges objektorientiertes Programmieren.

      Jedoch kommt das, was du da gescriptet hast, dem schon Nahe, denn du hast deine Klassen und deine Methoden.


      Was mir jedoch aufgefallen ist, ist, dass du deine Instanzen nicht in einer Variable zwischenspeicherst.
      So kannst du im Nachhinein nicht mehr auf sie zugreifen.
      Es geht ja eigentlich darum, eine Klasse zu haben, die ihre Methoden hat, und aus der man sich dann eine Instanz erzeugt.
      DEAL WITH IT.
    • Sowas z.B:

      LUA-Quellcode

      1. dxButton = {}
      2. function dxButton:createButton(x,y,w,h,text,callfunc)
      3. local o = setmetatable({},{__index = self})
      4. self.x = x
      5. self.y = y
      6. self.w = w
      7. self.h = h
      8. self.text = text
      9. self.callfunc = callfunc
      10. self.visibility = true
      11. return o
      12. end
      13. function dxButton:setVisible(boolean)
      14. self.visibility = boolean
      15. end
      Alles anzeigen
    • LUA-Quellcode

      1. function dxButton:getText()
      2. return self.text
      3. end
      4. local instanz1 = dxButton:createButton(1,1,1,1,"Hallo",func)
      5. local instanz2 = dxButton:createButton(1,1,1,1,"text",func)
      6. addCommandHandler("text",function()
      7. local text = dxButton:getText(instanz1)
      8. outputChatBox(text)
      9. end)
      Alles anzeigen


      Das Problem ist er gibt mir immer nur die Variable der letzt erstellten Instanz zurück. Heißt hier hat der mit anstatt "Hallo", "text" zurückgegeben, aber ich möchte halt auch mehrere Instanzen am laufen haben und von denen dann auch separat was verändern und aufrufen.
      Mfg Iven