Mercurial > MadButterfly
comparison pyink/domview.py @ 1350:17fa5d78200b
Refactory domview_monitor to move code to scenes_parser
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Sun, 13 Feb 2011 01:17:17 +0800 |
parents | 22a79dcbaec6 |
children | 9164a0782ba7 |
comparison
equal
deleted
inserted
replaced
1349:b0e54ae756f8 | 1350:17fa5d78200b |
---|---|
636 | 636 |
637 return use_node | 637 return use_node |
638 pass | 638 pass |
639 | 639 |
640 | 640 |
641 ## \brief Parser for scenes nodes. | |
642 # | |
643 # This class parses scenes nodes and collect ID of all nodes. | |
644 # | |
645 @trait | |
646 class scenes_parser(object): | |
647 _root = require | |
648 _scenes_node = require | |
649 _id2node = require | |
650 _group2scene = require | |
651 current = require | |
652 _maxframe = require | |
653 | |
654 def _find_maxframe(self, scenes_node): | |
655 maxframe = 0 | |
656 for child in scenes_node.childList(): | |
657 if child.name() != 'ns0:scene': | |
658 continue | |
659 | |
660 try: | |
661 start = child.getAttribute('start') | |
662 maxframe = max(int(start), maxframe) | |
663 except: | |
664 pass | |
665 try: | |
666 end = child.getAttribute('end') | |
667 maxframe = max(int(end), maxframe) | |
668 except: | |
669 pass | |
670 pass | |
671 return maxframe | |
672 | |
673 ## \brief Collect ID of nodes in the document. | |
674 # | |
675 # It is used to implement a fast mapping from an ID to the respective node. | |
676 # | |
677 def _collect_node_ids(self): | |
678 self._id2node = {} | |
679 root = self._root | |
680 for n in root.childList(): | |
681 self._collect_node_ids_recursive(n) | |
682 pass | |
683 pass | |
684 | |
685 def _collect_node_ids_recursive(self, node): | |
686 try: | |
687 node_id = node.getAttribute('id') | |
688 except: | |
689 pass | |
690 else: | |
691 self._id2node[node_id] = node | |
692 pass | |
693 | |
694 for n in node.childList(): | |
695 self._collect_node_ids_recursive(n) | |
696 pass | |
697 pass | |
698 | |
699 def parse_one_scene(self, scene_node): | |
700 assert scene_node.name() == 'ns0:scene' | |
701 | |
702 start = int(scene_node.getAttribute("start")) | |
703 try: | |
704 end = int(scene_node.getAttribute("end")) | |
705 except: | |
706 end = start | |
707 pass | |
708 | |
709 try: | |
710 scene_type = scene_node.getAttribute('type') | |
711 if scene_type == None: | |
712 scene_type = 'normal' | |
713 pass | |
714 except: | |
715 scene_type = 'normal' | |
716 pass | |
717 | |
718 return start, end, scene_type | |
719 | |
720 def _parse_one_scenes(self, scenes_node): | |
721 try: | |
722 cur = int(n.getAttribute("current")) | |
723 except: | |
724 cur = 0 | |
725 pass | |
726 self.current = cur | |
727 | |
728 for scene_node in scenes_node.childList(): | |
729 if scene_node.name() != 'ns0:scene': | |
730 continue | |
731 | |
732 try: | |
733 start, end, scene_type = self.parse_one_scene(scene_node) | |
734 group_id = scene_node.getAttribute("ref") | |
735 except: # the scene node is incompleted. | |
736 continue | |
737 | |
738 self._group2scene[group_id] = scene_node | |
739 pass | |
740 pass | |
741 | |
742 ## \brief Parse all scenes node in svg:metadata subtree. | |
743 # | |
744 def _collect_all_scenes(self): | |
745 scenes_node = self._scenes_node | |
746 self._parse_one_scenes(scenes_node) | |
747 self._maxframe = self._find_maxframe(scenes_node) | |
748 pass | |
749 pass | |
750 | |
751 ## \brief Return the node with given ID. | |
752 # | |
753 def get_node(self, node_id): | |
754 value = self._id2node[node_id] | |
755 if isinstance(value, list): | |
756 return value[-1] | |
757 return value | |
758 | |
759 ## \brief Return a scene node corresponding to a scene group of given ID. | |
760 # | |
761 def get_scene(self, group_id): | |
762 return self._group2scene[group_id] | |
763 | |
764 def new_id(self): | |
765 while True: | |
766 candidate = 's%d' % int(random.random()*100000) | |
767 if candidate not in self._id2node: | |
768 return candidate | |
769 pass | |
770 pass | |
771 pass | |
772 | |
641 ## \brief Monitor changes of DOM-tree. | 773 ## \brief Monitor changes of DOM-tree. |
642 # | 774 # |
643 # This class monitors DOM-tree to maintain _maxframe and maps for node ID to | 775 # This class monitors DOM-tree to maintain _maxframe and maps for node ID to |
644 # node and scene group ID to scene node. | 776 # node and scene group ID to scene node. |
777 @composite | |
645 class domview_monitor(object): | 778 class domview_monitor(object): |
779 use_traits = (scenes_parser,) | |
780 | |
781 method_map_traits = { | |
782 scenes_parser._find_maxframe: '_find_maxframe', | |
783 scenes_parser._collect_all_scenes: '_collect_all_scenes', | |
784 scenes_parser._collect_node_ids: '_collect_node_ids'} | |
785 | |
646 def __init__(self, *args, **kws): | 786 def __init__(self, *args, **kws): |
647 super(domview_monitor, self).__init__() | 787 super(domview_monitor, self).__init__() |
648 | 788 |
649 self._maxframe = 0 | 789 self._maxframe = 0 |
650 self._id2node = {} # map ID to the node in the DOM tree. | 790 self._id2node = {} # map ID to the node in the DOM tree. |
746 self._maxframe = max(int(start), self._maxframe) | 886 self._maxframe = max(int(start), self._maxframe) |
747 except: | 887 except: |
748 pass | 888 pass |
749 pass | 889 pass |
750 pass | 890 pass |
751 | |
752 def _find_maxframe(self, scenes_node): | |
753 maxframe = 0 | |
754 for child in scenes_node.childList(): | |
755 if child.name() != 'ns0:scene': | |
756 continue | |
757 | |
758 try: | |
759 start = child.getAttribute('start') | |
760 maxframe = max(int(start), maxframe) | |
761 except: | |
762 pass | |
763 try: | |
764 end = child.getAttribute('end') | |
765 maxframe = max(int(end), maxframe) | |
766 except: | |
767 pass | |
768 pass | |
769 return maxframe | |
770 | 891 |
771 def _on_remove_node(self, node, child): | 892 def _on_remove_node(self, node, child): |
772 for cchild in child.childList(): | 893 for cchild in child.childList(): |
773 self._on_remove_node(child, cchild) | 894 self._on_remove_node(child, cchild) |
774 pass | 895 pass |
845 self._maxframe = self._find_maxframe(scenes_node) | 966 self._maxframe = self._find_maxframe(scenes_node) |
846 else: | 967 else: |
847 self._maxframe = max(int(new_value), self._maxframe) | 968 self._maxframe = max(int(new_value), self._maxframe) |
848 pass | 969 pass |
849 pass | 970 pass |
850 pass | |
851 pass | |
852 | |
853 ## \brief Collect ID of nodes in the document. | |
854 # | |
855 # It is used to implement a fast mapping from an ID to the respective node. | |
856 # | |
857 def _collect_node_ids(self): | |
858 self._id2node = {} | |
859 root = self._root | |
860 for n in root.childList(): | |
861 self._collect_node_ids_recursive(n) | |
862 pass | |
863 pass | |
864 | |
865 def _collect_node_ids_recursive(self, node): | |
866 try: | |
867 node_id = node.getAttribute('id') | |
868 except: | |
869 pass | |
870 else: | |
871 self._id2node[node_id] = node | |
872 pass | |
873 | |
874 for n in node.childList(): | |
875 self._collect_node_ids_recursive(n) | |
876 pass | |
877 pass | |
878 | |
879 def parse_one_scene(self, scene_node): | |
880 assert scene_node.name() == 'ns0:scene' | |
881 | |
882 start = int(scene_node.getAttribute("start")) | |
883 try: | |
884 end = int(scene_node.getAttribute("end")) | |
885 except: | |
886 end = start | |
887 pass | |
888 | |
889 try: | |
890 scene_type = scene_node.getAttribute('type') | |
891 if scene_type == None: | |
892 scene_type = 'normal' | |
893 pass | |
894 except: | |
895 scene_type = 'normal' | |
896 pass | |
897 | |
898 return start, end, scene_type | |
899 | |
900 def _parse_one_scenes(self, scenes_node): | |
901 try: | |
902 cur = int(n.getAttribute("current")) | |
903 except: | |
904 cur = 0 | |
905 pass | |
906 self.current = cur | |
907 | |
908 for scene_node in scenes_node.childList(): | |
909 if scene_node.name() != 'ns0:scene': | |
910 continue | |
911 | |
912 try: | |
913 start, end, scene_type = self.parse_one_scene(scene_node) | |
914 group_id = scene_node.getAttribute("ref") | |
915 except: # the scene node is incompleted. | |
916 continue | |
917 | |
918 self._group2scene[group_id] = scene_node | |
919 pass | |
920 pass | |
921 | |
922 ## \brief Parse all scenes node in svg:metadata subtree. | |
923 # | |
924 def _collect_all_scenes(self): | |
925 scenes_node = self._scenes_node | |
926 self._parse_one_scenes(scenes_node) | |
927 self._maxframe = self._find_maxframe(scenes_node) | |
928 pass | |
929 pass | |
930 | |
931 ## \brief Return the node with given ID. | |
932 # | |
933 def get_node(self, node_id): | |
934 value = self._id2node[node_id] | |
935 if isinstance(value, list): | |
936 return value[-1] | |
937 return value | |
938 | |
939 ## \brief Return a scene node corresponding to a scene group of given ID. | |
940 # | |
941 def get_scene(self, group_id): | |
942 return self._group2scene[group_id] | |
943 | |
944 def new_id(self): | |
945 while True: | |
946 candidate = 's%d' % int(random.random()*100000) | |
947 if candidate not in self._id2node: | |
948 return candidate | |
949 pass | 971 pass |
950 pass | 972 pass |
951 pass | 973 pass |
952 | 974 |
953 | 975 |