Thread Tools Display Modes
08-29-11, 10:30 PM   #1
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
Object-Oriented System for lua

Well, I want to introduce my lib addon 'IGAS'. Although it's just in beta, I thought it's time to bring it in.

In this addon, I built a object-oriented system for lua. Here is a sample code running outside wow.

Code:
require "oop"

IGAS:NewAddon("MyTestAddon") -- keywords like 'class' only working under addon's enviroment

class "Test"  -- begin class definition
	inherit "System.Object"    -- inherit class, System.Object is the base class for others.

	script "OnNameChanged"  -- like "OnClick" for blz's button, the script handler declaration

        -- property definition
	property "Name" {
		Get = function(self)
			return self.__Name
		end,
		Set = function(self, name)
			self.__Name = name
			self:Fire("OnNameChanged", name)
		end,
		Type = String,  -- the type's value can be class, struct, enum or nil, used for validation.
	}

        -- Global function is the class's method
	function PrintName(self)
		print(self.__Name)
	end

        -- the function with the class's name is the constructor
	function Test(name)
		local obj = System.Object()

		obj.__Name = name

		return obj
	end
endclass "Test"  -- end class definition
Here is a test result pic:
Click image for larger version

Name:	testIGAS.jpg
Views:	1060
Size:	70.4 KB
ID:	6467

Some information about this system:
1. three base data structure type
class
enum
struct

2. Now base structs(WOW's structs not included) stored in global namespace:
System.Boolean
System.String
System.Number
System.Function
System.Table
System.Userdata
System.Thread
System.Any
System.LocaleString

2. Now classes stored in global namespace:
System.Object
System.Threading.Thread
System.Addon
System.Addon.Module
System.Locale
System.Logger

-- For wow
System.Widget.UIObject
System.Widget.VirtualUIObject

System.Widget.AnimationGroup
System.Widget.Animation
System.Widget.Translation
System.Widget.Rotation
System.Widget.Scale
System.Widget.Alpha

System.Widget.Font
System.Widget.Region
System.Widget.LayeredRegion
System.Widget.Frame
System.Widget.Texture
System.Widget.FontString
System.Widget.FontFrame
System.Widget.Button
System.Widget.Cooldown
System.Widget.ColorSelect
System.Widget.EditBox
System.Widget.GameTooltip
System.Widge*****ssageFrame
System.Widget.Minimap
System.Widget.Model
System.Widget.ScrollFrame
System.Widget.ScrollingMessageFrame
System.Widget.SimpleHTML
System.Widget.Slider
System.Widget.StatusBar
System.Widget.CheckButton
System.Widget.PlayerModel
System.Widget.DressUpModel
System.Widget.TabardModel
System.Widget.ArchaeologyDigSiteFrame
System.Widget.QuestPOIFrame
System.Widget.MovieFrame

System.Widget.NormalButton
System.Widget.Timer
System.Widget.ColorPicker
System.Widget.DropDownList
System.Widget.ScrollBar
System.Widget.ScrollForm
System.Widget.Form
System.Widget.GroupBox
System.Widget.List
System.Widget.ComboBox
System.Widget.SingleTextBox
System.Widget.MultiLineTextBox
System.Widget.TreeView
System.Widget.TabGroup
System.Widget.CheckBox
System.Widget.PopupDialog
System.Widget.MinimapIcon
System.Widget.OptionSlider
System.Widget.DataGrid

For the first step, go here for a look:
http://code.google.com/p/igas/wiki/IGAS_OOP

If you like it, I may find a way to post more information about this in the future time, Now I'm working on a CodeEditor to fix my IGAS_Studio(The in-game IDE), just a little busy.

Last edited by kurapica.igas : 08-29-11 at 10:34 PM.
  Reply With Quote
09-08-11, 03:11 AM   #2
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
Sample Addon to show the thread system, to count money you spent on the merchant for every time:

TestAddon.toc
Code:
## Interface: 40200
## Title: TestAddon
## DefaultState: Enabled
## RequiredDeps: IGAS
## LoadOnDemand: 0
TestAddon.lua
TestAddon.lua
Code:
-- make codes run under one addon's environment 
IGAS:NewAddon "TestAddon"

function OnLoad(self)        -- also can be written as 'function _Addon:OnLoad()'
    -- This script fired when the addon is loaded.

    -- make OnEnable script run as a thread
    self:ActiveThread("OnEnable")
end

function OnEnable(self)
    -- This script fired when the addon is enabled.Will occur once at the beginning, 
    -- or enable addon when it's disabled.

    local money

    while _Enabled do
        -- _Enabled is the addon's enabled property, also can be written as '_Addon._Enabled'

        -- make thread wait for visiting merchant
        System.Threading.WaitEvent("MERCHANT_SHOW")
    
        money = GetMoney()
        
        -- make thread wait for close merchant
        System.Threading.WaitEvent("MERCHANT_CLOSED")

        -- now count the cost
        if GetMoney() > money then
           print("You got "..FormatMoney(GetMoney() - money))
        elseif GetMoney() < money then
           print("You spent "..FormatMoney(money - GetMoney()))
        end
    end
end

-- Get Format money
function FormatMoney(money)
	if money > 10000 then
		return (GOLD_AMOUNT_TEXTURE.." "..SILVER_AMOUNT_TEXTURE.." "..COPPER_AMOUNT_TEXTURE):format(math.floor(money / 10000), 0, 0, math.floor(money % 10000 / 100), 0, 0, money % 100, 0, 0)
	elseif money > 100 then
		return (SILVER_AMOUNT_TEXTURE.." "..COPPER_AMOUNT_TEXTURE):format(math.floor(money % 10000 / 100), 0, 0, money % 100, 0, 0)
	else
		return (COPPER_AMOUNT_TEXTURE):format(money % 100, 0, 0)
	end
end
  Reply With Quote
09-08-11, 04:22 AM   #3
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
In all honesty, the existing API already does something like this.
lua Code:
  1. local frame=CreateFrame("Frame");
  2. frame:RegisterEvent("MERCHANT_SHOW");
  3. frame:RegisterEvent("MERCHANT_CLOSED");
  4.  
  5. local money=0;
  6. frame:SetScript("OnEvent",function(self,event,...)
  7.     if event=="MERCHANT_SHOW" then
  8.         money=GetMoney();
  9.     elseif event=="MERCHANT_CLOSED" then
  10.         local diff=GetMoney()-money;
  11.         if diff~=0 then
  12.             print(diff>0 and "You made" or "You spent",GetCoinTextureString(math.abs(diff)));
  13.         end
  14.     end
  15. end);

You create a UI object known as a Frame. Through this, you can register for certain event callbacks to be received through the Frame's OnEvent handler.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
09-08-11, 07:30 AM   #4
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Although I'm not one to bash other people's work, I'm afraid you've wasted a great deal of time building this lib. As SDPhantom stated, the API is already object based and doesn't require anything added to it.
  Reply With Quote
09-08-11, 07:45 AM   #5
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
That's a sample code to show thread system, not event system, I know what I'm doing, the final goal is to make UI simple, just like this

Click image for larger version

Name:	DataGrid.jpg
Views:	1111
Size:	97.2 KB
ID:	6482

the class system's inherit make creating widgets in an easy way.

Code:
IGAS:NewAddon("TestA")

import "System.Widget"

f = Form("TestF")
f.Caption = "Test"

dg = DataGrid("Dg", f)
dg:SetPoint("TOPLEFT", f, "TOPLEFT", 8, -30)
dg:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -8, 26)

dg.ColumnCount = 3

dg:SetColumnLabel(1, "Name")
dg:SetColumnLabel(2, "Score")
dg:SetColumnLabel(3, "Passed")

dg:SetColumnCellType(1, "Label")
dg:SetColumnCellType(2, "Number")
dg:SetColumnCellType(3, "Boolean")

dg.RowCount = 5

dg.Cells(1, 1).Text = "Kurapica"
dg.Cells(1, 2).Value = 30
dg.Cells(1, 3).Value = true
Well, you may find some information in my old addon(need update)
http://wow.curseforge.com/addons/igas_studio/

The lib has too many things to explain, but I thought the base class system is the most important to start.I only have three more widgets to do now, after that, I just want see if any person want to join...

Last edited by kurapica.igas : 09-08-11 at 08:35 AM.
  Reply With Quote
09-08-11, 01:00 PM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
If it's multithreading you're looking for, Lua has a built-in Coroutine lib that's supposedly available in the WoW API. See http://www.lua.org/manual/5.1/manual.html#5.2. However, Coroutines are only a psudo-multithread process. No other code can be run the same time a Coroutine is running.

Widget inheritence can already be done in the Widget API that WoW uses. This is done by creating a virtual frame in XML and using the inherits attribute when creating a copy of it in XML or passing its name in the inheritFrame argument of a CreateFrame() call.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 09-08-11 at 02:43 PM.
  Reply With Quote
09-08-11, 09:09 PM   #7
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
Well, thread is using to stop code running when needed, in many ways it save time to build an addon, I know one time one code running, so all the lua code.

As an example, in past development, when I need to used a popupdialog to confirm something, I need call the PopupDialog, and past a callback function to wait the popupdialog call it.But with the thread, I can do like this
Code:
if IGAS:MsgBox("Are you sure to repair all items?", "n") then
    RepairAllItems()
end
No callback, the popupdialog ask you to confirm if you want repair, choose ok, then RepairAllItems will be called.Just clear what you want to do.

For the inherit, xml inherit has too many thing can't be done or hard to do, I have work on wow addons for more then five years, I know what the xml can do, and what it can't do.Ace also have ACEGUI, it's not built on xml, we all see the disadvantage in this xml system, although it don't have a full inherit system.

I need a widget system with properties and methodes, making the addon's development just like we do in .Net. And that's all I do in this lib.

Do you like

frm.Visible = not frm.Visible

or

if frm:IsVisible() then frm:Hide() else frm:Show() end

As computer, it's all the same.But to author, many things like this would make the development more flexible.
  Reply With Quote
09-09-11, 03:16 AM   #8
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
It really comes down to programming style and system overhead. It's all a tradeoff between ease of writing code and running lightweight. It's like comparing ANSI C and VBasic.



BTW, I have been known to use this style of toggling.
Code:
frame[frame:IsShown() and "Hide" or "Show"](frame);
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 09-09-11 at 03:20 AM.
  Reply With Quote

WoWInterface » Developer Discussions » Dev Tools » Object-Oriented System for lua

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off