weird loopy jamming my app

BlitzPlus Forums/BlitzPlus Beginners Area/weird loopy jamming my app

Apollonius(Posted 2005) [#1]
I really need to master loops of all kind but theres no tutorial on them anywhere. My problem here is something in my loop is jamming all the closing app events.. like with the [X] and Cancel button.

Repeat
	;--------------------------------------------------------------------------
	; Gadget Generated Action
	;--------------------------------------------------------------------------
	If(WaitEvent()=$803) Then
		End
	EndIf
	
	If(EventSource()=mStart) Then
		Notify "This would start the game if there was one..."
	EndIf
	If(EventSource()=mCancel) Then
		End
	EndIf
	If(EventSource()=mtest) Then
		SCREEN=1
	EndIf
	;--------------------------------------------------------------------------
	; Screen Loop
	;--------------------------------------------------------------------------
	Select SCREEN
		Case 0
		; Neutral Space
		
		Case 1
		Repeat
			SetGadgetText txt_ini_total_dl, "Fetching First File..."
			timer = CreateTimer(5)
			If WaitEvent()=$4001 Then
				progress# = progress# + 0.01
				UpdateProgBar totalupdate, progress#
			EndIf
			
		Until progress# = 1
		SCREEN = 0
	End Select
	

Until (KeyHit(1))
End

Its probably a stupid error somewhere :|


CS_TBL(Posted 2005) [#2]
You need to master something else first: uniformity. Every app you show here looks different in codestyle. You need to start simple and small, forget about games and other big stuff for a while. You can't learn a language properly if you put your focus on big stuff, and tomorrow you'll be looking at a mess if you don't add a bit of structure.

You could for example adopt this framework:
window=CreateWindow("bla",0,0,640,480)

;
;
; create more stuff here..
;
;

Repeat
	Delay 2
	WaitEvent()
	If EventID()=$803 quit=True
	
	;
	;
	; event-checks of the rest of the app
	;
	;
	
Until quit

;
; clean-up things like images, banks etc. *HERE*
;

SetBuffer DesktopBuffer()
End


Using that framework, here's how things can work:

window=CreateWindow("bla",0,0,640,480)

Global img=CreateImage(160,160)
SetBuffer ImageBuffer(img)
Text 0,0,"Structure!"
Text 0,32,"..please.."

Global canvas=CreateCanvas(0,0,640,480,window)

Repeat
	Delay 2
	WaitEvent()
	If EventID()=$803 quit=True

	evFunction()
	
Until quit

FreeImage img
SetBuffer DesktopBuffer()
End

Function evFunction()
	If EventSource()=canvas
		If EventID()=$203
			x=EventX()
			y=EventY()
			SetBuffer CanvasBuffer(canvas)
				Color x Mod 256,y Mod 256,128
				TileBlock img,x/4,y/4
				Rect 320-x,240-y,240,200,True
				TileImage img,x/2,y/2
				Color y Mod 256,x Mod 256,128
				Rect 320-x*2,240-y*2,120,100,True
				TileImage img,x,y
			FlipCanvas canvas
		EndIf
	EndIf
End Function


So, put all the eventchecking in functions .. they're sorted then, and shielded from everything else.


CS_TBL(Posted 2005) [#3]
Why don't you start on something easy?

Try this:

* make a window of roughly 640x480
* put a 512x256 canvas on it
* put a 256x128 canvas below it
* make a windowmenu with some option to load an image
* when you load an image via that menu, draw it in the canvas
* let the 256x128 canvas be a zoomer for that image you just loaded (zoom @ 16*8 tiles?) ... unless there's no image ofcourse, then it shows some kinda 'empty' gfx..
* the zoomer is updated as you move your mouse over the 512x256 canvas with the image (if any image is loaded, that is)
* use the right mousebutton on the big canvas to scroll through the loaded image (when it's bigger than 512x256)
* put a few image-modifier-buttons/scrollbars/checkboxes next to the big canvas, they'll do whatever you want them to do. Invert, brightness, add noise, add scanlines etc. etc.

Ok, this might seem dull, and it might not seem to be a lot of work. But I'll tell you this:
- it's hundreds of lines, perhaps close to 1000!
- you'll learn a lot from it
- it's more work than you think :P

If you think *this* is a lot of work, don't even begin to think about games and bigger apps then :P


ozak(Posted 2005) [#4]
True, but isn't the solution to the problem at hand that WaitEvent() should be WaitEvent(0) to return immidiately? Otherwise WaitEvent will block the app until a GUI event occurs.


Apollonius(Posted 2005) [#5]
CS_TBL
On the countrary that seems like alot of work.. I mean, I wouldn't know where to begin.

This below is beyond me:
* let the 256x128 canvas be a zoomer for that image you just loaded (zoom @ 16*8 tiles?) ... unless there's no image ofcourse, then it shows some kinda 'empty' gfx..
* the zoomer is updated as you move your mouse over the 512x256 canvas with the image (if any image is loaded, that is)
* use the right mousebutton on the big canvas to scroll through the loaded image (when it's bigger than 512x256)
* put a few image-modifier-buttons/scrollbars/checkboxes next to the big canvas, they'll do whatever you want them to do. Invert, brightness, add noise, add scanlines etc. etc.

Zooming.. Loading an image I think I could do. I'm far from being a pro. But I'd be willing to practice making test apps like the one you mentioned above but I'd need guidance here and there. Do you have any instant messaging program CS_TBL?


CS_TBL(Posted 2005) [#6]
Yes, but I don't want to go that way.. in here it good enough.

My first serious B+ app I ever made *was* something like this app.. that's why I mentioned it :)
Before I made that app I was a bit wandering around, clueless, after I made that app I was quite well with B+. You need to focus on an app of which you know what it should look like and what it should do. That's way better than trying to make some big unknown app of which you can't even remotely imagine how big it'll be in terms of code.

Just start with the app here in this topic, gradually I can tell you what to do or how things work. But do me one favour: stick to that framework I showed!
Oh, and do learn those events by heart. After that first app I made I knew all eventcodes by heart!

So, just start, and post the source whenever you have something. Stick to a certain structure, use sense-making variable-names, try to avoid globals. You *might* want to look in the B+ tutorials section for my 2 tutorials about banks and gadgets..


CS_TBL(Posted 2005) [#7]
Otherwise WaitEvent will block the app until a GUI event occurs.


If you want regular updates of your app, say 25fps, while keeping the event-based nature, as opposed to polling, then use timers and event $4001 ..


Apollonius(Posted 2005) [#8]
As soon as i run this app, I click file, quit.
It doesn't work.

but if I do file->quit->file->quit it works.. I have to do it twise... whats worng with my code? O.o

If I move the window and the do file->quit on startup it works but if I don't touch the window and just click file, open or exit... it wont work right away.

The way Im using to handle the menu is the same way as in the tutorial within blitz+

mainwindow	=CreateWindow( "Practice", 10, 10, 640, 480)

mainmenu	=WindowMenu(mainwindow) 

file		=CreateMenu("File",0,mainmenu)
CreateMenu "Open",1,file
CreateMenu "",0,file
CreateMenu "Quit",3,file

UpdateWindowMenu mainwindow

; -----------------------------------------------------------------------------
; Main Loop
; -----------------------------------------------------------------------------

Repeat
; [X] Will Now Close the Window
If WaitEvent()=$803 Then End
; Check Menu Events
If WaitEvent()=$1001 Then
	Select EventData()
		Case 1 ; Open
			Notify "You clicked oepn!"
		Case 3 ; Exit
			End
	End Select
End If

Until KeyDown(1)
End



CS_TBL(Posted 2005) [#9]
humptidumptidum... framework.. humptidumptidum...

I *did* notify you of that framework, right? As soon as I changed your mainloop to my model, it all suddenly worked..

mainwindow	=CreateWindow( "Practice", 10, 10, 640, 480)

mainmenu	=WindowMenu(mainwindow) 

file		=CreateMenu("File",0,mainmenu)
CreateMenu "Open",1,file
CreateMenu "",0,file
CreateMenu "Quit",3,file

UpdateWindowMenu mainwindow

; -----------------------------------------------------------------------------
; Main Loop
; -----------------------------------------------------------------------------

Repeat
	WaitEvent() ; <----------- do it like this
	
	; [X] Will Now Close the Window
	If EventID()=$803 Then End ; <------- and this, even so, not a good idea
	; Check Menu Events
	If EventID()=$1001 Then ; <------- and this
		Select EventData()
			Case 1 ; Open
				Notify "You clicked oepn!"
			Case 3 ; Exit
				End ; <--- no good idea
		End Select
	End If

Until KeyDown(1)
;
; cleanup
;

End ; <--- and NOW you may end..



Oh ps, I learnt B+ without much reference to the tutorials in the B+ package.. they're far from structured. No offence to those who made them, tho ^_^


Apollonius(Posted 2005) [#10]
I wasn't too sure about what you meant by "framework", btw you said no good idea at a few places, why?

Because by doing end now it would by pass the ; cleanup? So I should do something until exit=true then instead of puttin end, id put exit=true..?

edited,
oh and waitevent() with no variable or anything what is it doing there? whats its purpose lonely like that?


CS_TBL(Posted 2005) [#11]
the 'no good idea' refers to the 'End' you put in the middle of your source.

You should end at the end, and not in the middle of your application. In some cases you can't just end.. you need to set the buffer to the desktopbuffer, and you might want to free some images, banks etc. before ending, otherwise you might get memory-leaks.

So, the only thing you should end is the main-repeatloop.. which can be done using a variable, like exit, or quit.. (which can be seen in my framework)

Framework is just the first piece of code you see here from me. It's just the thing you can fill-in with own stuff..

so again: *this* is a framework:
window=CreateWindow("bla",0,0,640,480)

;
;
; create more stuff here..
;
;

Repeat
	Delay 2
	WaitEvent()
	If EventID()=$803 quit=True
	
	;
	;
	; event-checks of the rest of the app
	;
	;
	
Until quit

;
; clean-up things like images, banks etc. *HERE*
;

SetBuffer DesktopBuffer()
End




Waitevent waits for events... that's all. When checking for events, you don't check "waitevent", you check EventSource(), EventData(), EventID(), EventX(), EventY()

When you have a single Waitevent in your loop then that's is enough for your whole application basically (few exceptions, but you're not even remotely up to that yet :)

So, 1 Waitevent, and for the rest those Events.., anywhere..


Apollonius(Posted 2005) [#12]
Ok, so far everything looks good, clean code and I like it. Alot of comments in it, but thats the way I like it. However I ran in a little problem, I tryed to draw 2 canvas and only 1 is drawn.

; -----------------------------------------------------------------------------
; Practice Exercise (PE)
; -----------------------------------------------------------------------------
AppTitle "Project PE"
window=CreateWindow("Practice Exercise",50,50,640,480)

; -----------------------------------------------------------------------------
; Menu Creation
; -----------------------------------------------------------------------------
menu=WindowMenu(window) 

file=CreateMenu("File",0,menu)
CreateMenu "Open",1,file
CreateMenu "",0,file
CreateMenu "Quit",3,file

; -----------------------------------------------------------------------------
; Draw the Canvas
; -----------------------------------------------------------------------------
canny1=CreateCanvas(10,10,512,256,window)
canny2=CreateCanvas(10,520,256,128,window)

; -----------------------------------------------------------------------------
; Update the Window with the gadgets and stuff?
; -----------------------------------------------------------------------------
UpdateWindowMenu window

; -----------------------------------------------------------------------------
; Main Loop
; -----------------------------------------------------------------------------

Repeat
	Delay 2
	WaitEvent()
	If EventID()=$803 quit=True
	
	;
	;
	; event-checks of the rest of the app
	;
	;
	
Until quit

;
; clean-up things like images, banks etc. *HERE*
;

SetBuffer DesktopBuffer()
End



EDITED,
errr I feel stupid. Canvas is drawn outside the window.. since 640x480... so I have two canvas that are way to big to both fit in the window :o


CS_TBL(Posted 2005) [#13]
There's one thing you might have to think of. If you're going to do the event-checking/updates in functions (and you *want* that) then the functions must have access to those gadgets you created. ATM they're *not* globals. You can solve it with 3 methods:

(1) Make them global, it's the easiest solution, but not really recommended. The best applications have little or no globals at all
(2) put the function-calls in the mainloop and use the gadgets you need as function-arguements, not really recommended. The function-call only works in the mainloop then, and you might end-up with enourmous arguement-lists
(3) store all gadgets you created in 1 bank, and:
-- make this bank global
-- move this bank around as a function-arguement


I personally would prefer option 3 as it's the most clean and reusable option. It does require a little thinking tho.. but that doesn't hurt. :P

If you have 5 gadgets, like canvas1, canvas2, button, window, panel and you want to store them, do like this, before you call any functions.. so, at the start..

bank=Createbank(5*4)
PokeInt bank, 0,canvas1
PokeInt bank, 4,canvas2
PokeInt bank, 8,button
PokeInt bank,12,window
PokeInt bank,16,panel


If you have a function Blah() and you need the button in there to check on events, do this:
Function Blah(bank)
  button=PeekInt(bank,08)
  ; and now the event-checking:
  If EventSource()=button
    ; do something here..
  EndIf
End Function


Now you can call this function anywhere, with:
Blah bank

(ps, to call the function from anywhere, 'bank' must be a global.. *or* you already know 'bank' because you're in a function and 'bank' was already given to you as function-arguement)

Naturally, if you need more gadgets from your bank, you need to PeekInt, PeekShort, PeekByte, PeekFloat a bit more than that.. basically you Peek what you need.
If you change a value you just peeked, and you wish to keep that new value, you need to store it again ofcourse, with Poke.


CS_TBL(Posted 2005) [#14]
so, did you give up? :P


Apollonius(Posted 2005) [#15]
Things happened, I didnt even have time to start on it and now I dont remember @#!*z so yeah I'm giving up. lol