Image Object (was Types as Objects Preview)

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
coderJeff
Site Admin
Posts: 3160
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Image Object (was Types as Objects Preview)

Postby coderJeff » Oct 11, 2006 4:04

Updated (feb/2008):

Just for fun, I created a working example of an IMAGE OBJECT to try a few things out using a type and some fbgfx.

Code: Select all

'' Defines a TYPE to contain an IMAGE BUFFER
'' LET overloaded to copy an image
'' AND, AND=, overloaded to mask bits in the image

#include "fbgfx.bi"

''
Type image
  _buffer as fb.image ptr

  Declare Constructor _
    ( _
      Byval w As Integer = 0, _
      Byval h As Integer = 0, _
      Byval c As Integer = 0 _
    )
  Declare Constructor ( Byref rhs As image )

  Declare Operator Let ( Byref rhs As image )

  Declare Destructor ()

  Declare Function Width() As Integer
  Declare Function height() As Integer
  Declare Function buffer() As Any Ptr
  Declare Function bytesperpixel() As Uinteger

  Declare Operator And= ( Byval mask As Uinteger )

End Type

Declare Operator And ( Byref this As image, Byval mask As Uinteger ) As image

Constructor image _
    ( _
      Byval w As Integer = 0, _
      Byval h As Integer = 0, _
      Byval c As Integer = 0 _
    )

  If( w > 0 And h > 0 ) Then
    _buffer = ImageCreate( w, h, c )
  Else
    _buffer = 0
  End If
End Constructor

Constructor image ( Byref rhs As image )
  _buffer = ImageCreate( rhs.Width, rhs.Height )
  Get rhs._buffer, (0,0)-( rhs.Width - 1, rhs.Height - 1), _buffer
End Constructor

Operator image.let ( Byref rhs As image )
  if( _buffer ) then
    ImageDestroy _buffer
  end if
  _buffer = ImageCreate( rhs.Width, rhs.Height )
  Get rhs._buffer, (0,0)-( rhs.Width - 1, rhs.Height - 1), _buffer
End Operator

Destructor image ()
  If( _buffer ) Then
    ImageDestroy _buffer
  End If
End Destructor

Function image.width () As Integer
  If( _buffer ) Then
    Return _buffer->width
  End If
  Return 0
End Function

Function image.height () As Integer
  If( _buffer ) Then
    Return _buffer->height
  End If
  Return 0
End Function

Function image.bytesperpixel () As Uinteger
  If( _buffer ) Then
    Return _buffer->bpp
  End If
  Return 0
End Function

Function image.buffer () As Any Ptr
  Return _buffer
End Function

Operator image.and= ( Byval mask As Uinteger )
  Dim As Integer x, y
  For x = 0 To this.width - 1
    For y = 0 To this.height - 1
      Pset _buffer, (x, y), Point( x, y, _buffer ) And mask
    Next y
  Next x
End Operator

Operator And ( Byref lhs As image, Byval mask As Uinteger ) As image
  Dim img As image = lhs
  img And= mask
  Return img
End Operator

'' -------------------------------------------------------

  Dim As Integer x, y
 
  screenres 640,480,32
 
  Dim img1 As image = image(256, 128)
 
  For x = 0 To 255
  For y = 0 To 127
    Pset img1.buffer, ( x, y ), RGB( y, 255-x, x )
  Next y
  Next x
 
  Draw String img1.buffer, ( 8, 8 ), _
    "This image is " & img1.width & " by " & img1.height, _
    rgb(255,255,255)
 
  ' make some copies and make some alterations

  Dim img2 As image = img1
  Line img2.buffer, ( 32, 32 ) - ( 224, 96 ), rgb( 127,0,0 ), bf

  Dim img3 As image
  img3 = img2
  Line img3.buffer, ( 32, 32 ) - ( 224, 96 ), rgb( 0,127,0 ), bf

  Dim img4 As image
  img4 = img3 And rgb( 0, 255, 0 ) ' mask green

  Put (  16, 16 ), img1.buffer, Pset
  Put ( 368, 16 ), img2.buffer, Pset

  img1 And= rgb(255, 0, 0) ' mask red
  img2 And= rgb(0, 0, 255) ' mask blue

  Put (  16, 160 ), img1.buffer, Pset
  Put ( 368, 160 ), img2.buffer, Pset

  Put (  16, 320 ), img3.buffer, Pset
  Put ( 368, 320 ), img4.buffer, Pset

  Sleep
Last edited by coderJeff on Feb 15, 2008 23:24, edited 2 times in total.
v1ctor
Site Admin
Posts: 3799
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Postby v1ctor » Oct 11, 2006 5:52

Really cool, a wrapper for the gfx lib would be nice, and there would be no name clashes or trashing so many new functions could be added, like you did.
D.J.Peters
Posts: 8019
Joined: May 28, 2005 3:28
Contact:

Postby D.J.Peters » Oct 11, 2006 13:07

Realy nice example.

Joshy
Sisophon2001
Posts: 1704
Joined: May 27, 2005 6:34
Location: Cambodia, Thailand, Lao, Ireland etc.
Contact:

Postby Sisophon2001 » Oct 11, 2006 14:24

I enjoyed the sample also, but in my case it took me 20 minutes to fully understand it, so it served very much as a useful learning exercise. I continue to be amazed with what v1ctor and his team have done to develop FB before our eyes.

What did the QB crowd ever do to deserve supporters of this caliber?

Garvan
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:

Postby relsoft » Oct 11, 2006 15:28

Awesome dude!! Now with new and delete... hmmmmm.. yummy!!!
coderJeff
Site Admin
Posts: 3160
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Postby coderJeff » Oct 11, 2006 16:29

Thanks guys. v1ctor's done a superb job of preserving the BASIC language syntax on this implementation. Aside from the "buffer as any ptr" there's hardly a pointer in sight. And if the example were updated to use the new image header by lillo, those cast()'s for width and height could be made clearer.

To those that were wondering what OOP was all about, well this is part of it. Instead of having 50 procedures to operate on the data in a TYPE, the TYPE itself exposes the operations that will work with the data.

Which makes it possible to construct a complex data type like a 1024 bit integer, a 3d vector, a GUI control, or a variant, and work with like it was a built-in standard data type: without actually having to make it a built-in data type.

Hopefully this is not too threatening to the QB traditionalists or users new to OOP, as it doesn't replace or break procedural style of programming.
D.J.Peters
Posts: 8019
Joined: May 28, 2005 3:28
Contact:

Postby D.J.Peters » Oct 11, 2006 18:48

Curently i don't use FreeBASIC 0.17 and my question are
how will be an constructor called for every item of an array of images/types/objects?

dim as image images(10)

Joshy
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Oct 11, 2006 19:03

@Joshy:

Code: Select all

type foo

  as integer x, y, z
 
  declare constructor
 
end type

constructor foo( )

  this.x = 3
  this.y = 4
  this.z = 5

end constructor

dim as foo bar( 10 )

dim as integer i


for i = 0 to 10

  ? bar( i ).x
  ? bar( i ).y
  ? bar( i ).z
  ?
 
next


fbc constructor.bas -r -g

outputted ASM:

Code: Select all

   .file "constructor.bas"
   .stabs "D:/prg/fb/cha0s/random/",100,0,0,.Lt_0001
   .stabs "constructor.bas",100,0,0,.Lt_0001

.section .text
.Lt_0001:
   .stabs "integer:t1=-1",128,0,0,0
   .stabs "void:t7=-11",128,0,0,0
   .stabs "byte:t2=-6",128,0,0,0
   .stabs "ubyte:t3=-5",128,0,0,0
   .stabs "char:t4=-2",128,0,0,0
   .stabs "short:t5=-3",128,0,0,0
   .stabs "ushort:t6=-7",128,0,0,0
   .stabs "uinteger:t8=-8",128,0,0,0
   .stabs "longint:t9=-31",128,0,0,0
   .stabs "ulongint:t10=-32",128,0,0,0
   .stabs "single:t11=-12",128,0,0,0
   .stabs "double:t12=-13",128,0,0,0
   .stabs "string:t13=s12data:15,0,32;len:1,32,32;size:1,64,32;;",128,0,0,0
   .stabs "fixstr:t14=-2",128,0,0,0
   .stabs "pchar:t15=*4;",128,0,0,0

   .stabs "constructor.bas",130,0,0,0
   .intel_syntax noprefix

   #constructor.bas' compilation started at 14:02:25 (FreeBASIC v0.17b)
   .stabs "__ZN3FOOC1Ev:F7",36,0,9,__ZN3FOOC1Ev
   .stabs "FOO:Tt16=s12X:1,0,32;Y:1,32,32;Z:1,64,32;;",128,0,0,0
   .stabs "THIS:v16",160,0,0,8
.balign 16

.globl __ZN3FOOC1Ev
__ZN3FOOC1Ev:
   push   ebp
   mov   ebp, esp
   .stabn 68,0,9,__ZN3FOOC1Ev-__ZN3FOOC1Ev
.Lt_0004:
##
.Lt_0006:
##  this.x = 3
   mov   eax, dword ptr [ebp+8]
   mov   dword ptr [eax], 0
   mov   eax, dword ptr [ebp+8]
   mov   dword ptr [eax+4], 0
   mov   eax, dword ptr [ebp+8]
   mov   dword ptr [eax+8], 0
   mov   eax, dword ptr [ebp+8]
   mov   dword ptr [eax], 3
.stabn 68,0,11,.Lt_0006-__ZN3FOOC1Ev
.Lt_0007:
##  this.y = 4
   mov   eax, dword ptr [ebp+8]
   mov   dword ptr [eax+4], 4
.stabn 68,0,12,.Lt_0007-__ZN3FOOC1Ev
.Lt_0008:
##  this.z = 5
##
   mov   eax, dword ptr [ebp+8]
   mov   dword ptr [eax+8], 5
.stabn 68,0,13,.Lt_0008-__ZN3FOOC1Ev
.Lt_0009:
##end constructor
.Lt_0005:
   mov   esp, ebp
   pop   ebp
   ret
   .stabn 68,0,15,.Lt_0005-__ZN3FOOC1Ev
   .stabn 192,0,0,.Lt_0004-__ZN3FOOC1Ev
   .stabn 224,0,0,.Lt_0005-__ZN3FOOC1Ev
.Lt_000A:
   .stabs "",36,0,0,.Lt_000A-__ZN3FOOC1Ev
   .stabs "main",42,0,17,_main
   .stabd 68,0,17
   .stabs "main:F1",36,0,17,_main
   .stabs "__FB_ARGC__:p1",160,0,0,8
   .stabs "__FB_ARGV__:p17=*18=*4",160,0,0,12
.balign 16

.globl _main
_main:
   push   ebp
   mov   ebp, esp
   and   esp, 0xFFFFFFF0
   sub   esp, 180
   .stabn 68,0,17,_main-_main
   mov   dword ptr [ebp-4], 0
   call   ___main
   push   dword ptr [ebp+12]
   push   dword ptr [ebp+8]
   call   _fb_Init@8
.Lt_0002:
.Lt_0015:
##type foo
##
##  as integer x, y, z
## 
##  declare constructor
## 
##end type
##
##constructor foo( )
##
##dim as foo bar( 10 )
   lea   eax, [ebp-136]
   mov   dword ptr [ebp-168], eax
   lea   eax, [ebp-136]
   mov   dword ptr [ebp-164], eax
   mov   dword ptr [ebp-160], 132
   mov   dword ptr [ebp-156], 12
   mov   dword ptr [ebp-152], 1
   mov   dword ptr [ebp-148], 11
   mov   dword ptr [ebp-144], 0
   mov   dword ptr [ebp-140], 10
   lea   eax, [ebp-136]
   mov   dword ptr [ebp-176], eax
   mov   dword ptr [ebp-172], 0
.Lt_000D:
##
   mov   eax, dword ptr [ebp-176]
   push   eax
   call   __ZN3FOOC1Ev
   add   esp, 4
   mov   eax, dword ptr [ebp-176]
   add   eax, 12
   mov   dword ptr [ebp-176], eax
   mov   eax, dword ptr [ebp-172]
   inc   eax
   mov   dword ptr [ebp-172], eax
   cmp   dword ptr [ebp-172], 11
   jne   .Lt_000D
.stabn 68,0,17,.Lt_0015-_main
.Lt_0016:
##dim as integer i
##
   mov   dword ptr [ebp-180], 0
.stabn 68,0,19,.Lt_0016-_main
.Lt_0017:
##
##for i = 0 to 10
   mov   dword ptr [ebp-180], 0
.Lt_0012:
.Lt_0013:
##
.stabn 68,0,22,.Lt_0017-_main
.Lt_0018:
##  ? bar( i ).x
   push   1
   mov   eax, dword ptr [ebp-180]
   imul   eax, 12
   push   dword ptr [ebp+eax-136]
   push   0
   call   _fb_PrintInt@12
.stabn 68,0,24,.Lt_0018-_main
.Lt_0019:
##  ? bar( i ).y
   push   1
   mov   eax, dword ptr [ebp-180]
   imul   eax, 12
   push   dword ptr [ebp+eax-132]
   push   0
   call   _fb_PrintInt@12
.stabn 68,0,25,.Lt_0019-_main
.Lt_001A:
##  ? bar( i ).z
   push   1
   mov   eax, dword ptr [ebp-180]
   imul   eax, 12
   push   dword ptr [ebp+eax-128]
   push   0
   call   _fb_PrintInt@12
.stabn 68,0,26,.Lt_001A-_main
.Lt_001B:
##  ?
## 
   push   1
   push   0
   call   _fb_PrintVoid@8
.stabn 68,0,27,.Lt_001B-_main
.Lt_001C:
##next
.Lt_0014:
.Lt_0010:
   inc   dword ptr [ebp-180]
.Lt_000F:
   cmp   dword ptr [ebp-180], 10
   jle   .Lt_0012
.Lt_0011:
##
.stabn 68,0,29,.Lt_001C-_main
.Lt_001D:
##
##
##
##
##
.Lt_0003:
   push   0
   call   _fb_End@4
   mov   eax, dword ptr [ebp-4]
   mov   esp, ebp
   pop   ebp
   ret
   .stabn 68,0,29,.Lt_0003-_main
   .stabs "BAR:19=ar1;0;10;16",128,0,0,-136
   .stabs "I:1",128,0,0,-180
   .stabn 192,0,0,.Lt_0002-_main
   .stabn 192,0,0,.Lt_0013-_main
   .stabn 224,0,0,.Lt_0014-_main
   .stabn 224,0,0,.Lt_0003-_main
.Lt_001E:
   .stabs "",36,0,0,.Lt_001E-_main
   #constructor.bas' compilation took 2.045651053409081e-002 secs
   .stabs "",100,0,0,.Lt_001F
.Lt_001F:




hehe
D.J.Peters
Posts: 8019
Joined: May 28, 2005 3:28
Contact:

Postby D.J.Peters » Oct 11, 2006 19:55

Thanx cha0s
...
redim preserve bar(15)
? bar(11).x
? bar(12).y
? bar(13).z
...

:lol:

Joshy
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Postby stylin » Oct 11, 2006 21:26

Array initializers, too, but currently there is a bug with static and shared objects with members having c/d/tors (like strings):

Code: Select all

':: compile with -g

const N as uinteger = 2

type UDT
   declare constructor (as integer, as integer, as integer)
   as integer   x, y, z
end type

constructor UDT (x as integer, y as integer, z as integer)
   this.x = x
   this.y = y
   this.z = z
end constructor

dim array(N - 1) as UDT = { UDT(0, 1, 2), UDT(3, 4, 5) }

dim i as uinteger
for i = 0 to N - 1
   ASSERT( array(i).x = i * 3 )
   ASSERT( array(i).y = i * 3 + 1)
   ASSERT( array(i).z = i * 3 + 2)
next
DaveUnit
Posts: 239
Joined: Apr 20, 2006 15:47
Location: Central MA
Contact:

Postby DaveUnit » Oct 15, 2006 15:58

someone should put a big ol' tutorial of this in qb express the next time it comes out. It would help everyone get a better grasp of this OOP stuff.
Deleter
Posts: 975
Joined: Jun 22, 2005 22:33

Postby Deleter » Oct 15, 2006 17:21

what about private/public/protected? That going to come about as well?
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Oct 19, 2006 17:05

Deleter wrote:what about private/public/protected? That going to come about as well?


yes. =)

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 5 guests