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
|