Oxygen Basic

Programming => Problems & Solutions => Topic started by: Aurel on March 08, 2015, 11:00:20 AM

Title: GDI functions & Init problems?
Post by: Aurel on March 08, 2015, 11:00:20 AM
This question is probably ..for Mike or Peter
I suspect that i have something not properly intitialized in my ruben GDI function.
Looks like some sort of DC corruption ?
When i look into DLib GDI drawing all looks different and not work very well in DLib  ::)
any help ..suggestion
thanks in advance !

Code: [Select]
' /////// Init GDI drawing functions from win32 Api \\\\\\\\\\
'==========================================================================
SUB InitDrawing(byval wnd as INT)
'INT ww,hh
''get current size of window
GetSize(wnd,0,0,ww,hh)
'get window DC
hdc=GetDC(wnd)
hdcMem = CreateCompatibleDC(0)
hbmMem = CreateCompatibleBitmap(hdc,ww,hh)
oldBmp = SelectObject( hdcMem, hbmMem )
oldBrush = SelectObject(hdcMem, CreateSolidBrush( RGB(231,223,231)) )
oldPen = SelectObject(hdcMem, CreatePen(PS_SOLID,1,RGB(231,223,231)))
'fill rectangle memDC with brush color
rc.right = ww + 1000
rc.bottom = hh + 1000

FillRect ( hdcMem,rc, oldBrush)
SetTextColor( hDC,RGB(0,0,0))
SetBkColor( hDC, RGB(231,223,231))
'blit to memDC
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
'UpdateWindow wnd
ReleaseDC( wnd, hdc)
End SUB

'=================================================
SUB TextColor (wID as INT,byval frontColor as sys,byval backColor as sys)
hdc = GetDC(wID)
fColor=frontColor
bColor = backColor
SetTextColor( hDC, frontColor)
SetBkColor( hDC, bColor)

BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)

ReleaseDC( wID, hdc)

End SUB
'=================================================
Sub TextOn( int wnd,sys x, y, string txt)
'INT ww,hh
hdc=GetDC(wnd)
GetSize(wnd,0,0,ww,hh)
TextOut hdc,x,y,txt,Len(txt)
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
ReleaseDC(wnd,Hdc)
End Sub

'=================================================
SUB LineXY (wID as INT,byval x as INT,byval y as INT,byval x1 as INT,byval y1 as INT)

hdc = GetDC(wID)
GetSize(wID,0,0,ww,hh)
'SelectObject(hdc, CreatePen(PS_SOLID,1,fColor))
 int np = CreatePen(PS_SOLID,1,fColor)
 int op = SelectObject(hdc, np)

MoveToEx hdc,x,y,Byval 0
LineTo hdc,x1,y1

BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
DeleteObject(SelectObject(hdc, op))
ReleaseDC( wID, hdc)

End SUB

'=================================================
SUB DrawRect(wID as INT,byval rx1 as INT,byval ry1 as INT,byval rx2 as INT,byval ry2 as INT)
hdc = GetDC(wID)
GetSize(wID,0,0,ww,hh)

SetBkMode( hDC, 1) 'transparent
SetBkColor(hDC, RGB(220,220,250))
int np = CreatePen(PS_SOLID,1,fColor)  'new pen
int op = SelectObject(hdc, np)
int nB = CreateSolidBrush( bColor)   'new Brush
int oB = SelectObject(hdc, nB)
'Rectangle bHdc,x,y,w+x,h+y ...hmmm
Rectangle (hdc,rx1,ry1,rx2+rx1,ry2+ry1)

BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
DeleteObject(SelectObject(hdc, op))
DeleteObject(SelectObject(hdc, oB))
ReleaseDC( wID, hdc)
END SUB

'=================================================
SUB Pset (wID as int , px as int ,py as int)
hdc = GetDC(wID)
'GetSize(wID,0,0,ww,hh)
SetPixel ( hdc, px, py, fColor)

BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)

ReleaseDC( wID, hdc)

End SUB

'====================================================================================
SUB Circle (wID as INT,byval cix as INT,byval ciy as INT,byval cra as INT)

hdc = GetDC(wID)
GetSize(wID,0,0,ww,hh)
'SelectObject(hdc, CreatePen(PS_SOLID,1,fColor))

SetBkMode( hDC, 1) 'transparent
SetBkColor(hDC, RGB(220,220,250))
int np = CreatePen(PS_SOLID,1,fColor)  'new pen
int op = SelectObject(hdc, np)
int nB = CreateSolidBrush( bColor)   'new Brush
int oB = SelectObject(hdc, nB)

Ellipse hdc,cix-cra,ciy-cra,cra+cix,cra+ciy

BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
DeleteObject(SelectObject(hdc, op))
DeleteObject(SelectObject(hdc, oB))
ReleaseDC( wID, hdc)
End SUB
'====================================================================================
' set window color
Sub FillSolidRect(wID as INT, x As Long, Y As Long, cx As Long, cy As Long, bbColor as INT)
    Dim hBr As Long ' rc As RECT
    hDC=GetDC(wID)
    rc.Left = x
    rc.Top = Y
    rc.right = x + cx
    rc.bottom = Y + cy
    hBr = CreateSolidBrush(bbColor)
    FillRect hDC, rc, hBr

    BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)

    ReleaseDC( wID, hdc)
End Sub
'----------------------------------------------------------
SUB WindowColor(wID as INT,wr as INT,wg as INT,wb as INT)
INT backColor = RGB (wr,wg,wb)
FillSolidRect(wID,0,0,ww,hh,backColor)

END SUB

'//////////////////////////////////////////////
SUB CleanUp
DeleteObject(SelectObject(hdcMem, oldBrush))
DeleteObject(SelectObject(hdcMem, oldPen))
DeleteObject(SelectObject(hdcMem, oldBmp))
DeleteDC(hdcMem)
End SUB
Title: Re: GDI functions & Intit problems?
Post by: Mike Lobanovsky on March 08, 2015, 11:51:50 AM
Hi Aurel,

Frankly, I don't want to dive deep into Ruben's sources. That is why, before I give a few practical pieces of advice without looking into them, please answer a few simple questions:
Thank you.
Title: Re: GDI functions & Intit problems?
Post by: Aurel on March 08, 2015, 01:39:53 PM
Hi Mike..

Quote
Frankly, I don't want to dive deep into Ruben's sources
.
that is ok ..

 
Quote
   1 Why do all your drawing operations paint directly into your screen window and then make a copy of it into the memory DC instead of doing it the other way round?
    2 Do you see at least some of your drawing operations, for example such as FillSolidRect() and WindowColor(), leaking GDI objects as seen in your Task Manager with the GDI Objects column visible?
    3 How does your main window callback handle the WM_ERASEBKGND message, if at all?

1.well i am not sure,but i think that is because i draw into backbuffer then BitBlit into
current window to create pesistent image .
New window have under WM_PAINT :

Code: [Select]
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Case win2

 
Select wMsg

Case WM_PAINT
If win2 <> 0
BitBlt(hDC, 0, 0, ww, hh, hdcMem, 0, 0, SRCCOPY)
End If

this is very simple and i think that you understand this far better than me.
So content of window is persistent even i resize window or move window around edges of screen.
Do you can agree with that  or i really do that completelly wrong ?

2. well this is a mystery point...
when i test my program last night everything work fine and when i try today same
programs start to work strange ..without drawings or ...
then after some try-s ,programs work again properly ...this is really weird.
Mike..the number of GDI objets in Task are still the same 48..no mather what kind of drawing i do
what is ok ..i think and this is really confusing...
maybe is something wrong with oxygen..i don't know
In fact when i remove Space() function interpretr start towork properly
i hope ... ::)
 
3.WM_ERASEBKGND message is not currently part of new window procedure..
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 08, 2015, 01:54:32 PM
Mike
my drawing with mouse move is based on FBSL example


.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 08, 2015, 02:33:13 PM
Also i found one interesting stuff in FBSL program Space Station
about how resize back buffer ..

Code: [Select]
Static hBmp As Integer
'===================================================
' Resize backbuffer DC
'===================================================
GetClientRect(ME, @rc)
DeleteObject(SelectObject(hBackDC, hBackBmp))
DeleteDC(hBackDC)
hBackDC = CreateCompatibleDC(GetDC(ME))
hBackBmp = SelectObject(hBackDC, CreateCompatibleBitmap(GetDC, rc.rcRight, rc.rcBottom))
ReleaseDC(ME, GetDC)
'===================================================
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 08, 2015, 02:57:37 PM
Also i found one interesting stuff in FBSL program Space Station
about how resize back buffer ..

Code: [Select]
Static hBmp As Integer
'===================================================
' Resize backbuffer DC
'===================================================
GetClientRect(ME, @rc)
DeleteObject(SelectObject(hBackDC, hBackBmp))
DeleteDC(hBackDC)
hBackDC = CreateCompatibleDC(GetDC(ME))
hBackBmp = SelectObject(hBackDC, CreateCompatibleBitmap(GetDC, rc.rcRight, rc.rcBottom))
ReleaseDC(ME, GetDC)
'===================================================

1. Yes but in any other language you will need one more temp var to store the value of GetDC(). This code is applicable in its verbatim form in the FBSL environment only!

2. Peter's code is better than yours but it isn't perfect either. For example, you don't need to select the new brush into the hDC in your FillSolidRect() sub. FillRect() works with any given brush directly, i.e. without selecting it into the context. But he's correct in pointing out to you that you must delete the new brush before the sub exits.

3. I'm currently writing a lengthy message to you. Let me take my time, please, before you make any hasty decisions.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 08, 2015, 03:06:38 PM
Quote
3. I'm currently writing a lengthy message to you. Let me take my time, please, before you make any hasty decisions.

thanks Mike
I will wait of course because i am not sure what might be best possible option


Ps..thanks Peter  ;)
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 08, 2015, 04:35:18 PM
OK Aurel,

Thanks for responding. I will give you my suggestions but you're free to follow them or not, even if for the obvious reasons of language authorship. :)

1.
my drawing with mouse move is based on FBSL example
You are free to use any piece of FBSL code found in the accompanying documentation or on the FBSL site for any purpose unless the code has an explicit license stated in the respective file. All such code is in the Public Domain and does not require any reference as to its origin. FBSL is freeware, after all. Thanks for the reference though. :)

2.
Quote
the number of GDI objets in Task are still the same 48..no mather what kind of drawing i do

I'm afraid this isn't so. Your FillSolidRect() creates a temporary (local) GDI object hBr and uses it to fill the rect but never deletes it when no longer needed. You must add DeleteObject(hBr) otherwise calling FillSolidRect() (or WindowColor() that uses it) in a loop will show you that your app is leaking one GDI object per each iteration.

3.
Quote
WM_ERASEBKGND message is not currently part of new window procedure.

If WindowColor() is the only  means to change the background color of your graphics window then you wouldn't want Windows to erase it with the graphics window's default color every time your app responds to a WM_PAINT message (every WM_PAINT is always preceded by WM_ERASEBKGND unless the latter is suppressed in your callback). Unsuppressed WM_ERASEBKGND followed by WindowColor() will cause your window to flicker like hell whenever it is resized or dragged from outside the screen bounds back onto your desktop. Add the following code to your callback to suppress WM_ERASEBKGND:

Code: OxygenBasic
  1. ...
  2.     Case WM_ERASEBKGND
  3.         Return 1
  4. ...

4. If your ww and wh parameters are the actual width and height of your graphics window's client area (I don't know what your GetSize() really does), then in order to make you graphics window respond to resizing events, add the following code to your callback:

Code: OxygenBasic
  1. ...
  2.     Case WM_SIZE
  3.         ww = lParam And &HFFFF ' equivalent to LoWord(lParam)
  4.        wh = lParam >> 16 ' equivalent to HiWord(lParam)
  5. ...

5. If your ww and wh parameters are the width and height of your graphics window's non-client area (effectively its outer sizes), then tell me so and I'll show you how to create a window from the very baginning based on the desired size of its client area rather than its outer dimensions.

6. You should create your memory DC's compatible bitmap to the exact size that your app needs rather than ww+1000 and wh+1000 because:

7. You tactics of blit-copying every single drawing operation into the memory DC is very very wasteful, both speed- and resource-wise. You will be much better off if you draw directly into the memory DC instead and have a new command called, say Refresh(hdc As Sys) (or Redraw like Peter's code has) that will be supposed to do only one thing, which will be to blit the contents of memory DC into the hDC of your graphics window:

Code: OxygenBasic
  1. Sub Refresh(hdc As Sys)
  2.     BitBlt(hdc, 0, 0, ww, wh, hDCmem, 0, 0, SRCCOPY)
  3. End Sub

Think for yourself: all you wanna do is set just one pixel on the entire canvas but at the same time you accompany that very simple and relatively fast task with an entire canvas blitting operation, and especially when your canvas is (ww*wh-1)+1000000 pixels larger than what's really needed! Now imagine what happens if you plan to draw a small row of a hundred pixels in a loop! :o I'm curious how Ruben can still draw anything at all! :)

8.
Quote
Code: OxygenBasic
  1. Case WM_PAINT
  2. If win2 <> 0
  3. BitBlt(hDC, 0, 0, ww, hh, hdcMem, 0, 0, SRCCOPY)
  4. End If

This is an absolutely unacceptable solution. The problem is that WM_PAINT uses its own, very special hDC value that does not generally coincide with the value returned by GetDC() in this particular message handler. You must use in this handler the value returned by a call to BeginPaint() and you must end this handler with a call to EndPaint(): Return 0 as prescribed by the Win32 Programmer's Reference: (watch out for line wrap!)

Code: OxygenBasic
  1. ...
  2.     Case WM_PAINT
  3.         Scope
  4.             Dim ps[64] As Byte ' this is a fake PAINTSTRUCT; we aren't going to use its members so no need to define it as genuine UDT
  5.            Refresh(BeginPaint(hwnd, ps)) ' hwnd is callback's argument, BeginPaint() returns hDC required to call Refresh()
  6.            EndPaint(hwnd, ps) ' ditto
  7.        End Scope
  8.         Return 0 ' as per Win32 SDK specs
  9. ...


Epilogue

We can discuss memory canvas resizing in WM_SIZE in further detail similar to what you found in the FBSL samples when and if you have implemented my suggestions. And my final advice would be that you and your users not attempt to draw anything at random places within your/their code (I remember you having been obsessed with this unreasonable idea some years ago) but rather have some well defined procedure (sub) where all drawing operations would be gathered together in order to be able to efficiently repaint the entire picture, if needed, and then blit it all from memory and into the on-screen graphics window in one go with a call to Refresh() as described above. This tactics would be very very handy to quickly restore the picture in case the window needs to be resized or restored from mini-/maximization.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 09, 2015, 12:38:58 PM
Well what to say ...
Some of your suggestions are really very good but some of them i already tested and
not get good results...
this is funny...
Quote
:o I'm curious how Ruben can still draw anything at all! :)
heh .. i agree with you about that .
WM_ERASEBGND is not a option because create mess on window area...
Your point that i must delete brush is true and i forget do that .
Oh..obssesion or not ..i would like to create window like i can in Creative Basic
but there is created with DIB (as far as i can see from source code )..
well ..thanks again on reply ;)
by the way MMove ruben example work very fine but you must try if is not problem...
in addition ..i will try to replicate double buffering in FBSL just to check how work
 :)
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 09, 2015, 02:11:02 PM
Tell you what, Aurel,

...Some of your suggestions are really very good but some of them i already tested and not get good results...
...WM_ERASEBGND is not a option because create mess on window area...

My suggestions as they have been formulated at this very stage of our conversation are not to be tested or even discussed -- they are to be implemented exactly and unimpeachably, because they are an indispensable prerequisite to convert the Ruben mess into some form of graphics application that can work at least theoretically. The first thing to do is to set up and follow a strategic plan what the application should do and what it shouldn't. Currently, Ruben doesn't have or follow any reasonable strategy and never will if you continue to base its development on your own misconceptions about what graphics programming is, how it works, and what it does to keep the application stable, integral, and usable beyond psetting a coupla pixels on a shaky canvas.

The batch of suggestions I spitted out at four o'clock in the morning when you were already sound asleep were just the first steps to drag you back out of the swamp and onto some solid ground. The longer you stick with you current Ruben mess, the fewer chances you have to ever see any satisfaction from your fruitless "work" over all these years.

So, it is as follows: you either reshuffle your Ruben together with me in order to get stable, reliable and possibly fast graphics or just delete that brush in your FillSolidRect() and go on trolling BASIC sites in your usual vein instead of doing something useful. But then also forget about ever asking me any questions any more.

This message isn't meant to insult you or whatever. It is meant to set forth some principles on which I might do for you something that noone has ever done before over these countless years that you're haunting BASIC sites: I might help you to develop some working code of your own. This is because I think that once you have it in your hands, you'll become better towards people, and people will become milder towards you. The feeling of accomplishment is a great thing to conceive, after all. :)
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 10, 2015, 03:58:35 AM
Ok
But you must understand that my english is not good as yours
so maybe i don't understand whole things properly..sorry about that

ok
i try Peter version of function
Code: [Select]
Sub FillSolidRect(wID as INT, x As Long, Y As Long, cx As Long, cy As Long, bbColor as INT)
    INT hBr,oBr ' rc As RECT
    hDC=GetDC(wID)
    rc.Left = x
    rc.Top = Y
    rc.right = x + cx
    rc.bottom = Y + cy
    hBr = CreateSolidBrush(bbColor)
    oBr = SelectObject hdc,hBr
    FillRect hDC, rc, hBr

    BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
    DeleteObject(SelectObject(hdc, oBr))
    ReleaseDC( wID, hdc)
End Sub

And then i compile and try
Of course i look into taskbar what i going on with GDI objects
nothing is changed...number of GDI objects is still 50 without increasing
and is stable.

Mike
You suggest me to draw directly into new window hdc..right?
And i can do that of course,but how then i can get persistent imege
if i dont use double buffering ?
I am completlly confused...?
sorry if i bothering you with all that things   
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 10, 2015, 07:02:12 AM
Guys,

Peter's version of the function is redundant. You don't have to select the hBr object into any device context if you want to use it only for fillind a rectangle. FillRect() uses any brush directly and it doesnt care if this brush is selected into a DC or not; the result will be the same. So why bother selecting it there, saving the old brush, and finally deselecting it again if FillRect() does not require it to be done? This needs three unnecessary extra API calls in just one drawing operation!

Peter's amendments should have looked as follows:
Code: OxygenBasic
  1. ' set window color
  2. Sub FillSolidRect(wID as INT, x As Long, Y As Long, cx As Long, cy As Long, bbColor as INT)
  3.     Dim hBr As Long ' rc As RECT
  4.    hDC=GetDC(wID)
  5.     rc.Left = x
  6.     rc.Top = Y
  7.     rc.right = x + cx
  8.     rc.bottom = Y + cy
  9.     hBr = CreateSolidBrush(bbColor)
  10.     FillRect hDC, rc, hBr
  11.     '=======================================================
  12.    DeleteObject hBr ' you can (and must) delete it directly
  13.                     ' because it isn't selected into any DC at all
  14.    '=======================================================
  15.  
  16.     BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
  17.  
  18.     ReleaseDC( wID, hdc)
  19. End Sub

Quote
nothing is changed...number of GDI objects is still 50 without increasing and is stable.

No! Everything is changed!

(Whenever I'm talking about a window, I mean the graphics window, its hWnd, its hDC, its callback and events, etc. I do not care if there are any other windows in your application.)

Write a short .RUB script that does the following (sorry, I don't know Ruben syntax but you must have something similar to express the loop):
Code: OxygenBasic
  1. .... ' your usual window initialization stuff goes here
  2. FOR i = 1 TO 10000000
  3.     FillSolidRect hWnd, 0, 0, 100, 100, 255 ' hWnd belongs to your graphics window, 255 is pure bright red
  4. NEXT i
  5. ....
and run it with your old implementation of FillSolidRect(). You will see that the number of GDI objects in your Task Manager increases with every passing second till your system may actually freeze or the application may crash. This is because there will be exactly one GDI object -- the hBr brush -- created in each iteration of this loop but never deleted in the same iteration, thus being lost both to you and the system eating its resources.

Now do the same with the new implementation of FillSolidRect() corrected as above and you will see that the number of GDI objects shown in your Task Manager remains the same (actually it may deviate +/- 1 GDI object while the loop runs depending on when the Task Manager actually takes its measurement) when the loop ends after 10 million iterations. This is how all of your function implementations, both old and new, should always be tested before they go public, here or elsewhere.

Quote
You suggest me to draw directly into new window hdc..right?

No again! I suggest you always:
Then add one more command to your vocabulary:
Code: OxygenBasic
  1. Sub Draw()
  2.     Sys hDC = GetDC(hWnd) ' the graphics window, naturally
  3.    Refresh hDC ' Refresh blits from the memory DC into the graphics window's on-screen DC
  4.    ReleaseDC hWnd, hDC
  5. End Sub
which is an analog to Refresh() for drawing anywhere outside the WM_PAINT handler, for example, in the WM_MOUSEMOVE handler as in the FBSL example that draws those colored bubbles, or in the WM_SIZE handler as described in item 4 above.

Now whenever and wherever you want to draw something on your screen, you just write e.g. the following: (pseudocode!)

For i = 1 To 1000000
PSet ...
Circle ...
DrawRect ...
FillSolidRect ...
Next i
Draw


and you spare yourself 3999999 GetDCs, 3999999 ReleaseDCs, and 3999999 BitBlts in just one single action in your graphics program.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 10, 2015, 01:49:02 PM
ok Mike
I modify FillSolidRect() function as you suggest :
Code: [Select]
Sub FillSolidRect(wID as INT, x As Long, Y As Long, cx As Long, cy As Long, bbColor as INT)
    INT hBr
    hDC=GetDC(wID)
    rc.Left = x
    rc.Top = Y
    rc.right = x + cx
    rc.bottom = Y + cy
    hBr = CreateSolidBrush(bbColor)
   
    FillRect hDC, rc, hBr
    DeleteObject hBr
    BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
   
    ReleaseDC( wID, hdc)
End Sub

Then i compile and try with 100000 iterations
(10 000 000 is to much for ruben )
number of GDI objects in taskbar is now 46 and is constant
in attacmnet is testing program..

Your idea that i should put all drawings into WM_PAINT is good ..
for now i have just 3 event handler implemented
@mousemove
@leftmbdown
@onclick

so next will be @onpaint


.
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 10, 2015, 02:49:29 PM
Hi Aurel,

Thanks for keeping me informed. I won't however download this file because I am not interested in working with Ruben's sources the way they are now; I consider this a waste of time, yours and mine alike.

My proposition still holds as follows:

1. You're stopping any of your planned activities to develop the older version of Ruben.

2. You're making a new copy of your Ruben's entire development folder saving the older folder as a backup that you may always return to in case you don't like what we're doing and/or how we're doing it.

3. You're introducing all of the changes that I described earlier in my messages to this new development folder without omissions, or additions of your own, or attempts to test run it ahead of time, or criticize it prematurely.

4. You're notifying me when you're through with this work and ready to send me these new sources in their entirety for final verification.

5. I'm looking through all the sources to verify them, add code as necessary to finalize clean resize of the graphics window with respect to its backbuffer, and send the finalized sources back to you.

6. You're field testing these finalized sources notifying me of any unexpected behavior, potential memory and GDI leaks, and other possible bugs.

7. Field testing over, you resume your development work as previously planned, but this time based on this new, dramatically faster and cleaner implementation of Ruben's GDI drawing engine. My mission ends there and then.

Please let me know a.s.a.p. if and when you're ready to follow this schedule.

Thank you.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 10, 2015, 10:56:57 PM
Quote
2. You're making a new copy of your Ruben's entire development folder saving the older folder as a backup that you may always return to in case you don't like what we're doing and/or how we're doing it.

ok..i i will backup current version - ruben3
and then i will made all changes you say in new ruben4
then i will post code .
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 11, 2015, 03:50:11 AM
Hi Aurel,

Thank you; I take it as your consent with my proposition. I will be waiting for your signal that all the changes are ready.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 11, 2015, 01:50:35 PM
Hi Mike
Just to inform you ,i made first small step and replace inside my interpreter loop
message processing from If PeekMessage (&wm,0,0,0,Pm_Remove)>0
to:
While PeekMessage (&wm,0,0,0,Pm_Remove)>0
and it looks to me that i get some speed up...what is good.. :D
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 11, 2015, 01:58:29 PM
Aurel,

C'mon, please...

Quote from: Myself
3. You're introducing all of the changes that I described earlier in my messages to this new development folder without omissions, or additions of your own, or attempts to test run it ahead of time, or criticize it prematurely.
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 20, 2015, 04:05:16 AM
Any news from the front, Aurel? :)
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 20, 2015, 05:16:32 AM
Hi Mike

sorry only bad news..
I remove all things from GDI functions as you suggested
i also remove InitDrawing() function where is created DC backbuffer.
then i try to implement @onpaint event ( WM_PAINT )
then everything else stop to work  >:(
when mousemove & leftbuttondown events work
it looks that wm_paint simply freez my interpteter . ::)
this is really weird ...
i will post source code ...
thanks for asking.. ;)
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 20, 2015, 05:21:08 AM
Mike
I just want to post here one program written in EBasic then you can tell me if is
created properly .Because it seems to me that work fine:
code in EB:
Code: [Select]
/*
 flicker_free_graph.eba by jos de jong
 with help from the ibasic forums (see codingmonkeys.com)
 tweaked by John Siino

 this version of flicker free graph does take a certain scale factor as constant,
 and depending on that calculates the boundaries xmin, xmax, ymin, ymax of the graph
 when the graph is resized or moved
 
 you can move the graph by dragging the mouse or with the arrow keys
 you can zoom the graph with keys + and -
*/

'DECLARATIONS
$INCLUDE "windows.inc"
DECLARE IMPORT, LoadCursor ALIAS LoadCursorA(hInstance AS INT,lpCursorName AS POINTER),INT
DECLARE IMPORT, GetCursorPos(lppoint:POINTER)
DECLARE IMPORT, ScreenToClient(HWND:uint, lppoint:POINTER)

WINDOW figure, plotwin

'axes of the graphics screen
DOUBLE xmin, xmax, ymin, ymax

'factors such that xscreen = x * xfactor + xshift and yscreen = y * yfactor + yshift
DOUBLE xfactor, xshift, yfactor, yshift

DEF MouseDownL, MouseDownR, MouseStartX, MouseStartY:INT
CONST Black=0

Figure_Load()
Refresh_Scale()
Plot_Graph()
SETFOCUS plotwin

WAITUNTIL figure=0
END

'_______________________________________________________________________
SUB Figure_Load()
'load window figure with subwindow plotwin
string figtxt
figtxt = "Figure - Move by dragging mouse or with arrow keys, zoom with + and -"

'load the window (outside the screen)
OPENWINDOW figure, -600,100,500,400, @MINBOX|@MAXBOX|@SIZE|@NOAUTODRAW, 0, figtxt, &RoutineFigure

 OPENWINDOW plotwin, 0,0,200,200, @NOCAPTION | @NOAUTODRAW, figure, "plot", &RoutinePlotWin

   'create this window with a sunken border
   _SetWindowLong(plotwin.hwnd,-20,512)
   _SetWindowPos(plotwin.hwnd,NULL,0,0,0,0,39)

   Resize()
   CfgSetDefault()

   'center the window in the screen so it is visible now
   CENTERWINDOW figure

   RETURN
ENDSUB

'_______________________________________________________________________
SUB RoutineFigure()
'handling of messages from window figure

   SELECT @MESSAGE
      CASE @IDCLOSEWINDOW
         'close the figure window
         CLOSEWINDOW plotwin
         CLOSEWINDOW figure     

      CASE @IDSIZECHANGED
         Resize()
         Refresh_Scale()
         Plot_Graph()

   ENDSELECT
   RETURN
ENDSUB

'_______________________________________________________________________
SUB RoutinePlotwin()              :'handling of messages from window plotwin
   SETTYPE @HITWINDOW, WINDOW

   SELECT @MESSAGE
      CASE @IDPAINT
         Refresh_Scale()
         Plot_Graph()

      CASE @IDLBUTTONDN
         'move axes
         _SetCapture(*@HITWINDOW.hwnd)
         GetCursorPos(&@MOUSEX)
         ScreenToClient(*@HITWINDOW.hwnd, &@MOUSEX)
         MouseStartX = @MOUSEX
         MouseStartY = @MOUSEY
         SETCURSOR plotwin, @CSCUSTOM, LoadCursor(NULL, IDC_SIZEALL)      :'cursor "move"

      CASE @IDLBUTTONUP
         _ReleaseCapture()
         SETCURSOR plotwin, @CSARROW               :' cursor back to normal cursor

      CASE @IDMOUSEMOVE
         if (_GetCapture() = *@HITWINDOW.hwnd)
            GetCursorPos(&@MOUSEX)
            ScreenToClient(*@HITWINDOW.hwnd, &@MOUSEX)
            'Left mousebutton down. move the plot with the mouse movement
            'xmin -= (@MOUSEX-MouseStartX) / xfactor
            'xmax -= (@MOUSEX-MouseStartX) / xfactor
            'ymin -= (@MOUSEY-MouseStartY) / yfactor
            'ymax -= (@MOUSEY-MouseStartY) / yfactor
            xshift += (@MOUSEX-MouseStartX)
            yshift += (@MOUSEY-MouseStartY)

            MouseStartX = @MOUSEX
            MouseStartY = @MOUSEY

            'replot
            Refresh_Scale()
            Plot_Graph()
         ENDIF
      CASE @IDKEYDOWN
         'check keypresses
         'for the keycodes, see the usersguide Appendix, Virtual key codes
         SELECT @WPARAM
            CASE 0x25
               'left arrow is pressed. move the graph to the left
               xshift -= 20
               Refresh_Scale()
               Plot_Graph()
            CASE 0x27
               'right arrow is pressed. move the graph to the right
               xshift += 20
               Refresh_Scale()
               Plot_Graph()
            CASE 0x26
               'up arrow is pressed. move the graph up
               yshift -= 20
               Refresh_Scale()
               Plot_Graph()
            CASE 0x28
               'down arrow is pressed. move the graph to down
               yshift += 20
               Refresh_Scale()
               Plot_Graph()
         ENDSELECT
      CASE @IDCHAR
         'check keypresses
         'for the keycodes, see the usersguide Appendix, Virtual key codes
         SELECT @WPARAM
            CASE ASC("+")
            CASE& ASC("=")
               '+ key is pressed. zoom the graph in
               xfactor *= 1.2
               yfactor *= 1.2
               Refresh_Scale()
               Plot_Graph()
            CASE ASC("-")
            CASE& ASC("_")
               '- key is pressed. zoom the graph out
               xfactor /= 1.2
               yfactor /= 1.2
               Refresh_Scale()
               Plot_Graph()
         ENDSELECT
   ENDSELECT
   RETURN
ENDSUB

'_______________________________________________________________________
SUB Plot_Graph()                         :'this sub repaints the graph
   INT L,T,W,H,  hdc, hdcMem, hbmMem,   oldBmp, oldBrush, oldPen, oldFont
   DOUBLE xscreen, yscreen

   GETCLIENTSIZE(plotwin, L,T,W,H)                :'get size of window

 'Create an off-screen DC for double-buffering
   hdc = _GetDC(plotwin.hwnd)
   hdcMem = _CreateCompatibleDC(0)
   hbmMem = _CreateCompatibleBitmap(hdc, W, H)
   oldBmp = _SelectObject(hdcMem, hbmMem)
   oldBrush = _SelectObject(hdcMem, _CreateSolidBrush(RGB(255,255,255)))
   oldPen = _SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(255,255,255)))

 'set specific font
   INT textW, textH,  fontsize, fontwt
   STRING fontface
   fontface = "Courier New"   :   fontsize = 12   :   fontwt = 600
   SETFONT plotwin, fontface, fontsize, fontwt, 0
   GETTEXTSIZE(plotwin, "A", textW, textH) :'find the desired text Height
   oldFont = _SelectObject(hdcMem, _CreateFont(textH,0,0,0,fontwt, 0,0,0,0,0,0,0,0, fontface))
   _SetTextColor(hdcMem, RGB(0,0,255))
   _SetBkMode(hdcMem, TRANSPARENT)
   _SetTextAlign(hdcMem,TA_UPDATECP)

   'empty window -> draw white, filled rectangle
   _Rectangle(hdcMem, 0, 0, W, H)
   
   'Paint axes with black frontpen
   _DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(0,0,0))))
   _MoveToEx(hdcMem, xmin * xfactor + xshift, 0 * yfactor + yshift, NULL)
   _LineTo(hdcMem, xmax * xfactor + xshift, 0 * yfactor + yshift)
   _MoveToEx(hdcMem, 0 * xfactor + xshift, ymin * yfactor + yshift, NULL)
   _LineTo(hdcMem, 0 * xfactor + xshift, ymax * yfactor + yshift)
   
  'paint the function with red frontpen
   _DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(255,0,0))))
   xscreen = 0  :  yscreen = -myfunction((xscreen-xshift)/xfactor) * yfactor + yshift
   _MoveToEx(hdcMem, xscreen, yscreen, NULL)
   FOR n=0 TO w+5 STEP 2
      xscreen = n  :  yscreen = -myfunction((xscreen-xshift)/xfactor) * yfactor + yshift
      _LineTo(hdcMem, xscreen, yscreen)
   NEXT n

  'Print some text with blue frontpen
   _DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(0,0,255))))
   STRING mystring   :   mystring = "Sin(x)"
   _MoveToEx(hdcMem, 10, 19 * H / 20, NULL)
   _TextOut(hdcMem, 0, 0, mystring, len(mystring))

  'Print axes labels with black frontpen
   _DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(0,0,0))))
   _MoveToEx(hdcMem, 19 * W / 20, yshift, NULL)
   _TextOut(hdcMem, 0, 0, "x", len("x"))
   _MoveToEx(hdcMem, xshift, H /40, NULL)
   _TextOut(hdcMem, 0, 0, " y", len(" y"))

  'Print axes tick marks with black frontpen
   _DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(0,0,0))))
   FOR n=0 TO w+5 STEP 1
      _MoveToEx(hdcMem, -n * xfactor + xshift, yshift - H / 50, NULL)
      _LineTo(hdcMem, -n * xfactor + xshift, yshift + H / 50)
      _MoveToEx(hdcMem, n * xfactor + xshift, yshift - H / 50, NULL)
      _LineTo(hdcMem, n * xfactor + xshift, yshift + H / 50)

      _MoveToEx(hdcMem, xshift - H / 50, -n * yfactor + yshift, NULL)
      _LineTo(hdcMem, xshift + H /50, -n * yfactor + yshift)
      _MoveToEx(hdcMem, xshift - H / 50, n * yfactor + yshift, NULL)
      _LineTo(hdcMem, xshift + H /50, n * yfactor + yshift)
   NEXT n

   'Transfer the off-screen DC to the screen
   _BitBlt(hdc, 0, 0, W, H, hdcMem, 0, 0, SRCCOPY)
   
   'Free-up the off-screen DC
   _DeleteObject(_SelectObject(hdcMem, oldFont))
   _DeleteObject(_SelectObject(hdcMem, oldBrush))
   _DeleteObject(_SelectObject(hdcMem, oldPen))
   _DeleteObject(_SelectObject(hdcMem, oldBmp))
   _DeleteDC(hdcMem)
   _ReleaseDC(plotwin.hwnd, hdc)
   RETURN
ENDSUB

'_______________________________________________________________________
SUB myfunction(value:DOUBLE),DOUBLE
'calculate a functionvalue
   RETURN sin(value)
ENDSUB

'_______________________________________________________________________
SUB Refresh_Scale()
'calculate the boundaries xmin, xmax, ymin, ymax for painting in the screen plotwin
'this depends on the scale of the graph and the size of the window plotwin
INT L,T,W,H
   GETCLIENTSIZE plotwin, L,T,W,H

   'xfactor = W / (xmax - xmin)
   'yfactor = -H / (ymax - ymin)
   'xshift = -xmin * xfactor
   'yshift = -ymax * yfactor

   xmin = (0-xshift) / xfactor
   xmax = (w-xshift) / xfactor
   ymin = (0-yshift) / yfactor
   ymax = (h-yshift) / yfactor

   RETURN
ENDSUB


'_______________________________________________________________________
SUB Resize()
'resize figure window with its subwindow
INT L,T,W,H
   GETCLIENTSIZE figure, L,T,W,H
   SETSIZE plotwin, 0,0,W,H

   RETURN
ENDSUB

'_______________________________________________________________________
SUB CfgSetDefault()
'set default values for the properties of the figure

INT L,T,W,H
   GETCLIENTSIZE plotwin, L,T,W,H

   'xmin=-5
   'xmax=5
   'ymin=-5
   'ymax=5

   xfactor = 40
   yfactor = 35
   xshift = W/2 :'start the axis at half the width of the plotwin
   yshift = H/2

   RETURN
ENDSUB

.
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 20, 2015, 06:55:41 AM
Hi Mike

sorry only bad news..
I remove all things from GDI functions as you suggested
i also remove InitDrawing() function where is created DC backbuffer.
then i try to implement @onpaint event ( WM_PAINT )
then everything else stop to work  >:(
when mousemove & leftbuttondown events work
it looks that wm_paint simply freez my interpteter . ::)
this is really weird ...
i will post source code ...
thanks for asking.. ;)

Thanks for the feedback, Aurel.

If you have implemented all the mods that I suggested, then simply PM me the resultant zip with all the Ruben sources. It is too early to test or criticize anything in it yet. It is only the beginning of the overhaul.
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 20, 2015, 07:10:09 AM
I can't judge the entire EBasic program because I have no personal experience with this dialect but the plotting subroutine's GDI code seems to be perfectly correct. It does create, select and delete its temporary GDI objects properly, and all the defaults are saved and restored correctly before the respective DCs are released and deleted. Unlike your Ruben, it follows the classic strategy of drawing into the memory DC and then blitting the image to the screen window DC. This is exactly what I suggest your Ruben should do too.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 20, 2015, 07:36:02 AM
Thanks Mike for reply and for trying EB program..
when i started GDI graphic i was looking into this program...
but something go wrong in my translation to oxygen (or some bugs in o2)  ::)
FIRST
i will try translate this program to oxygen again and then i will see if work properly .
Big problem i have in ruben is that i want to draw anywhere in program
not only under wm_paint.
Currently i can do that but with 44 GDI objects without increasing, as i say i tested
that in many programs i made ..
This program for example use in start 33 objects but when i resize window then
number of GDI ojects go up to 39.

ok
i don't want bothering you with my 'experience'  so i will post code of ruben4.

.
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 20, 2015, 08:10:54 AM
Big problem i have in ruben is that i want to draw anywhere in program not only under wm_paint.

But all drawing becomes visible on your screen window only as an effect of the WM_PAINT message, Aurel. That's how Windows GDI works.

It looks as if you don't read my explanations attentively enough. I have already mentioned that drawing "anywhere in program" can be done only if you draw directly into the memory DC and then flush it (i.e. bit-blit it) to the screen in one go, first, when all your commands to draw into the memory DC have been issued anywhere in your program, and second, automatically in response to the WM_PAINT message whenever a part of the window needs repainting when i) dragged from beyond the screen borders, or ii) when uncovered by dragging another window that's on top of it, or iii) when resized.

Quote
This program for example use in start 33 objects but when i resize window then
number of GDI ojects go up to 39.

That's normal. Not all GDI objects are created at once when the program starts. But the main idea is to keep that number stable once all persistent GDI objects have been created, and their exact number will depend on what platform the program actually runs. At the same time, all temporary GDI objects should be deleted cleanly when no longer needed.

Quote
i will post code of ruben4.

Thanks.


[EDIT]
Quote from: Myself
... PM me the resultant zip with all the Ruben sources ...

Please post RTL32.inc and awinh.inc here that your Ruben currently relies on.

[EDIT2]

... and BMPs too.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 20, 2015, 01:02:58 PM
ahh sorry i forget that, bitmaps ?
you can ignore bitmaps because are not important part of interpreter and i
in the beginning try to use main window (hidden) as sort of debuger window...

.
Title: Re: GDI functions & Init problems?
Post by: Aurel on March 20, 2015, 02:51:42 PM
Hi Mike
you can try this simple program and tell me how work on your computer
small correction ...enable InitDrawing(win2) under subroutine
exec_WINDOW()

Code: [Select]
'Black Hole
wform 0,0,800,720,#SYS,0,"BlackHole"
defn w,h,a,r,ps,i,px,py
defn rr,gg,bb,rx,ry
sET w=700/2:
sET h=700/2:
wcolor 0,0,0
set a=1
set r= 0

label again

For i,1,30
set ps=10000/(i/a)
set rr=RAND(255),gg=RAND(255),bb=RAND(255)
txcolor rr,gg,bb,rr,gg,bb
set rx=cos(i*r)*ps+w , ry=sin(i*r)*ps+h
rect ry,rx,4,4
pix rx,ry
Next i

set a= -0.1
If a,<,20
set a=a+0.01
EndIf
ser r= -360
If r,<,360
set r=r+0.01
EndIf
wcolor 0,0,0
jump again
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on March 20, 2015, 08:04:05 PM
Thanks Aurel,

I'll be back when Ruben4 begins to function as intended. Please give me some time.
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 12, 2015, 03:29:06 PM
Hi Mike
do you maybe check some strange things in my interpreter.
today i just try few drawing examples with new o2 dll...
maybe is not problem with dll but i get very big memory leaks over 220k
but number of GDI objects stay ok...
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on May 12, 2015, 05:31:30 PM
... maybe is not problem with dll but i get very big memory leaks over 220k ...

Hi Aurel,

If one and the same source code of Ruben doesn't leak memory with some older DLL but does leak it with the new one and you can show it, then probably it isn't a question to me but rather to Charles? :)

Moreover, I don't have Ruben's original sources so I can't run reliable checks. The raw Ruben4 isn't suitable for testing and I must confess that I haven't yet touched it to make it usable. I am sorry to keep you waiting for so long; the files are still on my desktop right before my eyes. :-[
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 12, 2015, 08:58:41 PM
Hi Mike
what you mean under raw...
do you mean without examples or something else
and as i say i am not sure what might be problem... ::)
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 12, 2015, 09:50:46 PM
Mike
there is no need to check whole interpreter...
do you can test only my GDI functions and and how should look properly
so without GDI leaks or multiply executions
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 13, 2015, 02:03:00 AM
Yes there is a big mem leak in new dll.
In attachmant are two versions ,one with memleak and one produced with old o2 dll
without mem leak.
old version when interpreter execute mandel stay on cca 3900k
when new grove ..grove...
this is really bad

Charles
please ...please ...please ...please fix this once for all times  :(

.
Title: Re: GDI functions & Init problems?
Post by: Charles Pegge on May 13, 2015, 07:18:37 AM
Hi Aurel,

I've done lots of string tests, but no memory leaks detected so far.

2 Suggestions which will benefit your code:

First, use #autodim off. This will expose any variable which have not been formally dim'ed.

It is essential that string variables are not created in the middle of a loop.

Second, ensure that the RTL matches the compiler. Using an old RTL with a recent compiler could be very risky.


Meanwhile, I will continue string testing for leaks. I might also create a stringy interpreter to aid this process, since there are many o2 examples that use strings but none do so in a highly iterative manner.


Title: Re: GDI functions & Init problems?
Post by: JRS on May 13, 2015, 08:35:30 AM
Quote
Meanwhile, I will continue string testing for leaks. I might also create a stringy interpreter to aid this process, since there are many o2 examples that use strings but none do so in a highly iterative manner.

May I suggest using your DLLC interface with Script BASIC to test your string engine? SB strings are rock solid and only limited by available memory.
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 13, 2015, 02:02:54 PM
Quote
Meanwhile, I will continue string testing for leaks. I might also create a stringy interpreter to aid this process, since there are many o2 examples that use strings but none do so in a highly iterative manner.
Ok i will download latest release with latest RTL if you think that part of problem is there.
But this things becomes very frustrating....
same code work with older version ...fine
but same code not work properly with new version and that is all the time  ::)
Title: Re: GDI functions & Init problems?
Post by: JRS on May 13, 2015, 02:31:32 PM
Aurel,

It would help Charles if you could be more detailed about the issues you're having with O2. Posting small code snippets that show the problem is really helpful. As you know, O2 is a work in process and I'm not aware of a stable release. I'm sure your code base is going to change over time as Charles finds better ways of doing things.

John
Title: Re: GDI functions & Init problems?
Post by: Charles Pegge on May 13, 2015, 08:47:24 PM
I found 6 bstrings in Ruben4. These should be strings for automatic garbage collection.
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 13, 2015, 09:34:47 PM
yes there are 6 bstrings but those bstrings are not part of interpreter loop
and are present when i compile program with old oxygen too but there is no mem leak
as i get with new dll.
Title: Re: GDI functions & Init problems?
Post by: Charles Pegge on May 13, 2015, 11:52:00 PM
No O2 memory leaks picked up so far.

My stringiest approximation to an interpreter, LeanLisp, has none

bstrings must be explicitly freed with frees (or freememory). It is important to eliminate bugs wherever they are found.

PS:

You have also commented out indexbase 0

This will cause instability when using arrays indexed at 0

Code: OxygenBasic
  1. For n = 0 TO 1000
  2. arg0[n]=""
  3. arg1[n]=""
  4. arg2[n]=""
  5. arg3[n]=""
  6. arg4[n]=""
  7. arg5[n]=""
  8. arg6[n]=""
  9. arg7[n]=""
  10. arg8[n]=""
  11. arg9[n]=""
  12. arg10[n]=""
  13. arg11[n]=""
  14. arg12[n]=""
  15. arg13[n]=""
  16. arg14[n]=""
  17. arg15[n]=""
  18. arg16[n]=""
  19. arg17[n]=""
  20. arg18[n]=""
  21. arg19[n]=""
  22. arg20[n]=""
  23. Next n
  24.  
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 14, 2015, 01:27:03 AM
ok i will remove bstrings and reformat array to indexbase 1
then wewill see...


.
Title: Re: GDI functions & Init problems?
Post by: Charles Pegge on May 14, 2015, 01:51:32 AM
Aurel, please stay with indexbase 0, if that is what your are accustomed to using. (As in FreeBasic)
Title: Re: GDI functions & Init problems?
Post by: JRS on May 14, 2015, 02:07:01 AM
I'm still confuse why Aurel would REM out indexbase 0 and then base his arrays on zero anyways?  :o

A. Sloppy/lazy programmer that finds it easier to blame others and let them fix his self inflicted problems.

B. O2 should be smart enough to assume Aurel's intension at any level.

C. Aurel need to brush up on his debugging skills and not assume if it doesn't work it must be O2's fault. Getting away with unplugged holes of the past is not justification that Charles is notorious for breaking things.  ::)
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 14, 2015, 12:52:49 PM
John
stop babeling about things you don't undrerstand
first try exes from zip memleak then you will see what is all about of course if
you are not stupid enough.
second problem is really in o2 because how explain that something work
as it suposed to be then in new release not work...do you understand now
mister -super john

Charles
I will try indexbase 0 & 1 and what is the difference ...
i will also test autodim off  ;)
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 14, 2015, 01:40:48 PM
Charles
i do next
all variables - #autodim off 
removed all bstrings
left indexbase 0

mem leak is now little bit less cca 50 000 k when without changes grove up to 200 000k
i have download latest release from wizzard ...do you have something new?

.
Title: Re: GDI functions & Init problems?
Post by: Mike Lobanovsky on May 14, 2015, 01:50:03 PM
I will try indexbase 0 & 1 and what is the difference ...

Hi,

On default, O2 assumes arrays start at index 1. indexbase lets you change this default behavior. If you are using arrays that start at index 0 but you haven't specified indexbase 0 then in the For/Next loop that Charles showed, O2 may either i) skip working for arg0[0] and develop memory leaks here (at best), or ii) crash completely (in the worst case). Either way, O2's behavior will be, technically speaking, undefined.

Try to always match you arrays with an explicit declaration of the respective indexbase. We will all be getting significantly fewer headches if we do it too. Don't rely on the language defaults; be very specific about everything you do in your code.

Do not use string assignments that generate temporary strings in For/Next, While/Wend, Do/End Do loops! OxygenBasic cannot automatically collect temporary string garbage generated internally in such loops!
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 14, 2015, 09:20:04 PM
Mike i check everything yesterday 4  times...
and download latest realease and problem is present
and i repeat....how then work fine with older dll without mem leak
dll which work is from old PeterW version oxyBasic.
 ::)
Title: Re: GDI functions & Init problems?
Post by: Charles Pegge on May 14, 2015, 09:36:51 PM
Hi Mike,

If strings are dim'ed before the loop then all is well.

But when dim'ed or auto-dim'ed inside a loop, the string's reference will be reset, and a new entry will be made on the Garbage Collector list. This is tolerable, though undesirable, for small iterations on local strings, but otherwise builds up a mountain of uncollected garbage.

Apart from global and local string GC lists, there is a list for temporary strings, which are to be freed after an expression.

Hi Aurel,

I've now tested all O2 string functions, and have not detected any leaks. However I detected one issue with local string arrays getting logged to the global GC, but all your arrays appear to be global anyway.

Oxygen DLL Update (200k)
http://www.oxygenbasic.org/o2zips/Oxygen.zip


Title: Re: GDI functions & Init problems?
Post by: Aurel on May 14, 2015, 10:03:43 PM
yes Charles all my arrays are global and there is no any direct imapact on interpreter loop.
Title: Re: GDI functions & Init problems?
Post by: JRS on May 14, 2015, 10:15:25 PM
@Aurel - Do you know where in your interpreter the leak is occurring? Is your claim based on "this is the memory available when I start the program and this is what it increased by once it ended"? Are you using any type of debugger in troubleshooting the issue your having? I guess what I'm asking, is this more than just a feeling you have or can you post a code snippet of it failing?

Title: Re: GDI functions & Init problems?
Post by: Aurel on May 15, 2015, 12:50:44 AM
John
open task manager and run ...then you will see how memory using grove...
simple ...
what kind of debugger  ???
Title: Re: GDI functions & Init problems?
Post by: JRS on May 15, 2015, 12:59:54 AM
John
open task manager and run ...then you will see how memory using grove...
simple ...
what kind of debugger  ???

Oh, I got it. You have no idea or proof O2 is leaking memory other than task manager which accumulates all processes used memory.

You need to do better than that if you want to call yourself a programmer.

Title: Re: GDI functions & Init problems?
Post by: Aurel on May 15, 2015, 02:49:02 AM
Quote
You need to do better than that if you want to call yourself a programmer
oh tutie-frutie managero  :P

enough for me
sorry but i am not creator of o2 , so how i know what is where  :o
SLS   ;D
Title: Re: GDI functions & Init problems?
Post by: JRS on May 15, 2015, 10:18:22 AM
Quote
You need to do better than that if you want to call yourself a programmer
oh tutie-frutie managero  :P

enough for me
sorry but i am not creator of o2 , so how i know what is where  :o
SLS   ;D

Unlike many of the Windows offerings, O2 comes with source and the only limitation is your curiosity and willingness to learn.
Title: Re: GDI functions & Init problems?
Post by: Charles Pegge on May 23, 2015, 01:31:10 AM
Hi Aurel,

I've made some progress, leak hunting in Ruben3.

 I traced down to a dropped optimization affecting instr(). When the optimization was restored, the memory leak disappeared, (testing with fern.RUB).

However, this only masks the underlying problem, adversely affecting instr(). So further investigation is required.

14 May 2015:
http://www.oxygenbasic.org/o2zips/Oxygen.zip
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 23, 2015, 01:45:23 PM
Hi Charles
I am glad that you find where problem is ...so
instr()...
i really don't have a idea what might be wrong when old release work as expected.
i must say that i have one experimental version of ruben written in old Emergence Basic
where i have only few commands including forLoop ...Diffrence...
ufff is BIG...
that version take only 2300k and there is no any sign of mem leak.
String operations in EB are very good BUT speed of execution is better with o2  :D
I don't have Power Basic but from what i read and what i can see in Eros work (tB)
i can say that i would like that o2 have such a speed with strings..
all best.. ;)
Title: Re: GDI functions & Init problems?
Post by: JRS on May 23, 2015, 02:03:21 PM
Good job Aurel sticking to your guns and blowing off people like me saying it must be you.  :-*

Quote from: Aurel
I don't have Power Basic

You would probably have better luck finding a copy on the torrents then getting anyone at PowerBASIC to sell you one.
Title: Re: GDI functions & Init problems?
Post by: Aurel on May 23, 2015, 02:18:33 PM
Yes Charles
 tested new dll and it seems that mem leak gone
mem usage is fixed to 4088k on my computer and work very fast.
Of course i will test tomorow whole code of ruben4.