diff --git a/NOTE.md b/NOTE.md index 7385ee9..fd8b2cf 100644 --- a/NOTE.md +++ b/NOTE.md @@ -1,8 +1,5 @@ -A faire : - - 1. Principal : - - Documenter (Docstring, README, ...) + - Documenter (Docstring, ...) - mode d'emploi (video + pdf) expliquant le fonctionnement 2. Bonus : diff --git a/main.pyw b/main.pyw index 082a27e..270df59 100644 --- a/main.pyw +++ b/main.pyw @@ -6,13 +6,13 @@ from source.gui.scene import MainMenu from source.gui.window import GameWindow -from source.path import path_font +from source.path import path_font, path_image from source.gui.better_pyglet import Label # Change la police par défaut utilisé pour le Century Gothic pyglet.font.add_directory(path_font) -Label.default_kwargs["font_name"] = "Century Gothic" # NOQA: Label à un "default_kwargs" avec la metaclass +Label.default_kwargs["font_name"] = "Century Gothic" # Créer une nouvelle fenêtre window = GameWindow( @@ -21,7 +21,8 @@ window = GameWindow( option_path=Path("./option.json") ) -try: window.set_icon(pyglet.image.load("./assets/image/icon/icon.png")) +# Change l'icône de cette fenêtre +try: window.set_icon(pyglet.image.load(path_image / "/icon/icon.png")) except: pass # NOQA E722 window.set_minimum_size(720, 480) diff --git a/setup.py b/setup.py index e94e529..68c767c 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,7 @@ from cx_Freeze import setup, Executable +from source.path import path_image, path_assets + setup( name='Bataille Navale', description='Bataille Navale', @@ -8,7 +10,7 @@ setup( options={ "build_exe": { - "include_files": ["./assets"], + "include_files": [path_assets], } }, @@ -17,7 +19,7 @@ setup( executables=[ Executable( "main.pyw", - icon="./assets/image/icon/icon.ico", + icon=path_image / "/icon/icon.ico", base="win32gui", target_name="Bataille Navale.exe", shortcut_name="Bataille Navale", diff --git a/source/event/Listener.py b/source/event/Listener.py index a59a162..34b3661 100644 --- a/source/event/Listener.py +++ b/source/event/Listener.py @@ -3,35 +3,36 @@ from typing import Callable class Listener: """ - The Listener can be subclassed to allow the subclass to add, remove and call event easily. + Les classes héritant de Listener permettent d'ajouter, retirer et appeler facilement des événements. """ def __init__(self): + # dictionnaire des événements et de leurs fonctions associées self._events_listener: dict[str, set[Callable]] = {} def add_listener(self, name: str, callback: Callable): """ - Add a function to an event name - :param name: the name of the event to react - :param callback: the function to call + Ajoute une fonction à un événement + :param name: le nom de l'événement + :param callback: la fonction à appeler """ if name not in self._events_listener: self._events_listener[name] = set() self._events_listener[name].add(callback) def remove_listener(self, name: str, callback: Callable): """ - Remove a function from an event name - :param name: the event name where to remove the callback - :param callback: the callback function to remove + Retire une fonction d'un événement + :param name: le nom de l'événement + :param callback: la fonction à retirer """ self._events_listener[name].remove(callback) def trigger_event(self, name: str, *args, **kwargs): """ - Call all the callback attached to an event - :param name: the name of the event to call - :param args: the args of the callbacks - :param kwargs: the kwargs of the callbacks + Appelle les fonctions associées à un événement + :param name: le nom de l'événement + :param args: les arguments des fonctions + :param kwargs: les arguments à clé des fonctions """ # .copy() pour que si le listener supprime un de ses événements, la liste de la boucle de change pas de taille diff --git a/source/gui/better_pyglet/abc/Element.py b/source/gui/better_pyglet/abc/Element.py index 10aa1f4..ec05f0f 100644 --- a/source/gui/better_pyglet/abc/Element.py +++ b/source/gui/better_pyglet/abc/Element.py @@ -3,5 +3,7 @@ from typing import Any class Element(ABC): + default_kwargs: dict[str, Any] + def __init_subclass__(cls, **kwargs): - cls.default_kwargs: dict[str, Any] = {} # all subclasses will have their own "default_kwargs" dict + cls.default_kwargs = {} # all subclasses will have their own "default_kwargs" dict diff --git a/source/network/Client.py b/source/network/Client.py index 8e01eb5..5c49b65 100644 --- a/source/network/Client.py +++ b/source/network/Client.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: class Client(StoppableThread): """ - The thread executed on the person who join a room. + Ce thread est utilisé pour la personne qui rejoint la salle. """ def __init__(self, window: "Window", @@ -39,9 +39,10 @@ class Client(StoppableThread): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as connection: try: + # Se connecte à l'opposant connection.connect((self.ip_address, self.port)) except ConnectionRefusedError: - # Appelle l'événement lorsque la connexion échoue + # Appelle la fonction prévue lorsque la connexion échoue if self.on_connexion_refused is not None: in_pyglet_context(self.on_connexion_refused) return @@ -91,13 +92,14 @@ class Client(StoppableThread): with open(path_old_save, "r", encoding="utf-8") as file: save_data = json.load(file) - # paramètres & jeu + # paramètres et jeu settings = PacketSettings.from_connection(connection) PacketUsername(username=self.username).send_data_connection(connection) enemy_username = PacketUsername.from_connection(connection).username if load_old_save: + # si les joueurs utilise une ancienne sauvegarde, créer la scène du jeu à partir des données game_scene = in_pyglet_context( self.window.set_scene, scene.Game.from_json, # depuis le fichier json @@ -109,6 +111,7 @@ class Client(StoppableThread): ) else: + # s'il n'y a pas de sauvegarde à utiliser, initialise une nouvelle scène game_scene = in_pyglet_context( self.window.set_scene, scene.Game, @@ -124,6 +127,7 @@ class Client(StoppableThread): my_turn=not settings.host_start ) + # commence la partie réseau du jeu game_network( thread=self, connection=connection, diff --git a/source/network/Host.py b/source/network/Host.py index 3516d47..e56f387 100644 --- a/source/network/Host.py +++ b/source/network/Host.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: class Host(StoppableThread): """ - The thread executed on the person who create a room. + Le thread utilisé lorsqu'un joueur créer une salle """ def __init__(self, window: "Window", port: int, username: str, settings: "PacketSettings", **kw): @@ -29,6 +29,7 @@ class Host(StoppableThread): self.settings = settings self.port = port + # condition utilisée lorsque l'on attend la décision de charger une partie ou non self.condition_load = Condition() self.accept_load: bool = False @@ -54,7 +55,7 @@ class Host(StoppableThread): path_old_save: Optional[Path] = None - for file in path_save.iterdir(): # cherche une ancienne sauvegarde correspondant à l'ip de l'adversaire + for file in path_save.iterdir(): # cherche une ancienne sauvegarde correspondant à l'IP de l'adversaire if file.stem.startswith(ip_address): path_old_save = file break @@ -72,7 +73,8 @@ class Host(StoppableThread): from source.gui.scene import GameLoad in_pyglet_context(self.window.set_scene, GameLoad, path=path_old_save, thread_host=self) - with self.condition_load: self.condition_load.wait() # attend que l'utilisateur choisisse l'option + # attend que l'utilisateur choisisse l'option + with self.condition_load: self.condition_load.wait() PacketLoadOldSave(value=self.accept_load).send_data_connection(connection) @@ -89,6 +91,7 @@ class Host(StoppableThread): PacketUsername(username=self.username).send_data_connection(connection) if self.accept_load: + # si une sauvegarde doit être chargée game_scene = in_pyglet_context( self.window.set_scene, scene.Game.from_json, # depuis le fichier json @@ -100,6 +103,7 @@ class Host(StoppableThread): ) else: + # s'il n'y a pas de sauvegarde à charger game_scene = in_pyglet_context( self.window.set_scene, scene.Game, @@ -115,6 +119,7 @@ class Host(StoppableThread): my_turn=self.settings.host_start ) + # commence la partie réseau du jeu game_network( thread=self, connection=connection, diff --git a/source/network/error.py b/source/network/error.py index 195f42f..fd81909 100644 --- a/source/network/error.py +++ b/source/network/error.py @@ -9,8 +9,15 @@ if TYPE_CHECKING: def handle_error(window: "Window", exception: Exception): + """ + Fonction permettant d'afficher le bon message d'erreur du au réseau. + :param window: la fenêtre du jeu + :param exception: l'erreur qui s'est produite + """ + message: str = "Erreur :\n" + # récupère le message d'erreur selon le type de l'erreur match type(exception): case builtins.ConnectionResetError: message += "Perte de connexion avec l'adversaire." diff --git a/source/network/game_network.py b/source/network/game_network.py index e51d965..daa4d74 100644 --- a/source/network/game_network.py +++ b/source/network/game_network.py @@ -18,12 +18,13 @@ def game_network( game_scene: "Game", ): """ - Run the networking to make the game work and react with the other player - :param game_scene: the scene of the game - :param thread: the thread where this function is called. - :param connection: the connection with the other player + Partie réseau permettant au jeu de fonctionner et de réagir avec l'autre joueur + :param game_scene: la scène du jeu + :param thread: le thread dans lequel la fonction est appelé + :param connection: la connexion avec l'autre joueur """ + # associe le type de packet avec la fonction correspondante game_methods: dict[Type["Packet"], Callable] = { packet.PacketChat: game_scene.network_on_chat, packet.PacketBoatPlaced: game_scene.network_on_boat_placed, @@ -35,16 +36,19 @@ def game_network( } while True: + # récupère le type de packet reçu data_type = Packet.type_from_connection(connection) if data_type is None: - if thread.stopped: return # vérifie si le thread n'est pas censé s'arrêter + # s'il n'y a pas de donnée reçue, vérifie si le thread devrait s'arrêter, sinon ignore + if thread.stopped: return continue + # récupère les données du packet data = data_type.from_connection(connection) in_pyglet_context( - game_methods[data_type], data # récupère la methode relié ce type de donnée + game_methods[data_type], data # récupère la methode relié à ce type de donnée ) # Appelle la méthode. if thread.stopped: return # vérifie si le thread n'est pas censé s'arrêter diff --git a/source/network/packet/PacketAskSave.py b/source/network/packet/PacketAskSave.py index 75b80d3..30f2945 100644 --- a/source/network/packet/PacketAskSave.py +++ b/source/network/packet/PacketAskSave.py @@ -6,5 +6,5 @@ from source.network.packet.abc import SignalPacket @dataclass class PacketAskSave(SignalPacket): """ - A packet that is sent when the player wish to save the game. + Un packet envoyé quand le joueur souhaite sauvegarder """ diff --git a/source/network/packet/PacketBoatPlaced.py b/source/network/packet/PacketBoatPlaced.py index ec740fa..c2e4864 100644 --- a/source/network/packet/PacketBoatPlaced.py +++ b/source/network/packet/PacketBoatPlaced.py @@ -6,5 +6,5 @@ from source.network.packet.abc import SignalPacket @dataclass class PacketBoatPlaced(SignalPacket): """ - A packet that signal that all the boat of the player have been placed + Un packet signalant que tous les bateaux du joueur ont été placé """ diff --git a/source/network/packet/PacketBoatsData.py b/source/network/packet/PacketBoatsData.py index 439a15b..f4044fd 100644 --- a/source/network/packet/PacketBoatsData.py +++ b/source/network/packet/PacketBoatsData.py @@ -9,6 +9,9 @@ from source.network.packet.abc import Packet @dataclass class PacketBoatsData(Packet): + """ + Un packet contenant les données de la position de tous les bateaux + """ boats: np.array = field() diff --git a/source/network/packet/PacketBombPlaced.py b/source/network/packet/PacketBombPlaced.py index 2da032f..87c360a 100644 --- a/source/network/packet/PacketBombPlaced.py +++ b/source/network/packet/PacketBombPlaced.py @@ -9,7 +9,7 @@ from source.type import Point2D @dataclass class PacketBombPlaced(SimplePacket): """ - A packet that signal that a bomb have been placed on the board + Un packet qui signale qu'une bombe à été placé sur la grille """ position: Point2D = field() diff --git a/source/network/packet/PacketBombState.py b/source/network/packet/PacketBombState.py index 4389ae1..3307de7 100644 --- a/source/network/packet/PacketBombState.py +++ b/source/network/packet/PacketBombState.py @@ -9,7 +9,7 @@ from source.type import Point2D @dataclass class PacketBombState(SimplePacket): """ - A packet that signal how a bomb exploded on the board + Un packet qui signale qu'une bombe à explosé sur la grille """ position: Point2D = field() diff --git a/source/network/packet/PacketChat.py b/source/network/packet/PacketChat.py index 0959650..a4e1588 100644 --- a/source/network/packet/PacketChat.py +++ b/source/network/packet/PacketChat.py @@ -6,7 +6,7 @@ from source.network.packet.abc import VariableLengthPacket @dataclass class PacketChat(VariableLengthPacket): """ - A packet that represent a message from the chat + Un packet qui représente un message du chat """ message: str = field() diff --git a/source/network/packet/PacketHaveSaveBeenFound.py b/source/network/packet/PacketHaveSaveBeenFound.py index 68c9d8f..e54ac0b 100644 --- a/source/network/packet/PacketHaveSaveBeenFound.py +++ b/source/network/packet/PacketHaveSaveBeenFound.py @@ -7,7 +7,7 @@ from source.network.packet.abc import SimplePacket @dataclass class PacketHaveSaveBeenFound(SimplePacket): """ - A packet that is sent when the player accept or refuse a requested save. + Un packet indiquant si le joueur à trouvé un ancien fichier de sauvegarde avec l'opposant """ value: bool = field() # True si requête accepter, sinon False diff --git a/source/network/packet/PacketLoadOldSave.py b/source/network/packet/PacketLoadOldSave.py index c46601e..36b86ae 100644 --- a/source/network/packet/PacketLoadOldSave.py +++ b/source/network/packet/PacketLoadOldSave.py @@ -7,7 +7,7 @@ from source.network.packet.abc import SimplePacket @dataclass class PacketLoadOldSave(SimplePacket): """ - A packet that is sent when the player accept or refuse a requested save. + Un packet qui est envoyé lorsque l'hôte accepte ou refuse de charger une ancienne sauvegarde """ value: bool = field() # True si requête accepter, sinon False diff --git a/source/network/packet/PacketQuit.py b/source/network/packet/PacketQuit.py index 479906d..78bc334 100644 --- a/source/network/packet/PacketQuit.py +++ b/source/network/packet/PacketQuit.py @@ -6,5 +6,5 @@ from source.network.packet.abc import SignalPacket @dataclass class PacketQuit(SignalPacket): """ - A packet that is sent when the player wish to quit a game. + Un packet envoyé lorsque le joueur souhaite quitter la partie """ diff --git a/source/network/packet/PacketResponseSave.py b/source/network/packet/PacketResponseSave.py index 20d356e..5f639d2 100644 --- a/source/network/packet/PacketResponseSave.py +++ b/source/network/packet/PacketResponseSave.py @@ -7,7 +7,7 @@ from source.network.packet.abc import SimplePacket @dataclass class PacketResponseSave(SimplePacket): """ - A packet that is sent when the player accept or refuse a requested save. + Un packet qui est envoyé lorsque le joueur accepte ou refuse une demande de sauvegarde """ value: bool = field() # True si requête accepter, sinon False diff --git a/source/network/packet/PacketSettings.py b/source/network/packet/PacketSettings.py index d61d431..af541c6 100644 --- a/source/network/packet/PacketSettings.py +++ b/source/network/packet/PacketSettings.py @@ -7,6 +7,10 @@ from source.network.packet.abc import Packet @dataclass class PacketSettings(Packet): + """ + Un packet contenant tous les paramètres de la partie + """ + grid_width: int = field() grid_height: int = field() host_start: bool = field() diff --git a/source/network/packet/PacketUsername.py b/source/network/packet/PacketUsername.py index 2792d90..3ef9ccd 100644 --- a/source/network/packet/PacketUsername.py +++ b/source/network/packet/PacketUsername.py @@ -5,6 +5,10 @@ from source.network.packet.abc import VariableLengthPacket @dataclass class PacketUsername(VariableLengthPacket): + """ + Un packet contenant le nom d'utilisateur de l'opposant + """ + username: str = field() @property diff --git a/source/network/packet/abc/Packet.py b/source/network/packet/abc/Packet.py index 77a263b..311df42 100644 --- a/source/network/packet/abc/Packet.py +++ b/source/network/packet/abc/Packet.py @@ -9,10 +9,8 @@ T = TypeVar("T", bound="Packet") class Packet(ABC): """ - A packet that can be sent on a socket. - Multiple subtype of packet can be sent and received in an easier way. - - The to_bytes and from_connection method need to be defined. + Un packet pouvant être envoyé dans un socket. + Permet aux sous-classes de ce packet d'être envoyé et reçu d'une manière beaucoup plus simple. """ packet_types: set[T] = set() diff --git a/source/network/packet/abc/SignalPacket.py b/source/network/packet/abc/SignalPacket.py index d33b729..dfd4fb2 100644 --- a/source/network/packet/abc/SignalPacket.py +++ b/source/network/packet/abc/SignalPacket.py @@ -10,8 +10,8 @@ T = TypeVar("T", bound="SignalPacket") class SignalPacket(Packet, ABC): """ - A packet that has for only usage to send a signal thanks to the type of the class. - It does not hold any other data. + Un packet ne contenant aucune donnée. + Permet de réagir à des événements seulement avec le type de la classe. """ def to_bytes(self) -> bytes: diff --git a/source/network/packet/abc/SimplePacket.py b/source/network/packet/abc/SimplePacket.py index eaed3b4..4dd55d4 100644 --- a/source/network/packet/abc/SimplePacket.py +++ b/source/network/packet/abc/SimplePacket.py @@ -11,8 +11,8 @@ T = TypeVar("T", bound="SimplePacket") class SimplePacket(Packet, ABC): """ - A packet with a simple packet format. - Only the from_bytes and to_bytes method need to be implemented. + Un packet avec un format plus simple. + Se base sur le "packet_format" pour envoyé et reservoir les données. """ packet_format: str = ">" @@ -21,9 +21,9 @@ class SimplePacket(Packet, ABC): @abstractmethod def from_bytes(cls, data: bytes) -> T: """ - Convert a bytes object into a packet. - :param data: the data to convert into a packet. Should be "packet_size" long. - :return: a packet corresponding to the bytes. + Convertie un objet bytes en un SimplePacket + :param data: les données à charger, doit être "packet_size" de long + :return: un SimplePacket correspondant à ces données """ pass diff --git a/source/network/packet/abc/VariableLengthPacket.py b/source/network/packet/abc/VariableLengthPacket.py index 7174685..0b4b652 100644 --- a/source/network/packet/abc/VariableLengthPacket.py +++ b/source/network/packet/abc/VariableLengthPacket.py @@ -11,8 +11,7 @@ T = TypeVar("T", bound="VariableLengthPacket") class VariableLengthPacket(Packet, ABC): """ - A Packet that represent a single value that can be encoded with a variable length. - The property "data" and the method "from_bytes" need to be defined. + Un packet représentant une seule valeur avec une longueur variable qui peut être encodé, comme une chaîne. """ packet_format: str = ">I" @@ -20,6 +19,11 @@ class VariableLengthPacket(Packet, ABC): @property @abstractmethod def data(self) -> bytes: + """ + Donnée à envoyer sur le réseau + :return: la donnée sous la forme d'un objet bytes + """ + pass def to_bytes(self) -> bytes: diff --git a/source/option/Option.py b/source/option/Option.py index 938bc87..dfe8b9c 100644 --- a/source/option/Option.py +++ b/source/option/Option.py @@ -9,6 +9,10 @@ if TYPE_CHECKING: class Option: + """ + Cette classe permet de modifier, sauvegarder et charger les options. + """ + def __init__(self, window: "GameWindow", volume_ambient: float = 0.1, volume_fx: float = 0.1, @@ -24,7 +28,7 @@ class Option: self.set_fps_limit(fps_limit) self.set_vsync(vsync) - # propriété + # propriétés @staticmethod def get_volume_ambient() -> float: return media.SoundAmbient.get_volume() diff --git a/source/type.py b/source/type.py index e44e637..2615e45 100644 --- a/source/type.py +++ b/source/type.py @@ -1,10 +1,10 @@ from typing import Union, Callable -Point2D = tuple[int, int] # a 2D point -BBox = tuple[int, int, int, int] # a boundary box -ColorRGB = tuple[int, int, int] # a RGB Color -ColorRGBA = tuple[int, int, int, int] # a RGBA Color +Point2D = tuple[int, int] # un point 2D +BBox = tuple[int, int, int, int] # une boîte de collision +ColorRGB = tuple[int, int, int] # une couleur RGB +ColorRGBA = tuple[int, int, int, int] # une couleur RGBA -DistanceFunc = Callable[["BoxWidget"], int] # a function that return a position / distance -Distance = Union[int, DistanceFunc] # a position / distance, represented by a number or a function +DistanceFunc = Callable[["BoxWidget"], int] # une fonction renvoyant une position / distance +Distance = Union[int, DistanceFunc] # une position / distance sous la forme d'un nombre ou d'une fonction diff --git a/source/utils/bbox.py b/source/utils/bbox.py index 9eebf9d..36074fe 100644 --- a/source/utils/bbox.py +++ b/source/utils/bbox.py @@ -3,10 +3,10 @@ from source.type import Point2D, BBox def in_bbox(point: Point2D, bbox: BBox) -> bool: """ - Return true if a point is inside a bounding box - :param point: the point to check - :param bbox: the bbox where to check the point - :return: True if the point is inside the bbox, False otherwise + Indique si un point est dans un rectangle + :param point: le point à vérifier + :param bbox: la bbox à vérifier + :return: True si le point est dans la bbox, sinon Faux """ point_x, point_y = point diff --git a/source/utils/dict.py b/source/utils/dict.py index 40bd58c..81bd99a 100644 --- a/source/utils/dict.py +++ b/source/utils/dict.py @@ -3,17 +3,15 @@ from typing import Callable, Any def dict_filter(filter_func: Callable[[Any, Any], bool], dictionary: dict[Any, Any]) -> dict[Any, Any]: """ - Filter a dict object with the filter function given. - :param filter_func: the function to filter with - :param dictionary: the dictionary to filter - :return: the filtered dictionary + Filtre les objets d'un dictionnaire avec la fonction de filtre donnée. + :param filter_func: La fonction utilisée pour le filtre. Reçois l'argument clé et valeur + :param dictionary: Le dictionnaire à filtrer + :return: Le dictionnaire filtrer - Example : + Exemple : filter_func = lambda key, value: key.startswith("valeur") dictionary = {"valeur1": 1, "valeur2": 2, "clé1": None} - - result = {"valeur1": 1, "valeur2": 2} - + -> {"valeur1": 1, "valeur2": 2} """ return { @@ -26,16 +24,15 @@ def dict_filter(filter_func: Callable[[Any, Any], bool], dictionary: dict[Any, A def dict_filter_prefix(prefix: str, dictionary: dict[str, Any]) -> dict[str, Any]: """ - Take only the keys that start with the prefix, and remove this prefix from the keys. - :param prefix: the prefix to use - :param dictionary: the dictionary to filter - :return: the dictionary with the prefix + Ne garde que les clés qui commencent avec ce préfixe dans le dictionnaire et retire leur préfixe. + :param prefix: le préfixe à utiliser + :param dictionary: le dictionnaire à filtrer + :return: le dictionnaire avec le préfixe - Example: + Exemple : prefix = "button" dictionary = {"button1": 1, "button2": 2, "label1": None} - - result = {"1": 1, "2": 2} + -> {"1": 1, "2": 2} """ return { @@ -48,10 +45,10 @@ def dict_filter_prefix(prefix: str, dictionary: dict[str, Any]) -> dict[str, Any def dict_add_prefix(prefix: str, dictionary: dict[str, Any]) -> dict[str, Any]: """ - Add a prefix to every key of the dictionary - :param prefix: the prefix to add - :param dictionary: the dictionary to modify - :return: the dictionary with the prefix at the start of the keys + Ajoute un préfixe à toute les clés d'un dictionnaire + :param prefix: le préfixe à ajouter + :param dictionary: le dictionnaire à modifier + :return: le dictionnaire avec le préfixe à chaque clé """ return { diff --git a/source/utils/matrice.py b/source/utils/matrice.py index ddf297d..cec10e6 100644 --- a/source/utils/matrice.py +++ b/source/utils/matrice.py @@ -5,10 +5,10 @@ from source.type import Point2D def copy_array_offset(src: np.array, dst: np.array, offset: Point2D) -> None: """ - Copy a numpy array into another one with an offset - :param src: source array - :param dst: destination array - :param offset: the offset where to copy the array + Copie une matrice dans une autre matrice avec un décalage. + :param src: la matrice source + :param dst: la matrice de destination + :param offset: le décalage avec lequel copier la matrice """ column, row = offset width, height = src.shape diff --git a/source/utils/path.py b/source/utils/path.py index 94bb119..fe79c4e 100644 --- a/source/utils/path.py +++ b/source/utils/path.py @@ -2,5 +2,10 @@ from datetime import datetime from pathlib import Path -def path_ctime_str(path: Path): +def path_ctime_str(path: Path) -> str: + """ + Un raccourci permettant d'obtenir la représentation de la date de création d'un fichier + :param path: le chemin du fichier + :return: la date correspondante sous la forme d'un texte + """ return datetime.fromtimestamp(path.lstat().st_ctime).strftime('%d/%m/%Y %H:%M:%S') diff --git a/source/utils/thread.py b/source/utils/thread.py index 8e6c1ea..1adbd7f 100644 --- a/source/utils/thread.py +++ b/source/utils/thread.py @@ -7,8 +7,9 @@ import pyglet class StoppableThread(Thread): """ - A thread that can be stopped. - The run method need to check for the "self._stop" variable and return manually if it is true. + Un thread pouvant être arrêté. + La méthode "run" doit souvent vérifier la variable self.stopped et faire un return manuellement si cette variable + est vrai. """ def __init__(self, *args, **kwargs): @@ -16,17 +17,18 @@ class StoppableThread(Thread): self.stopped = False def stop(self) -> None: + # indique que le thread devrait s'arrêter dès que possible self.stopped = True def in_pyglet_context(func: Callable, *args, **kwargs) -> Any: """ - This function can be call in a thread. It will call the "func" in the pyglet event loop, avoiding - some operation that are not allowed outside of the pyglet context, and return its result - :param func: the function to call in the pyglet context - :param args: the args of the function - :param kwargs: the kwargs of the function - :return: the result of the function + Cette fonction doit être appelée dans un thread. Elle appellera une fonction dans la boucle d'événement de pyglet, + ce qui permet d'éviter certaines opérations illégales en dehors de ce contexte et renvoie le résultat. + :param func: la fonction à appeler + :param args: les arguments de la fonction + :param kwargs: les arguments à clé de la fonction + :return: le résultat de la fonction """ queue = Queue()