Bläddra i källkod

replaced erroneous sourcecode parts, added resource saver (#2750)

* replaced erroneous sourcecode parts, added resource saver

* changed spaces to tabs

* changed tabs to 4space+tab(s)

* Update development/cpp/custom_resource_format_loaders.rst

Co-Authored-By: Hugo Locurcio <[email protected]>

Co-authored-by: Hugo Locurcio <[email protected]>
99alfie 5 år sedan
förälder
incheckning
6349d303af
1 ändrade filer med 233 tillägg och 130 borttagningar
  1. 233 130
      development/cpp/custom_resource_format_loaders.rst

+ 233 - 130
development/cpp/custom_resource_format_loaders.rst

@@ -57,55 +57,100 @@ read and handle data serialization.
 
 
 .. code-block:: cpp
 .. code-block:: cpp
 
 
-	#ifndef MY_JSON_LOADER_H
-	#define MY_JSON_LOADER_H
+    /* resource_loader_json.h */
 
 
-	#include "core/io/resource_loader.h"
+    #ifndef RESOURCE_LOADER_JSON_H
+    #define RESOURCE_LOADER_JSON_H
 
 
-	class ResourceFormatLoaderMyJson : public ResourceFormatLoader {
-	public:
-		virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = NULL);
-		virtual void get_recognized_extensions(List<String> *p_extensions) const;
-		virtual bool handles_type(const String &p_type) const;
-		virtual String get_resource_type(const String &p_path) const;
+    #include "core/io/resource_loader.h"
 
 
-		ResourceFormatLoaderMyJson();
-		virtual ~ResourceFormatLoaderMyJson() {}
-	};
-	#endif // MY_JSON_LOADER_H
+    class ResourceFormatLoaderJson : public ResourceFormatLoader {
+        GDCLASS(ResourceFormatLoaderJson, ResourceFormatLoader)
+    public:
+        virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = NULL);
+        virtual void get_recognized_extensions(List<String> *p_extensions) const;
+        virtual bool handles_type(const String &p_type) const;
+        virtual String get_resource_type(const String &p_path) const;
+    };
+    #endif // RESOURCE_LOADER_JSON_H
 
 
 .. code-block:: cpp
 .. code-block:: cpp
 
 
-	#include "my_json_loader.h"
-	#include "my_json.h"
+    /* resource_loader_json.cpp */
 
 
-	ResourceFormatLoaderMyJson::ResourceFormatLoaderMyJson() {
-	}
+    #include "resource_loader_json.h"
+    #include "resource_json.h"
 
 
-	RES ResourceFormatLoaderMyJson::load(const String &p_path, const String &p_original_path, Error *r_error) {
-		MyJson *my = memnew(MyJson);
-		if (r_error)
-			*r_error = OK;
-		Error err = my->set_file(p_path);
-		return Ref<MyJson>(my);
-	}
 
 
-	void ResourceFormatLoaderMyJson::get_recognized_extensions(List<String> *p_extensions) const {
-		p_extensions->push_back("mjson");
-	}
+    RES ResourceFormatLoaderJson::load(const String &p_path, const String &p_original_path, Error *r_error) {
+    Ref<JsonResource> json = memnew(JsonResource);
+    	if (r_error)
+    		*r_error = OK;
+    	Error err = json->load_file(p_path);
+    	return json;
+    }
+
+    void ResourceFormatLoaderJson::get_recognized_extensions(List<String> *p_extensions) const {
+    	if (!p_extensions->find("json"))
+    		p_extensions->push_back("json");
+    }
+
+    String ResourceFormatLoaderJson::get_resource_type(const String &p_path) const {
+    	return "Resource";
+    }
+
+    bool ResourceFormatLoaderJson::handles_type(const String &p_type) const {
+    	return (ClassDB::is_parent_class(p_type, "Resource"));
+    }
+
+Creating a ResourceFormatSaver
+------------------------------
+
+If you'd like to be able to edit and save a resource, you can implement a ResourceFormatSaver:
+
+
+.. code:: cpp
+
+    /* resource_saver_json.h */
+
+    #ifndef RESOURCE_SAVER_JSON_H
+    #define RESOURCE_SAVER_JSON_H
 
 
-	String ResourceFormatLoaderMyJson::get_resource_type(const String &p_path) const {
+    #include "core/io/resource_saver.h"
 
 
-		if (p_path.get_extension().to_lower() == "mjson")
-			return "MyJson";
-		return "";
-	}
+    class ResourceFormatSaverJson : public ResourceFormatSaver {
+    	GDCLASS(ResourceFormatSaverJson, ResourceFormatSaver)
+    public:
+    	virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
+    	virtual bool recognize(const RES &p_resource) const;
+    	virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
+    };
+    #endif // RESOURCE_SAVER_JSON_H
+    
+.. code:: cpp
 
 
-	bool ResourceFormatLoaderMyJson::handles_type(const String &p_type) const {
-		return (p_type == "MyJson");
-	}
+    /* resource_saver_json.cpp */
 
 
+    #include "resource_saver_json.h"
+    #include "resource_json.h"
+    #include "scene\resources\resource_format_text.h"
 
 
+
+    Error ResourceFormatSaverJson::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
+    	Ref<JsonResource> json = memnew(JsonResource);
+    	Error error = json->save_file(p_path, p_resource);
+    	return error;
+    }
+
+    bool ResourceFormatSaverJson::recognize(const RES &p_resource) const {
+    	return Object::cast_to<JsonResource>(*p_resource) != NULL;
+    }
+
+    void ResourceFormatSaverJson::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+    	if (Object::cast_to<JsonResource>(*p_resource))
+    		p_extensions->push_back("json");
+    }
+    
 Creating custom data types
 Creating custom data types
 --------------------------
 --------------------------
 
 
@@ -117,58 +162,95 @@ Here is an example of how to create a custom datatype
 
 
 .. code-block:: cpp
 .. code-block:: cpp
 
 
-	#ifndef MY_JSON_H
-	#define MY_JSON_H
-
-	#include "core/dictionary.h"
-	#include "core/io/json.h"
-	#include "core/reference.h"
-	#include "core/variant.h"
-	#include "core/variant_parser.h"
-
-	class MyJson : public Resource {
-		GDCLASS(MyJson, Resource);
-
-	protected:
-		static void _bind_methods() {
-			ClassDB::bind_method(D_METHOD("to_string"), &MyJson::to_string);
-		}
-
-	private:
-		Dictionary dict;
-
-	public:
-		Error set_file(const String &p_path) {
-			Error error_file;
-			FileAccess *file = FileAccess::open(p_path, FileAccess::READ, &error_file);
-
-			String buf = String("");
-			while (!file->eof_reached()) {
-				buf += file->get_line();
-			}
-			String err_string;
-			int err_line;
-			JSON cmd;
-			Variant ret;
-			Error err = cmd.parse(buf, ret, err_string, err_line);
-			dict = Dictionary(ret);
-			file->close();
-			return OK;
-		}
-
-		String to_string() const {
-			return String(*this);
-		}
-
-		operator String() const {
-			JSON a;
-			return a.print(dict);
-		}
-
-		MyJson() {};
-		~MyJson() {};
-	};
-	#endif // MY_JSON_H
+    /* resource_json.h */
+
+    #ifndef RESOURCE_JSON_H
+    #define RESOURCE_JSON_H
+
+    #include "core/io/json.h"
+    #include "core/variant_parser.h"
+
+    class JsonResource : public Resource {
+    	GDCLASS(JsonResource, Resource);
+
+    protected:
+    	static void _bind_methods() {
+    		ClassDB::bind_method(D_METHOD("set_dict", "dict"), &JsonResource::set_dict);
+    		ClassDB::bind_method(D_METHOD("get_dict"), &JsonResource::get_dict);
+
+    		ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "content", PROPERTY_HINT_NONE, ""), "set_dict", "get_dict");
+    	}
+
+    private:
+    	Dictionary content;
+
+    public:
+    	Error load_file(const String &p_path);
+    	Error save_file(const String &p_path, const RES &p_resource);
+
+    	void set_dict(const Dictionary &p_dict);
+    	Dictionary get_dict();
+    };
+    #endif // RESOURCE_JSON_H
+
+.. code:: cpp
+
+    /* resource_json.cpp */
+
+    #include "resource_json.h"
+
+    Error JsonResource::load_file(const String &p_path) {
+    	Error error;
+    	FileAccess *file = FileAccess::open(p_path, FileAccess::READ, &error);
+    	if (!error == OK) {
+    		if (file)
+    			file->close();
+    		return error;
+    	}
+
+    	String json_string = String("");
+    	while (!file->eof_reached())
+    		json_string += file->get_line();
+    	file->close();
+
+    	String error_string;
+    	int error_line;
+    	JSON json;
+    	Variant result;
+    	error = json.parse(json_string, result, error_string, error_line);
+    	if (!error == OK) {
+    		file->close();
+    		return error;
+    	}
+
+    	content = Dictionary(result);
+    	return OK;
+    }
+
+    Error JsonResource::save_file(const String &p_path, const RES &p_resource) {
+    	Error error;
+    	FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &error);
+    	if (!error == OK) {
+    		if (file)
+    			file->close();
+    		return error;
+    	}
+
+    	Ref<JsonResource> json_ref = p_resource.get_ref_ptr();
+    	JSON json;
+
+    	file->store_string(json.print(json_ref->get_dict(), "    "));
+    	file->close();
+    	return Error::OK;
+    }
+
+    void JsonResource::set_dict(const Dictionary &p_dict) {
+    	content = p_dict;
+    }
+
+    Dictionary JsonResource::get_dict() {
+    	return content;
+    }
 
 
 Considerations
 Considerations
 ~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~
@@ -181,32 +263,32 @@ calls into ``std::istream``.
 
 
 .. code-block:: cpp
 .. code-block:: cpp
 
 
-	#include <istream>
-	#include <streambuf>
-
-	class GodotFileInStreamBuf : public std::streambuf {
-
-	public:
-		GodotFileInStreamBuf(FileAccess *fa) {
-			_file = fa;
-		}
-		int underflow() {
-			if (_file->eof_reached()) {
-				return EOF;
-			} else {
-				size_t pos = _file->get_position();
-				uint8_t ret = _file->get_8();
-				_file->seek(pos); // required since get_8() advances the read head
-				return ret;
-			}
-		}
-		int uflow() {
-			return _file->eof_reached() ?  EOF : _file->get_8();
-		}
-
-	private:
-		FileAccess *_file;
-	};
+    #include <istream>
+    #include <streambuf>
+
+    class GodotFileInStreamBuf : public std::streambuf {
+
+    public:
+    	GodotFileInStreamBuf(FileAccess *fa) {
+    		_file = fa;
+    	}
+    	int underflow() {
+    		if (_file->eof_reached()) {
+    			return EOF;
+    		} else {
+    			size_t pos = _file->get_position();
+    			uint8_t ret = _file->get_8();
+    			_file->seek(pos); // required since get_8() advances the read head
+    			return ret;
+    		}
+    	}
+    	int uflow() {
+    		return _file->eof_reached() ?  EOF : _file->get_8();
+    	}
+
+    private:
+    	FileAccess *_file;
+    };
 
 
 
 
 References
 References
@@ -225,23 +307,42 @@ when ``load`` is called.
 
 
 .. code-block:: cpp
 .. code-block:: cpp
 
 
-	/* register_types.cpp */
-	#include "register_types.h"
-	#include "core/class_db.h"
+    /* register_types.h */
+
+    void register_json_types();
+    void unregister_json_types();
+
+.. code:: cpp
+
+    /* register_types.cpp */
+
+    #include "register_types.h"
+    #include "core/class_db.h"
+
+    #include "resource_loader_json.h"
+    #include "resource_saver_json.h"
+    #include "resource_json.h"
 
 
-	#include "my_json_loader.h"
-	#include "my_json.h"
+    static Ref<ResourceFormatLoaderJson> json_loader;
+    static Ref<ResourceFormatSaverJson> json_saver;
 
 
-	static ResourceFormatLoaderMyJson *my_json_loader = NULL;
-	void register_my_json_types() {
-		my_json_loader = memnew(ResourceFormatLoaderMyJson);
-		ResourceLoader::add_resource_format_loader(my_json_loader);
-		ClassDB::register_class<MyJson>();
-	}
+    void register_json_types() {
+    	ClassDB::register_class<JsonResource>();
 
 
-	void unregister_my_json_types() {
-		memdelete(my_json_loader);
-	}
+    	json_loader.instance();
+    	ResourceLoader::add_resource_format_loader(json_loader);
+
+    	json_saver.instance();
+    	ResourceSaver::add_resource_format_saver(json_saver);
+    }
+
+    void unregister_json_types() {
+    	ResourceLoader::remove_resource_format_loader(json_loader);
+    	json_loader.unref();
+
+    	ResourceSaver::remove_resource_format_saver(json_saver);
+    	json_saver.unref();
+    }
 
 
 References
 References
 ~~~~~~~~~~
 ~~~~~~~~~~
@@ -253,8 +354,9 @@ Loading it on GDScript
 
 
 .. code-block:: json
 .. code-block:: json
 
 
+    /* example .json file */
     {
     {
-      "savefilename" : "demo.mjson",
+      "savefilename" : "demo.json",
       "demo": [
       "demo": [
         "welcome",
         "welcome",
         "to",
         "to",
@@ -268,6 +370,7 @@ Loading it on GDScript
 
 
     extends Node
     extends Node
 
 
+    onready var json_resource = load("res://demo.json")
+
     func _ready():
     func _ready():
-        var myjson = load("res://demo.mjson")
-        print(myjson.to_string())
+    	print(json_resource.get_dict())