|
serial
|
 |
« on: June 10, 2007, 05:43:37 PM » |
|
Okay, I've been working on my world editor. Right now I'm working on class design.
Trying to figure out how I can design my classes so that I can access my Truevision objects easily.
I was thinking about just doing something like this. (kinds psuedo codish)
public mesh as tvmesh
mesh = scene.createmesh("test")
class myclass public currentmesh as tvmesh end class
public blah as myclass
blah.currentmesh = globals.getmesh("test")
from here I seem to be able to manipulte the mesh inside of my class. Seems to be referenced.
I'm just curious if this is safe to do in TV, and some of the possible draw backs of doing this?
Seems to work the way I want to, but I'm still fairly new to VB.NET
|
|
|
|
|
Logged
|
|
|
|
|
newborn
|
 |
« Reply #1 on: June 10, 2007, 09:32:52 PM » |
|
I would suggest to make it private and open the tvobject with properties or functions. private _mesh as tvmesh
public sub init mesh = scene.createmesh end sub
public property position(vposition as d3dvector3) set: _mesh = vposition get: return _mesh.getposition end property
there are many reasons why this approach wold be better, one being that you could use collections and another would be usability
|
|
|
|
|
Logged
|
|
|
|
jviper
Community Member

Posts: 2058
Discipline in training
|
 |
« Reply #2 on: June 10, 2007, 11:27:08 PM » |
|
That's what I did. Working on that sort of wrapper. Hopefully will be able to show it soon.
|
|
|
|
|
Logged
|
JAbstract.....Don't just imagine, make it happen!
|
|
|
|
Raine
|
 |
« Reply #3 on: June 11, 2007, 04:55:54 AM » |
|
Since we're talking about properties, I thought it would have been interesting to check performances. Not that they really matter if we're talking about editors, but they might in a real time environment. Something people might want to consider when outlining their classes. IL comparison of reading / writing with properties or methods: //############ Reading with property ############
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 36 (0x24) .maxstack 2 .locals init ([0] class ILTest1.Program/Exposer`1<object> m_Exposer) IL_0000: nop IL_0001: newobj instance void [mscorlib]System.Object::.ctor() IL_0006: newobj instance void class ILTest1.Program/Exposer`1<object>::.ctor(!0) IL_000b: stloc.0 IL_000c: ldloc.0 IL_000d: callvirt instance !0 class ILTest1.Program/Exposer`1<object>::get_Value() IL_0012: callvirt instance string [mscorlib]System.Object::ToString() IL_0017: call void [mscorlib]System.Console::WriteLine(string) IL_001c: nop IL_001d: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() IL_0022: pop IL_0023: ret } // end of method Program::Main
//############ Reading with method ############
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 36 (0x24) .maxstack 2 .locals init ([0] class ILTest1.Program/Exposer`1<object> m_Exposer) IL_0000: nop IL_0001: newobj instance void [mscorlib]System.Object::.ctor() IL_0006: newobj instance void class ILTest1.Program/Exposer`1<object>::.ctor(!0) IL_000b: stloc.0 IL_000c: ldloc.0 IL_000d: callvirt instance !0 class ILTest1.Program/Exposer`1<object>::GetValue() IL_0012: callvirt instance string [mscorlib]System.Object::ToString() IL_0017: call void [mscorlib]System.Console::WriteLine(string) IL_001c: nop IL_001d: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() IL_0022: pop IL_0023: ret } // end of method Program::Main
//############ Writing with property ############
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 31 (0x1f) .maxstack 2 .locals init ([0] class ILTest1.Program/Exposer`1<object> m_Exposer) IL_0000: nop IL_0001: newobj instance void [mscorlib]System.Object::.ctor() IL_0006: newobj instance void class ILTest1.Program/Exposer`1<object>::.ctor(!0) IL_000b: stloc.0 IL_000c: ldloc.0 IL_000d: newobj instance void [mscorlib]System.Object::.ctor() IL_0012: callvirt instance void class ILTest1.Program/Exposer`1<object>::set_Value(!0) IL_0017: nop IL_0018: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() IL_001d: pop IL_001e: ret } // end of method Program::Main
//############ Writing with method ############
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 31 (0x1f) .maxstack 2 .locals init ([0] class ILTest1.Program/Exposer`1<object> m_Exposer) IL_0000: nop IL_0001: newobj instance void [mscorlib]System.Object::.ctor() IL_0006: newobj instance void class ILTest1.Program/Exposer`1<object>::.ctor(!0) IL_000b: stloc.0 IL_000c: ldloc.0 IL_000d: newobj instance void [mscorlib]System.Object::.ctor() IL_0012: callvirt instance void class ILTest1.Program/Exposer`1<object>::SetValue(!0) IL_0017: nop IL_0018: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() IL_001d: pop IL_001e: ret } // end of method Program::Main
The produced IL is pretty much the same, as you can tell; though, I have tested the property _get against a GetValue:object method, and the latter seems to be performing slightly faster (ticks ratio, _get / GetValue(): 1.08 - 1.25), despite some random fluctuations. I believe the same might happen when writing to a property instead of calling a SetValue(object) method; MSDN says _set methods of properties are usually slow; there's no real comparison in there, but I believe it's usually true. I can post the program code if you want to test this further, perhaps adding the _set / SetValue(object) comparison as well. Please feel free to discuss, since optimization in the .net era has become a mysterious subject. 
|
|
|
|
|
Logged
|
|
|
|
|
Zaknafein
|
 |
« Reply #4 on: June 11, 2007, 07:04:27 AM » |
|
I find that when using the .NET Reflector or when reflecting in .NET classes that contain properties, get/set properties are seen as simple methods (GetGetMethod()/GetSetMethod(), which return a MethodInfo instance). So I'd assume properties are just a language featurette that makes the code easier on the eyes, but it all comes down to methods in the end, and so will have very little effect on performance.
|
|
|
|
|
Logged
|
|
|
|
Zombie
Community Member

Posts: 3
|
 |
« Reply #5 on: June 12, 2007, 07:12:53 PM » |
|
IL is pretty high level stuff, you may not get an accurate picture of perf by looking at an IL disassembly, because the JIT compilation process may (or may not) introduce various optimizations. In particular, short functions including property accessors may get compiled inline.
|
|
|
|
|
Logged
|
|
|
|
|
Raine
|
 |
« Reply #6 on: June 13, 2007, 01:20:46 AM » |
|
I am aware of this. However, I can't really understand the reason for those slight timing differences. Seems like the inlining occurs more often on methods rather than property methods? The code size is the same, and inlining depends on code size and its reuse afaik.
Moreover, I can't find that MSDN article reading that write-only properties are slower. Now that was an interesting statement.
While it is true that properties aren't inherently that different from their method counterparts, I wouldn't eventually want to find they perform worse than expected later on in the dev - especially since they're so common in class designs nowadays.
|
|
|
|
|
Logged
|
|
|
|
jviper
Community Member

Posts: 2058
Discipline in training
|
 |
« Reply #7 on: June 13, 2007, 10:30:16 AM » |
|
My only problem with a property is that in order to change them, you have to change the whole property, and not just the a component. For example, let's say you have a property that is of type TV_3DVector, and you want to just change the y component of that property. You have to actually pass all components of that vector. If I'm using properties, I expect to be able to do this: CL.Pos.y=Anumber It looks weird to me when I have to do this: TmpPos=CL.Pos TmpPos.y=ANumber CL.Pos=TmpPos
|
|
|
|
|
Logged
|
JAbstract.....Don't just imagine, make it happen!
|
|
|
|
Brac
|
 |
« Reply #8 on: June 13, 2007, 11:11:52 AM » |
|
My only problem with a property is that in order to change them, you have to change the whole property, and not just the a component. For example, let's say you have a property that is of type TV_3DVector, and you want to just change the y component of that property. You have to actually pass all components of that vector. If I'm using properties, I expect to be able to do this: CL.Pos.y=Anumber It looks weird to me when I have to do this: TmpPos=CL.Pos TmpPos.y=ANumber CL.Pos=TmpPos
This is not a downside of Properties, but of structs. As long as the accessed member is a reference type you don't have that problem. It only occures with value types (structs). Doh!
|
|
|
|
|
Logged
|
|
|
|
jviper
Community Member

Posts: 2058
Discipline in training
|
 |
« Reply #9 on: June 13, 2007, 07:42:03 PM » |
|
As long as the accessed member is a reference type you don't have that problem.
What do you mean? Do you mean if the type of the property I use has its own properties? Structure AType AMemberA as Integer AMemberB as single AMemberC as string AMemberD as long Property DoMemberA() as Integer Set..... Get..... End Property Property DoMemberB() as single...... Property DoMemberC() as string...... Property DoMemberD() as long..... End Structure
Class AClass Property AProperty() as AType Set..... Get..... End Property End Class Then I can do this..... AClass.AProperty.DoMemberA = ..... ...and not have to do this.... dim TmpProperty as AType TmpProperty = AClass.AProperty TmpProperty.DoMemberA = ..... AClass.AProperty = TmpProperty
?
|
|
|
|
|
Logged
|
JAbstract.....Don't just imagine, make it happen!
|
|
|
|
Zaknafein
|
 |
« Reply #10 on: June 13, 2007, 07:52:04 PM » |
|
Brac is 100% right and clear. The "problem" is that .NET languages allow to use value-types (structures), which are always returned as a copy, as opposed to reference types (classes) which are always returned as a reference. It has nothing to do with properties or which type has them.
So in your example, "AClass.AProperty.DoMemberA = ..." will not work because AProperty is an instance of a value-type, the AType structure. If you make that thing a Class, it'll work.
|
|
|
|
|
Logged
|
|
|
|
jviper
Community Member

Posts: 2058
Discipline in training
|
 |
« Reply #11 on: June 13, 2007, 08:23:09 PM » |
|
Will there be a memory usage problem if I do that to a large number of strucutures that are large (turn them into classes)?
|
|
|
|
|
Logged
|
JAbstract.....Don't just imagine, make it happen!
|
|
|
|
Zaknafein
|
 |
« Reply #12 on: June 13, 2007, 08:30:21 PM » |
|
Yes and no... In fact I'd encourage using classes for large data structures, because value-types means everywhere you're passing it or returning it it's a full copy of it. With a class it's just a 32-bit integer (the pointer).  But of course you have to instantiate classes whereas you can just take structures and use them when you want, so there's associated overhead, and probably additional memory usage since classes are only caught by the Garbage Collector when they stop being referenced. I'd say give it a shot.
|
|
|
|
|
Logged
|
|
|
|
kwazai
Community Member

Posts: 173
|
 |
« Reply #13 on: June 14, 2007, 07:27:26 AM » |
|
lurking- please post an example of this- I had been thinking of using a grid/database to store all my object(mesh) info, but would rather have 'property' and 'method' use. Mike
|
|
|
|
|
Logged
|
murphys law-28th corollary- if there are five ways for something to go wrong and you circumvent all five , a sixth will promptly develop.
|
|
|
|
Raine
|
 |
« Reply #14 on: June 14, 2007, 12:01:40 PM » |
|
|
|
|
|
|
Logged
|
|
|
|
jviper
Community Member

Posts: 2058
Discipline in training
|
 |
« Reply #15 on: June 14, 2007, 06:34:35 PM » |
|
Hummm, so it seems like trying to turn EVERYTHING into reference types is a bad idea, because on control of data. Hummm. Well I think that my code is cool enough anyway, so I should show it, and maybe perhaps I can get some help on what I can change to reference types, and what I cannot. But first I have to change my code back. ******* OK, I have changed my code back to using the value-types, so now I can begin sort of changing the code to use reference types (and this time with logic, and not just chaning everything). So here is a link to the code in vb.net module form (zipped). http://rapidshare.com/files/37329058/jviper_FrameWork3D.zipNow, you may find some interesting features here (or not, depending on what you think). The point of the code is to wrap the TV3D features and make it really easy syntax, then soon, this wrapper will be wrapped, then finally, user interface will be implemented (perhaps in level editor form). Currently, it wraps TV3D6.5, so sorry for you 6.2/6.3 users. But it should give you the overall idea of how it is done. Keep in mind it is still a work-in-progress, so not all the features are implemented yet. Here is some code on how to get it started: Public TV3D As F3d_Engine Public TV3DScr As F3d_Screen3D Public TV2DScr As F3d_Screen2D Public TVInput As F3d_Input Public MainScene As F3d_Scene Public MainView As F3d_Viewport Public MainLight As F3d_Light Public MainCamera As F3d_Camera
Public Sub Form1_Load() TV3D = New F3d_Engine("", "") TV3D.DebugFile = New props_DebugFile(Application.StartupPath + "/DebugFile.txt") TV3D.Init3DHandle(Me.Handle, True) TVInput = New F3d_Input MainScene = New F3d_Scene("MainScene") TV3DScr = New F3d_Screen3D() TV2DScr = New F3d_Screen2D() MainView = New F3d_Viewport(frm_OverHeadView.Handle, "MainView") MainView.BackgroundColor = New TV_COLOR(0, 0, 0, 1) MainView.AutoResize = True MainCamera = New F3d_Camera("MainCamera") MainLight = New F3d_Light(MainScene, CONST_TV_LIGHTTYPE.TV_LIGHT_POINT, "MainPoint") MainLight.Diffuse = New TV_COLOR(0, 1, 0, 1) MainLight.Ambient = New TV_COLOR(0, 0, 0, 0) MainLight.Specular = New TV_COLOR(1, 1, 1, 1) MainLight.Position = New TV_3DVECTOR(0, 2, 0) MainLight.Attenuation = New TV_3DVECTOR(1, 0, 0) MainLight.Range = 8 MainLight.FallOff = 12
MainCamera.ProjectionType = const_CameraType.FRUSTUM MainCamera.ViewAngle = 60 MainCamera.FarPlane = 1000 MainCamera.Position = New TV_3DVECTOR(-5, 4, 0) MainCamera.Direction = New TV_3DVECTOR(5, -4, 0) MainView.Camera=MainCamera End Sub
And then you go on to changing properties of objects, adding meshes and stuff, then you can go to your renderloop. To render, you simply: TV3DScr.BeginRender(False) TV3DScr.RenderView(MainView, MainScene, True) TV3DScr.FinalizeRender()
|
|
|
|
|
Logged
|
JAbstract.....Don't just imagine, make it happen!
|
|
|
jviper
Community Member

Posts: 2058
Discipline in training
|
 |
« Reply #16 on: June 15, 2007, 06:22:41 AM » |
|
When I tried turning everything into reference types, none of the meshes would render. Then I discovered that I messed up the convVector "+" and "-" operators. Yeah, when you do Return Vec1-Vec1, that doesn't work to well, because you tend to always get zero. So I suppose I can try that again.
|
|
|
|
|
Logged
|
JAbstract.....Don't just imagine, make it happen!
|
|
|
|