獲取屬性列表
今天摟草打兔,取得了腳本內(nèi)容
因?yàn)橐涯苋〉脤傩灾担蔷驮龠M(jìn)一步,取得屬性名列表
if (SameText(drGet.propertyName, "propertyNames", DRGRAPH_FLAG_CASESENSITIVE)) {
List<PropertyInfo> *p_list = new List<PropertyInfo>;
bool p_reversed = true;
destObject->get_property_list(p_list, p_reversed);
cofs << "OK";
for (List<PropertyInfo>::Iterator it = p_list->begin(); it != p_list->end(); ++it) {
Variant value = destObject->get(it->name);
cofs << str_format(U"%s[%s] = %s", it->name.utf8().get_data(),
VarType2String(it->type).c_str(), value.operator String().utf8().get_data());
}
delete p_list;
cofs << GetObjectHint(destObject);
}
相應(yīng)地,可以取得函數(shù)名列表、子對(duì)象列表
if (SameText(drGet.propertyName, "methodNames", DRGRAPH_FLAG_CASESENSITIVE)) {
List<MethodInfo> *p_list = new List<MethodInfo>;
destObject->get_method_list(p_list);
cofs << "OK";
for (List<MethodInfo>::Iterator it = p_list->begin(); it != p_list->end(); ++it) {
String content = it->name + "(";
for (List<PropertyInfo>::Iterator iter = it->arguments.begin(); iter != it->arguments.end(); ++iter) {
if (iter != it->arguments.begin())
content += ", ";
content += str_format("%s %s", VarType2String(iter->type).c_str(), iter->name.utf8().get_data()).c_str();
}
content += ")";
cofs << content;
}
delete p_list;
cofs << GetObjectHint(destObject);
}
if (SameText(drGet.propertyName, "childNames", DRGRAPH_FLAG_CASESENSITIVE)) {
if (Node *node = dynamic_cast<Node *>(destObject)) {
int count = node->get_child_count();
for (int i = 0; i < count; ++i) {
Node *subNode = node->get_child(i);
cofs << str_format(U"%s[%s]", subNode->get_name().operator String().utf8().get_data(),
subNode->get_class_name().operator String().utf8().get_data());
}
cofs << GetObjectHint(destObject);
}
}
其中,獲取對(duì)象信息(GetObjectHint)是期望能顯示對(duì)象的一些相應(yīng)信息
#define CAST(T, ptr) dynamic_cast<T>(static_cast<T>(ptr))
std::string GetObjectHint(void* ptr) {
String result = U"未處理對(duì)象";
if (Object *object = CAST(Object *, ptr)) {
result = str_format(U" ---==== [%s]類型對(duì)象 0X%08x ====---", object->get_class_name().operator String().utf8().get_data(), int(ptr));
if (Node *node = CAST(Node *, ptr)) {
String path = node->get_name();
Node *parent = node->get_parent();
while (parent) {
path = parent->get_name().operator String() + U"." + path;
parent = parent->get_parent();
}
result += U":\n\t\t\t\t\t\t路徑信息:";
result += path + U"\n\t\t\t\t\t\t子對(duì)象信息:";
int count = node->get_child_count();
for (int i = 0; i < count; ++i) {
Node *subNode = node->get_child(i);
result += str_format(U" %s[%s]", String2std(subNode->get_name().operator String()).c_str(),
String2std(subNode->get_class_name().operator String()).c_str());
}
}
} else if (Engine *engine = CAST(Engine *, ptr)) {
result = str_format(U"[Engine]類型對(duì)象 0X%08x", int(ptr));
}
return String2std(result);
}
測試一下,取得根節(jié)點(diǎn)(Book)的所有屬性名: Book.propertyNames
261. 15:58:53:368 > 【主線程】 > [Pipe.發(fā)送] > 發(fā)送數(shù)據(jù)中內(nèi)容[DrGraph.78: Request - wait 1000 ms]:
[int]類型 > 值 = 2
[UnicodeString]類型 > 值 = Book
[UnicodeString]類型 > 值 = propertyNames
262. 15:58:53:614 > 【主線程】 > [Pipe.Read] > 發(fā)送數(shù)據(jù)[DrGraph.78: Request - wait 1000 ms]成功返回 2396 字節(jié)... > PIPE響應(yīng)中內(nèi)容[godot -> DrGraph.78: Response - no return]:
[int]類型 > 值 = 3
[UnicodeString]類型 > 值 = OK
[UnicodeString]類型 > 值 = book.gd[NIL] = <null>
[UnicodeString]類型 > 值 = singlePage[BOOL] = false
[UnicodeString]類型 > 值 = middleBarWidth[INT] = 0
[UnicodeString]類型 > 值 = shader_rect[OBJECT] = ShaderRect:<ColorRect#26944209309>
[UnicodeString]類型 > 值 = currentPageMode[BOOL] = false
[UnicodeString]類型 > 值 = currentAreaType[INT] = 5
[UnicodeString]類型 > 值 = triggleAreaMoment[INT] = 745493
[UnicodeString]類型 > 值 = currentPageIndex[INT] = 30
[UnicodeString]類型 > 值 = pageCount[INT] = 100
[UnicodeString]類型 > 值 = pageImgPath[STRING] = res://Pages/
[UnicodeString]類型 > 值 = leftMouseDownMoment[INT] = 0
[UnicodeString]類型 > 值 = underAutoTurnPage[BOOL] = false
[UnicodeString]類型 > 值 = leftMouseDownPos[VECTOR2] = (0, 0)
[UnicodeString]類型 > 值 = dllStream[OBJECT] = <DllStream#67024979098>
[UnicodeString]類型 > 值 = AutoTurnObject[OBJECT] = <RefCounted#-9223372009692462686>
[UnicodeString]類型 > 值 = Node2D[NIL] = <null>
[UnicodeString]類型 > 值 = Transform[NIL] = <null>
[UnicodeString]類型 > 值 = position[VECTOR2] = (0, 0)
[UnicodeString]類型 > 值 = rotation[FLOAT] = 0
[UnicodeString]類型 > 值 = rotation_degrees[FLOAT] = 0
[UnicodeString]類型 > 值 = scale[VECTOR2] = (1, 1)
[UnicodeString]類型 > 值 = skew[FLOAT] = 0
[UnicodeString]類型 > 值 = transform[TRANSFORM2D] = [X: (1, 0), Y: (0, 1), O: (0, 0)]
[UnicodeString]類型 > 值 = global_position[VECTOR2] = (0, 0)
[UnicodeString]類型 > 值 = global_rotation[FLOAT] = 0
[UnicodeString]類型 > 值 = global_rotation_degrees[FLOAT] = 0
[UnicodeString]類型 > 值 = global_scale[VECTOR2] = (1, 1)
[UnicodeString]類型 > 值 = global_skew[FLOAT] = 0
[UnicodeString]類型 > 值 = global_transform[TRANSFORM2D] = [X: (1, 0), Y: (0, 1), O: (0, 0)]
[UnicodeString]類型 > 值 = CanvasItem[NIL] = <null>
[UnicodeString]類型 > 值 = Visibility[NIL] = <null>
[UnicodeString]類型 > 值 = visible[BOOL] = true
[UnicodeString]類型 > 值 = modulate[COLOR] = (1, 1, 1, 1)
[UnicodeString]類型 > 值 = self_modulate[COLOR] = (1, 1, 1, 1)
[UnicodeString]類型 > 值 = show_behind_parent[BOOL] = false
[UnicodeString]類型 > 值 = top_level[BOOL] = false
[UnicodeString]類型 > 值 = clip_children[INT] = 0
[UnicodeString]類型 > 值 = light_mask[INT] = 1
[UnicodeString]類型 > 值 = visibility_layer[INT] = 1
[UnicodeString]類型 > 值 = Ordering[NIL] = <null>
[UnicodeString]類型 > 值 = z_index[INT] = 0
[UnicodeString]類型 > 值 = z_as_relative[BOOL] = true
[UnicodeString]類型 > 值 = y_sort_enabled[BOOL] = false
[UnicodeString]類型 > 值 = Texture[NIL] = <null>
[UnicodeString]類型 > 值 = texture_filter[INT] = 0
[UnicodeString]類型 > 值 = texture_repeat[INT] = 0
[UnicodeString]類型 > 值 = Material[NIL] = <null>
[UnicodeString]類型 > 值 = material[OBJECT] = <Object#null>
[UnicodeString]類型 > 值 = use_parent_material[BOOL] = false
[UnicodeString]類型 > 值 = Node[NIL] = <null>
[UnicodeString]類型 > 值 = _import_path[NODE_PATH] =
[UnicodeString]類型 > 值 = name[STRING_NAME] = Book
[UnicodeString]類型 > 值 = unique_name_in_owner[BOOL] = false
[UnicodeString]類型 > 值 = scene_file_path[STRING] = res://book.tscn
[UnicodeString]類型 > 值 = owner[OBJECT] = <Object#null>
[UnicodeString]類型 > 值 = multiplayer[OBJECT] = <SceneMultiplayer#-9223372011168857674>
[UnicodeString]類型 > 值 = Process[NIL] = <null>
[UnicodeString]類型 > 值 = process_mode[INT] = 0
[UnicodeString]類型 > 值 = process_priority[INT] = 0
[UnicodeString]類型 > 值 = Editor Description[NIL] = <null>
[UnicodeString]類型 > 值 = editor_description[STRING] =
[UnicodeString]類型 > 值 = script[OBJECT] = <GDScript#-9223372010984308353>
[UnicodeString]類型 > 值 = ---==== [Node2D]類型對(duì)象 0X4d7c5600 ====---:
路徑信息:root.Book
子對(duì)象信息: LeftPage[Sprite2D] RightPage[Sprite2D] ShaderRect[ColorRect] LeftButton[Button] RightButton[Button] AutoTurnTimer[Timer] DrGraph[Node]
看到script屬性:[UnicodeString]類型 > 值 = script[OBJECT] = <GDScript#-9223372010984308353>
那就再取得Book.script.propertyNames來看下,結(jié)果發(fā)現(xiàn)返回了腳本內(nèi)容
仔細(xì)一看,是屬性 script/source?的值。那就單獨(dú)看一下該屬性: Book.script.script/source,果然得到相應(yīng)腳本內(nèi)容
倒是有點(diǎn)意思,屬性名稱為 script/source
源碼分析
在源碼中查找?script/source,在gdscript.cpp中有兩處,應(yīng)該是這個(gè)
void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
原來GDScript對(duì)象返回屬性名稱列表時(shí),就添加了這么一個(gè)玩意
這樣取屬性名稱列表時(shí),就有一個(gè)名為?script/source?的屬性
下來看看get該屬性時(shí)具體有哪些動(dòng)作,調(diào)試跟進(jìn)
Variant Object::get(const StringName &p_name, bool *r_valid) const {
Variant ret;
if (script_instance) {
if (script_instance->get(p_name, ret)) {
if (r_valid) {
*r_valid = true;
}
return ret;
}
}
if (_extension && _extension->get) {
// C style pointer casts should never trigger a compiler warning because the risk is assumed by the user, so GCC should keep quiet about it.
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
#endif
if (_extension->get(_extension_instance, (const GDExtensionStringNamePtr)&p_name, (GDExtensionVariantPtr)&ret)) {
if (r_valid) {
*r_valid = true;
}
return ret;
}
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
}
// Try built-in getter.
{
if (ClassDB::get_property(const_cast<Object *>(this), p_name, ret)) {
if (r_valid) {
*r_valid = true;
}
return ret;
}
}
if (p_name == CoreStringNames::get_singleton()->_script) {
ret = get_script();
if (r_valid) {
*r_valid = true;
}
return ret;
}
const Variant *const *V = metadata_properties.getptr(p_name);
if (V) {
ret = **V;
if (r_valid) {
*r_valid = true;
}
return ret;
} else {
#ifdef TOOLS_ENABLED
if (script_instance) {
bool valid;
ret = script_instance->property_get_fallback(p_name, &valid);
if (valid) {
if (r_valid) {
*r_valid = true;
}
return ret;
}
}
#endif
// Something inside the object... :|
bool success = _getv(p_name, ret);
if (success) {
if (r_valid) {
*r_valid = true;
}
return ret;
}
if (r_valid) {
*r_valid = false;
}
return Variant();
}
}
具體是在?bool success = _getv(p_name, ret);?中處理,直接在GDScript::_get中實(shí)質(zhì)處理
bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
{
const GDScript *top = this;
while (top) {
{
HashMap<StringName, Variant>::ConstIterator E = top->constants.find(p_name);
if (E) {
r_ret = E->value;
return true;
}
}
{
HashMap<StringName, Ref<GDScript>>::ConstIterator E = subclasses.find(p_name);
if (E) {
r_ret = E->value;
return true;
}
}
top = top->_base;
}
if (p_name == GDScriptLanguage::get_singleton()->strings._script_source) {
r_ret = get_source_code();
return true;
}
}
return false;
}
調(diào)試可知,在constants中,保存了各常量信息[key / value]
?而subclasses中保存了自定義的結(jié)構(gòu)(類)
?最終在get_source_code函數(shù)中,直接返回source
String GDScript::get_source_code() const {
return source;
}
也就是腳本文本內(nèi)容。
就這。
獲取腳本中變量值
從上面可看到屬性獲取邏輯,在script/source屬性獲取過程中,檢查了constants和subclasses,那試試能否獲取其中的變量值
發(fā)送Book.script.AREA_OUT,結(jié)果成功
自定義結(jié)構(gòu)
繼續(xù)測試自定義結(jié)構(gòu)
發(fā)送Book.script.TAutoTurn,結(jié)果返回為對(duì)象:?<GDScript#-9223372010833313372>
279. 16:18:07:517 > 【主線程】 > [Pipe.發(fā)送] > 發(fā)送數(shù)據(jù)中內(nèi)容[DrGraph.87: Request - wait 1000 ms]:
[int]類型 > 值 = 2
[UnicodeString]類型 > 值 = Book.script
[UnicodeString]類型 > 值 = TAutoTurn
280. 16:18:07:617 > 【主線程】 > [Pipe.Read] > 發(fā)送數(shù)據(jù)[DrGraph.87: Request - wait 1000 ms]成功返回 168 字節(jié)... > PIPE響應(yīng)中內(nèi)容[godot -> DrGraph.87: Response - no return]:
[int]類型 > 值 = 3
[UnicodeString]類型 > 值 = OK
[UnicodeString]類型 > 值 = <GDScript#-9223372010833313372>
檢查該對(duì)象屬性名列表
281. 16:18:21:175 > 【主線程】 > [Pipe.發(fā)送] > 發(fā)送數(shù)據(jù)中內(nèi)容[DrGraph.88: Request - wait 1000 ms]:
[int]類型 > 值 = 2
[UnicodeString]類型 > 值 = Book.script.TAutoTurn
[UnicodeString]類型 > 值 = propertyNames
282. 16:18:21:272 > 【主線程】 > [Pipe.Read] > 發(fā)送數(shù)據(jù)[DrGraph.88: Request - wait 1000 ms]成功返回 423 字節(jié)... > PIPE響應(yīng)中內(nèi)容[godot -> DrGraph.88: Response - no return]:
[int]類型 > 值 = 3
[UnicodeString]類型 > 值 = OK
[UnicodeString]類型 > 值 = GDScript[NIL] = <null>
[UnicodeString]類型 > 值 = script/source[STRING] =
[UnicodeString]類型 > 值 = Script[NIL] = <null>
[UnicodeString]類型 > 值 = source_code[STRING] =
[UnicodeString]類型 > 值 = Resource[NIL] = <null>
[UnicodeString]類型 > 值 = Resource[NIL] = <null>
[UnicodeString]類型 > 值 = resource_local_to_scene[BOOL] = false
[UnicodeString]類型 > 值 = resource_path[STRING] =
[UnicodeString]類型 > 值 = resource_name[STRING] =
[UnicodeString]類型 > 值 = RefCounted[NIL] = <null>
[UnicodeString]類型 > 值 = ---==== [GDScript]類型對(duì)象 0X4d771310 ====---:
路徑信息:
子對(duì)象信息:
也有script/source、source_code屬性,不過好象沒內(nèi)容,測試也還是真沒內(nèi)容返回
文章來源:http://www.zghlxwxcb.cn/news/detail-606137.html
?但能取得這些信息,感覺已經(jīng)足夠用的了文章來源地址http://www.zghlxwxcb.cn/news/detail-606137.html
到了這里,關(guān)于Godot 4 源碼分析 - 獲取腳本的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!