Need some Object advice
Monkey Forums/Monkey Programming/Need some Object advice
| ||
Hey all So I know about objects and stuff but I want to put all my classes for buttons, screens, text, gui, texture packs, etc. Into a more manageable and unified framework. Managed from one top level class. At the moment I have different classes for each feature such as; button1 = new Button(image,x,y) screen1 = new Screen texPack1 = new TexturePack(file) What I want is to prefex all these calls with an initial class (in this example its called FRAMEWORK, such as; button1 = new FRAMEWORK.Button(image,x,y) screen1 = new FRAMEWORK.Screen texPack1 = new FRAMEWORK.TexturePack(file) So ill be keeping them all as different classes I just want to call FRAMEWORK and from that IntelliSense takes over and give me routes in the Button, Screen, texture pack classes etc. I hope that makes sense. =) |
| ||
I generally have a few top-level classes that are just containers for global data. A few are "organised" groups like colour palette, fonts etc. but I also usually have something like GameGlobals for just chucking odds and ends into. |
| ||
I guess you could use a factory class for Framework, e.g. the call would be something like: button1 = Framework.CreateButton( x, y, image ) I'm not sure if it's worth the trouble, though - simply constructing a Button seems simple enough. What you might consider is having your controls all implement an interface with common functions such as GetRect:Rect(), MouseHitEvent:Int( mouse:Point ), Draw:Void()... things like that. So you could replace a button with a slider without changing much code etc. I haven't bothered with that myself, but I would do it if I were making an interface library. Or maybe have all controls inherit from a window class, like in MFC. |
| ||
A file counts as a namespace. That's why you can call mojo.DrawImage(...) So just create a framework.monkey file which import buttons, screens, etc |
| ||
Thanks guys - I ended up doing the following;' --- init Global Engine:= New FrameWorkClass Global button1:= New ButtonClass ' --- calls Engine.Button.Create(button1, 20, 20, 250, 100) Engine.Button.Render(button1) Engine.Button.Update(button1) ' --- classes Class FrameWorkClass Field Button:ButtonClass = New ButtonClass Field DebugLog:DebugLogClass = New DebugLogClass End Class Class ButtonClass Private Field x:Int, y:Int, width:Int, height:Int Method Create:Void(a:ButtonClass, x:int, y:Int, width:Int, height:int) a.x = x a.y = y a.width = width a.height = height End Method Method Render:Void(a:ButtonClass) DrawRect a.x, a.y, a.width, a.height End Method Method Update:Void(a:ButtonClass) ' blah End Method End Class Now I can just call Engine and go from there, just what I wanted. |
| ||
Personally I think it's a bit clunky but maybe that's just me. I would do it like this: ' --- init Global Engine:= New FrameWorkClass Global button1 := Engine.CreateButton(20, 20, 250, 100) ' --- calls Engine.Render(button1) Engine.Update(button1) ' --- classes Class FrameWorkClass Field DebugLog:DebugLogClass = New DebugLogClass Function CreateButton:Button(x:Int,y:Int,width:Int,height) Return New Button(x,y,width,height) End Function Function Render:Void(button:ButtonClass) button.Render() End Function Function Update:Void(button:ButtonClass) button.Update() End Function End Class Class ButtonClass Private Field x:Int, y:Int, width:Int, height:Int Method New(x:Int, y:Int, width:Int, height:Int) Self.x = x Self.y = y Self.width = width self.height = height End Method Method Render:Void() DrawRect x, y, width, height End Method Method Update:Void() ' blah End Method End Class |
| ||
If it works for you then fine but you're really just ignoring OO and using objects as buckets of procedures. The giveaway is that you're passing object references into your methods just like a procedural language. If you're going to do that then you may as well declare your "methods" as static functions on the class. |
| ||
yes that too. |
| ||
@Jess - that seems like more work TBH, harder to implement additional classes @Muddy - yeah screw OO I don't play the rules :p, I'll use proper OO so to speak for things outside my framework but I'd rather this method when using my frame work as I tend to forget what it can do. The only reason for doing it this way is for intellisense, no other reason. |
| ||
I agree it is clunky from an OO viewpoint (means you need a New AND a Create for every button) but I think Supertino wants to leverage his Intellisense. [Edit: I see he just said that.] |
| ||
I don't see how it's harder to implement additional classes. it's the same principle with every other class you add to it. it doesn't have to be any different. And the title do say that you want object advice. but whatever nothing to gain here for me. :) |
| ||
Would this be a solution? A container class which has a field for a 'first undefined' object : Class FrameWork Global FrameWorkList := New List<FrameWork> Field Typ%, Obj:Object Function Add:FrameWork(Typ%,x%,y%,width%,height%) Local loc:= New FrameWork loc.Typ=Typ Select loc.Typ Case BUTTON loc.Obj = New ButtonClass (x,y,width,height) End Return loc End Function Add:FrameWork(Typ%,t$) Local loc:= New FrameWork loc.Typ=Typ Select loc.Typ Case BUTTON Case TEXTUREPACK 'loc.Obj = New TextureClass (t$) End Return loc End Function RenderAll:Void() For Local loc:FrameWork=Eachin FrameWorkList Select loc.Typ Case BUTTON ButtonClass(loc.Obj).Render Case TEXTUREPACK 'TextureClass(loc.Obj).Render End Next End End And here the complete code: I did not test the code... only an idea... |
| ||
if that is the case than using a base class would be even better:' --- init Global Engine:= New FrameWorkClass Global button1 := Engine.CreateButton(20, 20, 250, 100) Global slider1 := engine.CreateSlider(100,100,45,200,0,100) ' --- calls Engine.Render(button1) Engine.Update(button1) Engine.Render(slider1) Engine.Update(slider1) ' --- classes Class FrameWorkClass Field DebugLog:DebugLogClass = New DebugLogClass Function CreateButton:Button(x:Int,y:Int,width:Int,height) Return New Button(x,y,width,height) End Function Function CreateSlider:Slider(x:Int,y:Int,width:Int,height:Int,min:Int,max:Int) Return New Slider(x,y,width,height,min:Int,max:Int) End Function Function Render:Void(obj:BaseClass) obj.Render() End Function Function Update:Void(Obj:BaseClass) obj.Update() End Function End Class Class BaseClass Field x:Float,y:Float Method Update:Void() Abstract Method Render:Void() Abstract End Class Class ButtonClass Extends BaseClass Private Field width:Int, height:Int Method New(x:Int, y:Int, width:Int, height:Int) Self.x = x Self.y = y Self.width = width self.height = height End Method Method Render:Void() DrawRect x, y, width, height End Method Method Update:Void() ' blah End Method End Class Class Slider Extends BaseClass Private Field width:Int,Height:Int,min:Int,max:Int Method New(x:Int, y:Int,width:Int,height:Int,min:Int,max:Int) Self.x = x Self.y = y Self.width = width Self.height = height Self.min = min Self.max = max End Method Method Update:Void() 'dodododo End Method Method Render:Void() 'dodododo End Method End Class on either case I don't think the Framework/engine idea is of any real use as it stands. As muddy mentioned, it's just a bucket of procedures. There needs to be more meaningful purpose for it to be of any real use. |