Explorar o código

More visual script improvements
-Added anti-aliasing on lines
-Improved draw performance enormously
-Removed sequence ports for most nodes, current visual scripts will likely be broken now. Sorry!

Juan Linietsky %!s(int64=9) %!d(string=hai) anos
pai
achega
fb4d6d1db0

+ 12 - 2
drivers/gles2/rasterizer_gles2.cpp

@@ -8196,7 +8196,7 @@ RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_tex
 	return NULL;
 	return NULL;
 }
 }
 
 
-void RasterizerGLES2::canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width) {
+void RasterizerGLES2::canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased) {
 
 
 	_bind_canvas_texture(RID());
 	_bind_canvas_texture(RID());
 	Color c=p_color;
 	Color c=p_color;
@@ -8208,8 +8208,18 @@ void RasterizerGLES2::canvas_draw_line(const Point2& p_from, const Point2& p_to,
 		Vector3(p_to.x,p_to.y,0)
 		Vector3(p_to.x,p_to.y,0)
 	};
 	};
 
 
+#ifdef GLEW_ENABLED
+	if (p_antialiased)
+		glEnable(GL_LINE_SMOOTH);
+#endif
 	glLineWidth(p_width);
 	glLineWidth(p_width);
 	_draw_primitive(2,verts,0,0,0);
 	_draw_primitive(2,verts,0,0,0);
+
+#ifdef GLEW_ENABLED
+	if (p_antialiased)
+		glDisable(GL_LINE_SMOOTH);
+#endif
+
 	_rinfo.ci_draw_commands++;
 	_rinfo.ci_draw_commands++;
 }
 }
 
 
@@ -9135,7 +9145,7 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem
 			case CanvasItem::Command::TYPE_LINE: {
 			case CanvasItem::Command::TYPE_LINE: {
 
 
 				CanvasItem::CommandLine* line = static_cast<CanvasItem::CommandLine*>(c);
 				CanvasItem::CommandLine* line = static_cast<CanvasItem::CommandLine*>(c);
-				canvas_draw_line(line->from,line->to,line->color,line->width);
+				canvas_draw_line(line->from,line->to,line->color,line->width,line->antialiased);
 			} break;
 			} break;
 			case CanvasItem::Command::TYPE_RECT: {
 			case CanvasItem::Command::TYPE_RECT: {
 
 

+ 1 - 1
drivers/gles2/rasterizer_gles2.h

@@ -1633,7 +1633,7 @@ public:
 	virtual void canvas_begin_rect(const Matrix32& p_transform);
 	virtual void canvas_begin_rect(const Matrix32& p_transform);
 	virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect);
 	virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect);
 	virtual void canvas_end_rect();
 	virtual void canvas_end_rect();
-	virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width);
+	virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased);
 	virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate);
 	virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate);
 	virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1));
 	virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1));
 	virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width);
 	virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width);

+ 2 - 0
modules/visual_script/register_types.cpp

@@ -69,9 +69,11 @@ void register_visual_script_types() {
 	ObjectTypeDB::register_type<VisualScriptComment>();
 	ObjectTypeDB::register_type<VisualScriptComment>();
 	ObjectTypeDB::register_type<VisualScriptConstructor>();
 	ObjectTypeDB::register_type<VisualScriptConstructor>();
 	ObjectTypeDB::register_type<VisualScriptLocalVar>();
 	ObjectTypeDB::register_type<VisualScriptLocalVar>();
+	ObjectTypeDB::register_type<VisualScriptLocalVarSet>();
 	ObjectTypeDB::register_type<VisualScriptInputAction>();
 	ObjectTypeDB::register_type<VisualScriptInputAction>();
 	ObjectTypeDB::register_type<VisualScriptDeconstruct>();
 	ObjectTypeDB::register_type<VisualScriptDeconstruct>();
 	ObjectTypeDB::register_type<VisualScriptPreload>();
 	ObjectTypeDB::register_type<VisualScriptPreload>();
+	ObjectTypeDB::register_type<VisualScriptTypeCast>();
 
 
 
 
 	ObjectTypeDB::register_type<VisualScriptFunctionCall>();
 	ObjectTypeDB::register_type<VisualScriptFunctionCall>();

+ 155 - 56
modules/visual_script/visual_script.cpp

@@ -106,6 +106,19 @@ void VisualScriptNode::_bind_methods() {
 	ADD_SIGNAL(MethodInfo("ports_changed"));
 	ADD_SIGNAL(MethodInfo("ports_changed"));
 }
 }
 
 
+VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess* p_inputs,int p_output) const {
+
+	PropertyInfo pinfo = get_output_value_port_info(p_output);
+
+	TypeGuess tg;
+
+	tg.type=pinfo.type;
+	if (pinfo.hint==PROPERTY_HINT_RESOURCE_TYPE) {
+		tg.obj_type=pinfo.hint_string;
+	}
+
+	return tg;
+}
 
 
 Ref<VisualScript> VisualScriptNode::get_visual_script() const {
 Ref<VisualScript> VisualScriptNode::get_visual_script() const {
 
 
@@ -133,15 +146,15 @@ VisualScriptNodeInstance::VisualScriptNodeInstance() {
 VisualScriptNodeInstance::~VisualScriptNodeInstance() {
 VisualScriptNodeInstance::~VisualScriptNodeInstance() {
 
 
 	if (sequence_outputs) {
 	if (sequence_outputs) {
-		memdelete(sequence_outputs);
+		memdelete_arr(sequence_outputs);
 	}
 	}
 
 
 	if (input_ports) {
 	if (input_ports) {
-		memdelete(input_ports);
+		memdelete_arr(input_ports);
 	}
 	}
 
 
 	if (output_ports) {
 	if (output_ports) {
-		memdelete(output_ports);
+		memdelete_arr(output_ports);
 	}
 	}
 
 
 }
 }
@@ -564,7 +577,7 @@ void VisualScript::get_data_connection_list(const StringName& p_func,List<DataCo
 	}
 	}
 }
 }
 
 
-void VisualScript::add_variable(const StringName& p_name,const Variant& p_default_value) {
+void VisualScript::add_variable(const StringName& p_name,const Variant& p_default_value,bool p_export) {
 
 
 	ERR_FAIL_COND( instances.size() );
 	ERR_FAIL_COND( instances.size() );
 	ERR_FAIL_COND(!String(p_name).is_valid_identifier());
 	ERR_FAIL_COND(!String(p_name).is_valid_identifier());
@@ -575,6 +588,7 @@ void VisualScript::add_variable(const StringName& p_name,const Variant& p_defaul
 	v.info.type=p_default_value.get_type();
 	v.info.type=p_default_value.get_type();
 	v.info.name=p_name;
 	v.info.name=p_name;
 	v.info.hint=PROPERTY_HINT_NONE;
 	v.info.hint=PROPERTY_HINT_NONE;
+	v._export=p_export;
 
 
 	variables[p_name]=v;
 	variables[p_name]=v;
 	script_variable_remap[SCRIPT_VARIABLES_PREFIX+String(p_name)]=p_name;
 	script_variable_remap[SCRIPT_VARIABLES_PREFIX+String(p_name)]=p_name;
@@ -638,6 +652,21 @@ PropertyInfo VisualScript::get_variable_info(const StringName& p_name) const{
 	return variables[p_name].info;
 	return variables[p_name].info;
 }
 }
 
 
+void VisualScript::set_variable_export(const StringName& p_name,bool p_export) {
+
+	ERR_FAIL_COND(!variables.has(p_name));
+
+	variables[p_name]._export=p_export;
+}
+
+bool VisualScript::get_variable_export(const StringName& p_name) const {
+
+	ERR_FAIL_COND_V(!variables.has(p_name),false);
+	return variables[p_name]._export;
+
+}
+
+
 void VisualScript::_set_variable_info(const StringName& p_name,const Dictionary& p_info) {
 void VisualScript::_set_variable_info(const StringName& p_name,const Dictionary& p_info) {
 
 
 	PropertyInfo pinfo;
 	PropertyInfo pinfo;
@@ -1067,7 +1096,8 @@ void VisualScript::get_script_property_list(List<PropertyInfo> *p_list) const {
 	get_variable_list(&vars);
 	get_variable_list(&vars);
 
 
 	for (List<StringName>::Element *E=vars.front();E;E=E->next()) {
 	for (List<StringName>::Element *E=vars.front();E;E=E->next()) {
-
+		if (!variables[E->get()]._export)
+			continue;
 		p_list->push_back(variables[E->get()].info);
 		p_list->push_back(variables[E->get()].info);
 	}
 	}
 }
 }
@@ -1088,6 +1118,7 @@ void VisualScript::_set_data(const Dictionary& p_data) {
 		add_variable(name);
 		add_variable(name);
 		_set_variable_info(name,v);
 		_set_variable_info(name,v);
 		set_variable_default_value(name,v["default_value"]);
 		set_variable_default_value(name,v["default_value"]);
+		set_variable_export(name,v.has("export") && bool(v["export"]));
 
 
 	}
 	}
 
 
@@ -1158,6 +1189,7 @@ Dictionary VisualScript::_get_data() const{
 		Dictionary var = _get_variable_info(E->key());
 		Dictionary var = _get_variable_info(E->key());
 		var["name"]=E->key(); //make sure it's the right one
 		var["name"]=E->key(); //make sure it's the right one
 		var["default_value"]=E->get().default_value;
 		var["default_value"]=E->get().default_value;
+		var["export"]=E->get()._export;
 		vars.push_back(var);
 		vars.push_back(var);
 	}
 	}
 	d["variables"]=vars;
 	d["variables"]=vars;
@@ -1268,13 +1300,15 @@ void VisualScript::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("data_disconnect","func","from_node","from_port","to_node","to_port"),&VisualScript::data_disconnect);
 	ObjectTypeDB::bind_method(_MD("data_disconnect","func","from_node","from_port","to_node","to_port"),&VisualScript::data_disconnect);
 	ObjectTypeDB::bind_method(_MD("has_data_connection","func","from_node","from_port","to_node","to_port"),&VisualScript::has_data_connection);
 	ObjectTypeDB::bind_method(_MD("has_data_connection","func","from_node","from_port","to_node","to_port"),&VisualScript::has_data_connection);
 
 
-	ObjectTypeDB::bind_method(_MD("add_variable","name","default_value"),&VisualScript::add_variable,DEFVAL(Variant()));
+	ObjectTypeDB::bind_method(_MD("add_variable","name","default_value","export"),&VisualScript::add_variable,DEFVAL(Variant()),DEFVAL(false));
 	ObjectTypeDB::bind_method(_MD("has_variable","name"),&VisualScript::has_variable);
 	ObjectTypeDB::bind_method(_MD("has_variable","name"),&VisualScript::has_variable);
 	ObjectTypeDB::bind_method(_MD("remove_variable","name"),&VisualScript::remove_variable);
 	ObjectTypeDB::bind_method(_MD("remove_variable","name"),&VisualScript::remove_variable);
 	ObjectTypeDB::bind_method(_MD("set_variable_default_value","name","value"),&VisualScript::set_variable_default_value);
 	ObjectTypeDB::bind_method(_MD("set_variable_default_value","name","value"),&VisualScript::set_variable_default_value);
 	ObjectTypeDB::bind_method(_MD("get_variable_default_value","name"),&VisualScript::get_variable_default_value);
 	ObjectTypeDB::bind_method(_MD("get_variable_default_value","name"),&VisualScript::get_variable_default_value);
 	ObjectTypeDB::bind_method(_MD("set_variable_info","name","value"),&VisualScript::_set_variable_info);
 	ObjectTypeDB::bind_method(_MD("set_variable_info","name","value"),&VisualScript::_set_variable_info);
 	ObjectTypeDB::bind_method(_MD("get_variable_info","name"),&VisualScript::_get_variable_info);
 	ObjectTypeDB::bind_method(_MD("get_variable_info","name"),&VisualScript::_get_variable_info);
+	ObjectTypeDB::bind_method(_MD("set_variable_export","name","enable"),&VisualScript::set_variable_export);
+	ObjectTypeDB::bind_method(_MD("get_variable_export","name"),&VisualScript::get_variable_export);
 	ObjectTypeDB::bind_method(_MD("rename_variable","name","new_name"),&VisualScript::rename_variable);
 	ObjectTypeDB::bind_method(_MD("rename_variable","name","new_name"),&VisualScript::rename_variable);
 
 
 	ObjectTypeDB::bind_method(_MD("add_custom_signal","name"),&VisualScript::add_custom_signal);
 	ObjectTypeDB::bind_method(_MD("add_custom_signal","name"),&VisualScript::add_custom_signal);
@@ -1351,6 +1385,8 @@ void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) c
 
 
 	for (const Map<StringName,VisualScript::Variable>::Element *E=script->variables.front();E;E=E->next()) {
 	for (const Map<StringName,VisualScript::Variable>::Element *E=script->variables.front();E;E=E->next()) {
 
 
+		if (!E->get()._export)
+			continue;
 		PropertyInfo p = E->get().info;
 		PropertyInfo p = E->get().info;
 		p.name=SCRIPT_VARIABLES_PREFIX+String(E->key());
 		p.name=SCRIPT_VARIABLES_PREFIX+String(E->key());
 		p_properties->push_back(p);
 		p_properties->push_back(p);
@@ -1416,7 +1452,59 @@ bool VisualScriptInstance::has_method(const StringName& p_method) const{
 //#define VSDEBUG(m_text) print_line(m_text)
 //#define VSDEBUG(m_text) print_line(m_text)
 #define VSDEBUG(m_text)
 #define VSDEBUG(m_text)
 
 
-Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p_stack, int p_stack_size, VisualScriptNodeInstance* p_node, int p_flow_stack_pos, bool p_resuming_yield, Variant::CallError &r_error) {
+void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance* node,int p_pass,int *pass_stack,const Variant **input_args,Variant **output_args,Variant *variant_stack,Variant::CallError& r_error,String& error_str,VisualScriptNodeInstance** r_error_node) {
+
+	ERR_FAIL_COND(node->pass_idx==-1);
+
+	if (pass_stack[node->pass_idx]==p_pass)
+		return;
+
+	pass_stack[node->pass_idx]=p_pass;
+
+	if (!node->dependencies.empty()) {
+
+		int dc = node->dependencies.size();
+		VisualScriptNodeInstance **deps=node->dependencies.ptr();
+
+		for(int i=0;i<dc;i++) {
+
+			_dependency_step(deps[i],p_pass,pass_stack,input_args,output_args,variant_stack,r_error,error_str,r_error_node);
+			if (r_error.error!=Variant::CallError::CALL_OK)
+				return;
+
+		}
+	}
+
+
+	for(int i=0;i<node->input_port_count;i++) {
+
+		int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
+
+
+		if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
+			//is a default value (unassigned input port)
+			input_args[i]=&default_values[index];
+		} else {
+			//regular temporary in stack
+			input_args[i]=&variant_stack[index];
+
+		}
+	}
+	for(int i=0 ; i<node->output_port_count ; i++) {
+		output_args[i] = &variant_stack[ node->output_ports[i] ];
+	}
+
+	Variant *working_mem=node->working_mem_idx>=0 ? &variant_stack[node->working_mem_idx] : (Variant*)NULL;
+
+	node->step(input_args,output_args,VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE,working_mem,r_error,error_str);
+	//ignore return
+	if (r_error.error!=Variant::CallError::CALL_OK) {
+		*r_error_node=node;
+	}
+
+}
+
+Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p_stack, int p_stack_size, VisualScriptNodeInstance* p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Variant::CallError &r_error) {
 
 
 	Map<StringName,Function>::Element *F = functions.find(p_method);
 	Map<StringName,Function>::Element *F = functions.find(p_method);
 	ERR_FAIL_COND_V(!F,Variant());
 	ERR_FAIL_COND_V(!F,Variant());
@@ -1429,6 +1517,7 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
 	Variant **output_args=(Variant**)(input_args + max_input_args);
 	Variant **output_args=(Variant**)(input_args + max_input_args);
 	int flow_max = f->flow_stack_size;
 	int flow_max = f->flow_stack_size;
 	int* flow_stack = flow_max? (int*)(output_args + max_output_args) : (int*)NULL;
 	int* flow_stack = flow_max? (int*)(output_args + max_output_args) : (int*)NULL;
+	int *pass_stack = flow_stack + flow_max;
 
 
 	String error_str;
 	String error_str;
 
 
@@ -1448,6 +1537,7 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
 
 
 	while(true) {
 	while(true) {
 
 
+		p_pass++; //increment pass
 		current_node_id=node->get_id();
 		current_node_id=node->get_id();
 
 
 		VSDEBUG("==========AT NODE: "+itos(current_node_id)+" base: "+node->get_base_node()->get_type());
 		VSDEBUG("==========AT NODE: "+itos(current_node_id)+" base: "+node->get_base_node()->get_type());
@@ -1466,41 +1556,46 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
 				input_args[i]=&variant_stack[i];
 				input_args[i]=&variant_stack[i];
 			}
 			}
 		} else {
 		} else {
-			//setup input pointers normally
-			VSDEBUG("INPUT PORTS: "+itos(node->input_port_count));
 
 
-			for(int i=0 ; i<node->input_port_count ; i++) {
+			//run dependencies first
 
 
 
 
-				int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
+			if (!node->dependencies.empty()) {
 
 
-				if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
-					//is a default value (unassigned input port)
-					input_args[i]=&default_values[index];
-					VSDEBUG("\tPORT "+itos(i)+" DEFAULT VAL");
-				} else if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_UNSEQUENCED_READ_BIT) {
-					//from a node that requires read
-					Function::UnsequencedGet *ug = &f->unsequenced_gets[index];
+				int dc = node->dependencies.size();
+				VisualScriptNodeInstance **deps=node->dependencies.ptr();
 
 
-					Variant* ug_working_mem=ug->from->working_mem_idx>=0 ? &variant_stack[ug->from->working_mem_idx] : (Variant*)NULL;
+				for(int i=0;i<dc;i++) {
 
 
-
-					bool ok = ug->from->get_output_port_unsequenced(i,&variant_stack[ug->to_stack],ug_working_mem,error_str);
-					if (!ok) {
-						r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
-						current_node_id=ug->from->get_id();
+					_dependency_step(deps[i],p_pass,pass_stack,input_args,output_args,variant_stack,r_error,error_str,&node);
+					if (r_error.error!=Variant::CallError::CALL_OK) {
 						error=true;
 						error=true;
-						working_mem=NULL;
+						current_node_id=node->id;
 						break;
 						break;
 					}
 					}
+				}
+			}
 
 
-					VSDEBUG("\tPORT "+itos(i)+" UNSEQ READ TO STACK: " + itos(ug->to_stack));
-					input_args[i]=&variant_stack[ug->to_stack];
-				} else {
-					//regular temporary in stack
-					input_args[i]=&variant_stack[index];
-					VSDEBUG("PORT "+itos(i)+" AT STACK "+itos(index));
+			if (!error) {
+
+				//setup input pointers normally
+				VSDEBUG("INPUT PORTS: "+itos(node->input_port_count));
 
 
+				for(int i=0 ; i<node->input_port_count ; i++) {
+
+
+					int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
+
+					if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
+						//is a default value (unassigned input port)
+						input_args[i]=&default_values[index];
+						VSDEBUG("\tPORT "+itos(i)+" DEFAULT VAL");
+					} else {
+						//regular temporary in stack
+						input_args[i]=&variant_stack[index];
+						VSDEBUG("PORT "+itos(i)+" AT STACK "+itos(index));
+
+					}
 				}
 				}
 			}
 			}
 		}
 		}
@@ -1567,6 +1662,7 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
 				state->node=node;
 				state->node=node;
 				state->flow_stack_pos=flow_stack_pos;
 				state->flow_stack_pos=flow_stack_pos;
 				state->stack.resize(p_stack_size);
 				state->stack.resize(p_stack_size);
+				state->pass=p_pass;
 				copymem(state->stack.ptr(),p_stack,p_stack_size);
 				copymem(state->stack.ptr(),p_stack,p_stack_size);
 				//step 2, run away, return directly
 				//step 2, run away, return directly
 				r_error.error=Variant::CallError::CALL_OK;
 				r_error.error=Variant::CallError::CALL_OK;
@@ -1834,6 +1930,7 @@ Variant VisualScriptInstance::call(const StringName& p_method, const Variant** p
 	total_stack_size+=f->node_count*sizeof(bool);
 	total_stack_size+=f->node_count*sizeof(bool);
 	total_stack_size+=(max_input_args+max_output_args)*sizeof(Variant*); //arguments
 	total_stack_size+=(max_input_args+max_output_args)*sizeof(Variant*); //arguments
 	total_stack_size+=f->flow_stack_size*sizeof(int); //flow
 	total_stack_size+=f->flow_stack_size*sizeof(int); //flow
+	total_stack_size+=f->pass_stack_size*sizeof(int);
 
 
 	VSDEBUG("STACK SIZE: "+itos(total_stack_size));
 	VSDEBUG("STACK SIZE: "+itos(total_stack_size));
 	VSDEBUG("STACK VARIANTS: : "+itos(f->max_stack));
 	VSDEBUG("STACK VARIANTS: : "+itos(f->max_stack));
@@ -1841,6 +1938,7 @@ Variant VisualScriptInstance::call(const StringName& p_method, const Variant** p
 	VSDEBUG("MAX INPUT: "+itos(max_input_args));
 	VSDEBUG("MAX INPUT: "+itos(max_input_args));
 	VSDEBUG("MAX OUTPUT: "+itos(max_output_args));
 	VSDEBUG("MAX OUTPUT: "+itos(max_output_args));
 	VSDEBUG("FLOW STACK SIZE: "+itos(f->flow_stack_size));
 	VSDEBUG("FLOW STACK SIZE: "+itos(f->flow_stack_size));
+	VSDEBUG("PASS STACK SIZE: "+itos(f->pass_stack_size));
 
 
 	void *stack = alloca(total_stack_size);
 	void *stack = alloca(total_stack_size);
 
 
@@ -1850,11 +1948,13 @@ Variant VisualScriptInstance::call(const StringName& p_method, const Variant** p
 	Variant **output_args=(Variant**)(input_args + max_input_args);
 	Variant **output_args=(Variant**)(input_args + max_input_args);
 	int flow_max = f->flow_stack_size;
 	int flow_max = f->flow_stack_size;
 	int* flow_stack = flow_max? (int*)(output_args + max_output_args) : (int*)NULL;
 	int* flow_stack = flow_max? (int*)(output_args + max_output_args) : (int*)NULL;
+	int *pass_stack = flow_stack + flow_max;
 
 
 	for(int i=0;i<f->node_count;i++) {
 	for(int i=0;i<f->node_count;i++) {
 		sequence_bits[i]=false; //all starts as false
 		sequence_bits[i]=false; //all starts as false
 	}
 	}
 
 
+	zeromem(pass_stack,f->pass_stack_size*sizeof(int));
 
 
 	Map<int,VisualScriptNodeInstance*>::Element *E = instances.find(f->node);
 	Map<int,VisualScriptNodeInstance*>::Element *E = instances.find(f->node);
 	if (!E) {
 	if (!E) {
@@ -1897,7 +1997,7 @@ Variant VisualScriptInstance::call(const StringName& p_method, const Variant** p
 		variant_stack[i]=*p_args[i];
 		variant_stack[i]=*p_args[i];
 	}
 	}
 
 
-	return _call_internal(p_method,stack,total_stack_size,node,0,false,r_error);
+	return _call_internal(p_method,stack,total_stack_size,node,0,0,false,r_error);
 
 
 
 
 }
 }
@@ -1969,6 +2069,7 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
 
 
 	for(const Map<StringName,VisualScript::Variable>::Element *E=script->variables.front();E;E=E->next()) {
 	for(const Map<StringName,VisualScript::Variable>::Element *E=script->variables.front();E;E=E->next()) {
 		variables[E->key()]=E->get().default_value;
 		variables[E->key()]=E->get().default_value;
+		//no hacer que todo exporte, solo las que queres!
 	}
 	}
 
 
 
 
@@ -1978,6 +2079,7 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
 		function.node=E->get().function_id;
 		function.node=E->get().function_id;
 		function.max_stack=0;
 		function.max_stack=0;
 		function.flow_stack_size=0;
 		function.flow_stack_size=0;
+		function.pass_stack_size=0;
 		function.node_count=0;
 		function.node_count=0;
 		Map<StringName,int> local_var_indices;
 		Map<StringName,int> local_var_indices;
 
 
@@ -2021,12 +2123,14 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
 			instance->output_port_count = node->get_output_value_port_count();
 			instance->output_port_count = node->get_output_value_port_count();
 			instance->sequence_output_count = node->get_output_sequence_port_count();
 			instance->sequence_output_count = node->get_output_sequence_port_count();
 			instance->sequence_index=function.node_count++;
 			instance->sequence_index=function.node_count++;
+			instance->pass_idx=-1;
 
 
 			if (instance->input_port_count) {
 			if (instance->input_port_count) {
 				instance->input_ports = memnew_arr(int,instance->input_port_count);
 				instance->input_ports = memnew_arr(int,instance->input_port_count);
 				for(int i=0;i<instance->input_port_count;i++) {
 				for(int i=0;i<instance->input_port_count;i++) {
+
 					instance->input_ports[i]=-1; //if not assigned, will become default value
 					instance->input_ports[i]=-1; //if not assigned, will become default value
-				}
+				}							
 			}
 			}
 
 
 			if (instance->output_port_count) {
 			if (instance->output_port_count) {
@@ -2043,11 +2147,16 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
 				}
 				}
 			}
 			}
 
 
-			if (node->cast_to<VisualScriptLocalVar>()) {
+			if (node->cast_to<VisualScriptLocalVar>() || node->cast_to<VisualScriptLocalVarSet>()) {
 				//working memory is shared only for this node, for the same variables
 				//working memory is shared only for this node, for the same variables
 				Ref<VisualScriptLocalVar> vslv = node;
 				Ref<VisualScriptLocalVar> vslv = node;
 
 
-				StringName var_name = String(vslv->get_var_name()).strip_edges();
+				StringName var_name;
+
+				if (node->cast_to<VisualScriptLocalVar>())
+					var_name = String(node->cast_to<VisualScriptLocalVar>()->get_var_name()).strip_edges();
+				else
+					var_name = String(node->cast_to<VisualScriptLocalVarSet>()->get_var_name()).strip_edges();
 
 
 				if (!local_var_indices.has(var_name)) {
 				if (!local_var_indices.has(var_name)) {
 					local_var_indices[var_name]=function.max_stack;
 					local_var_indices[var_name]=function.max_stack;
@@ -2092,24 +2201,17 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
 			}
 			}
 
 
 
 
-			if (from->is_output_port_unsequenced(dc.from_node)) {
-
-				//prepare an unsequenced read (must actually get the value from the output)
-				int stack_pos = function.max_stack++;
-
-				Function::UnsequencedGet uget;
-				uget.from=from;
-				uget.from_port=dc.from_port;
-				uget.to_stack=stack_pos;
-
-				to->input_ports[dc.to_port] = function.unsequenced_gets.size() | VisualScriptNodeInstance::INPUT_UNSEQUENCED_READ_BIT;
-				function.unsequenced_gets.push_back(uget);
-
-			} else {
-
-				to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; //read from wherever the stack is
+			if (from->get_sequence_output_count()==0 && to->dependencies.find(from)==-1) {
+				//if the node we are reading from has no output sequence, we must call step() before reading from it.
+				if (from->pass_idx==-1) {
+					from->pass_idx=function.pass_stack_size;
+					function.pass_stack_size++;
+				}
+				to->dependencies.push_back(from);
 			}
 			}
 
 
+			to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; //read from wherever the stack is
+
 		}
 		}
 
 
 		//third pass, do sequence connections
 		//third pass, do sequence connections
@@ -2244,7 +2346,7 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant** p_args, int
 
 
 	*working_mem=args; //arguments go to working mem.
 	*working_mem=args; //arguments go to working mem.
 
 
-	Variant ret = instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,true,r_error);
+	Variant ret = instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,pass,true,r_error);
 	function=StringName(); //invalidate
 	function=StringName(); //invalidate
 	return ret;
 	return ret;
 }
 }
@@ -2286,7 +2388,7 @@ Variant VisualScriptFunctionState::resume(Array p_args) {
 
 
 	*working_mem=p_args; //arguments go to working mem.
 	*working_mem=p_args; //arguments go to working mem.
 
 
-	Variant ret= instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,true,r_error);
+	Variant ret= instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,pass,true,r_error);
 	function=StringName(); //invalidate
 	function=StringName(); //invalidate
 	return ret;
 	return ret;
 }
 }
@@ -2512,8 +2614,6 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level,List<String>
 
 
 		if (in_from&VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
 		if (in_from&VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
 			p_values->push_back(_call_stack[l].instance->default_values[in_value]);
 			p_values->push_back(_call_stack[l].instance->default_values[in_value]);
-		} else if (in_from&VisualScriptNodeInstance::INPUT_UNSEQUENCED_READ_BIT) {
-			p_values->push_back( _call_stack[l].stack[ func->unsequenced_gets[ in_value ].to_stack ] );
 		} else {
 		} else {
 			p_values->push_back( _call_stack[l].stack[ in_value] );
 			p_values->push_back( _call_stack[l].stack[ in_value] );
 		}
 		}
@@ -2664,7 +2764,6 @@ void VisualScriptLanguage::get_registered_node_names(List<String> *r_names) {
 VisualScriptLanguage::VisualScriptLanguage() {
 VisualScriptLanguage::VisualScriptLanguage() {
 
 
 	notification="_notification";
 	notification="_notification";
-	_get_output_port_unsequenced="_get_output_port_unsequenced";
 	_step="_step";
 	_step="_step";
 	_subcall="_subcall";
 	_subcall="_subcall";
 	singleton=this;
 	singleton=this;

+ 22 - 16
modules/visual_script/visual_script.h

@@ -58,6 +58,18 @@ public:
 
 
 	virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance)=0;
 	virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance)=0;
 
 
+	struct TypeGuess {
+
+		Variant::Type type;
+		InputEvent::Type ev_type;
+		StringName obj_type;
+		String script_type;
+
+		TypeGuess() { type=Variant::NIL; ev_type=InputEvent::NONE; }
+	};
+
+	virtual TypeGuess guess_output_type(TypeGuess* p_inputs, int p_output) const;
+
 	VisualScriptNode();
 	VisualScriptNode();
 };
 };
 
 
@@ -71,7 +83,6 @@ friend class VisualScriptLanguage; //for debugger
 		INPUT_SHIFT=1<<24,
 		INPUT_SHIFT=1<<24,
 		INPUT_MASK=INPUT_SHIFT-1,
 		INPUT_MASK=INPUT_SHIFT-1,
 		INPUT_DEFAULT_VALUE_BIT=INPUT_SHIFT, // from unassigned input port, using default value (edited by user)
 		INPUT_DEFAULT_VALUE_BIT=INPUT_SHIFT, // from unassigned input port, using default value (edited by user)
-		INPUT_UNSEQUENCED_READ_BIT=INPUT_SHIFT<<1, //from unsequenced read (requires calling a function, used for constants, variales, etc).
 	};
 	};
 
 
 
 
@@ -79,11 +90,13 @@ friend class VisualScriptLanguage; //for debugger
 	int sequence_index;
 	int sequence_index;
 	VisualScriptNodeInstance **sequence_outputs;
 	VisualScriptNodeInstance **sequence_outputs;
 	int sequence_output_count;
 	int sequence_output_count;
+	Vector<VisualScriptNodeInstance*> dependencies;
 	int *input_ports;
 	int *input_ports;
 	int input_port_count;
 	int input_port_count;
 	int *output_ports;
 	int *output_ports;
 	int output_port_count;
 	int output_port_count;
 	int working_mem_idx;
 	int working_mem_idx;
+	int pass_idx;
 
 
 	VisualScriptNode *base;
 	VisualScriptNode *base;
 
 
@@ -117,10 +130,6 @@ public:
 
 
 	virtual int get_working_memory_size() const { return 0; }
 	virtual int get_working_memory_size() const { return 0; }
 
 
-	//unsequenced ports are those that can return a value even if no sequence happened through them, used for constants, variables, etc.
-	virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
-
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str)=0; //do a step, return which sequence port to go out
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str)=0; //do a step, return which sequence port to go out
 
 
 	Ref<VisualScriptNode> get_base_node() { return Ref<VisualScriptNode>( base ); }
 	Ref<VisualScriptNode> get_base_node() { return Ref<VisualScriptNode>( base ); }
@@ -209,6 +218,7 @@ friend class VisualScriptInstance;
 	struct Variable {
 	struct Variable {
 		PropertyInfo info;
 		PropertyInfo info;
 		Variant default_value;
 		Variant default_value;
+		bool _export;
 	};
 	};
 
 
 
 
@@ -270,13 +280,15 @@ public:
 	void get_data_connection_list(const StringName& p_func,List<DataConnection> *r_connection) const;
 	void get_data_connection_list(const StringName& p_func,List<DataConnection> *r_connection) const;
 	bool is_input_value_port_connected(const StringName& p_name,int p_node,int p_port) const;
 	bool is_input_value_port_connected(const StringName& p_name,int p_node,int p_port) const;
 
 
-	void add_variable(const StringName& p_name,const Variant& p_default_value=Variant());
+	void add_variable(const StringName& p_name,const Variant& p_default_value=Variant(),bool p_export=false);
 	bool has_variable(const StringName& p_name) const;
 	bool has_variable(const StringName& p_name) const;
 	void remove_variable(const StringName& p_name);
 	void remove_variable(const StringName& p_name);
 	void set_variable_default_value(const StringName& p_name,const Variant& p_value);
 	void set_variable_default_value(const StringName& p_name,const Variant& p_value);
 	Variant get_variable_default_value(const StringName& p_name) const;
 	Variant get_variable_default_value(const StringName& p_name) const;
 	void set_variable_info(const StringName& p_name,const PropertyInfo& p_info);
 	void set_variable_info(const StringName& p_name,const PropertyInfo& p_info);
 	PropertyInfo get_variable_info(const StringName& p_name) const;
 	PropertyInfo get_variable_info(const StringName& p_name) const;
+	void set_variable_export(const StringName& p_name,bool p_export);
+	bool get_variable_export(const StringName& p_name) const;
 	void get_variable_list(List<StringName> *r_variables) const;
 	void get_variable_list(List<StringName> *r_variables) const;
 	void rename_variable(const StringName& p_name,const StringName& p_new_name);
 	void rename_variable(const StringName& p_name,const StringName& p_new_name);
 
 
@@ -349,18 +361,10 @@ class VisualScriptInstance : public ScriptInstance {
 		int trash_pos;
 		int trash_pos;
 		int return_pos;
 		int return_pos;
 		int flow_stack_size;
 		int flow_stack_size;
+		int pass_stack_size;
 		int node_count;
 		int node_count;
 		int argument_count;
 		int argument_count;
 		bool valid;
 		bool valid;
-
-		struct UnsequencedGet {
-			VisualScriptNodeInstance* from;
-			int from_port;
-			int to_stack;
-		};
-
-		Vector<UnsequencedGet> unsequenced_gets;
-
 	};
 	};
 
 
 	Map<StringName,Function> functions;
 	Map<StringName,Function> functions;
@@ -370,7 +374,8 @@ class VisualScriptInstance : public ScriptInstance {
 
 
 	StringName source;
 	StringName source;
 
 
-	Variant _call_internal(const StringName& p_method, void* p_stack,int p_stack_size, VisualScriptNodeInstance* p_node, int p_flow_stack_pos, bool p_resuming_yield,Variant::CallError &r_error);
+	void _dependency_step(VisualScriptNodeInstance* node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Variant::CallError& r_error, String& error_str, VisualScriptNodeInstance **r_error_node);
+	Variant _call_internal(const StringName& p_method, void* p_stack,int p_stack_size, VisualScriptNodeInstance* p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield,Variant::CallError &r_error);
 
 
 
 
 	//Map<StringName,Function> functions;
 	//Map<StringName,Function> functions;
@@ -439,6 +444,7 @@ friend class VisualScriptInstance;
 	int variant_stack_size;
 	int variant_stack_size;
 	VisualScriptNodeInstance *node;
 	VisualScriptNodeInstance *node;
 	int flow_stack_pos;
 	int flow_stack_pos;
+	int pass;
 
 
 	Variant _signal_callback(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
 	Variant _signal_callback(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
 protected:
 protected:

+ 13 - 2
modules/visual_script/visual_script_builtin_funcs.cpp

@@ -69,12 +69,23 @@ const char* VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
 
 
 int VisualScriptBuiltinFunc::get_output_sequence_port_count() const {
 int VisualScriptBuiltinFunc::get_output_sequence_port_count() const {
 
 
-	return 1;
+	return has_input_sequence_port() ? 1 : 0;
 }
 }
 
 
 bool VisualScriptBuiltinFunc::has_input_sequence_port() const{
 bool VisualScriptBuiltinFunc::has_input_sequence_port() const{
 
 
-	return true;
+	switch(func) {
+
+		case MATH_RANDOMIZE:
+		case TEXT_PRINT:
+		case TEXT_PRINTERR:
+		case TEXT_PRINTRAW:
+			return true;
+		default:
+			return false;
+
+	}
+
 }
 }
 
 
 int VisualScriptBuiltinFunc::get_input_value_port_count() const{
 int VisualScriptBuiltinFunc::get_input_value_port_count() const{

+ 47 - 0
modules/visual_script/visual_script_editor.cpp

@@ -242,6 +242,11 @@ protected:
 			return true;
 			return true;
 		}
 		}
 
 
+		if (String(p_name)=="export") {
+			script->set_variable_export(var,p_value);
+			return true;
+		}
+
 
 
 		return false;
 		return false;
 	}
 	}
@@ -271,6 +276,11 @@ protected:
 			return true;
 			return true;
 		}
 		}
 
 
+		if (String(p_name)=="export") {
+			r_ret=script->get_variable_export(var);
+			return true;
+		}
+
 		return false;
 		return false;
 	}
 	}
 	void _get_property_list( List<PropertyInfo> *p_list) const {
 	void _get_property_list( List<PropertyInfo> *p_list) const {
@@ -286,6 +296,7 @@ protected:
 		p_list->push_back(PropertyInfo(script->get_variable_info(var).type,"value",script->get_variable_info(var).hint,script->get_variable_info(var).hint_string,PROPERTY_USAGE_DEFAULT));
 		p_list->push_back(PropertyInfo(script->get_variable_info(var).type,"value",script->get_variable_info(var).hint,script->get_variable_info(var).hint_string,PROPERTY_USAGE_DEFAULT));
 		p_list->push_back(PropertyInfo(Variant::INT,"hint",PROPERTY_HINT_ENUM,"None,Range,ExpRange,Enum,ExpEasing,Length,SpriteFrame,KeyAccel,BitFlags,AllFlags,File,Dir,GlobalFile,GlobalDir,ResourceType,MultilineText"));
 		p_list->push_back(PropertyInfo(Variant::INT,"hint",PROPERTY_HINT_ENUM,"None,Range,ExpRange,Enum,ExpEasing,Length,SpriteFrame,KeyAccel,BitFlags,AllFlags,File,Dir,GlobalFile,GlobalDir,ResourceType,MultilineText"));
 		p_list->push_back(PropertyInfo(Variant::STRING,"hint_string"));
 		p_list->push_back(PropertyInfo(Variant::STRING,"hint_string"));
+		p_list->push_back(PropertyInfo(Variant::BOOL,"export"));
 
 
 	}
 	}
 
 
@@ -685,12 +696,48 @@ void VisualScriptEditor::_update_members() {
 	variables->add_button(0,Control::get_icon("Add","EditorIcons"));
 	variables->add_button(0,Control::get_icon("Add","EditorIcons"));
 	variables->set_custom_bg_color(0,Control::get_color("prop_section","Editor"));
 	variables->set_custom_bg_color(0,Control::get_color("prop_section","Editor"));
 
 
+	Ref<Texture> type_icons[Variant::VARIANT_MAX]={
+		Control::get_icon("MiniVariant","EditorIcons"),
+		Control::get_icon("MiniBoolean","EditorIcons"),
+		Control::get_icon("MiniInteger","EditorIcons"),
+		Control::get_icon("MiniFloat","EditorIcons"),
+		Control::get_icon("MiniString","EditorIcons"),
+		Control::get_icon("MiniVector2","EditorIcons"),
+		Control::get_icon("MiniRect2","EditorIcons"),
+		Control::get_icon("MiniVector3","EditorIcons"),
+		Control::get_icon("MiniMatrix32","EditorIcons"),
+		Control::get_icon("MiniPlane","EditorIcons"),
+		Control::get_icon("MiniQuat","EditorIcons"),
+		Control::get_icon("MiniAabb","EditorIcons"),
+		Control::get_icon("MiniMatrix3","EditorIcons"),
+		Control::get_icon("MiniTransform","EditorIcons"),
+		Control::get_icon("MiniColor","EditorIcons"),
+		Control::get_icon("MiniImage","EditorIcons"),
+		Control::get_icon("MiniPath","EditorIcons"),
+		Control::get_icon("MiniRid","EditorIcons"),
+		Control::get_icon("MiniObject","EditorIcons"),
+		Control::get_icon("MiniInput","EditorIcons"),
+		Control::get_icon("MiniDictionary","EditorIcons"),
+		Control::get_icon("MiniArray","EditorIcons"),
+		Control::get_icon("MiniRawArray","EditorIcons"),
+		Control::get_icon("MiniIntArray","EditorIcons"),
+		Control::get_icon("MiniFloatArray","EditorIcons"),
+		Control::get_icon("MiniStringArray","EditorIcons"),
+		Control::get_icon("MiniVector2Array","EditorIcons"),
+		Control::get_icon("MiniVector3Array","EditorIcons"),
+		Control::get_icon("MiniColorArray","EditorIcons")
+	};
 
 
 	List<StringName> var_names;
 	List<StringName> var_names;
 	script->get_variable_list(&var_names);
 	script->get_variable_list(&var_names);
 	for (List<StringName>::Element *E=var_names.front();E;E=E->next()) {
 	for (List<StringName>::Element *E=var_names.front();E;E=E->next()) {
 		TreeItem *ti = members->create_item(variables);
 		TreeItem *ti = members->create_item(variables);
+
 		ti->set_text(0,E->get());
 		ti->set_text(0,E->get());
+		Variant var = script->get_variable_default_value(E->get());
+		ti->set_suffix(0,"="+String(var));
+		ti->set_icon(0,type_icons[script->get_variable_info(E->get()).type]);
+
 		ti->set_selectable(0,true);
 		ti->set_selectable(0,true);
 		ti->set_editable(0,true);
 		ti->set_editable(0,true);
 		ti->add_button(0,Control::get_icon("Edit","EditorIcons"),0);
 		ti->add_button(0,Control::get_icon("Edit","EditorIcons"),0);

+ 41 - 39
modules/visual_script/visual_script_func_nodes.cpp

@@ -12,12 +12,18 @@
 
 
 int VisualScriptFunctionCall::get_output_sequence_port_count() const {
 int VisualScriptFunctionCall::get_output_sequence_port_count() const {
 
 
-	return 1;
+	if (method_cache.flags&METHOD_FLAG_CONST)
+		return 0;
+	else
+		return 1;
 }
 }
 
 
 bool VisualScriptFunctionCall::has_input_sequence_port() const{
 bool VisualScriptFunctionCall::has_input_sequence_port() const{
 
 
-	return true;
+	if (method_cache.flags&METHOD_FLAG_CONST)
+		return false;
+	else
+		return true;
 }
 }
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 
 
@@ -403,6 +409,10 @@ void VisualScriptFunctionCall::_update_method_cache() {
 #endif
 #endif
 		}
 		}
 
 
+		if (mb->is_const()) {
+			method_cache.flags|=METHOD_FLAG_CONST;
+		}
+
 #ifdef DEBUG_METHODS_ENABLED
 #ifdef DEBUG_METHODS_ENABLED
 
 
 		method_cache.return_val = mb->get_argument_info(-1);
 		method_cache.return_val = mb->get_argument_info(-1);
@@ -926,12 +936,12 @@ static const char* event_type_names[InputEvent::TYPE_MAX]={
 
 
 int VisualScriptPropertySet::get_output_sequence_port_count() const {
 int VisualScriptPropertySet::get_output_sequence_port_count() const {
 
 
-	return 1;
+	return call_mode!=CALL_MODE_BASIC_TYPE ? 1 : 0;
 }
 }
 
 
 bool VisualScriptPropertySet::has_input_sequence_port() const{
 bool VisualScriptPropertySet::has_input_sequence_port() const{
 
 
-	return true;
+	return call_mode!=CALL_MODE_BASIC_TYPE ? true : false;
 }
 }
 
 
 Node *VisualScriptPropertySet::_get_base_node() const {
 Node *VisualScriptPropertySet::_get_base_node() const {
@@ -1590,12 +1600,12 @@ static Ref<VisualScriptNode> create_property_set_node(const String& p_name) {
 
 
 int VisualScriptPropertyGet::get_output_sequence_port_count() const {
 int VisualScriptPropertyGet::get_output_sequence_port_count() const {
 
 
-	return (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?0:1;
+	return 0;// (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?0:1;
 }
 }
 
 
 bool VisualScriptPropertyGet::has_input_sequence_port() const{
 bool VisualScriptPropertyGet::has_input_sequence_port() const{
 
 
-	return (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?false:true;
+	return false;//(call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?false:true;
 }
 }
 void VisualScriptPropertyGet::_update_base_type() {
 void VisualScriptPropertyGet::_update_base_type() {
 	//cache it because this information may not be available on load
 	//cache it because this information may not be available on load
@@ -2130,12 +2140,10 @@ public:
 	VisualScriptInstance *instance;
 	VisualScriptInstance *instance;
 
 
 
 
+	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+
 
 
-	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return (call_mode==VisualScriptPropertyGet::CALL_MODE_SELF || call_mode==VisualScriptPropertyGet::CALL_MODE_NODE_PATH); }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
 
 
-		//these two modes can be get directly, so they use unsequenced mode
 		switch(call_mode) {
 		switch(call_mode) {
 
 
 			case VisualScriptPropertyGet::CALL_MODE_SELF: {
 			case VisualScriptPropertyGet::CALL_MODE_SELF: {
@@ -2144,63 +2152,57 @@ public:
 
 
 				bool valid;
 				bool valid;
 
 
-				*r_value = object->get(property,&valid);
+				*p_outputs[0] = object->get(property,&valid);
 
 
 				if (!valid) {
 				if (!valid) {
-					//r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
-					r_error=RTR("Invalid index property name.");
-					return false;
+					r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+					r_error_str=RTR("Invalid index property name.");
+					return 0;
 				}
 				}
 			} break;
 			} break;
 			case VisualScriptPropertyGet::CALL_MODE_NODE_PATH: {
 			case VisualScriptPropertyGet::CALL_MODE_NODE_PATH: {
 
 
 				Node* node = instance->get_owner_ptr()->cast_to<Node>();
 				Node* node = instance->get_owner_ptr()->cast_to<Node>();
 				if (!node) {
 				if (!node) {
-					//r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
-					r_error=RTR("Base object is not a Node!");
-					return false;
+					r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+					r_error_str=RTR("Base object is not a Node!");
+					return 0;
 				}
 				}
 
 
 				Node* another = node->get_node(node_path);
 				Node* another = node->get_node(node_path);
 				if (!node) {
 				if (!node) {
-					//r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
-					r_error=RTR("Path does not lead Node!");
-					return false;
+					r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+					r_error_str=RTR("Path does not lead Node!");
+					return 0;
 				}
 				}
 
 
 				bool valid;
 				bool valid;
 
 
 
 
-				*r_value = another->get(property,&valid);
+				*p_outputs[0] = another->get(property,&valid);
 
 
 				if (!valid) {
 				if (!valid) {
-					//r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
-					r_error=vformat(RTR("Invalid index property name '%s' in node %s."),String(property),another->get_name());
-					return false;
+					r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+					r_error_str=vformat(RTR("Invalid index property name '%s' in node %s."),String(property),another->get_name());
+					return 0;
 				}
 				}
 
 
 			} break;
 			} break;
-			default: {};
-		}
-		return true;
-
-	}
+			default: {
 
 
-	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
-
-
-		bool valid;
-		Variant v = *p_inputs[0];
+				bool valid;
+				Variant v = *p_inputs[0];
 
 
-		*p_outputs[0] = v.get(property,&valid);
+				*p_outputs[0] = v.get(property,&valid);
 
 
-		if (!valid) {
-			r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
-			r_error_str=RTR("Invalid index property name.");
+				if (!valid) {
+					r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+					r_error_str=RTR("Invalid index property name.");
 
 
+				}
+			};
 		}
 		}
 
 
-
 		return 0;
 		return 0;
 	}
 	}
 
 

+ 3 - 0
modules/visual_script/visual_script_func_nodes.h

@@ -328,6 +328,9 @@ public:
 
 
 	virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
 	virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
 
 
+
+
+
 	VisualScriptEmitSignal();
 	VisualScriptEmitSignal();
 };
 };
 
 

+ 187 - 163
modules/visual_script/visual_script_nodes.cpp

@@ -254,8 +254,6 @@ public:
 	VisualScriptInstance *instance;
 	VisualScriptInstance *instance;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
-	//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
@@ -326,12 +324,12 @@ int VisualScriptFunction::get_stack_size() const {
 
 
 int VisualScriptOperator::get_output_sequence_port_count() const {
 int VisualScriptOperator::get_output_sequence_port_count() const {
 
 
-	return 1;
+	return 0;
 }
 }
 
 
 bool VisualScriptOperator::has_input_sequence_port() const{
 bool VisualScriptOperator::has_input_sequence_port() const{
 
 
-	return true;
+	return false;
 }
 }
 
 
 int VisualScriptOperator::get_input_value_port_count() const{
 int VisualScriptOperator::get_input_value_port_count() const{
@@ -567,8 +565,6 @@ public:
 	Variant::Operator op;
 	Variant::Operator op;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
-	//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
@@ -732,20 +728,14 @@ public:
 	VisualScriptInstance *instance;
 	VisualScriptInstance *instance;
 	StringName variable;
 	StringName variable;
 
 
-	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
-		 if (instance->get_variable(variable,r_value)==false) {
-			 r_error=RTR("VariableGet not found in script: ")+"'"+String(variable)+"'";
-			 return false;
-		 } else {
-			 return true;
-		 }
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
+		if (instance->get_variable(variable,p_outputs[0])==false) {
+			r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+			r_error_str=RTR("VariableGet not found in script: ")+"'"+String(variable)+"'";
+			return false;
+		}
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -875,17 +865,16 @@ public:
 	StringName variable;
 	StringName variable;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
 		if (instance->set_variable(variable,*p_inputs[0])==false) {
 		if (instance->set_variable(variable,*p_inputs[0])==false) {
-			r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD			;
+
+
+			r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
 			r_error_str=RTR("VariableSet not found in script: ")+"'"+String(variable)+"'";
 			r_error_str=RTR("VariableSet not found in script: ")+"'"+String(variable)+"'";
 		}
 		}
 
 
-
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1024,17 +1013,10 @@ public:
 
 
 	Variant constant;
 	Variant constant;
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
-		*r_value=constant;
-
-		return true;
-
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
+		*p_outputs[0]=constant;
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1144,17 +1126,10 @@ public:
 
 
 	Ref<Resource> preload;
 	Ref<Resource> preload;
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
-		*r_value=preload;
-
-		return true;
-
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
+		*p_outputs[0]=preload;
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1181,12 +1156,12 @@ VisualScriptPreload::VisualScriptPreload() {
 
 
 int VisualScriptIndexGet::get_output_sequence_port_count() const {
 int VisualScriptIndexGet::get_output_sequence_port_count() const {
 
 
-	return 1;
+	return 0;
 }
 }
 
 
 bool VisualScriptIndexGet::has_input_sequence_port() const{
 bool VisualScriptIndexGet::has_input_sequence_port() const{
 
 
-	return true;
+	return false;
 }
 }
 
 
 int VisualScriptIndexGet::get_input_value_port_count() const{
 int VisualScriptIndexGet::get_input_value_port_count() const{
@@ -1235,8 +1210,6 @@ public:
 
 
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	//virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
@@ -1327,8 +1300,6 @@ public:
 
 
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	//virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
@@ -1424,17 +1395,11 @@ public:
 
 
 	int index;
 	int index;
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
-		*r_value = GlobalConstants::get_global_constant_value(index);
-		return true;
-
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
 
 
+		*p_outputs[0] = GlobalConstants::get_global_constant_value(index);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1556,17 +1521,10 @@ public:
 
 
 	float value;
 	float value;
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
-		*r_value = value;
-		return true;
-
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
-
+		*p_outputs[0]=value;
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1673,16 +1631,10 @@ public:
 	Object* singleton;
 	Object* singleton;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
-		*r_value=singleton;
-		return true;
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
-
+		*p_outputs[0]=singleton;
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -1795,28 +1747,26 @@ public:
 	NodePath path;
 	NodePath path;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
+
+	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
 		Node* node = instance->get_owner_ptr()->cast_to<Node>();
 		Node* node = instance->get_owner_ptr()->cast_to<Node>();
 		if (!node) {
 		if (!node) {
-			r_error="Base object is not a Node!";
-			return false;
+			r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+			r_error_str="Base object is not a Node!";
+			return 0;
 		}
 		}
 
 
 
 
 
 
 		Node* another = node->get_node(path);
 		Node* another = node->get_node(path);
 		if (!node) {
 		if (!node) {
-			r_error="Path does not lead Node!";
-			return false;
+			r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+			r_error_str="Path does not lead Node!";
+			return 0;
 		}
 		}
 
 
-		*r_value=another;
-		return true;
-	}
-
-	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+		*p_outputs[0]=another;
 
 
 		return 0;
 		return 0;
 	}
 	}
@@ -1961,28 +1911,24 @@ public:
 	VisualScriptInstance *instance;
 	VisualScriptInstance *instance;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
+
+	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
 		Node* node = instance->get_owner_ptr()->cast_to<Node>();
 		Node* node = instance->get_owner_ptr()->cast_to<Node>();
 		if (!node) {
 		if (!node) {
-			r_error="Base object is not a Node!";
-			return false;
+			r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+			r_error_str="Base object is not a Node!";
+			return 0;
 		}
 		}
 
 
 		SceneTree* tree = node->get_tree();
 		SceneTree* tree = node->get_tree();
 		if (!tree) {
 		if (!tree) {
-			r_error="Attempt to get SceneTree while node is not in the active tree.";
-			return false;
+			r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+			r_error_str="Attempt to get SceneTree while node is not in the active tree.";
+			return 0;
 		}
 		}
 
 
-		*r_value=tree;
-		return true;
-
-	}
-
-	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
-
+		*p_outputs[0]=tree;
 
 
 		return 0;
 		return 0;
 	}
 	}
@@ -2079,14 +2025,10 @@ public:
 	String path;
 	String path;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-		*r_value = path;
-		return true;
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
+		*p_outputs[0] = path;
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -2176,15 +2118,10 @@ public:
 	VisualScriptInstance* instance;
 	VisualScriptInstance* instance;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
-		*r_value = instance->get_owner_ptr();
-		return true;
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
+		*p_outputs[0] = instance->get_owner_ptr();
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -2310,35 +2247,8 @@ public:
 	int in_count;
 	int in_count;
 	int out_count;
 	int out_count;
 	int work_mem_size;
 	int work_mem_size;
-	Vector<bool> out_unsequenced;
 
 
 	virtual int get_working_memory_size() const { return work_mem_size; }
 	virtual int get_working_memory_size() const { return work_mem_size; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return out_unsequenced[p_idx]; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
-		if (!node->get_script_instance() || !node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_get_output_port_unsequenced)) {
-#ifdef DEBUG_ENABLED
-			r_error=RTR("Custom node has no _get_output_port_unsequenced(idx,wmem), but unsequenced ports were specified.");
-			return false;
-		}
-#endif
-
-		Array work_mem(true);
-		work_mem.resize(work_mem_size);
-
-		*r_value = node->get_script_instance()->call(VisualScriptLanguage::singleton->_get_output_port_unsequenced,p_idx,work_mem);
-
-
-		for(int i=0;i<work_mem_size;i++) {
-			if (i<work_mem.size()) {
-				p_working_mem[i]=work_mem[i];
-			}
-		}
-
-		return true;
-
-	}
-
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
 		if (node->get_script_instance()) {
 		if (node->get_script_instance()) {
@@ -2411,10 +2321,6 @@ VisualScriptNodeInstance* VisualScriptCustomNode::instance(VisualScriptInstance*
 	instance->in_count=get_input_value_port_count();
 	instance->in_count=get_input_value_port_count();
 	instance->out_count=get_output_value_port_count();
 	instance->out_count=get_output_value_port_count();
 
 
-	for(int i=0;i<instance->out_count;i++) {
-		bool unseq = get_script_instance() && get_script_instance()->has_method("_is_output_port_unsequenced") && bool(get_script_instance()->call("_is_output_port_unsequenced",i));
-		instance->out_unsequenced.push_back(unseq);
-	}
 
 
 	if (get_script_instance() && get_script_instance()->has_method("_get_working_memory_size")) {
 	if (get_script_instance() && get_script_instance()->has_method("_get_working_memory_size")) {
 		instance->work_mem_size = get_script_instance()->call("_get_working_memory_size");
 		instance->work_mem_size = get_script_instance()->call("_get_working_memory_size");
@@ -2447,8 +2353,6 @@ void VisualScriptCustomNode::_bind_methods() {
 	BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_category") );
 	BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_category") );
 
 
 	BIND_VMETHOD( MethodInfo(Variant::INT,"_get_working_memory_size") );
 	BIND_VMETHOD( MethodInfo(Variant::INT,"_get_working_memory_size") );
-	BIND_VMETHOD( MethodInfo(Variant::INT,"_is_output_port_unsequenced",PropertyInfo(Variant::INT,"idx")) );
-	BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_port_unsequenced",PropertyInfo(Variant::INT,"idx"),PropertyInfo(Variant::ARRAY,"work_mem")) );
 	BIND_VMETHOD( MethodInfo(Variant::NIL,"_step:Variant",PropertyInfo(Variant::ARRAY,"inputs"),PropertyInfo(Variant::ARRAY,"outputs"),PropertyInfo(Variant::INT,"start_mode"),PropertyInfo(Variant::ARRAY,"working_mem")) );
 	BIND_VMETHOD( MethodInfo(Variant::NIL,"_step:Variant",PropertyInfo(Variant::ARRAY,"inputs"),PropertyInfo(Variant::ARRAY,"outputs"),PropertyInfo(Variant::INT,"start_mode"),PropertyInfo(Variant::ARRAY,"working_mem")) );
 
 
 	BIND_CONSTANT( START_MODE_BEGIN_SEQUENCE );
 	BIND_CONSTANT( START_MODE_BEGIN_SEQUENCE );
@@ -2560,8 +2464,6 @@ public:
 	bool valid;
 	bool valid;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
-	//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; };
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
@@ -2705,8 +2607,6 @@ public:
 	VisualScriptInstance* instance;
 	VisualScriptInstance* instance;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
-	//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; };
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
@@ -2757,12 +2657,12 @@ VisualScriptComment::VisualScriptComment() {
 
 
 int VisualScriptConstructor::get_output_sequence_port_count() const {
 int VisualScriptConstructor::get_output_sequence_port_count() const {
 
 
-	return 1;
+	return 0;
 }
 }
 
 
 bool VisualScriptConstructor::has_input_sequence_port() const{
 bool VisualScriptConstructor::has_input_sequence_port() const{
 
 
-	return true;
+	return false;
 }
 }
 
 
 int VisualScriptConstructor::get_input_value_port_count() const{
 int VisualScriptConstructor::get_input_value_port_count() const{
@@ -2839,8 +2739,6 @@ public:
 	int argcount;
 	int argcount;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
-	//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; };
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
@@ -2906,16 +2804,16 @@ static Ref<VisualScriptNode> create_constructor_node(const String& p_name) {
 
 
 int VisualScriptLocalVar::get_output_sequence_port_count() const {
 int VisualScriptLocalVar::get_output_sequence_port_count() const {
 
 
-	return 1;
+	return 0;
 }
 }
 
 
 bool VisualScriptLocalVar::has_input_sequence_port() const{
 bool VisualScriptLocalVar::has_input_sequence_port() const{
 
 
-	return true;
+	return false;
 }
 }
 
 
 int VisualScriptLocalVar::get_input_value_port_count() const{
 int VisualScriptLocalVar::get_input_value_port_count() const{
-	return 1;
+	return 0;
 }
 }
 int VisualScriptLocalVar::get_output_value_port_count() const{
 int VisualScriptLocalVar::get_output_value_port_count() const{
 
 
@@ -2929,7 +2827,7 @@ String VisualScriptLocalVar::get_output_sequence_port_text(int p_port) const {
 
 
 PropertyInfo VisualScriptLocalVar::get_input_value_port_info(int p_idx) const{
 PropertyInfo VisualScriptLocalVar::get_input_value_port_info(int p_idx) const{
 
 
-	return PropertyInfo(type,"set");
+	return PropertyInfo();
 }
 }
 PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const{
 PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const{
 
 
@@ -2939,7 +2837,7 @@ PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const{
 
 
 String VisualScriptLocalVar::get_caption() const {
 String VisualScriptLocalVar::get_caption() const {
 
 
-	return "LocalVar";
+	return "LocalVarGet";
 }
 }
 
 
 
 
@@ -2990,15 +2888,8 @@ public:
 
 
 
 
 	virtual int get_working_memory_size() const { return 1; }
 	virtual int get_working_memory_size() const { return 1; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-		*r_value=*p_working_mem;
-		return true;
-	}
-
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
-		*p_working_mem=*p_inputs[0];
 		*p_outputs[0]=*p_working_mem;
 		*p_outputs[0]=*p_working_mem;
 		return 0;
 		return 0;
 	}
 	}
@@ -3043,6 +2934,144 @@ VisualScriptLocalVar::VisualScriptLocalVar() {
 
 
 }
 }
 
 
+//////////////////////////////////////////
+////////////////LocalVar///////////
+//////////////////////////////////////////
+
+int VisualScriptLocalVarSet::get_output_sequence_port_count() const {
+
+	return 1;
+}
+
+bool VisualScriptLocalVarSet::has_input_sequence_port() const{
+
+	return true;
+}
+
+int VisualScriptLocalVarSet::get_input_value_port_count() const{
+	return 1;
+}
+int VisualScriptLocalVarSet::get_output_value_port_count() const{
+
+	return 1;
+}
+
+String VisualScriptLocalVarSet::get_output_sequence_port_text(int p_port) const {
+
+	return "";
+}
+
+PropertyInfo VisualScriptLocalVarSet::get_input_value_port_info(int p_idx) const{
+
+	return PropertyInfo(type,"set");
+}
+PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) const{
+
+	return PropertyInfo(type,"get");
+}
+
+
+String VisualScriptLocalVarSet::get_caption() const {
+
+	return "LocalVarSet";
+}
+
+
+String VisualScriptLocalVarSet::get_text() const {
+
+	return name;
+}
+
+
+String VisualScriptLocalVarSet::get_category() const {
+
+	return "data";
+}
+
+
+void VisualScriptLocalVarSet::set_var_name(const StringName& p_name) {
+
+	if (name==p_name)
+		return;
+
+	name=p_name;
+	ports_changed_notify();
+
+}
+
+StringName VisualScriptLocalVarSet::get_var_name() const {
+
+	return name;
+}
+
+void VisualScriptLocalVarSet::set_var_type(Variant::Type p_type) {
+
+	type=p_type;
+	ports_changed_notify();
+}
+
+Variant::Type VisualScriptLocalVarSet::get_var_type() const {
+
+	return type;
+}
+
+
+class VisualScriptNodeInstanceLocalVarSet : public VisualScriptNodeInstance {
+public:
+
+	VisualScriptInstance* instance;
+	StringName name;
+
+
+	virtual int get_working_memory_size() const { return 1; }
+	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+
+		*p_working_mem=*p_inputs[0];
+		*p_outputs[0]=*p_working_mem;
+		return 0;
+	}
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptLocalVarSet::instance(VisualScriptInstance* p_instance) {
+
+	VisualScriptNodeInstanceLocalVarSet * instance = memnew(VisualScriptNodeInstanceLocalVarSet );
+	instance->instance=p_instance;
+	instance->name=name;
+
+	return instance;
+}
+
+
+
+void VisualScriptLocalVarSet::_bind_methods() {
+
+	ObjectTypeDB::bind_method(_MD("set_var_name","name"),&VisualScriptLocalVarSet::set_var_name);
+	ObjectTypeDB::bind_method(_MD("get_var_name"),&VisualScriptLocalVarSet::get_var_name);
+
+	ObjectTypeDB::bind_method(_MD("set_var_type","type"),&VisualScriptLocalVarSet::set_var_type);
+	ObjectTypeDB::bind_method(_MD("get_var_type"),&VisualScriptLocalVarSet::get_var_type);
+
+	String argt="Any";
+	for(int i=1;i<Variant::VARIANT_MAX;i++) {
+		argt+=","+Variant::get_type_name(Variant::Type(i));
+	}
+
+	ADD_PROPERTY( PropertyInfo(Variant::STRING,"variable/name"),_SCS("set_var_name"),_SCS("get_var_name"));
+	ADD_PROPERTY( PropertyInfo(Variant::INT,"variable/type",PROPERTY_HINT_ENUM,argt),_SCS("set_var_type"),_SCS("get_var_type"));
+
+
+}
+
+VisualScriptLocalVarSet::VisualScriptLocalVarSet() {
+
+	name="new_local";
+	type=Variant::NIL;
+
+}
+
+
 //////////////////////////////////////////
 //////////////////////////////////////////
 ////////////////LocalVar///////////
 ////////////////LocalVar///////////
 //////////////////////////////////////////
 //////////////////////////////////////////
@@ -3122,14 +3151,10 @@ public:
 
 
 
 
 	virtual int get_working_memory_size() const { return 1; }
 	virtual int get_working_memory_size() const { return 1; }
-	virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
-	virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-		*r_value=Input::get_singleton()->is_action_pressed(action);
-		return true;
-	}
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
+		*p_outputs[0]=Input::get_singleton()->is_action_pressed(action);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -3203,12 +3228,12 @@ VisualScriptInputAction::VisualScriptInputAction() {
 
 
 int VisualScriptDeconstruct::get_output_sequence_port_count() const {
 int VisualScriptDeconstruct::get_output_sequence_port_count() const {
 
 
-	return 1;
+	return 0;
 }
 }
 
 
 bool VisualScriptDeconstruct::has_input_sequence_port() const{
 bool VisualScriptDeconstruct::has_input_sequence_port() const{
 
 
-	return true;
+	return false;
 }
 }
 
 
 int VisualScriptDeconstruct::get_input_value_port_count() const{
 int VisualScriptDeconstruct::get_input_value_port_count() const{
@@ -3335,8 +3360,6 @@ public:
 	Vector<StringName> outputs;
 	Vector<StringName> outputs;
 
 
 	//virtual int get_working_memory_size() const { return 0; }
 	//virtual int get_working_memory_size() const { return 0; }
-	//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
-	//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; };
 
 
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 	virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
 
 
@@ -3430,7 +3453,8 @@ void register_visual_script_nodes() {
 	VisualScriptLanguage::singleton->add_register_func("custom/custom_node",create_node_generic<VisualScriptCustomNode>);
 	VisualScriptLanguage::singleton->add_register_func("custom/custom_node",create_node_generic<VisualScriptCustomNode>);
 	VisualScriptLanguage::singleton->add_register_func("custom/sub_call",create_node_generic<VisualScriptSubCall>);
 	VisualScriptLanguage::singleton->add_register_func("custom/sub_call",create_node_generic<VisualScriptSubCall>);
 	VisualScriptLanguage::singleton->add_register_func("data/comment",create_node_generic<VisualScriptComment>);
 	VisualScriptLanguage::singleton->add_register_func("data/comment",create_node_generic<VisualScriptComment>);
-	VisualScriptLanguage::singleton->add_register_func("data/local_var",create_node_generic<VisualScriptLocalVar>);
+	VisualScriptLanguage::singleton->add_register_func("data/get_local_variable",create_node_generic<VisualScriptLocalVar>);
+	VisualScriptLanguage::singleton->add_register_func("data/set_local_variable",create_node_generic<VisualScriptLocalVarSet>);
 	VisualScriptLanguage::singleton->add_register_func("data/preload",create_node_generic<VisualScriptPreload>);
 	VisualScriptLanguage::singleton->add_register_func("data/preload",create_node_generic<VisualScriptPreload>);
 	VisualScriptLanguage::singleton->add_register_func("data/action",create_node_generic<VisualScriptInputAction>);
 	VisualScriptLanguage::singleton->add_register_func("data/action",create_node_generic<VisualScriptInputAction>);
 
 

+ 39 - 0
modules/visual_script/visual_script_nodes.h

@@ -820,6 +820,45 @@ public:
 	VisualScriptLocalVar();
 	VisualScriptLocalVar();
 };
 };
 
 
+class VisualScriptLocalVarSet: public VisualScriptNode {
+
+	OBJ_TYPE(VisualScriptLocalVarSet,VisualScriptNode)
+
+	StringName name;
+	Variant::Type type;
+
+protected:
+
+	static void _bind_methods();
+public:
+	virtual int get_output_sequence_port_count() const;
+	virtual bool has_input_sequence_port() const;
+
+
+	virtual String get_output_sequence_port_text(int p_port) const;
+
+
+	virtual int get_input_value_port_count() const;
+	virtual int get_output_value_port_count() const;
+
+
+	virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+	virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+	virtual String get_caption() const;
+	virtual String get_text() const;
+	virtual String get_category() const;
+
+	void set_var_name(const StringName& p_name);
+	StringName get_var_name() const;
+
+	void set_var_type(Variant::Type p_type);
+	Variant::Type get_var_type() const;
+
+	virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+	VisualScriptLocalVarSet();
+};
 
 
 
 
 
 

+ 6 - 5
scene/2d/canvas_item.cpp

@@ -650,21 +650,22 @@ int CanvasItem::get_light_mask() const{
 }
 }
 
 
 
 
-void CanvasItem::item_rect_changed() {
+void CanvasItem::item_rect_changed(bool p_size_changed) {
 
 
-	update();
+	if (p_size_changed)
+		update();
 	emit_signal(SceneStringNames::get_singleton()->item_rect_changed);
 	emit_signal(SceneStringNames::get_singleton()->item_rect_changed);
 }
 }
 
 
 
 
-void CanvasItem::draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width) {
+void CanvasItem::draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased) {
 
 
 	if (!drawing) {
 	if (!drawing) {
 		ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
 		ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
 		ERR_FAIL();
 		ERR_FAIL();
 	}
 	}
 
 
-	VisualServer::get_singleton()->canvas_item_add_line(canvas_item,p_from,p_to,p_color,p_width);
+	VisualServer::get_singleton()->canvas_item_add_line(canvas_item,p_from,p_to,p_color,p_width,p_antialiased);
 }
 }
 
 
 void CanvasItem::draw_rect(const Rect2& p_rect, const Color& p_color) {
 void CanvasItem::draw_rect(const Rect2& p_rect, const Color& p_color) {
@@ -1028,7 +1029,7 @@ void CanvasItem::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top);
 	ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top);
 	//ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
 	//ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
 
 
-	ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0));
+	ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0),DEFVAL(false));
 	ObjectTypeDB::bind_method(_MD("draw_rect","rect","color"),&CanvasItem::draw_rect);
 	ObjectTypeDB::bind_method(_MD("draw_rect","rect","color"),&CanvasItem::draw_rect);
 	ObjectTypeDB::bind_method(_MD("draw_circle","pos","radius","color"),&CanvasItem::draw_circle);
 	ObjectTypeDB::bind_method(_MD("draw_circle","pos","radius","color"),&CanvasItem::draw_circle);
 	ObjectTypeDB::bind_method(_MD("draw_texture","texture:Texture","pos","modulate"),&CanvasItem::draw_texture,DEFVAL(Color(1,1,1,1)));
 	ObjectTypeDB::bind_method(_MD("draw_texture","texture:Texture","pos","modulate"),&CanvasItem::draw_texture,DEFVAL(Color(1,1,1,1)));

+ 2 - 2
scene/2d/canvas_item.h

@@ -157,7 +157,7 @@ protected:
 
 
 	_FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify && notify_local_transform) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); }
 	_FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify && notify_local_transform) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); }
 
 
-	void item_rect_changed();
+	void item_rect_changed(bool p_size_changed=true);
 
 
 	void _notification(int p_what);
 	void _notification(int p_what);
 	static void _bind_methods();
 	static void _bind_methods();
@@ -207,7 +207,7 @@ public:
 
 
 	/* DRAWING API */
 	/* DRAWING API */
 
 
-	void draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0);
+	void draw_line(const Point2& p_from, const Point2& p_to, const Color& p_color, float p_width=1.0, bool p_antialiased=false);
 	void draw_rect(const Rect2& p_rect, const Color& p_color);
 	void draw_rect(const Rect2& p_rect, const Color& p_color);
 	void draw_circle(const Point2& p_pos, float p_radius, const Color& p_color);
 	void draw_circle(const Point2& p_pos, float p_radius, const Color& p_color);
 	void draw_texture(const Ref<Texture>& p_texture, const Point2& p_pos, const Color &p_modulate=Color(1,1,1,1));
 	void draw_texture(const Ref<Texture>& p_texture, const Point2& p_pos, const Color &p_modulate=Color(1,1,1,1));

+ 38 - 11
scene/gui/control.cpp

@@ -449,6 +449,13 @@ void Control::remove_child_notify(Node *p_child) {
 
 
 }
 }
 
 
+void Control::_update_canvas_item_transform() {
+
+	Matrix32 xform=Matrix32(data.rotation,get_pos());
+	xform.scale_basis(data.scale);
+	VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(),xform);
+
+}
 
 
 void Control::_notification(int p_notification) {
 void Control::_notification(int p_notification) {
 
 
@@ -600,10 +607,9 @@ void Control::_notification(int p_notification) {
 		} break;
 		} break;
 		case NOTIFICATION_DRAW: {
 		case NOTIFICATION_DRAW: {
 
 
-			Matrix32 xform=Matrix32(data.rotation,get_pos());
-			xform.scale_basis(data.scale);
-			VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(),xform);
-			VisualServer::get_singleton()->canvas_item_set_custom_rect( get_canvas_item(),true, Rect2(Point2(),get_size()));
+			_update_canvas_item_transform();
+			VisualServer::get_singleton()->canvas_item_set_custom_rect( get_canvas_item(),!data.disable_visibility_clip, Rect2(Point2(),get_size()));
+
 			//emit_signal(SceneStringNames::get_singleton()->draw);
 			//emit_signal(SceneStringNames::get_singleton()->draw);
 
 
 		} break;
 		} break;
@@ -1272,17 +1278,24 @@ void Control::_size_changed() {
 	new_size_cache.x = MAX( minimum_size.x, new_size_cache.x );
 	new_size_cache.x = MAX( minimum_size.x, new_size_cache.x );
 	new_size_cache.y = MAX( minimum_size.y, new_size_cache.y );
 	new_size_cache.y = MAX( minimum_size.y, new_size_cache.y );
 
 
-
-	if (new_pos_cache == data.pos_cache && new_size_cache == data.size_cache)
-		return; // did not change, don't emit signal
+	bool pos_changed = new_pos_cache != data.pos_cache;
+	bool size_changed = new_size_cache != data.size_cache;
 
 
 	data.pos_cache=new_pos_cache;
 	data.pos_cache=new_pos_cache;
 	data.size_cache=new_size_cache;
 	data.size_cache=new_size_cache;
 
 
-	notification(NOTIFICATION_RESIZED);
-	item_rect_changed();
-	_change_notify_margins();
-	_notify_transform();
+	if (size_changed) {
+		notification(NOTIFICATION_RESIZED);
+	}
+	if (pos_changed || size_changed) {
+		item_rect_changed(size_changed);
+		_change_notify_margins();
+		_notify_transform();
+	}
+
+	if (pos_changed && !size_changed) {
+		_update_canvas_item_transform(); //move because it won't be updated
+	}
 }
 }
 
 
 float Control::_get_parent_range(int p_idx) const {
 float Control::_get_parent_range(int p_idx) const {
@@ -2382,6 +2395,19 @@ bool Control::is_minimum_size_adjust_blocked() const {
 
 
 	return data.block_minimum_size_adjust;
 	return data.block_minimum_size_adjust;
 }
 }
+
+
+void Control::set_disable_visibility_clip(bool p_ignore) {
+
+	data.disable_visibility_clip=p_ignore;
+	update();
+}
+
+bool Control::is_visibility_clip_disabled() const {
+
+	return data.disable_visibility_clip;
+}
+
 void Control::_bind_methods() {
 void Control::_bind_methods() {
 
 
 
 
@@ -2610,6 +2636,7 @@ Control::Control() {
 	data.drag_owner=0;
 	data.drag_owner=0;
 	data.modal_frame=0;
 	data.modal_frame=0;
 	data.block_minimum_size_adjust=false;
 	data.block_minimum_size_adjust=false;
+	data.disable_visibility_clip=false;
 
 
 
 
 	for (int i=0;i<4;i++) {
 	for (int i=0;i<4;i++) {

+ 5 - 0
scene/gui/control.h

@@ -129,6 +129,7 @@ private:
 		bool stop_mouse;
 		bool stop_mouse;
 
 
 		bool block_minimum_size_adjust;
 		bool block_minimum_size_adjust;
+		bool disable_visibility_clip;
 
 
 		Control *parent;
 		Control *parent;
 		ObjectID drag_owner;
 		ObjectID drag_owner;
@@ -195,6 +196,7 @@ private:
 	void _unref_font( Ref<Font> p_sc);
 	void _unref_font( Ref<Font> p_sc);
 	void _font_changed();
 	void _font_changed();
 
 
+	void _update_canvas_item_transform();
 
 
 
 
 friend class Viewport;
 friend class Viewport;
@@ -402,6 +404,9 @@ public:
 	void set_block_minimum_size_adjust(bool p_block);
 	void set_block_minimum_size_adjust(bool p_block);
 	bool is_minimum_size_adjust_blocked() const;
 	bool is_minimum_size_adjust_blocked() const;
 
 
+	void set_disable_visibility_clip(bool p_ignore);
+	bool is_visibility_clip_disabled() const;
+
 	Control();
 	Control();
 	~Control();
 	~Control();
 
 

+ 109 - 52
scene/gui/graph_edit.cpp

@@ -62,6 +62,7 @@ Error GraphEdit::connect_node(const StringName& p_from, int p_from_port,const St
 	connections.push_back(c);
 	connections.push_back(c);
 	top_layer->update();
 	top_layer->update();
 	update();
 	update();
+	connections_layer->update();
 
 
 	return OK;
 	return OK;
 }
 }
@@ -87,6 +88,7 @@ void GraphEdit::disconnect_node(const StringName& p_from, int p_from_port,const
 			connections.erase(E);
 			connections.erase(E);
 			top_layer->update();
 			top_layer->update();
 			update();
 			update();
+			connections_layer->update();
 			return;
 			return;
 		}
 		}
 	}
 	}
@@ -118,7 +120,11 @@ Vector2 GraphEdit::get_scroll_ofs() const{
 
 
 void GraphEdit::_scroll_moved(double) {
 void GraphEdit::_scroll_moved(double) {
 
 
-	_update_scroll_offset();
+
+	if (!awaiting_scroll_offset_update) {
+		call_deferred("_update_scroll_offset");
+		awaiting_scroll_offset_update=true;
+	}
 	top_layer->update();
 	top_layer->update();
 	update();
 	update();
 
 
@@ -129,6 +135,8 @@ void GraphEdit::_scroll_moved(double) {
 
 
 void GraphEdit::_update_scroll_offset() {
 void GraphEdit::_update_scroll_offset() {
 
 
+	set_block_minimum_size_adjust(true);
+
 	for(int i=0;i<get_child_count();i++) {
 	for(int i=0;i<get_child_count();i++) {
 
 
 		GraphNode *gn=get_child(i)->cast_to<GraphNode>();
 		GraphNode *gn=get_child(i)->cast_to<GraphNode>();
@@ -138,9 +146,15 @@ void GraphEdit::_update_scroll_offset() {
 		Point2 pos=gn->get_offset()*zoom;
 		Point2 pos=gn->get_offset()*zoom;
 		pos-=Point2(h_scroll->get_val(),v_scroll->get_val());
 		pos-=Point2(h_scroll->get_val(),v_scroll->get_val());
 		gn->set_pos(pos);
 		gn->set_pos(pos);
-		gn->set_scale(Vector2(zoom,zoom));
+		if (gn->get_scale()!=Vector2(zoom,zoom)) {
+			gn->set_scale(Vector2(zoom,zoom));
+		}
 	}
 	}
 
 
+	connections_layer->set_pos(-Point2(h_scroll->get_val(),v_scroll->get_val())*zoom);
+	set_block_minimum_size_adjust(false);
+	awaiting_scroll_offset_update=false;
+
 }
 }
 
 
 void GraphEdit::_update_scroll() {
 void GraphEdit::_update_scroll() {
@@ -149,6 +163,9 @@ void GraphEdit::_update_scroll() {
 		return;
 		return;
 
 
 	updating=true;
 	updating=true;
+
+	set_block_minimum_size_adjust(true);
+
 	Rect2 screen;
 	Rect2 screen;
 	for(int i=0;i<get_child_count();i++) {
 	for(int i=0;i<get_child_count();i++) {
 
 
@@ -183,7 +200,13 @@ void GraphEdit::_update_scroll() {
 	else
 	else
 		v_scroll->show();
 		v_scroll->show();
 
 
-	_update_scroll_offset();
+	set_block_minimum_size_adjust(false);
+
+	if (!awaiting_scroll_offset_update) {
+		call_deferred("_update_scroll_offset");
+		awaiting_scroll_offset_update=true;
+	}
+
 	updating=false;
 	updating=false;
 }
 }
 
 
@@ -196,6 +219,16 @@ void GraphEdit::_graph_node_raised(Node* p_gn) {
 	if (gn->is_comment()) {
 	if (gn->is_comment()) {
 		move_child(gn,0);
 		move_child(gn,0);
 	}
 	}
+	int first_not_comment=0;
+	for(int i=0;i<get_child_count();i++) {
+		GraphNode *gn=get_child(i)->cast_to<GraphNode>();
+		if (gn && !gn->is_comment()) {
+			first_not_comment=i;
+			break;
+		}
+	}
+
+	move_child(connections_layer,first_not_comment);
 	top_layer->raise();
 	top_layer->raise();
 	emit_signal("node_selected",p_gn);
 	emit_signal("node_selected",p_gn);
 
 
@@ -208,6 +241,7 @@ void GraphEdit::_graph_node_moved(Node *p_gn) {
 	ERR_FAIL_COND(!gn);
 	ERR_FAIL_COND(!gn);
 	top_layer->update();
 	top_layer->update();
 	update();
 	update();
+	connections_layer->update();
 }
 }
 
 
 void GraphEdit::add_child_notify(Node *p_child) {
 void GraphEdit::add_child_notify(Node *p_child) {
@@ -265,6 +299,7 @@ void GraphEdit::_notification(int p_what) {
 	}
 	}
 	if (p_what==NOTIFICATION_DRAW) {
 	if (p_what==NOTIFICATION_DRAW) {
 
 
+
 		draw_style_box( get_stylebox("bg"),Rect2(Point2(),get_size()) );
 		draw_style_box( get_stylebox("bg"),Rect2(Point2(),get_size()) );
 		VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true);
 		VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true);
 
 
@@ -310,53 +345,7 @@ void GraphEdit::_notification(int p_what) {
 
 
 		}
 		}
 
 
-		{
-			//draw connections
-			List<List<Connection>::Element* > to_erase;
-			for(List<Connection>::Element *E=connections.front();E;E=E->next()) {
-
-				NodePath fromnp(E->get().from);
-
-				Node * from = get_node(fromnp);
-				if (!from) {
-					to_erase.push_back(E);
-					continue;
-				}
-
-				GraphNode *gfrom = from->cast_to<GraphNode>();
-
-				if (!gfrom) {
-					to_erase.push_back(E);
-					continue;
-				}
-
-				NodePath tonp(E->get().to);
-				Node * to = get_node(tonp);
-				if (!to) {
-					to_erase.push_back(E);
-					continue;
-				}
-
-				GraphNode *gto = to->cast_to<GraphNode>();
-
-				if (!gto) {
-					to_erase.push_back(E);
-					continue;
-				}
 
 
-				Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_pos();
-				Color color = gfrom->get_connection_output_color(E->get().from_port);
-				Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_pos();
-				Color tocolor = gto->get_connection_input_color(E->get().to_port);
-				_draw_cos_line(this,frompos,topos,color,tocolor);
-
-			}
-
-			while(to_erase.size()) {
-				connections.erase(to_erase.front()->get());
-				to_erase.pop_front();
-			}
-		}
 
 
 	}
 	}
 
 
@@ -588,6 +577,7 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) {
 		connecting=false;
 		connecting=false;
 		top_layer->update();
 		top_layer->update();
 		update();
 		update();
+		connections_layer->update();
 
 
 	}
 	}
 
 
@@ -625,7 +615,7 @@ void GraphEdit::_bake_segment2d(CanvasItem* p_where,float p_begin, float p_end,c
 
 
 
 
 
 
-		p_where->draw_line(beg,end,p_color.linear_interpolate(p_to_color,mp),2);
+		p_where->draw_line(beg,end,p_color.linear_interpolate(p_to_color,mp),2,true);
 		lines++;
 		lines++;
 	} else {
 	} else {
 		_bake_segment2d(p_where,p_begin,mp,p_a,p_out,p_b,p_in,p_depth+1,p_min_depth,p_max_depth,p_tol,p_color,p_to_color,lines);
 		_bake_segment2d(p_where,p_begin,mp,p_a,p_out,p_b,p_in,p_depth+1,p_min_depth,p_max_depth,p_tol,p_color,p_to_color,lines);
@@ -636,6 +626,7 @@ void GraphEdit::_bake_segment2d(CanvasItem* p_where,float p_begin, float p_end,c
 
 
 void GraphEdit::_draw_cos_line(CanvasItem* p_where,const Vector2& p_from, const Vector2& p_to,const Color& p_color,const Color& p_to_color) {
 void GraphEdit::_draw_cos_line(CanvasItem* p_where,const Vector2& p_from, const Vector2& p_to,const Color& p_color,const Color& p_to_color) {
 
 
+
 #if 1
 #if 1
 
 
 	//cubic bezier code
 	//cubic bezier code
@@ -654,8 +645,7 @@ void GraphEdit::_draw_cos_line(CanvasItem* p_where,const Vector2& p_from, const
 	Vector2 c2 = Vector2(-cp_offset,0);
 	Vector2 c2 = Vector2(-cp_offset,0);
 
 
 	int lines=0;
 	int lines=0;
-	_bake_segment2d(p_where,0,1,p_from,c1,p_to,c2,0,5,12,8,p_color,p_to_color,lines);
-	//print_line("used lines: "+itos(lines));
+	_bake_segment2d(p_where,0,1,p_from,c1,p_to,c2,0,3,9,8,p_color,p_to_color,lines);
 
 
 
 
 #else
 #else
@@ -689,6 +679,59 @@ void GraphEdit::_draw_cos_line(CanvasItem* p_where,const Vector2& p_from, const
 #endif
 #endif
 }
 }
 
 
+
+void GraphEdit::_connections_layer_draw() {
+
+
+	{
+		//draw connections
+		List<List<Connection>::Element* > to_erase;
+		for(List<Connection>::Element *E=connections.front();E;E=E->next()) {
+
+			NodePath fromnp(E->get().from);
+
+			Node * from = get_node(fromnp);
+			if (!from) {
+				to_erase.push_back(E);
+				continue;
+			}
+
+			GraphNode *gfrom = from->cast_to<GraphNode>();
+
+			if (!gfrom) {
+				to_erase.push_back(E);
+				continue;
+			}
+
+			NodePath tonp(E->get().to);
+			Node * to = get_node(tonp);
+			if (!to) {
+				to_erase.push_back(E);
+				continue;
+			}
+
+			GraphNode *gto = to->cast_to<GraphNode>();
+
+			if (!gto) {
+				to_erase.push_back(E);
+				continue;
+			}
+
+			Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_offset();
+			Color color = gfrom->get_connection_output_color(E->get().from_port);
+			Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_offset();
+			Color tocolor = gto->get_connection_input_color(E->get().to_port);
+			_draw_cos_line(connections_layer,frompos,topos,color,tocolor);
+
+		}
+
+		while(to_erase.size()) {
+			connections.erase(to_erase.front()->get());
+			to_erase.pop_front();
+		}
+	}
+}
+
 void GraphEdit::_top_layer_draw() {
 void GraphEdit::_top_layer_draw() {
 
 
 	_update_scroll();
 	_update_scroll();
@@ -854,6 +897,7 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
 
 
 			top_layer->update();
 			top_layer->update();
 			update();
 			update();
+			connections_layer->update();
 		}
 		}
 
 
 		if (b.button_index==BUTTON_LEFT && b.pressed) {
 		if (b.button_index==BUTTON_LEFT && b.pressed) {
@@ -979,6 +1023,7 @@ void GraphEdit::clear_connections() {
 
 
 	connections.clear();
 	connections.clear();
 	update();
 	update();
+	connections_layer->update();
 }
 }
 
 
 void GraphEdit::set_zoom(float p_zoom) {
 void GraphEdit::set_zoom(float p_zoom) {
@@ -1112,6 +1157,7 @@ void GraphEdit::set_use_snap(bool p_enable) {
 
 
 	snap_button->set_pressed(p_enable);
 	snap_button->set_pressed(p_enable);
 	update();
 	update();
+
 }
 }
 
 
 bool GraphEdit::is_using_snap() const{
 bool GraphEdit::is_using_snap() const{
@@ -1175,6 +1221,10 @@ void GraphEdit::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_snap_value_changed"),&GraphEdit::_snap_value_changed);
 	ObjectTypeDB::bind_method(_MD("_snap_value_changed"),&GraphEdit::_snap_value_changed);
 
 
 	ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event);
 	ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event);
+	ObjectTypeDB::bind_method(_MD("_update_scroll_offset"),&GraphEdit::_update_scroll_offset);
+	ObjectTypeDB::bind_method(_MD("_connections_layer_draw"),&GraphEdit::_connections_layer_draw);
+
+
 
 
 	ObjectTypeDB::bind_method(_MD("set_selected","node"),&GraphEdit::set_selected);
 	ObjectTypeDB::bind_method(_MD("set_selected","node"),&GraphEdit::set_selected);
 
 
@@ -1195,6 +1245,7 @@ void GraphEdit::_bind_methods() {
 GraphEdit::GraphEdit() {
 GraphEdit::GraphEdit() {
 	set_focus_mode(FOCUS_ALL);
 	set_focus_mode(FOCUS_ALL);
 
 
+	awaiting_scroll_offset_update=false;
 	top_layer=NULL;
 	top_layer=NULL;
 	top_layer=memnew(GraphEditFilter(this));
 	top_layer=memnew(GraphEditFilter(this));
 	add_child(top_layer);
 	add_child(top_layer);
@@ -1204,6 +1255,12 @@ GraphEdit::GraphEdit() {
 	top_layer->set_stop_mouse(false);
 	top_layer->set_stop_mouse(false);
 	top_layer->connect("input_event",this,"_top_layer_input");
 	top_layer->connect("input_event",this,"_top_layer_input");
 
 
+	connections_layer = memnew( Control );
+	add_child(connections_layer);
+	connections_layer->connect("draw",this,"_connections_layer_draw");
+	connections_layer->set_name("CLAYER");
+	connections_layer->set_disable_visibility_clip(true); // so it can draw freely and be offseted
+
 	h_scroll = memnew(HScrollBar);
 	h_scroll = memnew(HScrollBar);
 	h_scroll->set_name("_h_scroll");
 	h_scroll->set_name("_h_scroll");
 	top_layer->add_child(h_scroll);
 	top_layer->add_child(h_scroll);

+ 3 - 0
scene/gui/graph_edit.h

@@ -110,6 +110,7 @@ private:
 	bool setting_scroll_ofs;
 	bool setting_scroll_ofs;
 	bool right_disconnects;
 	bool right_disconnects;
 	bool updating;
 	bool updating;
+	bool awaiting_scroll_offset_update;
 	List<Connection> connections;
 	List<Connection> connections;
 
 
 	void _bake_segment2d(CanvasItem* p_where,float p_begin, float p_end, const Vector2& p_a, const Vector2& p_out, const Vector2& p_b, const Vector2& p_in, int p_depth, int p_min_depth, int p_max_depth, float p_tol, const Color& p_color, const Color& p_to_color, int &lines) const;
 	void _bake_segment2d(CanvasItem* p_where,float p_begin, float p_end, const Vector2& p_a, const Vector2& p_out, const Vector2& p_b, const Vector2& p_in, int p_depth, int p_min_depth, int p_max_depth, float p_tol, const Color& p_color, const Color& p_to_color, int &lines) const;
@@ -123,9 +124,11 @@ private:
 	void _scroll_moved(double);
 	void _scroll_moved(double);
 	void _input_event(const InputEvent& p_ev);
 	void _input_event(const InputEvent& p_ev);
 
 
+	Control *connections_layer;
 	GraphEditFilter *top_layer;
 	GraphEditFilter *top_layer;
 	void _top_layer_input(const InputEvent& p_ev);
 	void _top_layer_input(const InputEvent& p_ev);
 	void _top_layer_draw();
 	void _top_layer_draw();
+	void _connections_layer_draw();
 	void _update_scroll_offset();
 	void _update_scroll_offset();
 
 
 	Array _get_connection_list() const;
 	Array _get_connection_list() const;

+ 27 - 1
scene/gui/tree.cpp

@@ -171,6 +171,21 @@ String TreeItem::get_text(int p_column) const {
 
 
 }
 }
 
 
+void TreeItem::set_suffix(int p_column,String p_suffix) {
+
+	ERR_FAIL_INDEX( p_column, cells.size() );
+	cells[p_column].suffix=p_suffix;
+
+	_changed_notify(p_column);
+
+}
+
+String TreeItem::get_suffix(int p_column) const {
+
+	ERR_FAIL_INDEX_V( p_column, cells.size(), "" );
+	return cells[p_column].suffix;
+
+}
 
 
 void TreeItem::set_icon(int p_column,const Ref<Texture>& p_icon) {
 void TreeItem::set_icon(int p_column,const Ref<Texture>& p_icon) {
 
 
@@ -927,8 +942,12 @@ void Tree::draw_item_rect(const TreeItem::Cell& p_cell,const Rect2i& p_rect,cons
 
 
 	Ref<Font> font = cache.font;
 	Ref<Font> font = cache.font;
 
 
+	String text = p_cell.text;
+	if (p_cell.suffix!=String())
+		text+=" "+p_cell.suffix;
+
 	rect.pos.y+=Math::floor((rect.size.y-font->get_height())/2.0) +font->get_ascent();
 	rect.pos.y+=Math::floor((rect.size.y-font->get_height())/2.0) +font->get_ascent();
-	font->draw(ci,rect.pos,p_cell.text,p_color,rect.size.x);
+	font->draw(ci,rect.pos,text,p_color,rect.size.x);
 
 
 }
 }
 
 
@@ -1175,6 +1194,9 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2&
 						String s = p_item->cells[i].text;
 						String s = p_item->cells[i].text;
 						s=s.get_slicec(',',option);
 						s=s.get_slicec(',',option);
 
 
+						if (p_item->cells[i].suffix!=String())
+							s+=" "+p_item->cells[i].suffix;
+
 						Ref<Texture> downarrow = cache.select_arrow;
 						Ref<Texture> downarrow = cache.select_arrow;
 
 
 						font->draw(ci, text_pos, s, col,item_rect.size.x-downarrow->get_width() );
 						font->draw(ci, text_pos, s, col,item_rect.size.x-downarrow->get_width() );
@@ -1191,6 +1213,10 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2&
 
 
 						String valtext = String::num( p_item->cells[i].val, Math::step_decimals( p_item->cells[i].step ) );
 						String valtext = String::num( p_item->cells[i].val, Math::step_decimals( p_item->cells[i].step ) );
 						//String valtext = rtos( p_item->cells[i].val );
 						//String valtext = rtos( p_item->cells[i].val );
+
+						if (p_item->cells[i].suffix!=String())
+							valtext+=" "+p_item->cells[i].suffix;
+
 						font->draw( ci, text_pos, valtext, col, item_rect.size.x-updown->get_width());
 						font->draw( ci, text_pos, valtext, col, item_rect.size.x-updown->get_width());
 
 
 						if (!p_item->cells[i].editable)
 						if (!p_item->cells[i].editable)

+ 4 - 0
scene/gui/tree.h

@@ -69,6 +69,7 @@ friend class Tree;
 		Ref<Texture> icon;
 		Ref<Texture> icon;
 		Rect2i icon_region;
 		Rect2i icon_region;
 		String text;
 		String text;
+		String suffix;
 		double min,max,step,val;
 		double min,max,step,val;
 		int icon_max_w;
 		int icon_max_w;
 		bool expr;
 		bool expr;
@@ -168,6 +169,9 @@ public:
 	void set_text(int p_column,String p_text);
 	void set_text(int p_column,String p_text);
 	String get_text(int p_column) const;
 	String get_text(int p_column) const;
 
 
+	void set_suffix(int p_column,String p_suffix);
+	String get_suffix(int p_column) const;
+
 	void set_icon(int p_column,const Ref<Texture>& p_icon);
 	void set_icon(int p_column,const Ref<Texture>& p_icon);
 	Ref<Texture> get_icon(int p_column) const;
 	Ref<Texture> get_icon(int p_column) const;
 
 

+ 2 - 1
servers/visual/rasterizer.h

@@ -685,6 +685,7 @@ public:
 			Point2 from,to;
 			Point2 from,to;
 			Color color;
 			Color color;
 			float width;
 			float width;
+			bool antialiased;
 			CommandLine() { type = TYPE_LINE; }
 			CommandLine() { type = TYPE_LINE; }
 		};
 		};
 
 
@@ -948,7 +949,7 @@ public:
 	virtual void canvas_begin_rect(const Matrix32& p_transform)=0;
 	virtual void canvas_begin_rect(const Matrix32& p_transform)=0;
 	virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect)=0;
 	virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect)=0;
 	virtual void canvas_end_rect()=0;
 	virtual void canvas_end_rect()=0;
-	virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width)=0;
+	virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased)=0;
 	virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate)=0;
 	virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate)=0;
 	virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0;
 	virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0;
 	virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width)=0;
 	virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width)=0;

+ 1 - 1
servers/visual/rasterizer_dummy.cpp

@@ -1615,7 +1615,7 @@ void RasterizerDummy::canvas_end_rect() {
 
 
 }
 }
 
 
-void RasterizerDummy::canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width) {
+void RasterizerDummy::canvas_draw_line(const Point2& p_from, const Point2& p_to, const Color& p_color, float p_width, bool p_antialiased) {
 
 
 
 
 
 

+ 1 - 1
servers/visual/rasterizer_dummy.h

@@ -706,7 +706,7 @@ public:
 	virtual void canvas_begin_rect(const Matrix32& p_transform);
 	virtual void canvas_begin_rect(const Matrix32& p_transform);
 	virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect);
 	virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect);
 	virtual void canvas_end_rect();
 	virtual void canvas_end_rect();
-	virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width);
+	virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased);
 	virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate);
 	virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate);
 	virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1));
 	virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1));
 	virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width);
 	virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width);

+ 2 - 1
servers/visual/visual_server_raster.cpp

@@ -3629,7 +3629,7 @@ float VisualServerRaster::canvas_item_get_self_opacity(RID p_item, float p_self_
 }
 }
 
 
 
 
-void VisualServerRaster::canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width) {
+void VisualServerRaster::canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased) {
 	VS_CHANGED;
 	VS_CHANGED;
 	CanvasItem *canvas_item = canvas_item_owner.get( p_item );
 	CanvasItem *canvas_item = canvas_item_owner.get( p_item );
 	ERR_FAIL_COND(!canvas_item);
 	ERR_FAIL_COND(!canvas_item);
@@ -3640,6 +3640,7 @@ void VisualServerRaster::canvas_item_add_line(RID p_item, const Point2& p_from,
 	line->from=p_from;
 	line->from=p_from;
 	line->to=p_to;
 	line->to=p_to;
 	line->width=p_width;
 	line->width=p_width;
+	line->antialiased=p_antialiased;
 	canvas_item->rect_dirty=true;
 	canvas_item->rect_dirty=true;
 
 
 
 

+ 1 - 1
servers/visual/visual_server_raster.h

@@ -1168,7 +1168,7 @@ public:
 
 
 	virtual void canvas_item_attach_viewport(RID p_item, RID p_viewport);
 	virtual void canvas_item_attach_viewport(RID p_item, RID p_viewport);
 
 
-	virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0);
+	virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to, const Color& p_color, float p_width=1.0, bool p_antialiased=false);
 	virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color);
 	virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color);
 	virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color);
 	virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color);
 	virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false);
 	virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false);

+ 1 - 1
servers/visual/visual_server_wrap_mt.h

@@ -602,7 +602,7 @@ public:
 
 
 	FUNC2(canvas_item_attach_viewport,RID, RID );
 	FUNC2(canvas_item_attach_viewport,RID, RID );
 
 
-	FUNC5(canvas_item_add_line,RID, const Point2& , const Point2& ,const Color& ,float );
+	FUNC6(canvas_item_add_line,RID, const Point2& , const Point2& ,const Color& ,float,bool);
 	FUNC3(canvas_item_add_rect,RID, const Rect2& , const Color& );
 	FUNC3(canvas_item_add_rect,RID, const Rect2& , const Color& );
 	FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& );
 	FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& );
 	FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool );
 	FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool );

+ 1 - 1
servers/visual_server.h

@@ -1020,7 +1020,7 @@ public:
 	virtual void canvas_item_set_on_top(RID p_item, bool p_on_top)=0;
 	virtual void canvas_item_set_on_top(RID p_item, bool p_on_top)=0;
 	virtual bool canvas_item_is_on_top(RID p_item) const=0;
 	virtual bool canvas_item_is_on_top(RID p_item) const=0;
 
 
-	virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0)=0;
+	virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0,bool p_antialiased=false)=0;
 	virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color)=0;
 	virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color)=0;
 	virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color)=0;
 	virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color)=0;
 	virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0;
 	virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0;