extern "C" __declspec( dllexport ) void DllMainEx(bool compiler) { char executable[1025]; DWORD size = GetModuleFileName(NULL, executable, 1024); executable[size] = 0; // xp patch size_t last = size; if(last) while(last > 0 && executable[last - 1] != '\\' && executable[last - 1] != '/') last--; char* executable_name = (char*)((size_t)executable + last); if(!Log) Log=(void (__cdecl *)(const char* frmt, ...))printf; ScopeInitializer<S_Global> init(&Global); /* order of listing: - forward declarations of global types - global properties - class declarations - global functions */ // forward declarations of global types for(unsigned int i = 0, j = ASEngine->GetObjectTypeCount(); i < j; i++) { asIObjectType* obj = ASEngine->GetObjectTypeByIndex(i); bool is_template = obj->GetSubTypeId()>=0; Class* cl= new Class(); cl->BaseName = string(obj->GetName()); if(is_template) { cl->Name = string("template <typename T> class ") + cl->BaseName; cl->BaseName += "<T>"; } else cl->Name = string("class ") + cl->BaseName; Global->Classes.push_back(cl); } // global properties for(unsigned int i = 0, j = ASEngine->GetGlobalPropertyCount(); i< j; i++) { const char* name; const char* namespace_; int type_id; bool is_const; const char* type_name; ASEngine->GetGlobalPropertyByIndex(i, &name, &namespace_, &type_id, &is_const); type_name = ASEngine->GetTypeDeclaration(type_id); string namespace_s(namespace_); string name_s(name); string type_name_s(type_name); Property* prop = new Property(); prop->Name = name_s; prop->Namespace = namespace_s; prop->Type = type_name_s; Global->Properties.push_back(prop); } // class declarations for(int i =0 , j = ASEngine->GetObjectTypeCount(); i < j; i++) { // properties asIObjectType* obj = ASEngine->GetObjectTypeByIndex(i); bool is_template = obj->GetSubTypeId() >= 0; string class_name(obj->GetName()); Class* cl = Global->Classes[i]; for(unsigned int n = 0, m=obj->GetPropertyCount(); n < m; n++) cl->Properties.push_back(string(obj->GetPropertyDeclaration(n))); // methods for(unsigned int n = 0, m = obj->GetMethodCount(); n < m; n++) { asIScriptFunction* func = obj->GetMethodByIndex(n); string decl = func->GetDeclaration(false); Member* member = new Member(); member->Declaration = decl; member->ProcessDeclaration(); member->Name = func->GetName(); member->Applied = false; cl->Members.push_back(member); // is the method an operator? if(Global->OperUnaryPost.count(member->Name)) member->ParamCount = func->GetParamCount(); } } // global functions for(int i = 0, j = ASEngine->GetGlobalFunctionCount(); i < j; i++) { asIScriptFunction* func = ASEngine->GetGlobalFunctionByIndex(i); Function* fn = new Function(); fn->Declaration = func->GetDeclaration(false); fn->Name = func->GetName(); fn->Applied = false; fn->ProcessDeclaration(); Global->Functions.push_back(fn); } SubSystem sys = SysUnknown; if(Global->FindClass("Critter")) sys = SysServer; else if(Global->FindClass("CritterCl")) sys = SysClient; else if(Global->FindClass("MapperObject")) sys = SysMapper; string message = string("Processing parameters from ") + executable_name + " (" + SubsystemNames[sys] + " subsystem)...\n"; // here we try to fetch parameters from dlls ProcessParameters(executable, message.c_str()); FILE* f = fopen(FileNames[sys], "w"); if(!f) { Log("Couldn't open %s for writing.\n", FileNames[sys]); return; } fprintf(f,"// Generated by FOnline Intellisense Creator for MSVC.\n// Manual changes in this file will be lost if the program is run again.\n\n"); fprintf(f,"// Used file:\n"); fprintf(f,"// %s\n", executable_name); fprintf(f,"\n#define in\n#define inout\n#define out\n"); // type definitions fprintf(f, "\n// Type definitions\n"); fprintf(f, "typedef unsigned long long uint64;\n"); fprintf(f, "typedef unsigned int uint;\n"); fprintf(f, "typedef unsigned short uint16;\n"); fprintf(f, "typedef unsigned char uint8;\n"); fprintf(f, "typedef long long int64;\n"); fprintf(f, "typedef short int int16;\n"); fprintf(f, "typedef signed char int8;\n"); fprintf(f, "typedef void* unknown; // for anonymous types\n"); fprintf(f,"\n// Forward declarations of global types\n"); for(auto it = Global->Classes.begin(); it != Global->Classes.end(); ++it) fprintf(f, "%s;\n", (*it)->Name.c_str()); fprintf(f,"\n // Global properties\n"); for(auto it = Global->Properties.begin(); it != Global->Properties.end(); ++it) { Property* prop = *it; Process(prop->Type); if(prop->Namespace.empty()) fprintf(f, "%s %s;\n", prop->Type.c_str(), prop->Name.c_str()); else fprintf(f, "%s %s::%s;\n", prop->Type.c_str(), prop->Namespace.c_str(), prop->Name.c_str()); } fprintf(f,"\n // Registered types declarations\n"); for(auto it = Global->Classes.begin(); it != Global->Classes.end(); ++it) { Class* cls = *it; fprintf(f,"%s\n{\n", cls->Name.c_str()); for(auto it2 = cls->Properties.begin(); it2 != cls->Properties.end(); ++it2) { Process(*it2); fprintf(f,"\t%s;\n", it2->c_str()); } for(auto it2 = cls->Members.begin(); it2 != cls->Members.end(); ++it2) { Member* member = *it2; Process(member->Declaration); fprintf(f, "\t%s;", member->Declaration.c_str()); if(member->Comment.size()) fprintf(f,"%s", member->Comment.c_str()); fprintf(f,"\n"); string name = member->Name; auto opDisplay = [&](const StrStrMMap& map, bool params) { auto it = map.lower_bound(name); if(it == map.end()) return; // not an operator int pos = member->Declaration.find(name); for(auto end = map.upper_bound(name); it != end; ++it) { string decl = member->Declaration; decl.replace(pos, it->first.length(), it->second); if(params) { pos = decl.find("("); decl.replace(pos, 1, member->ParamCount ? "(int," : "(int"); } fprintf(f, "\t%s; // created from the previous\n", decl.c_str()); } }; opDisplay(Global->OperUnaryPrefOrIndex, false); opDisplay(Global->OperUnaryPost, true); opDisplay(Global->OperAssignOrBinary, false); } fprintf(f,"};\n\n"); } fprintf(f,"\n // Global functions\n"); for(auto it = Global->Functions.begin(); it != Global->Functions.end(); ++it) { Function* func = *it; Process(func->Declaration); fprintf(f, "%s;", func->Declaration.c_str()); if(func->Comment.size()) fprintf(f, "%s", func->Comment.c_str()); fprintf(f,"\n"); } Log("File %s successfully generated.\n", FileNames[sys]); fclose(f); }