101 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			101 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								# People's Video Editor: high quality, GPU accelerated mp4 editor
							 | 
						||
| 
								 | 
							
								# Copyright (C) 2025 Roz K <roz@rozk.net>
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# This file is part of People's Video Editor.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# People's Video Editor is free software: you can redistribute it and/or modify it under the terms of the
							 | 
						||
| 
								 | 
							
								# GNU General Public License as published by the Free Software Foundation, either version 3 of the License,
							 | 
						||
| 
								 | 
							
								# or (at your option) any later version.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# People's Video Editor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
							 | 
						||
| 
								 | 
							
								# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
							 | 
						||
| 
								 | 
							
								# See the GNU General Public License for more details.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# You should have received a copy of the GNU General Public License along with People's Video Editor.
							 | 
						||
| 
								 | 
							
								# If not, see <https://www.gnu.org/licenses/>.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from weakref import ref
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Node:
							 | 
						||
| 
								 | 
							
								    __slots__ = 'parent', 'children', 'state', '__weakref__'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    STATE_NEW      = 0
							 | 
						||
| 
								 | 
							
								    STATE_MODIFIED = 1
							 | 
						||
| 
								 | 
							
								    STATE_BUILT    = 2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __init__(self, parent = None, children = None):
							 | 
						||
| 
								 | 
							
								        self.parent = None
							 | 
						||
| 
								 | 
							
								        self.children = None
							 | 
						||
| 
								 | 
							
								        self.state = Node.STATE_NEW
							 | 
						||
| 
								 | 
							
								        if children is not None:
							 | 
						||
| 
								 | 
							
								            self.add_children(children)
							 | 
						||
| 
								 | 
							
								        if parent is not None:
							 | 
						||
| 
								 | 
							
								            parent.add_child(self)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __del__(self):
							 | 
						||
| 
								 | 
							
								        if self.parent is not None:
							 | 
						||
| 
								 | 
							
								            self.parent().remove_child(self)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def add_child(self, child: Node):
							 | 
						||
| 
								 | 
							
								        assert child.parent is None
							 | 
						||
| 
								 | 
							
								        child.parent = ref(self)
							 | 
						||
| 
								 | 
							
								        if self.children is None:
							 | 
						||
| 
								 | 
							
								            self.children = [child]
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            self.children.append(child)
							 | 
						||
| 
								 | 
							
								        child.state = Node.STATE_NEW
							 | 
						||
| 
								 | 
							
								        self.set_modified()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def add_children(self, children):
							 | 
						||
| 
								 | 
							
								        for child in children:
							 | 
						||
| 
								 | 
							
								            self.add_child(child)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def remove_child(self, child: Node):
							 | 
						||
| 
								 | 
							
								        assert child.parent is self
							 | 
						||
| 
								 | 
							
								        child.parent = None
							 | 
						||
| 
								 | 
							
								        self.children.remove(child)
							 | 
						||
| 
								 | 
							
								        self.set_modified()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def remove_children(self, children):
							 | 
						||
| 
								 | 
							
								        for child in children:
							 | 
						||
| 
								 | 
							
								            self.remove_child(child)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def is_new(self):
							 | 
						||
| 
								 | 
							
								        return self.state == Node.STATE_NEW
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def needs_rebuilding(self):
							 | 
						||
| 
								 | 
							
								        return self.state != Node.STATE_BUILT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def set_modified(self):
							 | 
						||
| 
								 | 
							
								        if self.needs_rebuilding():
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        self.state = Node.STATE_MODIFIED
							 | 
						||
| 
								 | 
							
								        if self.parent is not None:
							 | 
						||
| 
								 | 
							
								            self.set_parent_modified(self.parent())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def set_parent_modified(self, parent):
							 | 
						||
| 
								 | 
							
								        parent.set_modified()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def rebuild(self):
							 | 
						||
| 
								 | 
							
								        if not self.needs_rebuilding():
							 | 
						||
| 
								 | 
							
								            return True
							 | 
						||
| 
								 | 
							
								        if self.children is not None:
							 | 
						||
| 
								 | 
							
								            if not self.rebuild_children(self.children):
							 | 
						||
| 
								 | 
							
								                return False
							 | 
						||
| 
								 | 
							
								        if not self.build():
							 | 
						||
| 
								 | 
							
								            return False
							 | 
						||
| 
								 | 
							
								        self.state = Node.STATE_BUILT
							 | 
						||
| 
								 | 
							
								        return True
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def rebuild_children(self, children):
							 | 
						||
| 
								 | 
							
								        for child in children:
							 | 
						||
| 
								 | 
							
								            if not self.rebuild_child(child):
							 | 
						||
| 
								 | 
							
								                return False
							 | 
						||
| 
								 | 
							
								        return True
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def rebuild_child(self, child):
							 | 
						||
| 
								 | 
							
								        return child.rebuild()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def build(self):
							 | 
						||
| 
								 | 
							
								        return True
							 |