diff --git a/modules/cscript/SCsub b/modules/cscript/SCsub new file mode 100644 index 000000000..a4af0cf66 --- /dev/null +++ b/modules/cscript/SCsub @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_gdscript = env_modules.Clone() + +env_gdscript.add_source_files(env.modules_sources, "*.cpp") + +if env["tools"]: + env_gdscript.add_source_files(env.modules_sources, "./editor/*.cpp") + \ No newline at end of file diff --git a/modules/cscript/config.py b/modules/cscript/config.py new file mode 100644 index 000000000..f22ac6711 --- /dev/null +++ b/modules/cscript/config.py @@ -0,0 +1,21 @@ + +def can_build(env, platform): + #return True + #not yet + return False + + +def configure(env): + pass + + +def get_doc_classes(): + return [ + "@CScript", + "CScript", + "CScriptFunctionState", + ] + + +def get_doc_path(): + return "doc_classes" diff --git a/modules/cscript/cscript.cpp b/modules/cscript/cscript.cpp new file mode 100644 index 000000000..db110202a --- /dev/null +++ b/modules/cscript/cscript.cpp @@ -0,0 +1,2293 @@ +/*************************************************************************/ +/* gdscript.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "cscript.h" + +#include "core/core_string_names.h" +#include "core/engine.h" +#include "core/global_constants.h" +#include "core/io/file_access_encrypted.h" +#include "core/os/file_access.h" +#include "core/os/os.h" +#include "core/project_settings.h" +#include "cscript_compiler.h" + +/////////////////////////// + +GDScriptNativeClass::GDScriptNativeClass(const StringName &p_name) { + name = p_name; +} + +bool GDScriptNativeClass::_get(const StringName &p_name, Variant &r_ret) const { + bool ok; + int v = ClassDB::get_integer_constant(name, p_name, &ok); + + if (ok) { + r_ret = v; + return true; + } else { + return false; + } +} + +void GDScriptNativeClass::_bind_methods() { + ClassDB::bind_method(D_METHOD("new"), &GDScriptNativeClass::_new); +} + +Variant GDScriptNativeClass::_new() { + Object *o = instance(); + ERR_FAIL_COND_V_MSG(!o, Variant(), "Class type: '" + String(name) + "' is not instantiable."); + + Reference *ref = Object::cast_to(o); + if (ref) { + return REF(ref); + } else { + return o; + } +} + +Object *GDScriptNativeClass::instance() { + return ClassDB::instance(name); +} + +void GDScript::_clear_pending_func_states() { + GDScriptLanguage::get_singleton()->lock.lock(); + while (SelfList *E = pending_func_states.first()) { + // Order matters since clearing the stack may already cause + // the GDSCriptFunctionState to be destroyed and thus removed from the list. + pending_func_states.remove(E); + E->self()->_clear_stack(); + } + GDScriptLanguage::get_singleton()->lock.unlock(); +} + +GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) { + /* STEP 1, CREATE */ + + GDScriptInstance *instance = memnew(GDScriptInstance); + instance->base_ref = p_isref; + instance->members.resize(member_indices.size()); + instance->script = Ref(this); + instance->owner = p_owner; +#ifdef DEBUG_ENABLED + //needed for hot reloading + for (Map::Element *E = member_indices.front(); E; E = E->next()) { + instance->member_indices_cache[E->key()] = E->get().index; + } +#endif + instance->owner->set_script_instance(instance); + + /* STEP 2, INITIALIZE AND CONSTRUCT */ + + GDScriptLanguage::singleton->lock.lock(); + instances.insert(instance->owner); + GDScriptLanguage::singleton->lock.unlock(); + + initializer->call(instance, p_args, p_argcount, r_error); + + if (r_error.error != Variant::CallError::CALL_OK) { + instance->script = Ref(); + instance->owner->set_script_instance(nullptr); +#ifndef NO_THREADS + GDScriptLanguage::singleton->lock.lock(); +#endif + instances.erase(p_owner); +#ifndef NO_THREADS + GDScriptLanguage::singleton->lock.unlock(); +#endif + + ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, nullptr); //error constructing + } + + //@TODO make thread safe + return instance; +} + +Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { + /* STEP 1, CREATE */ + + if (!valid) { + r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + + r_error.error = Variant::CallError::CALL_OK; + REF ref; + Object *owner = nullptr; + + GDScript *_baseptr = this; + while (_baseptr->_base) { + _baseptr = _baseptr->_base; + } + + ERR_FAIL_COND_V(_baseptr->native.is_null(), Variant()); + if (_baseptr->native.ptr()) { + owner = _baseptr->native->instance(); + } else { + owner = memnew(Reference); //by default, no base means use reference + } + ERR_FAIL_COND_V_MSG(!owner, Variant(), "Can't inherit from a virtual class."); + + Reference *r = Object::cast_to(owner); + if (r) { + ref = REF(r); + } + + GDScriptInstance *instance = _create_instance(p_args, p_argcount, owner, r != nullptr, r_error); + if (!instance) { + if (ref.is_null()) { + memdelete(owner); //no owner, sorry + } + return Variant(); + } + + if (ref.is_valid()) { + return ref; + } else { + return owner; + } +} + +bool GDScript::can_instance() const { +#ifdef TOOLS_ENABLED + return valid && (tool || ScriptServer::is_scripting_enabled()); +#else + return valid; +#endif +} + +Ref