LUAPLUS_API void MergeObjects(LuaObject& mergeTo, LuaObject& mergeFrom, bool replaceDuplicates)
{
	if (mergeTo.GetState() == mergeFrom.GetState())
	{
		for (LuaTableIterator it(mergeFrom); it; ++it)
		{
			LuaObject toNodeKeyObj = mergeTo[it.GetKey()];
			if (it.GetValue().IsTable())
			{
				if (toNodeKeyObj.IsNil()  ||  replaceDuplicates)
				{
					toNodeKeyObj = mergeTo.CreateTable(it.GetKey());
				}
				MergeObjects(toNodeKeyObj, it.GetValue(), replaceDuplicates);
			}
			else if (toNodeKeyObj.IsNil()  ||  replaceDuplicates)
			{
				mergeTo.SetObject(it.GetKey(), it.GetValue());
			}
		}
	}
	else
	{
		for (LuaTableIterator it(mergeFrom); it; ++it)
		{
			LuaObject obj;
			switch (it.GetKey().Type())
			{
				case LUA_TBOOLEAN:	obj.AssignBoolean(mergeTo.GetState(), it.GetKey().GetBoolean());		break;
				case LUA_TNUMBER:	obj.AssignNumber(mergeTo.GetState(), it.GetKey().GetNumber());			break;
				case LUA_TSTRING:	obj.AssignString(mergeTo.GetState(), it.GetKey().GetString());			break;
				case LUA_TWSTRING:	obj.AssignWString(mergeTo.GetState(), it.GetKey().GetWString());		break;
			}

			LuaObject toNodeKeyObj = mergeTo[obj];

			if (it.GetValue().IsTable())
			{
				if (toNodeKeyObj.IsNil()  ||  replaceDuplicates)
				{
					toNodeKeyObj = mergeTo.CreateTable(it.GetKey());
				}
				MergeObjects(toNodeKeyObj, it.GetValue(), replaceDuplicates);
			}
			else if (toNodeKeyObj.IsNil()  ||  replaceDuplicates)
			{
				LuaObject toKeyObj;
				switch (it.GetKey().Type())
				{
					case LUA_TBOOLEAN:	toKeyObj.AssignBoolean(mergeTo.GetState(), it.GetKey().GetBoolean());		break;
					case LUA_TNUMBER:	toKeyObj.AssignNumber(mergeTo.GetState(), it.GetKey().GetNumber());			break;
					case LUA_TSTRING:	toKeyObj.AssignString(mergeTo.GetState(), it.GetKey().GetString());			break;
					case LUA_TWSTRING:	toKeyObj.AssignWString(mergeTo.GetState(), it.GetKey().GetWString());		break;
				}

				switch (it.GetValue().Type())
				{
					case LUA_TBOOLEAN:	mergeTo.SetBoolean(toKeyObj, it.GetValue().GetBoolean());	break;
					case LUA_TNUMBER:	mergeTo.SetNumber(toKeyObj, it.GetValue().GetNumber());		break;
					case LUA_TSTRING:	mergeTo.SetString(toKeyObj, it.GetValue().GetString());		break;
					case LUA_TWSTRING:	mergeTo.SetWString(toKeyObj, it.GetValue().GetWString());	break;
				}
			}
		}
	}
}
Beispiel #2
0
void AutoCompData::Build( const AutoCompPageArray& files, AutoCompExports* exports )
{
   Clear();

   // Copy in the export data first... this ensures that
   // we overload exports if something in the scripts
   // has the same name.
   if ( exports )
   {
      m_Exports = new AutoCompExports( *exports );

      const AutoCompClassArray& classes = m_Exports->GetClasses();
      for ( int i=0; i < classes.GetCount(); i++ )
      {
         wxASSERT( classes[i] );
         wxASSERT( !FindClassOrObject( classes[i]->GetName() ) );
         m_Classes.Add( classes[i] );
      }

      const AutoCompFunctionArray& functions = m_Exports->GetFunctions();
      for ( int i=0; i < functions.GetCount(); i++ )
      {
         wxASSERT( functions[i] );
         wxASSERT( !AutoCompFunction::Find( functions[i]->GetName(), m_Functions ) );
         m_Functions.Add( functions[i] );
      }
   }

   // Make a copy of the files.
   for ( int i=0; i < files.GetCount(); i++ )
   {
      wxASSERT( files[i] );
      m_Files.Add( new AutoCompPage( *files[i] ) );
   }

   // Now we merge the objects and vars into our global
   // arrays... this allows for quickly finding data
   // without the need to dig thru pages.
   for ( int i=0; i < m_Files.GetCount(); i++ ) 
   {
      wxASSERT( m_Files[i] );

      MergeObjects( m_Files[i]->GetObjects() );
      MergeVars( m_Files[i]->GetVars() );
   }

   // Now do a pass merging functions so that they are properly
   // made into members of existing objects and classes or added
   // into new namespaces.
   for ( int i=0; i < m_Files.GetCount(); i++ ) 
   {
      wxASSERT( m_Files[i] );
      MergeFunctions( m_Files[i]->GetFunctions() );
   }

   // Now we build the string lists.
   wxString name;
   m_CompList.Empty();
   m_CompIndex.Empty();
   m_ClassList.Empty();
   m_ClassIndex.Empty();
   m_DatablockList.Empty();
   m_DatablockIndex.Empty();
   m_GlobalsList.Empty();
   m_GlobalsIndex.Empty();

   //
   // Grab all the global vars for autocomplete
   // triggered by entering a $.
   //
   m_TempArray.Empty();
   for ( int i=0; i < m_Vars.GetCount(); i++ )
   {
      wxASSERT( m_Vars[i]->IsGlobal() );

      name = m_Vars[i]->m_Name + IDENT_VAR;

      m_TempArray.Add( name );
   }

   BuildString( m_TempArray, &m_GlobalsList, &m_GlobalsIndex );

   //
   // Gather all the concrete datablock types for 
   // autocomplete when the type name is needed.
   //
   m_TempArray.Empty();
   for ( int i=0; i < m_Classes.GetCount(); i++ ) {

      if ( !m_Classes[i]->IsDatablock() || !m_Classes[i]->IsExport() )
         continue;

      name = m_Classes[i]->GetName() + IDENT_DATABLOCK;
      //if ( m_TempArray.Index( name, false ) ) {
         m_TempArray.Add( name );
      //}
   }

   BuildString( m_TempArray, &m_DatablockList, &m_DatablockIndex );

   //
   // Gather all the concrete class types for 
   // autocomplete when the type name is needed.
   //
   m_TempArray.Empty();
   for ( int i=0; i < m_Classes.GetCount(); i++ ) {

      if ( !m_Classes[i]->IsExport() )
         continue;

      name = m_Classes[i]->GetName() + IDENT_CLASS;
      m_TempArray.Add( name );
   }

   BuildString( m_TempArray, &m_ClassList, &m_ClassIndex );

   //
   // Gather all global general identifiers into the 
   // main autocomplete list...
   //
   // Objects (both types and instances)
   // Datablocks (both types and instances)
   // Namespaces
   // Global functions
   // TorqueScript Keywords
   //
   m_TempArray.Empty();
   for ( int i=0; i < m_Functions.GetCount(); i++ ) {

      name = m_Functions[i]->GetName() + IDENT_FUNCTION;
      //if ( m_TempArray.Index( name, false ) ) {
         m_TempArray.Add( name );
      //}
   }

   for ( int i=0; i < m_Classes.GetCount(); i++ ) {

      name = m_Classes[i]->GetName();
      if ( m_Classes[i]->IsDatablock() )
         name += IDENT_DATABLOCK;
      else
         name += IDENT_CLASS;

      //if ( m_TempArray.Index( name, false ) ) {
      m_TempArray.Add( name );
      //}
   }

   for ( int i=0; i < m_Objects.GetCount(); i++ ) 
   {
      name = m_Objects[i]->GetName();

      // Skip adding unnamed objects.
      if ( name.IsEmpty() )
         continue;

      if ( m_Objects[i]->IsNamespace() )
         name += IDENT_NAMESPACE;
      else if ( m_Objects[i]->IsDatablock() )
         name += ITYPE_DATABLOCKOBJECT;
      //else if ( objects[i]->IsDatablock() )
      //   name += IDENT_NAMESPACE;
      else
         name += IDENT_OBJECT;

      //if ( m_TempArray.Index( name, false ) ) {
         m_TempArray.Add( name );
      //}
   }

   // Add in the reserved words.
   m_TempArray.Add( "break?8" );
   m_TempArray.Add( "case?8" );
   m_TempArray.Add( "continue?8" );
   m_TempArray.Add( "datablock?8" );
   m_TempArray.Add( "default?8" );
   m_TempArray.Add( "else?8" );
   m_TempArray.Add( "false?8" );
   m_TempArray.Add( "for?8" );
   m_TempArray.Add( "function?8" );
   m_TempArray.Add( "if?8" );
   m_TempArray.Add( "local?8" );   
   m_TempArray.Add( "new?8" );
   m_TempArray.Add( "or?8" );
   m_TempArray.Add( "package?8" );
   m_TempArray.Add( "return?8" );
   m_TempArray.Add( "singleton?8" );  
   m_TempArray.Add( "switch?8" );
   m_TempArray.Add( "switch$?8" );
   m_TempArray.Add( "true?8" );
   m_TempArray.Add( "while?8" );

   BuildString( m_TempArray, &m_CompList, &m_CompIndex );
}