summaryrefslogtreecommitdiff
path: root/modules/mono
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono')
-rw-r--r--modules/mono/config.py2
-rw-r--r--modules/mono/csharp_script.cpp26
-rw-r--r--modules/mono/csharp_script.h1
-rw-r--r--modules/mono/editor/bindings_generator.cpp5
-rw-r--r--modules/mono/glue/cs_files/StringExtensions.cs32
-rw-r--r--modules/mono/glue/cs_files/Transform.cs4
-rwxr-xr-xmodules/mono/glue/cs_files/VERSION.txt2
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp31
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp27
9 files changed, 91 insertions, 39 deletions
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 5591ed25bf..831d849ea6 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -161,7 +161,7 @@ def configure(env):
mono_lib_path = ''
mono_so_name = ''
- mono_prefix = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).strip()
+ mono_prefix = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip()
tmpenv = Environment()
tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 525b918b1f..1d0afa7f2d 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -282,6 +282,15 @@ void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const {
p_delimiters->push_back("@\" \""); // verbatim string literal
}
+static String get_base_class_name(const String &p_base_class_name, const String p_class_name) {
+
+ String base_class = p_base_class_name;
+ if (p_class_name == base_class) {
+ base_class = "Godot." + base_class;
+ }
+ return base_class;
+}
+
Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
String script_template = "using " BINDINGS_NAMESPACE ";\n"
@@ -308,7 +317,8 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin
"// }\n"
"}\n";
- script_template = script_template.replace("%BASE_CLASS_NAME%", p_base_class_name)
+ String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
+ script_template = script_template.replace("%BASE_CLASS_NAME%", base_class_name)
.replace("%CLASS_NAME%", p_class_name);
Ref<CSharpScript> script;
@@ -327,12 +337,24 @@ bool CSharpLanguage::is_using_templates() {
void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
String src = p_script->get_source_code();
- src = src.replace("%BASE%", p_base_class_name)
+ String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
+ src = src.replace("%BASE%", base_class_name)
.replace("%CLASS%", p_class_name)
.replace("%TS%", _get_indentation());
p_script->set_source_code(src);
}
+String CSharpLanguage::validate_path(const String &p_path) const {
+
+ String class_name = p_path.get_file().get_basename();
+ List<String> keywords;
+ get_reserved_words(&keywords);
+ if (keywords.find(class_name)) {
+ return TTR("Class name can't be a reserved keyword");
+ }
+ return "";
+}
+
Script *CSharpLanguage::create_script() const {
return memnew(CSharpScript);
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 1f609627de..8666149111 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -294,6 +294,7 @@ public:
virtual bool is_using_templates();
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
/* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const { return true; }
+ virtual String validate_path(const String &p_path) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
virtual bool supports_builtin_mode() const;
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 315c1e2f1c..a210b8e480 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -103,7 +103,7 @@
#define C_METHOD_MANAGED_TO_DICT C_NS_MONOMARSHAL "::mono_object_to_Dictionary"
#define C_METHOD_MANAGED_FROM_DICT C_NS_MONOMARSHAL "::Dictionary_to_mono_object"
-#define BINDINGS_GENERATOR_VERSION UINT32_C(1)
+#define BINDINGS_GENERATOR_VERSION UINT32_C(2)
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n";
@@ -730,7 +730,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
}
output.push_back(INDENT1 "public ");
- output.push_back(itype.is_singleton ? "static class " : "class ");
+ bool is_abstract = !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled'
+ output.push_back(itype.is_singleton ? "static class " : (is_abstract ? "abstract class " : "class "));
output.push_back(itype.proxy_name);
if (itype.is_singleton) {
diff --git a/modules/mono/glue/cs_files/StringExtensions.cs b/modules/mono/glue/cs_files/StringExtensions.cs
index 5c3ceff97d..cbc337ab19 100644
--- a/modules/mono/glue/cs_files/StringExtensions.cs
+++ b/modules/mono/glue/cs_files/StringExtensions.cs
@@ -287,7 +287,7 @@ namespace Godot
if (sep == -1)
return @base;
- return @base + rs.substr(0, sep);
+ return @base + rs.Substr(0, sep);
}
// <summary>
@@ -478,7 +478,7 @@ namespace Godot
// </summary>
public static bool IsValidIpAddress(this string instance)
{
- string[] ip = instance.split(".");
+ string[] ip = instance.Split(".");
if (ip.Length != 4)
return false;
@@ -489,7 +489,7 @@ namespace Godot
if (!n.IsValidInteger())
return false;
- int val = n.to_int();
+ int val = n.ToInt();
if (val < 0 || val > 255)
return false;
}
@@ -571,7 +571,7 @@ namespace Godot
// <summary>
// Do a simple case insensitive expression match, using ? and * wildcards (see [method expr_match]).
// </summary>
- public static bool matchn(this string instance, string expr)
+ public static bool Matchn(this string instance, string expr)
{
return instance.ExprMatch(expr, false);
}
@@ -830,7 +830,7 @@ namespace Godot
// <summary>
// Split the string by a divisor string, return an array of the substrings. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
// </summary>
- public static string[] split(this string instance, string divisor, bool allow_empty = true)
+ public static string[] Split(this string instance, string divisor, bool allow_empty = true)
{
return instance.Split(new string[] { divisor }, StringSplitOptions.RemoveEmptyEntries);
}
@@ -838,7 +838,7 @@ namespace Godot
// <summary>
// Split the string in floats by using a divisor string, return an array of the substrings. Example "1,2.5,3" will return [1,2.5,3] if split by ",".
// </summary>
- public static float[] split_floats(this string instance, string divisor, bool allow_empty = true)
+ public static float[] SplitFloats(this string instance, string divisor, bool allow_empty = true)
{
List<float> ret = new List<float>();
int from = 0;
@@ -872,7 +872,7 @@ namespace Godot
// <summary>
// Return a copy of the string stripped of any non-printable character at the beginning and the end. The optional arguments are used to toggle stripping on the left and right edges respectively.
// </summary>
- public static string strip_edges(this string instance, bool left = true, bool right = true)
+ public static string StripEdges(this string instance, bool left = true, bool right = true)
{
if (left)
{
@@ -890,7 +890,7 @@ namespace Godot
// <summary>
// Return part of the string from the position [code]from[/code], with length [code]len[/code].
// </summary>
- public static string substr(this string instance, int from, int len)
+ public static string Substr(this string instance, int from, int len)
{
return instance.Substring(from, len);
}
@@ -898,7 +898,7 @@ namespace Godot
// <summary>
// Convert the String (which is a character array) to PoolByteArray (which is an array of bytes). The conversion is speeded up in comparison to to_utf8() with the assumption that all the characters the String contains are only ASCII characters.
// </summary>
- public static byte[] to_ascii(this string instance)
+ public static byte[] ToAscii(this string instance)
{
return Encoding.ASCII.GetBytes(instance);
}
@@ -906,7 +906,7 @@ namespace Godot
// <summary>
// Convert a string, containing a decimal number, into a [code]float[/code].
// </summary>
- public static float to_float(this string instance)
+ public static float ToFloat(this string instance)
{
return float.Parse(instance);
}
@@ -914,7 +914,7 @@ namespace Godot
// <summary>
// Convert a string, containing an integer number, into an [code]int[/code].
// </summary>
- public static int to_int(this string instance)
+ public static int ToInt(this string instance)
{
return int.Parse(instance);
}
@@ -922,7 +922,7 @@ namespace Godot
// <summary>
// Return the string converted to lowercase.
// </summary>
- public static string to_lower(this string instance)
+ public static string ToLower(this string instance)
{
return instance.ToLower();
}
@@ -930,7 +930,7 @@ namespace Godot
// <summary>
// Return the string converted to uppercase.
// </summary>
- public static string to_upper(this string instance)
+ public static string ToUpper(this string instance)
{
return instance.ToUpper();
}
@@ -938,7 +938,7 @@ namespace Godot
// <summary>
// Convert the String (which is an array of characters) to PoolByteArray (which is an array of bytes). The conversion is a bit slower than to_ascii(), but supports all UTF-8 characters. Therefore, you should prefer this function over to_ascii().
// </summary>
- public static byte[] to_utf8(this string instance)
+ public static byte[] ToUtf8(this string instance)
{
return Encoding.UTF8.GetBytes(instance);
}
@@ -946,7 +946,7 @@ namespace Godot
// <summary>
// Return a copy of the string with special characters escaped using the XML standard.
// </summary>
- public static string xml_escape(this string instance)
+ public static string XmlEscape(this string instance)
{
return SecurityElement.Escape(instance);
}
@@ -954,7 +954,7 @@ namespace Godot
// <summary>
// Return a copy of the string with escaped characters replaced by their meanings according to the XML standard.
// </summary>
- public static string xml_unescape(this string instance)
+ public static string XmlUnescape(this string instance)
{
return SecurityElement.FromString(instance).Text;
}
diff --git a/modules/mono/glue/cs_files/Transform.cs b/modules/mono/glue/cs_files/Transform.cs
index 5214100d36..9853721f98 100644
--- a/modules/mono/glue/cs_files/Transform.cs
+++ b/modules/mono/glue/cs_files/Transform.cs
@@ -24,7 +24,7 @@ namespace Godot
public Transform LookingAt(Vector3 target, Vector3 up)
{
Transform t = this;
- t.set_look_at(origin, target, up);
+ t.SetLookAt(origin, target, up);
return t;
}
@@ -43,7 +43,7 @@ namespace Godot
return new Transform(basis.Scaled(scale), origin * scale);
}
- public void set_look_at(Vector3 eye, Vector3 target, Vector3 up)
+ public void SetLookAt(Vector3 eye, Vector3 target, Vector3 up)
{
// Make rotation matrix
// Z vector
diff --git a/modules/mono/glue/cs_files/VERSION.txt b/modules/mono/glue/cs_files/VERSION.txt
index d00491fd7e..0cfbf08886 100755
--- a/modules/mono/glue/cs_files/VERSION.txt
+++ b/modules/mono/glue/cs_files/VERSION.txt
@@ -1 +1 @@
-1
+2
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 1ebef04561..0646580eaa 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -74,7 +74,31 @@ void gdmono_MonoPrintCallback(const char *string, mono_bool is_stdout) {
GDMono *GDMono::singleton = NULL;
+namespace {
+
+void setup_runtime_main_args() {
+ CharString execpath = OS::get_singleton()->get_executable_path().utf8();
+
+ List<String> cmdline_args = OS::get_singleton()->get_cmdline_args();
+
+ List<CharString> cmdline_args_utf8;
+ Vector<char *> main_args;
+ main_args.resize(cmdline_args.size() + 1);
+
+ main_args[0] = execpath.ptrw();
+
+ int i = 1;
+ for (List<String>::Element *E = cmdline_args.front(); E; E = E->next()) {
+ CharString &stored = cmdline_args_utf8.push_back(E->get().utf8())->get();
+ main_args[i] = stored.ptrw();
+ i++;
+ }
+
+ mono_runtime_set_main_args(main_args.size(), main_args.ptrw());
+}
+
#ifdef DEBUG_ENABLED
+
static bool _wait_for_debugger_msecs(uint32_t p_msecs) {
do {
@@ -96,9 +120,7 @@ static bool _wait_for_debugger_msecs(uint32_t p_msecs) {
return mono_is_debugger_attached();
}
-#endif
-#ifdef DEBUG_ENABLED
void gdmono_debug_init() {
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
@@ -125,8 +147,11 @@ void gdmono_debug_init() {
};
mono_jit_parse_options(2, (char **)options);
}
+
#endif
+} // namespace
+
void GDMono::initialize() {
ERR_FAIL_NULL(Engine::get_singleton());
@@ -179,6 +204,8 @@ void GDMono::initialize() {
GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread());
+ setup_runtime_main_args(); // Required for System.Environment.GetCommandLineArgs
+
runtime_initialized = true;
OS::get_singleton()->print("Mono: Runtime initialized\n");
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 2ce1b0a9df..d062d56dcf 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -85,19 +85,22 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d
path = search_dir.plus_file(name);
if (FileAccess::exists(path)) {
res = _load_assembly_from(name.get_basename(), path, refonly);
- break;
+ if (res != NULL)
+ break;
}
} else {
path = search_dir.plus_file(name + ".dll");
if (FileAccess::exists(path)) {
res = _load_assembly_from(name, path, refonly);
- break;
+ if (res != NULL)
+ break;
}
path = search_dir.plus_file(name + ".exe");
if (FileAccess::exists(path)) {
res = _load_assembly_from(name, path, refonly);
- break;
+ if (res != NULL)
+ break;
}
}
}
@@ -123,6 +126,7 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse
const char *rootdir = mono_assembly_getrootdir();
if (rootdir) {
search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5"));
+ search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5").plus_file("Facades"));
}
if (assemblies_path) {
@@ -151,19 +155,15 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse
path = search_dir.plus_file(name);
if (FileAccess::exists(path)) {
res = _load_assembly_from(name.get_basename(), path, refonly);
- break;
+ if (res != NULL)
+ break;
}
} else {
path = search_dir.plus_file(name + ".dll");
if (FileAccess::exists(path)) {
res = _load_assembly_from(name, path, refonly);
- break;
- }
-
- path = search_dir.plus_file(name + ".exe");
- if (FileAccess::exists(path)) {
- res = _load_assembly_from(name, path, refonly);
- break;
+ if (res != NULL)
+ break;
}
}
}
@@ -212,14 +212,15 @@ Error GDMonoAssembly::load(bool p_refonly) {
String image_filename(path);
- MonoImageOpenStatus status;
+ MonoImageOpenStatus status = MONO_IMAGE_OK;
image = mono_image_open_from_data_with_name(
(char *)&data[0], data.size(),
true, &status, refonly,
image_filename.utf8().get_data());
- ERR_FAIL_COND_V(status != MONO_IMAGE_OK || image == NULL, ERR_FILE_CANT_OPEN);
+ ERR_FAIL_COND_V(status != MONO_IMAGE_OK, ERR_FILE_CANT_OPEN);
+ ERR_FAIL_NULL_V(image, ERR_FILE_CANT_OPEN);
#ifdef DEBUG_ENABLED
String pdb_path(path + ".pdb");