Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Freeing Allocated Objects for a Class
Index -> Programming, Turing -> Turing Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Cervantes




PostPosted: Thu Jun 02, 2005 5:36 pm   Post subject: Freeing Allocated Objects for a Class

So I've got my button class going on overload. Buttons everywhere (313 at the maximum [in case you're wondering, 300 of them represent seats]). Each button has a font that it uses to draw the label on top of itself.
Sometimes, my program will crash, saying that "Font was never allocated". Okay, it definately was. I allocate the font in my INIT procedure and use it in a few other procedures, but only AFTER I've called the INIT procedure. This I am sure of.
The thing is, I don't EVER free the fonts. I free the instances of the button class at the end of my program, but I don't have a Font.Free procedure or line in my class. (Freeing the instance of the class doesn't free the fonts, does it?) I suspect this is the problem.
If so, how would I impliment a freeing of the fonts? Right now the best idea I have is making a procedure to free the font and call that procedure for every button I have just before I free the instances of the button class. This would not be all that pretty, however. I'm wondering if anyone has any better ideas.

Also, what are Turing's limitations in terms of fonts? With pictures, you can't have more than 1000 active at any time. I tried a basic program that ran through a for loop and created 12500 fonts, and it did not crash, though it got really really slow. What are the ways a program can overdo it with the fonts, and crash because of it?

Thanks!
Sponsor
Sponsor
Sponsor
sponsor
Delos




PostPosted: Thu Jun 02, 2005 9:11 pm   Post subject: (No subject)

So, what you're saying is that for ButtonA, you have a font stream fontA, and for ButtonB...etc etc.
Is that it? That seems a little excessive to me, since you could just use the same font stream for all, but set your parameters up to handle the text.
This seems self-evident, so I doubt that this is the case - I have a little more faith than that in you...

I've never seen that particular error before, having rarely dabbled with Fonts myself. Just set up an error catching routine that you can call after each procedure call (something that checks for Error.Last, and possible pauses the programme, opens a new window, and displays a message).
It could help with the debugging. Of course, figuring out where to put it would be fun...Very Happy

If only Turing could have some sort of implicit call that gets associated with every procedure.
Have fun, and it wouldn't hurt to show us a little code to...expidite the proceedings.
Cervantes




PostPosted: Thu Jun 02, 2005 10:03 pm   Post subject: (No subject)

Thanks for the reply, Delos.
Delos wrote:

So, what you're saying is that for ButtonA, you have a font stream fontA, and for ButtonB...etc etc.
Is that it? That seems a little excessive to me, since you could just use the same font stream for all, but set your parameters up to handle the text.

Yes, each button has its own fonts. In the INIT procedure, a few of the parameters determine the font, fontheight, and font colour. I could have several buttons in several different programs that have different fonts and colours. I did not want to make this class like Turing's built-in GUI; I wanted mine to be easily customizable.
If I were to have the same font stream for all buttons, it would mean giving the program(me) that accesses the class much more access to the way the buttons operate. It would also mean forcing them all to have the same font. Lastly, it would mean more coding. Confused

Delos wrote:

I've never seen that particular error before, having rarely dabbled with Fonts myself.

Yeah, it seems to be a rare error, and so far it seems very difficult to understand. What's more frustrating is that after some tinkering I managed to get the error "Unknown Error Message", and yet I managed to figure that one out! Laughing

As for source, I don't think it will help, but here it is. You probably won't get the error though, as it does not occur that often and I've not narrowed down when it occurs. Also, you can see I've got some commented lines of Font.Free's and Font.New's, wrapped around wherever I need to use a font. This seems to work perfectly, though when I've got 300 buttons on one screen the Font.Free's and Font.New's make things get rather slow.
Turing:

/*
 Geoff Stanley
 Created: March 2005
 This class allows the creation of multiple, customizable buttons.
 ****************NOTES*******************
 To create multiple buttons in a program, create an array of instances of this class.  For example, to create 6 buttons:
 var buttons : array 1 .. 6 of ^BUTTON
 for i : 1 .. upper (buttons)
 new BUTTON, buttons (i)
 end for
 then, use the INIT procedure to each button.  If you don't want the button to be shown right away, hide it immediately after INITing it.
 */

class BUTTON
    import Mouse    %were this a unit (as it normally is.  I just made it like this to avoid the bother of saving files to see an example) this import line would not be needed
    export INIT, changeLabel, setActivity, setColour, move, show, hide, visible, clicked, draw
    var button :
        record
            x1, y1, x2, y2 : int
            xPadding, yPadding : int
            active : boolean
            show : boolean
            pressed : boolean %if the mouse is over it and the button is held down
            released : boolean  %if the mouse is over it and the button is held down then released
            boarder : %the boarder of the button
                record
                    width, height : int %default: 1 (pixel)
                    clr :
                        record
                            top_left : int %default: white when not pressed, black when pressed
                            bottom_right : int %default: black when not pressed, white when pressed
                        end record
                end record
            label_ : %the text that appears on the button
                record
                    text : string
                    font, fontHeight : int
                    fontName : string
                    x, y : int %will default so the text appears in the middle of the button
                    xDraw, yDraw : int %used to draw the label.  Changes if the button is clicked.
                    clr : int
                end record
            clr : %the colour of the button
                record
                    current : int %
                    main, highlight, select : int
                end record
        end record

    /*initialize the button.
     x1, y1, x2, y2 --> the coordinates of the bottom left and top right corners of the button
     Alternatively, if x2 = 0, then x1 becomes the centre of the button.  The width is determined by the fontsize, the font, the text, and the xPadding.
     Similarly, if y2 = 0, then y1 becomes the centre of the button.  The height is determined by the fontsize and the yPadding.
     xPadding, yPadding --> if 0 is used for width and height, xPadding and yPadding are responsible for the number of pixels from the
     edge of the button to the text
     labelText --> the text that will appear in the button
     fontName --> the name of the font.  eg.  "Times New Roman"
     fontHeight --> the size (height, in pixels) of the font.  eg. 12
     labelClr --> the colour number for the text
     mainClr --> the colour number of the button when it is not pressed or highlighted
     highlightClr --> the colournumber of the button when the mouse is over it
     selectClr --> the colour number of the button when it has been released
     */

    proc INIT (x1, y1, x2, y2 : int, xPadding, yPadding : int, labelText : string, fontName : string, fontHeight : int,
            labelClr : int, mainClr, highlightClr, selectClr : int)

        button.label_.font := Font.New (fontName + ":" + intstr (fontHeight))
        button.label_.fontName := fontName
        button.label_.fontHeight := fontHeight
        %------------
        if x2 = 0 then
            button.x1 := round (x1 - Font.Width (labelText, button.label_.font) / 2 - xPadding)
            button.x2 := round (x1 + Font.Width (labelText, button.label_.font) / 2 + xPadding)
        else
            button.x1 := x1
            button.x2 := x2
        end if

        if y2 = 0 then
            button.y1 := round (y1 - fontHeight / 2 - yPadding)
            button.y2 := round (y1 + fontHeight / 1.5 + yPadding)  %fontHeight / 1.5 (not / 2) because of hanging letters like "g"
        else
            button.y1 := y1
            button.y2 := y2
        end if
        button.xPadding := xPadding
        button.yPadding := yPadding
        %-------------
        button.active := true
        button.show := true
        button.pressed := false
        button.released := false
        %-------------
        button.boarder.width := 1
        button.boarder.height := 1
        button.boarder.clr.top_left := white
        button.boarder.clr.bottom_right := black
        %-------------
        button.label_.text := labelText
        button.label_.x := round ((button.x1 + button.x2) / 2 - Font.Width (labelText, button.label_.font) / 2)
        button.label_.y := round ((button.y1 + button.y2) / 2 - fontHeight / 2)
        button.label_.xDraw := button.label_.x
        button.label_.yDraw := button.label_.y
        button.label_.clr := labelClr
        %-------------
        button.clr.current := mainClr
        button.clr.main := mainClr
        button.clr.highlight := highlightClr
        button.clr.select := selectClr

        %Font.Free (button.label_.font)
    end INIT

    proc changeLabel (newLabel, fontName : string, fontHeight : int)
        button.label_.text := newLabel
        button.label_.fontName := fontName
        button.label_.fontHeight := fontHeight
        %button.label_.font := Font.New (fontName + ":" + intstr (fontHeight))
        button.label_.x := round ((button.x1 + button.x2) / 2 - Font.Width (newLabel, button.label_.font) / 2)
        %Font.Free (button.label_.font)
    end changeLabel

    proc setActivity (active : boolean)
        button.active := active
    end setActivity

    proc setColour (mainClr, highlightClr, selectClr : int)
        button.clr.current := mainClr
        button.clr.main := mainClr
        button.clr.highlight := highlightClr
        button.clr.select := selectClr
    end setColour

    proc move (newX1, newY1, newX2, newY2 : int)
        %button.label_.font := Font.New (button.label_.fontName + ":" + intstr (button.label_.fontHeight))

        if newX2 = 0 then
            button.x1 := round (newX1 - Font.Width (button.label_.text, button.label_.font) / 2 - button.xPadding)
            button.x2 := round (newX1 + Font.Width (button.label_.text, button.label_.font) / 2 + button.xPadding)
        else
            button.x1 := newX1
            button.x2 := newX2
        end if

        if newY2 = 0 then
            button.y1 := round (newY1 - button.label_.fontHeight / 2 - button.yPadding)
            button.y2 := round (newY1 + button.label_.fontHeight / 1.5 + button.yPadding)  %fontHeight / 1.5 (not / 2) because of hanging letters like "g"
        else
            button.y1 := newY1
            button.y2 := newY2
        end if
        button.label_.x := round ((button.x1 + button.x2) / 2 - Font.Width (button.label_.text, button.label_.font) / 2)
        button.label_.y := round ((button.y1 + button.y2) / 2 - button.label_.fontHeight / 2)
        button.label_.xDraw := button.label_.x
        button.label_.yDraw := button.label_.y

        %Font.Free (button.label_.font)
    end move

    %draws the button
    proc draw
        if button.show then
            Draw.FillBox (button.x1, button.y1, button.x2, button.y2, button.clr.current)
            %button.label_.font := Font.New (button.label_.fontName + ":" + intstr (button.label_.fontHeight))
            Font.Draw (button.label_.text, button.label_.xDraw, button.label_.yDraw, button.label_.font, button.label_.clr)
            %Font.Free (button.label_.font)
            for w : 1 .. button.boarder.width
                Draw.Line (button.x1 - w, button.y1, button.x1 - w, button.y2, button.boarder.clr.top_left)
                Draw.Line (button.x2 + w, button.y1, button.x2 + w, button.y2, button.boarder.clr.bottom_right)
            end for
            for h : 1 .. button.boarder.height
                Draw.Line (button.x1, button.y2 + h, button.x2, button.y2 + h, button.boarder.clr.top_left)
                Draw.Line (button.x1, button.y1 - h, button.x2, button.y1 - h, button.boarder.clr.bottom_right)
            end for
        end if
    end draw

    % This function accomplishes two tasks.  First, it sets the appropraite colour for the button.
    % Second, it returns true if the button is released, false if it is not.
    fcn clicked : boolean %make sure released is called before check in the loop.  Reason: button.pressed
        var x, y, btn : int %mouse
        if button.show & button.active then
            Mouse.Where (x, y, btn)
            if x >= button.x1 and x <= button.x2 and y >= button.y1 and y <= button.y2 then
                if btn ~= 0 then
                    button.pressed := true %it's pressed if the button is down
                    button.clr.current := button.clr.select
                    button.boarder.clr.top_left := black
                    button.boarder.clr.bottom_right := white
                    button.label_.xDraw := button.label_.x + 1
                    button.label_.yDraw := button.label_.y - 1
                else
                    button.clr.current := button.clr.highlight
                    button.boarder.clr.top_left := white
                    button.boarder.clr.bottom_right := black
                    if button.pressed then %if the mouse button is released but button.pressed is true, then the button has just been released
                        button.released := true
                        button.pressed := false
                    end if
                    button.label_.xDraw := button.label_.x
                    button.label_.yDraw := button.label_.y
                end if
            else
                button.pressed := false
                button.clr.current := button.clr.main
                button.boarder.clr.top_left := white
                button.boarder.clr.bottom_right := black
                button.label_.xDraw := button.label_.x
                button.label_.yDraw := button.label_.y
            end if
            if button.released then
                button.released := false
                result true
            end if
        end if
        result false
    end clicked

    %hides the button so it cannot be seen or released
    proc hide
        button.show := false
    end hide

    %shows the button so it can be seen and released
    proc show
        button.show := true
    end show

    fcn visible : boolean
        result button.show
    end visible

end BUTTON


%example button
View.Set ("offscreenonly")

var button : ^BUTTON
new BUTTON, button
button -> INIT (maxx div 2, maxy div 2, 0, 0, 20, 7, "Test Button", "Times New Roman", 12, black, 26, 28, 24)

loop
    if button -> clicked then
    end if

    cls
    button -> draw
    View.Update
    delay (10)
end loop
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 3 Posts ]
Jump to:   


Style:  
Search: