def test_add_ext_node(self): """Test GDScene.add_ext_node""" scene = GDScene() res = scene.add_ext_resource("res://Other.tscn", "PackedScene") node = scene.add_ext_node("Root", res.id) self.assertEqual(node.name, "Root") self.assertEqual(node.instance, res.id)
def test_write(self): """Test writing scene out to a file""" scene = GDScene() outfile = tempfile.mkstemp()[1] scene.write(outfile) with open(outfile, "r") as ifile: gen_scene = GDScene.parse(ifile.read()) self.assertEqual(scene, gen_scene)
def test_file_equality(self): """Tests for GDFile == GDFile""" s1 = GDScene(GDResourceSection()) s2 = GDScene(GDResourceSection()) self.assertEqual(s1, s2) resource = s1.find_section("resource") resource["key"] = "value" self.assertNotEqual(s1, s2)
def test_ext_resource(self): """Test serializing a scene with an ext_resource""" scene = GDScene() scene.add_ext_resource("res://Other.tscn", "PackedScene") self.assertEqual( str(scene), """[gd_scene load_steps=2 format=2] [ext_resource path="res://Other.tscn" type="PackedScene" id=1] """, )
def test_sub_resource(self): """Test serializing a scene with an sub_resource""" scene = GDScene() scene.add_sub_resource("Animation") self.assertEqual( str(scene), """[gd_scene load_steps=2 format=2] [sub_resource type="Animation" id=1] """, )
def test_insert_child(self): """ Test for insert_child() """ scene = GDScene() scene.add_node("RootNode") scene.add_node("Child1", parent=".") with scene.use_tree() as tree: child = Node("Child2", type="Node") tree.root.insert_child(0, child) child1 = scene.find_section("node", name="Child1") child2 = scene.find_section("node", name="Child2") idx1 = scene.get_sections().index(child1) idx2 = scene.get_sections().index(child2) print(scene.get_sections()) self.assertLess(idx2, idx1)
def test_get_node(self): """ Test for get_node() """ scene = GDScene() scene.add_node("RootNode") scene.add_node("Child", parent=".") child = scene.add_node("Child2", parent="Child") node = scene.get_node("Child/Child2") self.assertEqual(node, child)
def test_load_inherited(self): """ Can load an inherited scene and read the nodes """ scene = GDScene.load(self.leaf_scene) with scene.use_tree() as tree: node = tree.get_node("Health/LifeBar") self.assertIsNotNone(node) self.assertEqual(node.type, "TextureProgress")
def test_tree_create(self): """Test creating a scene with the tree API""" scene = GDScene() with scene.use_tree() as tree: tree.root = Node("RootNode", type="Node2D") tree.root.add_child( Node("Child", type="Area2D", properties={"visible": False})) self.assertEqual( str(scene), """[gd_scene load_steps=1 format=2] [node name="RootNode" type="Node2D"] [node name="Child" type="Area2D" parent="."] visible = false """, )
def test_invalid_tree(self): """ Raise exception when tree is invalid """ scene = GDScene() scene.add_node("RootNode") scene.add_node("Child", parent="Missing") self.assertRaises(TreeMutationException, lambda: scene.get_node("Child"))
def test_section_ordering(self): """Sections maintain an ordering""" scene = GDScene() node = scene.add_node("RootNode") scene.add_ext_resource("res://Other.tscn", "PackedScene") res = scene.find_section("ext_resource") self.assertEqual(scene.get_sections()[1:], [res, node])
def test_inherit_properties(self): """ Inherited nodes inherit properties """ scene = GDScene.load(self.leaf_scene) with scene.use_tree() as tree: self.assertEqual(tree.root["shape"], SubResource(1)) self.assertEqual(tree.root["collision_layer"], 4) self.assertEqual(tree.root.get("collision_layer"), 4) self.assertEqual(tree.root.get("missing"), None) self.assertRaises(KeyError, lambda: tree.root["missing"])
def test_disappear_sections(self): """ Inherited nodes are removed from sections if we change their configuration to match parent """ scene = GDScene.load(self.leaf_scene) with scene.use_tree() as tree: sprite = tree.get_node("Sprite") sprite["flip_h"] = False # Sprite should match parent now, and not be in file node = scene.find_section("node", name="Sprite") self.assertIsNone(node)
def test_overwrite_sections(self): """ Inherited nodes appear in sections if we change their configuration """ scene = GDScene.load(self.leaf_scene) with scene.use_tree() as tree: node = tree.get_node("Health/LifeBar") node["pause_mode"] = 2 num_nodes = len(scene.get_nodes()) self.assertEqual(num_nodes, 3) node = scene.find_section("node", name="LifeBar", parent="Health") self.assertIsNotNone(node)
def test_cannot_remove(self): """ Cannot remove inherited nodes """ scene = GDScene.load(self.leaf_scene) with scene.use_tree() as tree: node = tree.get_node("Health") self.assertRaises(TreeMutationException, node.remove_from_parent) self.assertRaises(TreeMutationException, lambda: tree.root.remove_child(0)) self.assertRaises(TreeMutationException, lambda: tree.root.remove_child("Health"))
def setUpClass(cls): super(TestInheritedScenes, cls).setUpClass() cls.project_dir = tempfile.mkdtemp() with open(os.path.join(cls.project_dir, "project.godot"), "w") as ofile: ofile.write("fake project") cls.root_scene = os.path.join(cls.project_dir, "Root.tscn") cls.mid_scene = os.path.join(cls.project_dir, "Mid.tscn") cls.leaf_scene = os.path.join(cls.project_dir, "Leaf.tscn") scene = GDScene.parse(""" [gd_scene load_steps=1 format=2] [node name="Root" type="KinematicBody2D"] collision_layer = 3 [node name="CollisionShape2D" type="CollisionShape2D" parent="."] disabled = true [node name="Sprite" type="Sprite" parent="."] flip_h = false [node name="Health" type="Control" parent="."] [node name="LifeBar" type="TextureProgress" parent="Health"] """) scene.write(cls.root_scene) scene = GDScene.parse(""" [gd_scene load_steps=2 format=2] [ext_resource path="res://Root.tscn" type="PackedScene" id=1] [node name="Mid" instance=ExtResource( 1 )] collision_layer = 4 [node name="Health" parent="." index="2"] pause_mode = 2 """) scene.write(cls.mid_scene) scene = GDScene.parse(""" [gd_scene load_steps=2 format=2] [ext_resource path="res://Mid.tscn" type="PackedScene" id=1] [sub_resource type="CircleShape2D" id=1] [node name="Leaf" instance=ExtResource( 1 )] shape = SubResource( 1 ) [node name="Sprite" type="Sprite" parent="." index="1"] flip_h = true """) scene.write(cls.leaf_scene)
def test_unchanged_sections(self): """ Inherited nodes do not appear in sections """ scene = GDScene.load(self.leaf_scene) num_nodes = len(scene.get_nodes()) self.assertEqual(num_nodes, 2) with scene.use_tree() as tree: sprite = tree.get_node("Sprite") sprite["flip_v"] = True # No new nodes num_nodes = len(scene.get_nodes()) self.assertEqual(num_nodes, 2)
def test_remove_unused_resource(self): """Can remove unused resources""" scene = GDScene() res = scene.add_ext_resource("res://Res.tscn", "PackedScene") scene.remove_unused_resources() resources = scene.get_sections("ext_resource") self.assertEqual(len(resources), 0)
def test_tree_deep_create(self): """Test creating a scene with nested children using the tree API""" scene = GDScene() with scene.use_tree() as tree: tree.root = Node("RootNode", type="Node2D") child = Node("Child", type="Node") tree.root.add_child(child) child.add_child(Node("ChildChild", type="Node")) child.add_child(Node("ChildChild2", type="Node")) self.assertEqual( str(scene), """[gd_scene load_steps=1 format=2] [node name="RootNode" type="Node2D"] [node name="Child" type="Node" parent="."] [node name="ChildChild" type="Node" parent="Child"] [node name="ChildChild2" type="Node" parent="Child"] """, )
def test_find_node(self): """Test GDScene.find_node""" scene = GDScene() n1 = scene.add_node("Root", "Node") n2 = scene.add_node("Child", "Node", parent=".") node = scene.find_node(name="Root") self.assertEqual(node, n1) node = scene.find_node(parent=".") self.assertEqual(node, n2)
def test_add_new_nodes(self): """ Can add new nodes to an inherited scene """ scene = GDScene.load(self.leaf_scene) with scene.use_tree() as tree: tree.get_node("Health/LifeBar") node = Node("NewChild", type="Control") tree.root.add_child(node) # Non-inherited node can change name, type, instance node.instance = 2 node.type = "Node2D" node.name = "NewChild2" found = scene.find_section("node", name="NewChild2") self.assertIsNotNone(found) self.assertEqual(found.type, "Node2D") self.assertEqual(found.parent, ".") self.assertEqual(found.index, 3)
def test_properties(self): """ Test for changing properties on a node """ scene = GDScene() scene.add_node("RootNode") with scene.use_tree() as tree: tree.root["vframes"] = 10 self.assertEqual(tree.root["vframes"], 10) tree.root["hframes"] = 10 del tree.root["hframes"] del tree.root["hframes"] self.assertIsNone(tree.root.get("hframes")) child = scene.find_section("node") self.assertEqual(child["vframes"], 10)
def test_cannot_mutate(self): """ Cannot change the name/type/instance of inherited nodes """ scene = GDScene.load(self.leaf_scene) def change_name(x): x.name = "foo" def change_type(x): x.type = "foo" def change_instance(x): x.instance = 2 with scene.use_tree() as tree: node = tree.get_node("Health") self.assertRaises(TreeMutationException, lambda: change_name(node)) self.assertRaises(TreeMutationException, lambda: change_type(node)) self.assertRaises(TreeMutationException, lambda: change_instance(node))
def test_node(self): """Test serializing a scene with a node""" scene = GDScene() scene.add_node("RootNode", type="Node2D") scene.add_node("Child", type="Area2D", parent=".") self.assertEqual( str(scene), """[gd_scene load_steps=1 format=2] [node name="RootNode" type="Node2D"] [node name="Child" type="Area2D" parent="."] """, )
def test_find_constraints(self): """Test for the find_section constraints""" scene = GDScene() res1 = scene.add_sub_resource("CircleShape2D", radius=1) res2 = scene.add_sub_resource("CircleShape2D", radius=2) found = list(scene.find_all("sub_resource")) self.assertCountEqual(found, [res1, res2]) found = list(scene.find_all("sub_resource", id=res1.id)) self.assertEqual(found, [res1]) found = list(scene.find_all("sub_resource", {"radius": 2})) self.assertEqual(found, [res2])
def test_basic_scene(self): """Run the parsing test cases""" self.assertEqual(str(GDScene()), "[gd_scene load_steps=1 format=2]\n")
def godot_export_scene(root, pipeline, logger): root.dump() scene = GDScene() extresources = {} with scene.use_tree() as tree: tree.root = Node("Scene", type="Node2D") idx = 0 rooms = root.find("/Rooms") rooms = rooms.individualize().flatten().clean() for obj in rooms.children: idx += 1 nodename = obj.name.replace(":", "_") polygon = GDObject( "PoolVector2Array", *coords_to_godot_vector2array(obj.geom.exterior.coords)) gdnode = Node(nodename + "_" + str(idx), type="Polygon2D", properties={'polygon': polygon}) tree.root.add_child(gdnode) if obj.get('uv', None): uvs = obj.get('uv') # TODO: Do not transpose here! transpose when assigining UVs (this was done to overcome uvmapping.path_2d working on Y not X) uvs = [(uv[1], uv[0]) for uv in uvs] uvs = GDObject("PoolVector2Array", *coords_to_godot_vector2array(uvs)) gdnode['uv'] = uvs if obj.extra.get('ddd:collider', False): gdstaticbody = Node("StaticBody2D", type="StaticBody2D", properties={'collision_layer': 16}) gdnode.add_child(gdstaticbody) gdcollider = Node("CollisionPolygon2D", type="CollisionPolygon2D", properties={'polygon': polygon}) gdstaticbody.add_child(gdcollider) if obj.extra.get('ddd:occluder', False): occluderpolygon_res = scene.add_sub_resource( "OccluderPolygon2D", polygon=polygon) gdstaticbody = Node( "LightOccluder2D", type="LightOccluder2D", properties={'occluder': occluderpolygon_res.reference}) gdnode.add_child(gdstaticbody) if obj.mat and obj.mat.color: gdnode['self_modulate'] = GDObject( "Color", *[x / 255.0 for x in obj.mat.color_rgba]) if obj.mat.texture: if obj.mat.texture not in extresources: extresources[obj.mat.texture] = scene.add_ext_resource( obj.mat.texture, "Texture") texture_res = extresources[obj.mat.texture] gdnode['texture'] = texture_res.reference gdnode['texture_scale'] = GDObject( "Vector2", 2.0, 1.0) # TODO: this is temp For grass tests if 'ddd:z_index' in obj.extra: gdnode['z_index'] = obj.extra['ddd:z_index'] gdnode['z_as_relative'] = False nodes = root.find("/Items") #nodes = nodes.individualize().flatten().clean() for obj in nodes.children: idx += 1 nodename = obj.name.replace(":", "_") gdnode = None if obj.extra.get('godot:instance', False): if obj.extra['godot:instance'] not in extresources: extresources[ obj.extra['godot:instance']] = scene.add_ext_resource( obj.extra['godot:instance'], "PackedScene") packedscene = extresources[obj.extra['godot:instance']] gdnode = Node(nodename + "_" + str(idx), instance=packedscene.id, properties={ 'position': GDObject("Vector2", obj.geom.coords[0][0], obj.geom.coords[0][1]) }) tree.root.add_child(gdnode) #if obj.mat and obj.mat.color: # gdnode['self_modulate'] = GDObject("Color", *[x / 255.0 for x in obj.mat.color_rgba]) if 'ddd:z_index' in obj.extra: gdnode['z_index'] = obj.extra['ddd:z_index'] gdnode['z_as_relative'] = False if 'ddd:angle' in obj.extra: gdnode['rotation'] = obj.extra['ddd:angle'] output_path = "/tmp/ddd-godot.tscn" logger.info("Writing to: %s" % (output_path, )) scene.write(output_path) """
def test_get_missing_node(self): """ get_node on missing node should return None """ scene = GDScene() scene.add_node("RootNode") node = scene.get_node("Foo/Bar/Baz") self.assertIsNone(node)
def test_addremove_ext_res(self): """Test adding and removing an ext_resource""" scene = GDScene() res = scene.add_ext_resource("res://Res.tscn", "PackedScene") self.assertEqual(res.id, 1) res2 = scene.add_ext_resource("res://Sprite.png", "Texture") self.assertEqual(res2.id, 2) node = scene.add_node("Sprite", "Sprite") node["texture"] = res2.reference node["textures"] = [res2.reference] node["texture_map"] = {"tex": res2.reference} node["texture_pool"] = GDObject("ResourcePool", res2.reference) s = scene.find_section(path="res://Res.tscn") scene.remove_section(s) scene.renumber_resource_ids() s = scene.find_section("ext_resource") self.assertEqual(s.id, 1) self.assertEqual(node["texture"], s.reference) self.assertEqual(node["textures"][0], s.reference) self.assertEqual(node["texture_map"]["tex"], s.reference) self.assertEqual(node["texture_pool"].args[0], s.reference)
def test_get_node_none(self): """get_node() works with no nodes""" scene = GDScene() n = scene.get_node() self.assertIsNone(n)