How to create a "trigger" function when a variable changes value?

Asked

Viewed 130 times

1

Watching pygame.Surface.get_rect(), I realize that when I change a variable, for example left, pygame automatically recalculates all class variables (center, right, etc.).

I’d like to know how it’s done?

How is it possible to detect the change of a variable value and from this "Trigger", to trigger a function?

  • off-topic, but taking the opportunity - yesterday you asked a pertinent question about pygame, but deleted it when it won a downvote- however, it had a valid answer. I find it a little annoying for those who have bothered to answer your question. I would not consider "unleash it" ?

  • @jsbueno, I did not delete the question because of the downvote, but because I had made a mistake in the test I had done before and I posted a wrong question in a hasty way, therefore the question was unnecessary. I apologize.

  • ok - anyway, the answer there included something I didn’t know. (I can read yet - I don’t remember from how many points of reputation it is possible to read deleted posts)

  • 1

    @jsbueno, I found the post and I was able to "unfold": https://answall.com/a/3332/110948

1 answer

5


Pygame doesn’t use any special technique in code flow, like "callback" in rectangles - it’s just a well-planned example of using properties.

Next: Python has a mechanism called "Descriptor Protocol" - which allows access to attributes of an instance or class to be customized. Works if a class attribute is an object that itself has a method among __get__, __set__ or __del__.

To further facilitate the use of this mechanism, the language has built-in property, which is normally used as a Decorator.

In the case of a rectangle like pygame, it is a matter of choosing which data will be stored internally in the rectangle, and then writing the code of the getters and setters in the form of properties for all the properties we want to expose. For example, to keep making "left, top, width, height" as real attributes, and exposing the property, which can be changed "right", all that is required is:

class Rect:
   def __init__(self, seq):
        self.top, self.left, self.width, self.height = seq

   @property
   def right(self):
        return self.left + self.width

   @right.setter
   def right(self, value):
        self.width = value - self.left

The nice thing about using Descriptors, even with the "Property" simplifier, is that the user of your object doesn’t notice the difference of simply reading or setting an attribute.

In the specific case of the pygame. Rect, the class code is written in C, and then the getters and setters are less generic to write than with a pure Python Scriptor. The source code is online here: https://github.com/pygame/pygame/blob/master/src_c/rect.c

The properties' getters and settesr functions begin to be written from the 1247 line, are associated with the properties themselves in the struct starting from the 1625 line and are ultimately associated with the class on the 1696 line. You can see that the little functions to be able to inspect various rectangle values, and change some all operate only in the "real" properties"x, y, w, h", as I did in the example above for the property "right".

(That file from the rect. c of Pygame is one that could probably be rewritten in Cython and get about 1/5 of the same tamamho and the same performance - the interesting thing about it being in native code, is that so collision check functions can easily check hundreds of rectangles per frame without "tiring" a modern CPU)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.