{"action":"created","issue":{"url":"https://api.github.com/repos/godotengine/godot/issues/19778","repository_url":"https://api.github.com/repos/godotengine/godot","labels_url":"https://api.github.com/repos/godotengine/godot/issues/19778/labels{/name}","comments_url":"https://api.github.com/repos/godotengine/godot/issues/19778/comments","events_url":"https://api.github.com/repos/godotengine/godot/issues/19778/events","html_url":"https://github.com/godotengine/godot/pull/19778","id":335652033,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk3Mjk2Nzg0","number":19778,"title":"TypeDB and GDScript 'Scripts' global added.","user":{"login":"willnationsdev","id":16217563,"node_id":"MDQ6VXNlcjE2MjE3NTYz","avatar_url":"https://avatars1.githubusercontent.com/u/16217563?v=4","gravatar_id":"","url":"https://api.github.com/users/willnationsdev","html_url":"https://github.com/willnationsdev","followers_url":"https://api.github.com/users/willnationsdev/followers","following_url":"https://api.github.com/users/willnationsdev/following{/other_user}","gists_url":"https://api.github.com/users/willnationsdev/gists{/gist_id}","starred_url":"https://api.github.com/users/willnationsdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/willnationsdev/subscriptions","organizations_url":"https://api.github.com/users/willnationsdev/orgs","repos_url":"https://api.github.com/users/willnationsdev/repos","events_url":"https://api.github.com/users/willnationsdev/events{/privacy}","received_events_url":"https://api.github.com/users/willnationsdev/received_events","type":"User","site_admin":false},"labels":[{"id":73330068,"node_id":"MDU6TGFiZWw3MzMzMDA2OA==","url":"https://api.github.com/repos/godotengine/godot/labels/feature%20proposal","name":"feature proposal","color":"1144ff","default":false},{"id":279097966,"node_id":"MDU6TGFiZWwyNzkwOTc5NjY=","url":"https://api.github.com/repos/godotengine/godot/labels/topic:core","name":"topic:core","color":"ffdd44","default":false},{"id":279098082,"node_id":"MDU6TGFiZWwyNzkwOTgwODI=","url":"https://api.github.com/repos/godotengine/godot/labels/topic:gdscript","name":"topic:gdscript","color":"ffdd44","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/godotengine/godot/milestones/7","html_url":"https://github.com/godotengine/godot/milestone/7","labels_url":"https://api.github.com/repos/godotengine/godot/milestones/7/labels","id":2529217,"node_id":"MDk6TWlsZXN0b25lMjUyOTIxNw==","number":7,"title":"3.1","description":"","creator":{"login":"akien-mga","id":4701338,"node_id":"MDQ6VXNlcjQ3MDEzMzg=","avatar_url":"https://avatars0.githubusercontent.com/u/4701338?v=4","gravatar_id":"","url":"https://api.github.com/users/akien-mga","html_url":"https://github.com/akien-mga","followers_url":"https://api.github.com/users/akien-mga/followers","following_url":"https://api.github.com/users/akien-mga/following{/other_user}","gists_url":"https://api.github.com/users/akien-mga/gists{/gist_id}","starred_url":"https://api.github.com/users/akien-mga/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akien-mga/subscriptions","organizations_url":"https://api.github.com/users/akien-mga/orgs","repos_url":"https://api.github.com/users/akien-mga/repos","events_url":"https://api.github.com/users/akien-mga/events{/privacy}","received_events_url":"https://api.github.com/users/akien-mga/received_events","type":"User","site_admin":false},"open_issues":1085,"closed_issues":1693,"state":"open","created_at":"2017-05-18T13:33:56Z","updated_at":"2018-06-28T18:05:13Z","due_on":null,"closed_at":null},"comments":42,"created_at":"2018-06-26T04:10:46Z","updated_at":"2018-06-28T18:19:47Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/godotengine/godot/pulls/19778","html_url":"https://github.com/godotengine/godot/pull/19778","diff_url":"https://github.com/godotengine/godot/pull/19778.diff","patch_url":"https://github.com/godotengine/godot/pull/19778.patch"},"body":"@reduz @karroffel \r\n\r\nThis PR makes several changes to a variety of systems in Godot, but it's meant to mostly be confined to the editor and gdscript areas.\r\n\r\nThe functional summary is that it permits the namespaced registration of scripts (eventually scenes), enables scripting languages to inspect this data, improves editor responsiveness to the registration of types without hiding any information about the presence of a script, and gives GDScript an interface to access and inherit from these registered scripts by name.\r\n\r\n# Changes to Core\r\n\r\n- The `Script` class now has a `get_script_metadata()` method. This method's purpose is purely to have an implementation-specific means of acquiring script data that is important to the Editor. I initially attempted to NOT have a method like this whereby the Editor would directly inspect the file extension of a script, open up the file, and parse data directly from the source code in an effort to not modify core. However, this was just as dirty/hacky as it sounds, and it isn't even applicable to things like NativeScript which have no perceptible source code. Instead, any script may now define this method (probably a static method) to return a Dictionary containing the relevant editor metadata. It's simpler, cross-language compatible, and has been given a default implementation to return the results of the defined method, if it exists.\r\n\r\n- To simplify the implementation of a method in the `DocData` class which can generate an XML documentation file from a `Script` class, I appended a defaulted-to-false `p_no_inheritance` boolean parameter to the `get_script_property_list` method so that I could more easily extract only the properties related to the current script when generating documentation. I also have in mind to re-apply this method in the unrelated PR #13116.\r\n\r\n# Major Changes\r\n\r\n- The custom type system in EditorData has been replaced with a TypeDB class that allows users to register types of scripts. It is designed with the intention of eventually including scenes as well, but the UI for this has not been implemented.\r\n\r\n    - The TypeDB has a set of methods which mimic the behavior of the ClassDB. The only one of these methods which actually wraps ClassDB functionality is the `is_parent_class` method.\r\n    - TypeDB types are distinguished from ClassDB types in that they *must* have a namespace prefix, designated with a period '.' delimeter. Only C++ types will exist in the global namespace.\r\n    - For backwards compatibility, the `EditorPlugin::add_custom_type()` method inserts the \"Custom.\" namespace as a prefix to any registered types which do not already have a namespace.\r\n    - Whenever the filesystem is changed, the TypeDB is serialized into a `StringName typename => String filepath` Dictionary stored in ProjectSettings at `typedb/scripts` and `typedb/scenes`.\r\n\r\n- The GDScript language accesses the TypeDB's serialized data from ProjectSettings to generate a pair of `Scripts` and `Scenes` globals.\r\n\r\n    - The parser identifies usages of these globals and parses their subsequent identifiers for matching namespaced typenames. If one is found, the parser interprets it as a `RESOURCE_LOAD` operation with the filepath as a parameter.\r\n    - The parser also puts together a Scripts.Namespace.Typename pattern for the `extends_class` array, enabling inheritance.\r\n    - The compiler parses the inherited name and likewise tries to find a match in the Scripts global.\r\n\r\n- GDScript files may now optionally export their class name, whether they are custom, and if custom, whether they are abstract and/or have a custom icon. This is executed using the `export` keyword and is expected to be the first line of a GDScript file, save for any comments.\r\n\r\n        # my_node.gd, variations include...\r\n        export(\"Game.MyNode\") # merely registers the name in the Scripts global. No editor functionality.\r\n        export(\"Game.MyNode\", CUSTOM) # registered as custom type using base type icon\r\n        export(\"Game.MyNode\", CUSTOM, \"res://icon_my_node.svg\") # registered as custom type with custom icon.\r\n        export(\"Game.MyNode\", ABSTRACT, CUSTOM) # registered as abstract custom type (similar to CanvasItem) with the base type icon.\r\n        export(\"Game.MyNode\", ABSTRACT, CUSTOM, \"res://icon_my_node.svg\") # everything\r\n        extends Node\r\n\r\n- The Editor has improved responsiveness to custom types.\r\n\r\n    - Custom types have a faded script icon in the Scene dock, indicating that the script is overrideable, but still a script. The \"add a script\" button is displayed if a node with a custom script is selected. Clicking on the faded script icon will take you to the custom script.\r\n    - Clicking on the \"add a script\" button will open the `ScriptCreateDialog` with the `inherits` field pre-populated. The content here is determined by a method within the TypeDB in cases where the node already has a script that is a custom type.\r\n    - Clicking the \"remove script\" button on a node with a script that derives a custom script in its inheritance hierarchy will remove the script, but reinstate the most-derived custom script.\r\n\r\n- The `EditorPlugin` (Edit, moved to the `EditorInterface` for `EditorScript` compatibility) now has exposed API methods for XML documentation, namely, generating a file from a `Script` and loading up all files within a directory. These methods are mostly implemented within the `DocData` class.\r\n- Edit: The EditorPluginSettings now has create and edit buttons which open a new PluginCreateDialog to simplify the process of building and editing plugins.\r\n- Edit: A docs reload button now exists in Projects -> Tools -> Rebuild Documentation. It simply calls the godot executable with \"--doctool .\" parameters.\r\n- Edit: The Editor now automatically adds and removes any *registered* custom types when the plugin is activated and deactivated, respectively. As such, if using exclusively GDScript at this point, all one needs is an EditorPlugin tool script defined (with no other content) in order to define custom types as a group.\r\n\r\nA demo of the changes can be found on my [YouTube video](https://youtu.be/TwEV4NmcLT0). Note that the following issues from the video are already fixed:\r\n\r\n1. Only pre-populating the `inherits` field of the `ScriptCreateDialog` when appropriate.\r\n2. Making the icon an optional parameter in the GDScript class export.\r\n\r\nDuring my rebase with master, the most conflicts I had were in the `editor_properties.cpp` file where many references to the old custom type system had been made. I believe I made the updates properly, but I had trouble determining how to test the changed code.\r\n\r\nAnyway, please let me know if there are additional changes I need to make before this can be integrated for 3.1.\r\n\r\n# Known Bugs At This Time (Will Update)\r\n\r\n- ~The Inspector is showing certain custom types in submenus when it shouldn't be.~\r\n- Resolve conflicts that will inevitably happen with #19264 based on changes to the compiler."},"comment":{"url":"https://api.github.com/repos/godotengine/godot/issues/comments/401127319","html_url":"https://github.com/godotengine/godot/pull/19778#issuecomment-401127319","issue_url":"https://api.github.com/repos/godotengine/godot/issues/19778","id":401127319,"node_id":"MDEyOklzc3VlQ29tbWVudDQwMTEyNzMxOQ==","user":{"login":"willnationsdev","id":16217563,"node_id":"MDQ6VXNlcjE2MjE3NTYz","avatar_url":"https://avatars1.githubusercontent.com/u/16217563?v=4","gravatar_id":"","url":"https://api.github.com/users/willnationsdev","html_url":"https://github.com/willnationsdev","followers_url":"https://api.github.com/users/willnationsdev/followers","following_url":"https://api.github.com/users/willnationsdev/following{/other_user}","gists_url":"https://api.github.com/users/willnationsdev/gists{/gist_id}","starred_url":"https://api.github.com/users/willnationsdev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/willnationsdev/subscriptions","organizations_url":"https://api.github.com/users/willnationsdev/orgs","repos_url":"https://api.github.com/users/willnationsdev/repos","events_url":"https://api.github.com/users/willnationsdev/events{/privacy}","received_events_url":"https://api.github.com/users/willnationsdev/received_events","type":"User","site_admin":false},"created_at":"2018-06-28T18:19:47Z","updated_at":"2018-06-28T18:19:47Z","author_association":"CONTRIBUTOR","body":"@samdze \r\n\r\n> It's all about tradeoffs, scenes-only registration requires a little more work to setup by the user to register a new \"simple node script\" type, but it's more powerful as it also allows the registration of all kinds of complex scenes, all with the same procedure.\r\n\r\nYou're exactly right. And I'll be getting to the scenes as well later on (probably with the 3.1.1 release or something), but in the meantime, scripts are *already ready to go, more or less*, so once I refactor things to account for @vnen's #19264 changes, the script side will be finished. We're still gonna get registration of complex scenes, and in fact they DO use the same procedure under-the-hood, but there's a lot of additional logic for the editor support and tooling that will need to go along with the scenes (which isn't ready yet).\r\n\r\n> And as already said, problems like being unsure of accessing a Scipt or a PackedScene would disappear.\r\n\r\n@chanon's suggestion to \"let Script exports not need Scripts. prefix, but Scenes will be in Scenes.. (Since Scripts exports will be the most commonly used/typed.)\" already deals with this problem, and much more effectively since it preserves the simplicity of creating registered and custom type scripts.\r\n\r\n> The fact that scene registration doesn't work now has nothing to do with what I'm saying, I'm only proposing solutions.\r\nUnfortunately it may not be sure that the best solution saves what you have already implemented.\r\n\r\nIt does matter since it determines whether or not this PR even gets integrated, or whether we delay till a different release when the functionality is better prepared.\r\n\r\n> However, this doesn't take into account custom Resources, therefore this whole single solution could be easily discarded as simple script custom types remain necessary, so I agree this is not a good idea.\r\n\r\nActually, it DOES take into account custom Resources. They are classes after all. Scripts. If you are talking about registering actual resource files (*.tres), that has never been a feature in the first place(?). I even solved a bug earlier on where my custom types were showing up in custom resource locations when they weren't deriving Resource (which I've since fixed).\r\n\r\n> Probably as long as valid identifiers have a hint of them being a Script or a PackedScene, like a different text color and the right new() or instance() autocomplete, prefixes and naming conventions are not needed.\r\n\r\nThat's an interesting proposition, but I think we'd still run into circumstances where a registered script or scene may share a name (which isn't a case we can just ignore), and then we'd have to force a \"hiding\" system where one takes priority over the other, forcing people to change the names of things and refactor if they want to use the hidden typename. It's simply much easier on the user's side if there is a syntactic way of clearly differentiating the two groups."}}
{"actor":{"display_login":"willnationsdev"}}