Jump to content

[WIP] openFrame - The first fully OOP LUA Framework!


Orange

Recommended Posts

Yes! Finally, our team is going to finish the first version. Let me say about main ideas of this project:

Defaulty in mta, global variables are available "in a list", so when we have files:

  • 1.lua (can access just global variables from 1.lua)
  • 2.lua (can access global variables from 1.lua and 2.lua)
  • 3.lua (1.lua, 2.lua and 3.lua)

and we can use global variables of file "1.lua" in files: 1.lua, 2.lua, 3.lua, but when you'll try to use global variable from 2.lua in file 1.lua, you'll get an error. That's why I made "Storage" class. It's the first loaded class. It allows to store variables and use it in resources, which was loaded before. For example, "1.lua" is Storage class. I'd like to make a SQL connection in "3.lua" and use it in "2.lua". The code will look like that:

3.lua

local SQL = MySQLConnection:Create("host", "user", "password", "db")
Storage:Store("SQL", SQL)

2.lua

local SQL = Storage:Get("SQL")
SQL:Query("blah blah blah")

It's simple - isn't it? But it's just first class of others included in openFrame.

The second class is Database Wrapper, which currently supports just MySQL. It allows you to easier use your database. For example, querying a string and doing operations on result is something like that:

local SQL = MySQLConnection:Create("host", "user", "password", "db")
local r = SQL:Query("SELECT * FROM example_table")
while true do
local row = r:fetchAssoc()
	if (not row) then break end
       outputDebugString(row["example_column"])
end
r:freeResult()

That's easy too... But you can make making your queries a lot easier. Our third class called "Builder" allows you to build SQL queries!

local result = SQL:Query(Builder:Select("*"):Where("1 = 1", "2 = 2"):Order_By("id", ASC):Get("example_table"))

If you'll debug it, the builder will return string like:

SELECT * FROM example_table WHERE 1 = 1 AND 2 = 2 ORDER BY id ASC

also, if you'd replace "Where" with "WhereOR", it would return:

SELECT * FROM example_table WHERE 1 = 1 OR 2 = 2 ORDER BY id ASC

Also, there's an Event System. It can replace

addEvent("testEvent", true)
addEventHandler("testEvent", getRootElement(), func)

to

Event:Create("testEvent", true):Handle(func, getRootElement())

It's a lot easier and shorter.

These are currently finished classes. I'm working at finishing SQL classes (Builder and Database). Later, I'll finish server classes, but I have to do basic client ones before :P

Can you say something about this idea? Maybe, suggestion about new module? Post it! I'll read this topic everyday :)

Edited by Guest
Link to comment

It's a good start.

I would like making new elements as new instance of a class and accessing data fields as class fields (instead of getElementData()) with extra setting to make any field synced (element data) or not (just a class field), so the class would be one-stop place for any temporary data fields that don't need to be synced while also the synced element data. Let's call it Element class.

If that would be ready, adding new specific classes for element types, like Player, Ped, Vehicle, Team, etc wouldn't be a problem by inheriting the Element class and adding specific methods (i.e for player getMoney() or similar).

Usage of the Element class (yes, table in Lua, but I hope it's okay to call it class for easier understanding) could be something like this:

-- Make new fictional element, let's say it's an ant
local ant = Element:new()
 
-- Add synced data called "mood" with initial value "happy" (3rd argument is isSynced, so it's also accessible client-side)
ant:addData("mood", "happy", true)
-- Get it directly
ant.mood
-- or via global getter (we could also make a new method getMood if wanted, so we could do any extra processing, but that's not part of the framework)
ant:getData("mood")
 
-- Add unsynced data called "numberOfLegs" with initial value 6 (it would be nice to remember the type 'number', so number is returned when using getter, even if it's synced (as using getElementData returns string iirc) (3rd argument is isSynced, which is set to false, so it's not sent to client, nor synced when changed)
ant:addData("numberOfLegs", 6, false)

And anything could be added to here, like listeners (event handlers if element data changes).

Hope I gave any ideas, as you have the right idea. Doing more complex gamemodes or other resources get's messy without a nice common framework.

EDIT: Of course, my example is a bit naive, but gives the idea.

Edited by Guest
Link to comment

Madis - I totally forgot about it :P It's a very good idea, I'd implent it, when I'll finish Event and Builder classes - It will be available at svn.

Additionaly, I registered at Google Code. Here's the link :P

Also, the code will be tested on a new "Andromeda Test Server", which will be ready in next week. Thanks for "xSzyneKx" for sponsoring it.

The next svn version of Event class will include "Use" function for default events. For example:

Event:Use("onPlayerJoin"):Handle(onJoin)

Thanks for reading this post. By the way, does someone want to join me with creating openFrame?

Link to comment

Update:

To reduce amount of used variables, I've made a "of" table with all classes stored in.

Also, making of these classes is simplified. "of.class:new" allows to inherit and automatically add "elementData" (.data) arrays.

For me, next update will be more smiliar than r6.

Link to comment
  • 1 month later...
Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...