Hi.

At last, I tryed to do something on OOP, it was quite easy, and using the Object in programm is soo cool and easy (:

I made CData, the idea is to have a big buffer, and keep some multiple "Named" information in it. Like variables in mIRC:
%var1 = ABCDEF

%var2 = GGG
%var3 = 9090
Then they are stored in variables.ini, but that requires
smart string operations.

This simple Object can ADD, REMOVE, and RENEW(remove then add) data.

http://www.hot.ee/valk777/data.rar

Special thanks to: NaN, Thomas for creating Object Creator and object.inc
Posted on 2004-12-08 16:01:31 by zabnik
Hi zabnik!
It's fine to see a new OOPer here!
My suggestion here is to switch to ObjAsm32 as soon as possible. The model you are using has been discontinued and ObjAsm32 contains all the features of NaN's old model. Check this post http://www.asmcommunity.net/board/viewtopic.php?t=17620

Regards and good luck 8)

Biterider
Posted on 2004-12-09 01:10:12 by Biterider
it is very different
Posted on 2004-12-09 10:20:58 by zabnik
Hi zabnik
If you look under the surface, you will see a lot of equivalences. OA32 has a more elaborated syntax to make things easier and extensions that allow the use of COM interfaces and events.

Regards,

Biterider
Posted on 2004-12-09 10:35:31 by Biterider
Wow! New objects.inc is very scary inside, I think I need few week's to understand how to make object.
Posted on 2004-12-09 11:21:31 by zabnik
To start up using the model, I recommend the use of the documentation or directly one of the first demos. Much of the code is commented and the macros are self explanatory.

Your are right, the Objects.inc file looks pretty complex due the fact that there are a lot of checks and error reporting macros build in. These aside, the core of this model and all other OOP models is the construction of structures and templates and the corresponding procs to handle them.
You will see that there are macro and code libraries for all common tasks for your asm coding daily business.

If you have problems to start up, I will be glad to help you.

Regards,

Biterider
Posted on 2004-12-09 14:01:54 by Biterider
Whats the diference between this:

RedefineMethod
StaticMethod
PrivateMethod
DynamicMethod

and

DefineVariable
RedefineVariable

?
Posted on 2004-12-10 15:41:25 by zabnik
!!!
http://www.hot.ee/valk777/data2.rar

Done, now CData with new OOP Base. But im still don't know why
Static,dynamic,redefine -method. And I know nothing about Inhertance.
Posted on 2004-12-10 17:02:18 by zabnik
Hi zabnik
Really good work! I have seen from your code that you are doing the learning curve pretty fast?

Here my thoughts about the work:
1. The EndMethod macro has some build in features: one of them is the ReleaseObject/ret instruction set. By this way it is not necessary to write them at the end of the method 8) .
2. EndMethod also includes a label called @@EOM (End Of Method) to directly jump out of the method.
3. You have a handy macro to create dynamic memory blocks called MemAlloc. Check your Memory.inc file.
4. Use Demo12 to check the correct preservation of the registers (Checks menu option). BTW, you don?t need to preserve ecx.

To your questions
You have seen that we have 3 types of methods: StaticMethod, DynamicMethod, and InterfaceMethod. The last one is supposed for the use with COM.
The first 2 are the most important. A static method is a procedure that is linked to the object through its internal method table (in the model called SMT = Static method table). Since the SMT is common to all object instances, if you make a change there, it will be reflected on all instances (superclassing). But what about if you only want to change the behavior of a single instance? Now comes DynamicMethod into the game. Dynamicmethod links your procedure to the object instance through a hidden object variable. This way, each object can manage a different procedure with the same name! This is a sort of subclassing.
Most of the times you have to deal with static methods.
All inheritance rules apply to these 3 method types.
Finally, PrivateMethod is a variation of a StaticMethod. It is used when you want to protect some methods to be used from outside the scope of its object. (This is a more advanced topic)

The RedefineMethod macro is intended to replace an inherited method that is defined somewhere in one of the parents. You can replace the method completely. Usually this is not the case, since you want to reuse the code of your parent. This is achieved using the ACall (Ancestor call), usually at the beginning of a constructor method and at the end of a destructor method.

Note that the universal destructor ?Done? is called automatically when you call the Destroy macro.

DefineVariable is used to define the type and initial value of an object variable. You can redefine the initial value in a descendant using the RedefineVariable macro.

I hope this helps a little bit?

Regards,

Biterider
Posted on 2004-12-11 03:58:23 by Biterider
PROBLEM IN NEW OOP MODEL:

I was doing some simple stuff... learning OOP (:
But this one won't compile

Method _lstr.replace,uses edi,buffa:DWORD,replacewhat:BYTE,replaceto:BYTE

; cuted...
MethodEnd
...
OCall hlstr::_lstr.replace,addr buffer,"\",02Fh
...
ProbnikGL.asm(166) : error A2008: syntax error : in directive
MacroLoop(1): iteration 1: Macro Called From
String(7): Macro Called From
$OfsCStrX(5): Macro Called From
MacroLoop(2): iteration 3: Macro Called From
@invoke(11): Macro Called From
ObjectCall(46): Macro Called From
OCall(63): Macro Called From
ProbnikGL.asm(166): Main Line Code
ProbnikGL.asm(166) : error A2006: undefined symbol : ??0694
@invoke(12): Macro Called From
ObjectCall(46): Macro Called From
OCall(63): Macro Called From
ProbnikGL.asm(166): Main Line Code
ProbnikGL.asm(166) : error A2114: INVOKE argument type mismatch : argument : 3
@invoke(12): Macro Called From
ObjectCall(46): Macro Called From
OCall(63): Macro Called From
ProbnikGL.asm(166): Main Line Code


So I have to use 05Ch istead of "\".
Posted on 2004-12-15 08:31:17 by zabnik
Hi zabnik
Thanks for the warning. I have detected the problem since a few days. It is a bug introduced with the last revision, concerning the handling of string shortcuts (i.e. ?\n?) in the $ConvEscSeqs macro located in the system.inc file.
You will see that the registrations of the COM servers are also affected.

To solve this problem use $OfsCStr(?\?) in place of ?\? in the problematic code line. :)

Regards,

Biterider
Posted on 2004-12-15 09:15:28 by Biterider
Nothing problematic, just converting ASCII to HEX takes time (:
And... $OfsCStr("\")

OCall hlstr::_lstr.replace,addr buffer,$OfsCStr("\"),02Fh

...
ProbnikGL.asm(542) : error A2114: INVOKE argument type mismatch : argument : 3
@invoke(12): Macro Called From
ObjectCall(46): Macro Called From
OCall(63): Macro Called From
ProbnikGL.asm(542): Main Line Code

...

; and I had tryed this one:
OCall hlstr::_lstr.replace,addr buffer,$OfsCStr(?\?),02Fh
...
ProbnikGL.asm(542) : error A2044: invalid character in file
MacroLoop(1): iteration 1: Macro Called From
String(7): Macro Called From
$OfsCStr(4): Macro Called From
OCall(1): Macro Called From
ProbnikGL.asm(542): Main Line Code
ProbnikGL.asm(542) : error A2006: undefined symbol : ??0B6D
@invoke(12): Macro Called From
ObjectCall(46): Macro Called From
OCall(63): Macro Called From
ProbnikGL.asm(542): Main Line Code
ProbnikGL.asm(542) : error A2114: INVOKE argument type mismatch : argument : 3
@invoke(12): Macro Called From
ObjectCall(46): Macro Called From
OCall(63): Macro Called From
ProbnikGL.asm(542): Main Line Code
nasty...
Posted on 2004-12-15 14:58:04 by zabnik
Hi zabnik
In your case, you are trying to pass a byte value to your method. If you use double quotes, you are signalizing that you will pass an offset to a string allocated in the .const segment. The right syntax in this case to pass a byte value is using single quotes, like ?\?.

OCall hlstr::_lstr.replace,addr buffer,?\?, ?/?


Regards,

Biterider
Posted on 2004-12-15 15:54:17 by Biterider
zabnik,

First off, im glad to see your inspired to learn our newest OOP model. Biterider has far exceeded our origional model (NaN & Thomas) and it is worth learning the newest versions.

That said, i understand your confusions as the newest model had far more in the capabilities as well as places to go wrong (the unfortunate paradox that haunts all projects).

All this aside, your probably doing quite well with your own R&D into the architecture. So if you dont mind, post your source and we can help you learn giving you corrections and/or suggestions to achieve your ideas. (It also helps us by getting a better idea of where the stumbling blocks are for beginners (another paradox for those who develope such things ;) )

Best of luck!
Regards,
:NaN:
Posted on 2004-12-15 21:37:55 by NaN
OCall hlstr::_lstr.replace,addr buffer,?\?, ?/?

Is working! Thank's. I post the full source a bit later, because Im OOP'ing my ProbnikGL (which load bsp maps), and not everything is done.
Posted on 2004-12-16 08:25:07 by zabnik
I updated, and uploaded: http://www.hot.ee/valk777/ProbnikGL_0_06.rar
What may I change to make it betted?
Posted on 2004-12-16 14:13:41 by zabnik
Hi zabnik
Thanks for posting your code! I took a look into it to check things concerning OOP and haven?t seen anything wrong.
Nevertheless some points need an explanation:
1. The MethodEnd macro includes the ret instruction, so you don?t need to type it at the end of your methods.
2. The register preservation rule indicates to preserve ebx, edi and esi. All other registers can be changed freely. The ?uses? statement can be restricted to these 3 registers (if used) to save unnecessary push and pops. Demo12 checking tools give me 4 files where the register preservation failed: Camera.inc, Frustum.inc, lstr.inc, Quake3Bsp.inc. Little changes here will guarantee a better stability of your app!
3. To improve your typing work, some macro parameters are taken by defaults. I.e., the SetObject macro takes it second parameter from the current method scope. The line 455 in the Quake3Bsp.inc file can be simply written as SetObject edi. The same rule applies to the XCalls. Line 514 can be written as OCall edi.RenderFace, ?

Unfortunately, I can?t compile your work, since I miss some files. The exe file works pretty well on my box! Congrats! :alright:

Regards,

Biterider
Posted on 2004-12-17 02:08:35 by Biterider
Yeah, I see, forgot to check for missing files, but I uploaded, so you can compile it:
http://www.hot.ee/valk777/ProbnikGL_libs.rar

Btw, Do I use these ID's correctly:
; #########################################################################

Quake3BspID equ 0001
lstrID equ 0002
FrustumID equ 0003
CameraID equ 0004
ImageID equ 0005
FontID equ 0006
QuaternionID equ 0007
; #########################################################################
.data? ; OOP
hBsp dd ?
hlstr dd ?
hFrustum dd ?
hCamera dd ?
hImage dd ?
hFont dd ?
; #########################################################################
include lstr.inc
include Image.inc
include Quake3Bsp.inc
include Frustum.inc
include Camera.inc
include Font.inc
; #########################################################################

And can I do something with inheritance stuff? Because all Object inheritance path is Primer, I want do something ExTReMe:
Inheritance path: Primer

Inheritance path: Primer - Streamable
Inheritance path: Primer - _lstr
Inheritance path: Primer - Image
Inheritance path: Primer - Quake3Bsp
Inheritance path: Primer - Frustum
Inheritance path: Primer - Camera

I just don't understand it, but I want to. (:
Posted on 2004-12-17 07:09:29 by zabnik
Hi zabnik
I recommend to check your own object IDs with the model IDs located in ObjAsm32\Objects\ObjIDs.inc file. It?s not a good idea to put your IDs in this file, since new model revisions will override it. Create your own MyObjIDs.inc file. The IDs are used to identify the objects, especially for error reporting and streaming (See Stream object).

It?s a good idea to take a look into the ?collection? object. It?s a flexible and fast iterator. I used it also for the API -3D engine (Demo14) and I think it may be useful for you, too. 8)

The inheritance path witch is shown when you compile your app, lets you know how the compilation of the object is done. In your case, all objects derive from Primer, since they have nothing in common. The clue with the OOP inheritance is to group properties and methods that are common to different objects and put them in a common ancestor. Check Demo1 to see this point.

Regards, :alright:

Biterider
Posted on 2004-12-18 12:24:46 by Biterider
Create your own MyObjIDs.inc file.

Like this?:
; MyObjectID.inc

Quake3BspID equ 0001
lstrID equ 0002
FrustumID equ 0003
CameraID equ 0004
ImageID equ 0005
FontID equ 0006
QuaternionID equ 0007


...

Look what I have done with inheritance:
Inheritance path: Primer

Inheritance path: Primer - Streamable
Inheritance path: Primer - _lstr
Inheritance path: Primer - Quake3Bsp
Inheritance path: Primer - Quake3Bsp - Image
Inheritance path: Primer - Camera
Inheritance path: Primer - Camera - Frustum
Inheritance path: Primer - Camera - Quaternions
Inheritance path: Primer - Font


I found cool macro is System.inc
; So I convert this:

;mov eax,[esi].BSP_HEADER.Faces._offset
;add eax,[edi].pMemBSP
;mov [edi].m_pFace,eax

;mov eax,[esi].BSP_HEADER.Leafs._offset
;add eax,[edi].pMemBSP
;mov [edi].m_pLeaf,eax

;mov eax,[esi].BSP_HEADER.Leaffaces._offset
;add eax,[edi].pMemBSP
;mov [edi].m_pLeafface,eax

;mov eax,[esi].BSP_HEADER.Vertexes._offset
;add eax,[edi].pMemBSP
;mov [edi].m_pVertex,eax
; To this:
mov [edi].m_pFace,$eax(add $eax(mov eax,[esi].BSP_HEADER.Faces._offset),[edi].pMemBSP)
mov [edi].m_pLeaf,$eax(add $eax(mov eax,[esi].BSP_HEADER.Leafs._offset),[edi].pMemBSP)
mov [edi].m_pLeafface,$eax(add $eax(mov eax,[esi].BSP_HEADER.Leaffaces._offset),[edi].pMemBSP)
mov [edi].m_pVertex,$eax(add $eax(mov eax,[esi].BSP_HEADER.Vertexes._offset),[edi].pMemBSP)


Also a mini problem: How to retrieve a variable contents from object?
I do this:
		.if [$eax(mov eax,hQuake3Bsp)].Quake3Bsp.g_bTextures ; Turn texture mapping on/off

mov [eax].Quake3Bsp.g_bTextures,0
push GL_TEXTURE1_ARB
call glActiveTextureARB ;
invoke glEnable,GL_TEXTURE_2D
.else ; If we don't want texture mapping
mov [eax].Quake3Bsp.g_bTextures,1
push GL_TEXTURE1_ARB
call glActiveTextureARB
invoke glDisable,GL_TEXTURE_2D ; Disable texture mapping
.endif

Maybe there is somewhere a cool macro, another solution, or Im doing that right? (:

And have you tried compiling ProbnikGL?
Posted on 2004-12-18 15:11:27 by zabnik