[GME-commit]
GMESRC/Tools/AutoLayout AutoLayoutComponent.dsp,NONE,1.1
Component.rc,NONE,1.1 ComponentConfig.h,NONE,1.1
ComponentDll.cpp,NONE,1.1 ComponentDll.h,NONE,1.1
ComponentLib.idl,NONE,1.1 ComponentObj.cpp,NONE,1.1
ComponentObj.h,NONE,1.1 DlgAutoLayout.cpp,NONE,1.1
DlgAutoLayout.h,NONE,1.1 GAOptimizer.cpp,NONE,1.1
GAOptimizer.h,NONE,1.1 GMEGraph.cpp,NONE,1.1 GMEGraph.h,NONE,1.1
Graph.cpp,NONE,1.1 Graph.h,NONE,1.1 LayoutOptimization.cpp,NONE,1.1
LayoutOptimization.h,NONE,1.1 Random.cpp,NONE,1.1 Random.h,NONE,1.1
RawComponent.cpp,NONE,1.1 RawComponent.h,NONE,1.1
StdAfx.cpp,NONE,1.1 StdAfx.h,NONE,1.1 compicon.ico,NONE,1.1
component.def,NONE,1.1 resource.h,NONE,1.1
gme-commit at list.isis.vanderbilt.edu
gme-commit at list.isis.vanderbilt.edu
Fri Apr 23 17:51:46 CDT 2004
Update of /var/lib/gme/GMESRC/Tools/AutoLayout
In directory braindrain:/tmp/cvs-serv23884
Added Files:
AutoLayoutComponent.dsp Component.rc ComponentConfig.h
ComponentDll.cpp ComponentDll.h ComponentLib.idl
ComponentObj.cpp ComponentObj.h DlgAutoLayout.cpp
DlgAutoLayout.h GAOptimizer.cpp GAOptimizer.h GMEGraph.cpp
GMEGraph.h Graph.cpp Graph.h LayoutOptimization.cpp
LayoutOptimization.h Random.cpp Random.h RawComponent.cpp
RawComponent.h StdAfx.cpp StdAfx.h compicon.ico component.def
resource.h
Log Message:
no message
CVS User: bogyom
--- NEW FILE: AutoLayoutComponent.dsp ---
# Microsoft Developer Studio Project File - Name="AutoLayout" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=AutoLayout - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "AutoLayoutComponent.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "AutoLayoutComponent.mak" CFG="AutoLayout - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "AutoLayout - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "AutoLayout - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "AutoLayout - Win32 Debug"
# PROP BASE Use_MFC 2
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 2
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /I "..\..\GME\Common" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /i "Debug" /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# Begin Custom Build - Performing registration
OutDir=.\Debug
TargetPath=.\Debug\AutoLayoutComponent.dll
InputPath=.\Debug\AutoLayoutComponent.dll
SOURCE="$(InputPath)"
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
regsvr32 /s /c "$(TargetPath)"
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
# End Custom Build
!ELSEIF "$(CFG)" == "AutoLayout - Win32 Release"
# PROP BASE Use_MFC 2
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 2
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O1 /I "." /I "..\..\GME\Common" /D "NDEBUG" /D "_ATL_STATIC_REGISTRY" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /i "Release" /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 /nologo /subsystem:windows /dll /machine:I386
# Begin Custom Build - Performing registration
OutDir=.\Release
TargetPath=.\Release\AutoLayoutComponent.dll
InputPath=.\Release\AutoLayoutComponent.dll
SOURCE="$(InputPath)"
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
regsvr32 /s /c "$(TargetPath)"
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
# End Custom Build
!ENDIF
# Begin Target
# Name "AutoLayout - Win32 Debug"
# Name "AutoLayout - Win32 Release"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\GME\Common\CommonError.cpp
# End Source File
# Begin Source File
SOURCE=..\..\GME\Common\CommonSmart.cpp
# End Source File
# Begin Source File
SOURCE=.\Component.def
# End Source File
# Begin Source File
SOURCE=.\Component.rc
# End Source File
# Begin Source File
SOURCE=.\ComponentDll.cpp
# End Source File
# Begin Source File
SOURCE=.\ComponentLib.idl
# End Source File
# Begin Source File
SOURCE=.\ComponentObj.cpp
# End Source File
# Begin Source File
SOURCE=.\DlgAutoLayout.cpp
# End Source File
# Begin Source File
SOURCE=.\GAOptimizer.cpp
# End Source File
# Begin Source File
SOURCE=.\GMEGraph.cpp
# End Source File
# Begin Source File
SOURCE=.\Graph.cpp
# End Source File
# Begin Source File
SOURCE=.\LayoutOptimization.cpp
# End Source File
# Begin Source File
SOURCE=.\Random.cpp
# End Source File
# Begin Source File
SOURCE=.\RawComponent.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\GME\Common\CommonError.h
# End Source File
# Begin Source File
SOURCE=..\..\GME\Common\CommonSmart.h
# End Source File
# Begin Source File
SOURCE=.\ComponentConfig.h
# End Source File
# Begin Source File
SOURCE=.\ComponentDll.h
# End Source File
# Begin Source File
SOURCE=.\ComponentObj.h
# End Source File
# Begin Source File
SOURCE=.\DlgAutoLayout.h
# End Source File
# Begin Source File
SOURCE=.\GAOptimizer.h
# End Source File
# Begin Source File
SOURCE=.\GMEGraph.h
# End Source File
# Begin Source File
SOURCE=.\Graph.h
# End Source File
# Begin Source File
SOURCE=.\LayoutOptimization.h
# End Source File
# Begin Source File
SOURCE=.\Random.h
# End Source File
# Begin Source File
SOURCE=.\RawComponent.h
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\CompIcon.ico
# End Source File
# End Group
# End Target
# End Project
--- NEW FILE: Component.rc ---
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"1 TYPELIB ""ComponentLib.tlb""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "Interpreter Module\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "Interpreter\0"
VALUE "LegalCopyright", "Copyright 2000\0"
VALUE "OriginalFilename", "Interpreter.DLL\0"
VALUE "ProductName", "Interpreter Module\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
VALUE "OLESelfRegister", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_COMPICON ICON DISCARDABLE "compicon.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG_AUTOLAYOUT DIALOG DISCARDABLE 0, 0, 630, 466
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "GME AutoLayout Component"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Aspects to optimize",IDC_STATIC,503,18,62,8
LISTBOX IDC_LIST_ASPECTS,503,30,109,119,LBS_NOINTEGRALHEIGHT |
LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "Optimize Selected",IDC_BUTTON1,503,178,110,14
CONTROL "Progress1",IDC_PROGRESS_OPT,"msctls_progress32",
WS_BORDER,503,220,109,11
CONTROL "Button2",IDC_BUTTON_GRAPH,"Button",BS_OWNERDRAW |
WS_TABSTOP,15,18,459,433
GROUPBOX "Layout",IDC_STATIC,7,7,475,452
GROUPBOX "",IDC_STATIC,493,7,130,452
CONTROL "Progress2",IDC_PROGRESS_ASPECT,"msctls_progress32",
WS_BORDER,503,202,109,11
CONTROL "Start from scratch",IDC_CHECK_STARTFROMSCRATCH,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,503,161,71,10
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_DIALOG_AUTOLAYOUT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 623
VERTGUIDE, 503
VERTGUIDE, 612
TOPMARGIN, 7
BOTTOMMARGIN, 459
HORZGUIDE, 18
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_PROJNAME "Component"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
1 TYPELIB "ComponentLib.tlb"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
--- NEW FILE: ComponentConfig.h ---
// Component configuration file automatically generated as ComponentConfig.h
// by ConfigureComponent on Tue Apr 20 16:21:38 2004
#define RAWCOMPONENT
// COM UUID-s, names and progID
#define TYPELIB_UUID "2CF3864B-B2C2-405E-A63F-768D682CD1E0"
#define TYPELIB_NAME "MGA Interpreter TypeLibrary (AutoLayout)"
#define COCLASS_UUID "B2B949C9-23C0-4D19-B0B1-2760FA48511F"
#define COCLASS_NAME "MGA Interpreter CoClass (AutoLayout)"
#define COCLASS_PROGID "MGA.PlugIn.AutoLayout"
// This name will appear in the popup window for interpreter selection.
#define COMPONENT_NAME "AutoLayout"
// This text will appear in the toolbar icon tooltip and in the menu.
#define TOOLTIP_TEXT "Auto Layout PlugIn"
// This #define determines the interpreter type:
#define GME_PLUGIN
#define PARADIGM_INDEPENDENT
// This is the location of the GME interfaces file (Mga.idl, Meta.idl, etc)
#define GME_BASE ../../GME
//#define GME_BASE C:/Program Files/GME
#define BON_ICON_SUPPORT
// not defined: #define BON_CUSTOM_TRANSACTIONS
#define REGISTER_SYSTEMWIDE
// Just to please the whims of those Microsoft jerks:
#define COCLASS_UUID_EXPLODED1 0xB2B949C9
#define COCLASS_UUID_EXPLODED2 0x23C0
#define COCLASS_UUID_EXPLODED3 0x4D19
#define COCLASS_UUID_EXPLODED4 0xB0
#define COCLASS_UUID_EXPLODED5 0xB1
#define COCLASS_UUID_EXPLODED6 0x27
#define COCLASS_UUID_EXPLODED7 0x60
#define COCLASS_UUID_EXPLODED8 0xFA
#define COCLASS_UUID_EXPLODED9 0x48
#define COCLASS_UUID_EXPLODED10 0x51
#define COCLASS_UUID_EXPLODED11 0x1F
--- NEW FILE: ComponentDll.cpp ---
// Component.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
//#include <afxctl.h>
#include "ComponentDll.h"
#include "ComponentObj.h"
#include <ComponentConfig.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// Note!
//
// If this DLL is dynamically linked against the MFC
// DLLs, any functions exported from this DLL which
// call into MFC must have the AFX_MANAGE_STATE macro
// added at the very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
//
// It is very important that this macro appear in each
// function, prior to any calls into MFC. This means that
// it must appear as the first statement within the
// function, even before any object variable declarations
// as their constructors may generate calls into the MFC
// DLL.
//
// Please see MFC Technical Notes 33 and 58 for additional
// details.
//
/////////////////////////////////////////////////////////////////////////////
// CComponentApp
BEGIN_MESSAGE_MAP(CComponentApp, CWinApp)
//{{AFX_MSG_MAP(CComponentApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CComponentApp construction
CComponentApp::CComponentApp() : CWinApp(COMPONENT_NAME)
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CComponentApp object
CComponentApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CComponentApp initialization
BOOL CComponentApp::InitInstance()
{
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
COleObjectFactory::RegisterAll();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// Special entry points required for inproc servers
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return AfxDllGetClassObject(rclsid, riid, ppv);
}
STDAPI DllCanUnloadNow(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return AfxDllCanUnloadNow();
}
#define COMRETURN(hr) { HRESULT res; if((res = (hr)) != S_OK) return res; }
// this flag supresses running Dll(Un)RegisterServer if DllInstall is also used
// bool called = false;
// by exporting DllRegisterServer, you can use regsvr.exe
STDAPI DllRegisterServer(void)
{
/*
if(called) return S_OK;
called = true;
*/
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!COleObjectFactory::UpdateRegistryAll(TRUE))
return SELFREG_E_CLASS;
// Note:
// We can register the typelib either from the .tlb file
// or from the resources. But the resource ID of the
// TYPELIB must be 1 !!!
/*
if( !AfxOleRegisterTypeLib(AfxGetInstanceHandle(),
LIBID_MgaComponentLib, NULL) )
return E_FAIL;
*/
CComponentReg reg;
#ifdef REGISTER_SYSTEMWIDE
COMRETURN( reg.RegisterParadigms(REGACCESS_SYSTEM));
#else
COMRETURN( reg.RegisterParadigms());
#endif
return S_OK;
}
STDAPI DllUnregisterServer(void)
{
/*
if(called) return S_OK;
called = true;
*/
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!COleObjectFactory::UpdateRegistryAll(FALSE))
return SELFREG_E_CLASS;
CComponentReg reg;
#ifdef REGISTER_SYSTEMWIDE
COMRETURN( reg.UnregisterParadigms(REGACCESS_SYSTEM));
#else
COMRETURN( reg.UnregisterParadigms());
#endif
return S_OK;
}
#define DIM(x) (sizeof(x)/sizeof((x)[0]))
STDAPI DllInstall(BOOL bInstall, LPCWSTR cmdl) {
regaccessmode_enum code = REGACCESS_NONE;
if(iswdigit(cmdl[0]) && cmdl[1] == 0) {
code = regaccessmode_enum(cmdl[0] - L'0');
}
else {
struct {
LPCWSTR name;
regaccessmode_enum cc;
} mnemonics[] = { { L"USER" , REGACCESS_USER},
{ L"REGACCESS_USER" , REGACCESS_USER},
{ L"SYSTEM" , REGACCESS_SYSTEM},
{ L"REGACCESS_SYSTEM" , REGACCESS_SYSTEM},
{ L"BOTH" , REGACCESS_BOTH},
{ L"REGACCESS_BOTH" , REGACCESS_BOTH} };
for(int i = 0; i < DIM(mnemonics); i++) {
if(_wcsicmp(cmdl, mnemonics[i].name) == 0) {
code = mnemonics[i].cc;
break;
}
}
}
// if(called || code == REGACCESS_NONE) return E_INVALIDARG;
// called = true;
CComponentReg reg;
if(bInstall) { COMRETURN(reg.RegisterParadigms(code)); }
else { COMRETURN(reg.UnregisterParadigms(code)); }
return S_OK;
};
--- NEW FILE: ComponentDll.h ---
// ComponentDll.h : main header file for the Component DLL
//
#if !defined(AFX_COMPONENTAPP_H__DC43D02A_061D_11D2_BBB3_0040051F7117__INCLUDED_)
#define AFX_COMPONENTAPP_H__DC43D02A_061D_11D2_BBB3_0040051F7117__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CComponentApp
// See Component.cpp for the implementation of this class
//
class CComponentApp : public CWinApp
{
public:
CComponentApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CComponentApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
//{{AFX_MSG(CComponentApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COMONENTAPP_H__DC43D02A_061D_11D2_BBB3_0040051F7117__INCLUDED_)
--- NEW FILE: ComponentLib.idl ---
// This file will be processed by the MIDL compiler to produce the
// type library (ComponentLib.tlb).
#include "ComponentConfig.h"
#define MAKE_STR(PAR) #PAR
#define PATH3(X,Y) MAKE_STR(X##Y)
#define PATH2(X,Y) PATH3(X,Y)
#define PATH(NAME) PATH2(GME_BASE,NAME)
#include PATH(/Interfaces/InterfaceColl.h)
#include PATH(/Interfaces/meta.idl)
#include PATH(/Interfaces/mga.idl)
#include PATH(/Interfaces/mgautil.idl)
#include PATH(/Interfaces/gme.idl)
#include PATH(/Interfaces/mgadecorator.idl)
[
uuid(TYPELIB_UUID),
version(1.0),
helpstring(TYPELIB_NAME)
]
library MgaComponentLib
{
importlib("stdole32.tlb");
[
// you have to copy this GUID to the ComponentObj.cpp,
uuid(COCLASS_UUID),
helpstring(COCLASS_NAME)
]
coclass MgaComponent
{
[default] interface IMgaComponentEx;
interface IMgaComponent;
interface IMgaVersionInfo;
};
};
--- NEW FILE: ComponentObj.cpp ---
//////////////////////////////////////////////////////////////////////////////
// ComponentObj.cpp : implementation file
//
// In case of standard and simple components, this file does not need tobe modified
// However, if anything except Component.[cpp,h] or RawComponent.[cpp,h] is to be modified,
// this is the likely and preferred candidate
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// How to convert deprecated BON invoke mechanism into new one
// SITUATION DESCRIPTION:
// The IMgaComponent interface has been extended (IMgaComponentEx), and, accordingly,
// the BON invoke mechanism has also changed, for some time, the
// old mechanism (old Component.h) will also be supported to a limited extent.
// The old BON invoke function was
// void Invoke(CBuilder &builder, CBuilderObjectList &selected, long param);
// The new one is:
// void InvokeEx(CBuilder &builder,CBuilderObject *focus, CBuilderObjectList &selected, long param);
// Differences:
[...1029 lines suppressed...]
return S_OK;
}
HRESULT CComponentReg::RegisterParadigms(regaccessmode_enum loc) {
CComPtr<IMgaRegistrar> registrar;
COMRETURN(registrar.CoCreateInstance(OLESTR("Mga.MgaRegistrar")));
COMRETURN(registrar->RegisterComponent(CComBSTR(COCLASS_PROGID),EXCETYPE, CComBSTR(COMPONENT_NAME), loc));
#ifdef BON_ICON_SUPPORT
COMRETURN(registrar->put_ComponentExtraInfo(loc, CComBSTR(COCLASS_PROGID), CComBSTR("Icon"), CComBSTR(",IDI_COMPICON")));
#endif
COMRETURN(registrar->put_ComponentExtraInfo(loc, CComBSTR(COCLASS_PROGID), CComBSTR("Tooltip"), CComBSTR(TOOLTIP_TEXT)));
POSITION pos = paradigms.GetHeadPosition();
while(pos)
{
CString paradigm = paradigms.GetNext(pos);
COMRETURN(registrar->Associate(CComBSTR(COCLASS_PROGID), CComBSTR(paradigm), loc));
}
return S_OK;
}
--- NEW FILE: ComponentObj.h ---
#if !defined(AFX_INTERPRETEROBJ_H__1DBDD345_023D_11D2_BBB3_0040051F7117__INCLUDED_)
#define AFX_INTERPRETEROBJ_H__1DBDD345_023D_11D2_BBB3_0040051F7117__INCLUDED_
//#include "ComHelp.h"
//#include "GMECOM.h"
#include "ComponentConfig.h"
#include "ComponentLib.h"
#if defined(BUILDER_OBJECT_NETWORK)
#else
// BY PAKA BEGIN
#ifdef BUILDER_OBJECT_NETWORK_V2
#include "BON.h"
#include <BON2Component.h>
#else
#include <RawComponent.h>
#endif // BUILDER_OBJECT_NETWORK_V2
// BY PAKA END
#endif // BUILDER_OBJECT_NETWORK
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// InterpreterObj.h : header file
//
class CComponentObj;
#ifdef GME_ADDON
#ifndef RAWCOMPONENT_H
// BY PAKA BEGIN
#ifndef BON2Component_h
#error GME AddOn-s must be built with the RAW Component interface or BON2 Component Interface
#endif // BON2Component_h
// BY PAKA END
#endif // RAWCOMPONENT_H
class CEventSink : public CCmdTarget {
DECLARE_DYNCREATE(CEventSink)
CEventSink(); // protected constructor used by dynamic creation
public:
CComponentObj *comp;
IMgaEventSink* GetInterface() { return &m_xComponent; }
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CComponentObj)
public:
virtual void OnFinalRelease();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CEventSink();
DECLARE_MESSAGE_MAP()
DECLARE_OLECREATE(CEventSink)
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(CComponentObj)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
public:
BEGIN_INTERFACE_PART(Component, IMgaEventSink)
STDMETHODIMP GlobalEvent(globalevent_enum event);
STDMETHODIMP ObjectEvent(IMgaObject * obj, unsigned long eventmask, VARIANT v);
END_INTERFACE_PART(Component)
};
#endif // GME_ADDON
/////////////////////////////////////////////////////////////////////////////
// CComponentObj command target
class CComponentObj : public CCmdTarget
{
DECLARE_DYNCREATE(CComponentObj)
CComponentObj(); // protected constructor used by dynamic creation
void RegisterActiveObject();
unsigned long registeractiveobjectret;
// Attributes
public:
// Operations
public:
IMgaComponentEx* GetInterface() { return &m_xComponent; }
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CComponentObj)
public:
virtual void OnFinalRelease();
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CComponentObj();
void UnregisterActiveObject();
// Generated message map functions
//{{AFX_MSG(CComponentObj)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
DECLARE_OLECREATE(CComponentObj)
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(CComponentObj)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
BEGIN_INTERFACE_PART(Component, IMgaComponentEx)
STDMETHODIMP InvokeEx( IMgaProject *project, IMgaFCO *currentobj, IMgaFCOs *selectedobjs, long param);
STDMETHODIMP ObjectsInvokeEx( IMgaProject *project, IMgaObject *currentobj, IMgaObjects *selectedobjs, long param);
STDMETHODIMP Invoke(IMgaProject* gme, IMgaFCOs *models, long param);
STDMETHODIMP Initialize(struct IMgaProject *);
STDMETHODIMP Enable(VARIANT_BOOL newVal);
STDMETHODIMP get_InteractiveMode(VARIANT_BOOL *enabled);
STDMETHODIMP get_ComponentParameter(BSTR name, VARIANT *pVal);
STDMETHODIMP put_ComponentParameter(BSTR name, VARIANT newVal);
STDMETHODIMP put_InteractiveMode(VARIANT_BOOL enabled);
STDMETHODIMP get_ComponentType( componenttype_enum *t);
STDMETHODIMP get_ComponentProgID(BSTR *pVal) {
*pVal = CComBSTR(COCLASS_PROGID).Detach();
return S_OK;
};
STDMETHODIMP get_ComponentName(BSTR *pVal) {
*pVal = CComBSTR(COMPONENT_NAME).Detach();
return S_OK;
};
STDMETHODIMP get_Paradigm( BSTR *pVal) {
#ifdef PARADIGM_INDEPENDENT
*pVal = CComBSTR("*").Detach();
#else
*pVal = CComBSTR(PARADIGMS).Detach();
#endif // PARADIGM_INDEPENDENT
return S_OK;
};
END_INTERFACE_PART(Component)
BEGIN_INTERFACE_PART(VersionInfo, IMgaVersionInfo)
STDMETHODIMP get_version(enum MgaInterfaceVersion *pVal);
END_INTERFACE_PART(VersionInfo)
public:
bool interactive;
#ifdef BUILDER_OBJECT_NETWORK
typedef CMap<CString, LPCSTR, CString, LPCSTR> CStringMap;
CStringMap parmap;
#endif
#ifdef RAWCOMPONENT_H
RawComponent rawcomp;
#ifdef GME_ADDON
CComPtr<IMgaEventSink> e_sink;
#endif // GME_ADDON
#endif // RAWCOMPONENT_H
// BY PAKA BEGIN
#ifdef BUILDER_OBJECT_NETWORK_V2
BON::Component bon2Comp;
#ifdef GME_ADDON
CComPtr<IMgaAddOn> addon;
CComPtr<IMgaEventSink> e_sink;
#endif // GME_ADDON
void HandleError( Util::Exception* pEx );
#endif // BUILDER_OBJECT_NETWORK_V2
// BY PAKA END
}; // CComponentObj
class CPushRoutingFrame
{
protected:
CFrameWnd* pOldRoutingFrame;
_AFX_THREAD_STATE* pThreadState;
public:
CPushRoutingFrame(CFrameWnd* pNewRoutingFrame)
{
pThreadState = AfxGetThreadState();
pOldRoutingFrame = pThreadState->m_pRoutingFrame;
pThreadState->m_pRoutingFrame = pNewRoutingFrame;
}
~CPushRoutingFrame()
{ pThreadState->m_pRoutingFrame = pOldRoutingFrame; }
};
class CComponentReg
{
public:
CComponentReg();
CStringList paradigms;
HRESULT RegisterParadigms(regaccessmode_enum loc = REGACCESS_USER);
HRESULT UnregisterParadigms(regaccessmode_enum loc = REGACCESS_USER);
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_INTERPRETEROBJ_H__1DBDD345_023D_11D2_BBB3_0040051F7117__INCLUDED_)
--- NEW FILE: DlgAutoLayout.cpp ---
// DlgAutoLayout.cpp : implementation file
//
#include "stdafx.h"
#include "DlgAutoLayout.h"
#include "CommonSmart.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgAutoLayout dialog
CDlgAutoLayout::CDlgAutoLayout(CWnd* pParent /*=NULL*/)
: CDialog(CDlgAutoLayout::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlgAutoLayout)
m_startFromScratch = TRUE;
//}}AFX_DATA_INIT
m_currentSolution = NULL;
}
CDlgAutoLayout::~CDlgAutoLayout()
{
}
void CDlgAutoLayout::initialzie( IMgaProject * project, IMgaModel* model )
{
m_project = project;
m_model = model;
COMTHROW( m_model->get_Meta((IMgaMetaFCO**)PutOut(m_metaModel)) );
COMTHROW( m_metaModel->get_Aspects( PutOut(m_metaAspects) ) );
}
void CDlgAutoLayout::update( int percentage, LayoutSolution * sol, double score )
{
m_score = score;
m_currentSolution = sol;
m_progressOptimization.SetPos(percentage);
m_graph.Invalidate(FALSE);
m_graph.UpdateWindow();
//Invalidate(FALSE);
UpdateWindow();
}
void CDlgAutoLayout::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgAutoLayout)
DDX_Control(pDX, IDC_LIST_ASPECTS, m_listAspects);
DDX_Control(pDX, IDC_PROGRESS_OPT, m_progressOptimization);
DDX_Control(pDX, IDC_PROGRESS_ASPECT, m_progressAspect);
DDX_Control(pDX, IDC_BUTTON_GRAPH, m_graph);
DDX_Check(pDX, IDC_CHECK_STARTFROMSCRATCH, m_startFromScratch);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlgAutoLayout, CDialog)
//{{AFX_MSG_MAP(CDlgAutoLayout)
ON_WM_DRAWITEM()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgAutoLayout message handlers
BOOL CDlgAutoLayout::OnInitDialog()
{
CDialog::OnInitDialog();
m_graph.GetClientRect( m_graphRect );
m_backBrush.CreateSolidBrush( RGB( 192, 192, 192 ) );
CDC* dc = m_graph.GetDC();
m_graphDC.CreateCompatibleDC( dc );
m_graphBmp.CreateCompatibleBitmap( dc, m_graphRect.Width(), m_graphRect.Height() );
m_graphOldBmp = (CBitmap*)m_graphDC.SelectObject( &m_graphBmp );
m_graph.ReleaseDC( dc );
long aspectNum;
COMTHROW( m_metaAspects->get_Count( &aspectNum ) );
m_listAspects.ResetContent();
for( int i=0; i<aspectNum; ++i )
{
CComObjPtr<IMgaMetaAspect> aspect;
COMTHROW( m_metaAspects->get_Item( i+1, PutOut(aspect) ) );
CComBSTR aspectName;
COMTHROW( aspect->get_Name(&aspectName) );
m_listAspects.AddString( CString(aspectName) );
}
m_listAspects.SetSel(0,TRUE);
m_progressOptimization.ShowWindow( SW_HIDE );
m_progressAspect.ShowWindow( SW_HIDE );
return TRUE;
}
void CDlgAutoLayout::drawSolution( CDC * dc, LayoutSolution * sol )
{
int i,j;
// draw background
dc->FillRect( &m_graphRect, &m_backBrush );
dc->Draw3dRect( &m_graphRect, RGB( 128, 128, 128 ), RGB( 255, 255, 255 ) );
if( sol == NULL )
return;
// draw nodes
NodePosVec& nodes = sol->getNodes();
LayoutOptProblem * problem = sol->getProblem();
double psx = problem->getWidth();
double psy = problem->getHeight();
for( i=0; i<nodes.size(); ++i )
{
int x = (int)(m_graphRect.Width() * nodes[i].m_x / psx);
int y = (int)(m_graphRect.Height() * nodes[i].m_y / psy);
int sx = (int)(m_graphRect.Width() * nodes[i].m_node->m_sx / psx );
int sy = (int)(m_graphRect.Height() * nodes[i].m_node->m_sy / psy );
dc->Rectangle( x, y, x+sx, y+sy );
// draw ports
for( j=0; j<nodes[i].m_node->m_ports.size(); ++j )
{
Node * port = nodes[i].m_node->m_ports[j];
int x1 = x + (int)(m_graphRect.Width() * port->m_x / psx);
int y1 = y + (int)(m_graphRect.Height() * port->m_y / psy);
int sx1 = (int)(m_graphRect.Width() * port->m_sx / psx);
int sy1 = (int)(m_graphRect.Height() * port->m_sy / psy);
dc->Rectangle( x1, y1, x1+sx1, y1+sy1 );
}
}
// draw edges
EdgeVec& edges = problem->getEdges();
for( i=0; i<edges.size(); ++i )
{
int x1, y1, x2, y2;
sol->calcEdgeEnds( edges[i], x1, y1, x2, y2 );
int xp1 = (int)(m_graphRect.Width() * x1 / psx);
int yp1 = (int)(m_graphRect.Height() * y1 / psy);
int xp2 = (int)(m_graphRect.Width() * x2 / psx);
int yp2 = (int)(m_graphRect.Height() * y2 / psy);
dc->MoveTo( xp1, yp1 );
dc->LineTo( xp2, yp2 );
}
// draw score
dc->SetBkMode( TRANSPARENT );
CString scoreLabel;
scoreLabel.Format("Fitness = %.6f", m_score );
dc->TextOut( 10, 10, scoreLabel );
}
void CDlgAutoLayout::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* dc = CDC::FromHandle( lpDrawItemStruct->hDC );
if( nIDCtl == IDC_BUTTON_GRAPH )
{
drawSolution( &m_graphDC, m_currentSolution );
dc->BitBlt( 0, 0, m_graphRect.right, m_graphRect.bottom, &m_graphDC, 0, 0, SRCCOPY );
}
}
void CDlgAutoLayout::OnButton1()
{
UpdateData();
m_progressOptimization.ShowWindow( SW_SHOW );
m_progressAspect.ShowWindow( SW_SHOW );
m_progressAspect.SetPos(1);
m_progressAspect.UpdateWindow();
int selNum = m_listAspects.GetSelCount();
int aspectsProcessed = 0;
if( selNum == 0 )
return;
for( int i=0; i<m_listAspects.GetCount(); ++i )
{
if( m_listAspects.GetSel(i) > 0 )
{
aspectsProcessed++;
m_progressAspect.SetPos( (int)(100*aspectsProcessed/(double)selNum) );
CComObjPtr<IMgaMetaAspect> aspect;
COMTHROW( m_metaAspects->get_Item( i+1, PutOut(aspect) ) );
// oprimize aspect layout
GMEGraph graph( m_project, m_model, aspect );
LayoutOptimizer optimizer( &graph );
optimizer.optimize( this, m_startFromScratch>0 );
m_currentSolution = NULL;
m_graph.Invalidate(FALSE);
// write back results to gme
CComObjPtr<IMgaParts> parts;
long n;
COMTHROW( m_model->get_AspectParts(aspect, 0, PutOut(parts)) );
COMTHROW( parts->get_Count(&n) );
for( int i=0; i<n; ++i )
{
CComObjPtr<IMgaPart> part;
CComObjPtr<IMgaFCO> fco;
CComBSTR icon;
long x,y;
COMTHROW( parts->get_Item(i+1, PutOut(part)) );
COMTHROW( part->get_FCO(PutOut(fco)) );
for( int j=0; j<graph.m_nodes.size(); ++j )
{
if( fco == graph.m_nodes[j]->m_fco )
{
COMTHROW( part->GetGmeAttrs(&icon, &x, &y) );
COMTHROW( part->SetGmeAttrs(icon, graph.m_nodes[j]->m_x, graph.m_nodes[j]->m_y) );
}
}
}
}
}
m_progressOptimization.ShowWindow( SW_HIDE );
m_progressAspect.ShowWindow( SW_HIDE );
CDialog::OnOK();
}
--- NEW FILE: DlgAutoLayout.h ---
#if !defined(AFX_DLGAUTOLAYOUT_H__FF60C817_C49F_4110_96C7_BD85490C6F17__INCLUDED_)
#define AFX_DLGAUTOLAYOUT_H__FF60C817_C49F_4110_96C7_BD85490C6F17__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DlgAutoLayout.h : header file
//
#include "resource.h"
#include "ComponentLib.h"
#include "GMEGraph.h"
#include "LayoutOptimization.h"
#include "GAOptimizer.h"
#include "CommonSmart.h"
/////////////////////////////////////////////////////////////////////////////
// CDlgAutoLayout dialog
class CDlgAutoLayout : public CDialog, public LayoutOptimizerListener
{
// Construction
public:
CDlgAutoLayout(CWnd* pParent = NULL); // standard constructor
virtual ~CDlgAutoLayout();
void initialzie( IMgaProject * project, IMgaModel* model );
virtual void update( int percentage, LayoutSolution * sol, double score );
// Dialog Data
//{{AFX_DATA(CDlgAutoLayout)
enum { IDD = IDD_DIALOG_AUTOLAYOUT };
CListBox m_listAspects;
CProgressCtrl m_progressOptimization;
CProgressCtrl m_progressAspect;
CButton m_graph;
BOOL m_startFromScratch;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgAutoLayout)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
void drawSolution( CDC * dc, LayoutSolution * sol );
CRect m_graphRect;
CBrush m_backBrush;
CDC m_graphDC;
CBitmap m_graphBmp;
CBitmap * m_graphOldBmp;
LayoutSolution * m_currentSolution; // only for display purpose
double m_score;
CComObjPtr<IMgaProject> m_project;
CComObjPtr<IMgaModel> m_model;
CComObjPtr<IMgaMetaModel> m_metaModel;
CComObjPtr<IMgaMetaAspects> m_metaAspects;
// Generated message map functions
//{{AFX_MSG(CDlgAutoLayout)
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual BOOL OnInitDialog();
afx_msg void OnButton1();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DLGAUTOLAYOUT_H__FF60C817_C49F_4110_96C7_BD85490C6F17__INCLUDED_)
--- NEW FILE: GAOptimizer.cpp ---
#include <cfloat>
#include <cmath>
#include <algorithm>
#include "GAOptimizer.h"
#include "Random.h"
namespace GAOptimizer
{
bool genotypeCompare( IGenotype* elem1, IGenotype* elem2 )
{
return (elem1->m_fitness > elem2->m_fitness);
}
TestGenoType::TestGenoType()
{
random();
}
void TestGenoType::derive( IGenotype * parent1, IGenotype * parent2 )
{
m_x = ((TestGenoType*)parent1)->m_x + 0.05 * Random::nextGaussian();
}
void TestGenoType::random()
{
m_x = Random::nextDouble();
}
IGenotype * TestProblem::createRandomSolution()
{
return new TestGenoType();
}
double TestProblem::evaluteSolution( IGenotype * solution )
{
double x = ((TestGenoType*)solution)->m_x;
return sin(10*x)+0.4*sin(5*(x+4));
}
Optimizer::Optimizer()
{
m_problem = NULL;
m_bestSolution = NULL;
}
Optimizer::~Optimizer()
{
clear();
}
void Optimizer::clear()
{
for( unsigned int i=0; i<m_population.size(); ++i )
delete m_population[i];
m_population.clear();
m_subPopulation.clear();
m_problem = NULL;
m_bestSolution = NULL;
}
void Optimizer::init( IProblem * problem, int populationSize, int subPopulationSize )
{
clear();
m_problem = problem;
m_populationSize = populationSize;
m_subPopulationSize = subPopulationSize;
// initialize population with random solutions, find the best individal
m_maxFitness = -DBL_MAX;
m_population.resize( m_populationSize );
for( int i=0; i<m_populationSize; ++i )
{
m_population[i] = m_problem->createRandomSolution(i);
m_population[i]->m_fitness = m_problem->evaluteSolution(m_population[i]);
if( m_population[i]->m_fitness > m_maxFitness )
{
m_maxFitness = m_population[i]->m_fitness;
m_bestSolution = m_population[i];
}
}
// create subpopulation
m_subPopulation.resize( m_subPopulationSize );
m_bestIndNum = (int)floor(0.2 * m_subPopulationSize + 0.5);
m_firstBadInd = m_subPopulationSize - m_bestIndNum;
}
void Optimizer::step()
{
int i;
// select random subpopulation
for( i=0; i<m_subPopulationSize; ++i )
m_subPopulation[i] = m_population[Random::nextInt(m_populationSize)];
// sort subpopulation
std::sort( m_subPopulation.begin(), m_subPopulation.end(), genotypeCompare );
// generate new individuals
for( i=m_firstBadInd; i<m_subPopulationSize; ++i )
{
IGenotype * parent1 = m_subPopulation[Random::nextInt(m_bestIndNum)];
IGenotype * parent2 = m_subPopulation[Random::nextInt(m_bestIndNum)];
IGenotype * child = m_subPopulation[i];
if( child != m_bestSolution && child != parent1 && child != parent2 && parent1 != parent2 )
{
child->derive( parent1, parent2 );
m_subPopulation[i]->m_fitness = m_problem->evaluteSolution( m_subPopulation[i] );
if( m_subPopulation[i]->m_fitness > m_maxFitness )
{
m_maxFitness = m_subPopulation[i]->m_fitness;
m_bestSolution = m_subPopulation[i];
}
}
}
}
void Optimizer::step( int n )
{
for( int i=0; i<n; ++i )
step();
}
IGenotype * Optimizer::getBest()
{
return m_bestSolution;
}
GenotypeVec& Optimizer::getPopulation()
{
return m_population;
}
double Optimizer::getMaxFitness()
{
return m_maxFitness;
}
}
--- NEW FILE: GAOptimizer.h ---
#ifndef _GAOPTIMIZER_H_
#define _GAOPTIMIZER_H_
#include <vector>
#include <functional>
namespace GAOptimizer
{
class IGenotype
{
public:
virtual void derive ( IGenotype * parent1, IGenotype * parent2 ) = 0;
virtual void random () = 0;
double m_fitness;
};
typedef std::vector<IGenotype*> GenotypeVec;
class IProblem
{
public:
virtual IGenotype * createRandomSolution( int i ) = 0;
virtual double evaluteSolution( IGenotype * solution ) = 0;
};
class TestProblem: public IProblem
{
public:
virtual IGenotype * createRandomSolution();
virtual double evaluteSolution( IGenotype * solution );
};
class TestGenoType: public IGenotype
{
public:
TestGenoType();
virtual void derive ( IGenotype * parent1, IGenotype * parent2 );
virtual void random ();
double m_x;
};
class Optimizer
{
public:
Optimizer ();
virtual ~Optimizer ();
void init ( IProblem * problem, int populationSize, int subPopulationSize );
void step ();
void step ( int n );
IGenotype * getBest ();
GenotypeVec& getPopulation ();
double getMaxFitness ();
private:
void clear();
private:
IProblem * m_problem;
int m_populationSize;
int m_subPopulationSize;
GenotypeVec m_population;
GenotypeVec m_subPopulation;
IGenotype * m_bestSolution;
double m_maxFitness;
int m_bestIndNum;
int m_firstBadInd;
};
}
#endif // _GAOPTIMIZER_H_
--- NEW FILE: GMEGraph.cpp ---
#include "stdafx.h"
#include "ComponentLib.h"
#include "CommonSmart.h"
#include "GMEGraph.h"
GMEGraph::GMEGraph( IMgaProject *project, IMgaModel* model, IMgaMetaAspect* aspect )
{
CComObjPtr<IMgaParts> parts;
COMTHROW( model->get_AspectParts(aspect, 0, PutOut(parts)) );
fillNodes( project, parts );
fillConnections( project, parts );
fillSubGraphField();
}
GMEGraph::~GMEGraph()
{
for( int i=0; i<m_nodes.size(); ++i )
{
if( m_nodes[i]->m_fco != NULL )
{
m_nodes[i]->m_fco->Release();
m_nodes[i]->m_fco = NULL;
}
for( int j=0; j<m_nodes[i]->m_ports.size(); ++j )
{
if( m_nodes[i]->m_ports[j]->m_fco != NULL )
{
m_nodes[i]->m_ports[j]->m_fco->Release();
m_nodes[i]->m_ports[j]->m_fco = NULL;
}
}
}
clear();
}
void GMEGraph::fillNodes( IMgaProject *project, IMgaParts* parts )
{
long n;
COMTHROW( parts->get_Count(&n) );
for( int i=0; i<n; ++i )
{
CComObjPtr<IMgaPart> part;
CComObjPtr<IMgaFCO> fco;
CComObjPtr<IMgaMetaPart> metaPart;
objtype_enum type;
CComBSTR icon;
long x,y,sx,sy;
COMTHROW( parts->get_Item(i+1, PutOut(part)) );
COMTHROW( part->get_FCO(PutOut(fco)) );
COMTHROW( part->get_Meta(PutOut(metaPart)) );
COMTHROW( fco->get_ObjType(&type) );
COMTHROW( part->GetGmeAttrs(&icon,&x,&y) );
if( type == OBJTYPE_ATOM || type == OBJTYPE_MODEL || type == OBJTYPE_REFERENCE )
{
CComBSTR decoratorProgID;
COMTHROW( fco->get_RegistryValue(L"decorator",&decoratorProgID) );
CComObjPtr<IMgaDecorator> decorator;
if( decoratorProgID.Length() == 0 )
decorator.CoCreateInstance(L"Mga.BoxDecorator");
else
decorator.CoCreateInstance(decoratorProgID);
COMTHROW( decorator->Initialize( project, metaPart, fco ) );
COMTHROW( decorator->GetPreferredSize( &sx, &sy ) );
COMTHROW( decorator->SetLocation( x, y, x+sx, y+sy ) );
Node * node = new Node( sx, sy );
node->m_x = x;
node->m_y = y;
node->m_fco = fco;
node->m_fco->AddRef();
CComObjPtr<IMgaFCOs> fcos;
COMTHROW( decorator->GetPorts(PutOut(fcos)) );
long fcoNum;
COMTHROW( fcos->get_Count(&fcoNum) );
for( int j=0; j<fcoNum; ++j )
{
CComObjPtr<IMgaFCO> port_fco;
COMTHROW( fcos->get_Item(j+1, PutOut(port_fco)) );
long port_sx, port_sy, port_ex, port_ey;
COMTHROW( decorator->GetPortLocation( port_fco, &port_sx, &port_sy, &port_ex, &port_ey ) );
int x1 = port_ex;
int x2 = port_sx;
if( x2 < x1 )
{
x1 = port_sx;
x2 = port_ex;
}
int y1 = port_ey;
int y2 = port_sy;
if( y2 < y1 )
{
y1 = port_sy;
y2 = port_ey;
}
Node * port = new Node( node, x1, y1, x2-x1, y2-y1 );
port->m_fco = port_fco;
port->m_fco->AddRef();
node->m_ports.push_back( port );
}
m_nodes.push_back( node );
}
}
}
void GMEGraph::fillConnections( IMgaProject *project, IMgaParts* parts )
{
long n;
COMTHROW( parts->get_Count(&n) );
for( int i=0; i<n; ++i )
{
CComObjPtr<IMgaPart> part;
CComObjPtr<IMgaFCO> fco;
objtype_enum type;
COMTHROW( parts->get_Item(i+1, PutOut(part)) );
COMTHROW( part->get_FCO(PutOut(fco)) );
COMTHROW( fco->get_ObjType(&type) );
if( type == OBJTYPE_CONNECTION )
{
CComObjPtr<IMgaSimpleConnection> conn( (IMgaSimpleConnection*)fco.p );
CComObjPtr<IMgaFCO> fco_from;
CComObjPtr<IMgaFCO> fco_to;
COMTHROW( conn->get_Src(PutOut(fco_from)) );
COMTHROW( conn->get_Dst(PutOut(fco_to)) );
Node * nodeFrom = findFCO( fco_from.p );
Node * nodeTo = findFCO( fco_to.p );
if( nodeFrom != NULL && nodeTo != NULL )
{
Edge * e = new Edge( nodeFrom, nodeTo );
setRoutingPrefs(e);
m_edges.push_back( e );
nodeFrom->m_edges.push_back( e );
if( nodeFrom->m_parent != NULL )
nodeFrom->m_parent->m_edges.push_back(e);
if( nodeFrom != nodeTo )
{
nodeTo->m_edges.push_back( e );
if( nodeTo->m_parent != NULL )
nodeTo->m_parent->m_edges.push_back(e);
}
}
}
}
}
Node * GMEGraph::findFCO( IMgaFCO * fco )
{
for( int i=0; i<m_nodes.size(); ++i )
{
Node * n = m_nodes[i];
if( n->m_fco == fco )
return n;
for( int j=0; j<n->m_ports.size(); ++j )
{
Node * p = n->m_ports[j];
if( p->m_fco == fco )
return p;
}
}
return NULL;
}
void GMEGraph::setRoutingPrefs( Edge * e )
{
bool nodeFromIsPort = (e->m_nodeFrom->m_parent != NULL);
bool nodeToIsPort = (e->m_nodeTo->m_parent != NULL);
if( nodeFromIsPort )
{
if( e->m_nodeFrom->m_x < e->m_nodeFrom->m_parent->m_sx/2 )
e->cannotStartToEast = true;
else
e->cannotStartToWest = true;
}
else
{
CComBSTR prefs;
COMTHROW( e->m_nodeFrom->m_fco->get_RegistryValue( L"autorouterPref", &prefs ) );
CString prefs2(prefs);
if( prefs.Length() > 0 )
{
bool N = prefs2.Find("N")!=-1;
bool E = prefs2.Find("E")!=-1;
bool S = prefs2.Find("S")!=-1;
bool W = prefs2.Find("W")!=-1;
if( !N && !E && S && !W ) e->cannotStartToNorth = true;
if( !N && !E && !S && W ) e->cannotStartToEast = true;
if( N && !E && !S && !W ) e->cannotStartToSouth = true;
if( !N && E && !S && !W ) e->cannotStartToWest = true;
}
}
if( nodeToIsPort )
{
if( e->m_nodeTo->m_x < e->m_nodeTo->m_parent->m_sx/2 )
e->cannotEndFromEast = true;
else
e->cannotEndFromWest = true;
}
else
{
CComBSTR prefs;
COMTHROW( e->m_nodeTo->m_fco->get_RegistryValue( L"autorouterPref", &prefs ) );
CString prefs2(prefs);
if( prefs.Length() > 0 )
{
bool N = prefs2.Find("n")!=-1;
bool E = prefs2.Find("e")!=-1;
bool S = prefs2.Find("s")!=-1;
bool W = prefs2.Find("w")!=-1;
if( !N && !E && S && !W ) e->cannotEndFromNorth = true;
if( !N && !E && !S && W ) e->cannotEndFromEast = true;
if( N && !E && !S && !W ) e->cannotEndFromSouth = true;
if( !N && E && !S && !W ) e->cannotEndFromWest = true;
}
}
}
--- NEW FILE: GMEGraph.h ---
#ifndef _GMEGRAPH_H_
#define _GMEGRAPH_H_
#include "ComponentLib.h"
#include "Graph.h"
class GMEGraph : public Graph
{
public:
GMEGraph ( IMgaProject *project, IMgaModel* model, IMgaMetaAspect* aspect );
~GMEGraph ();
private:
void fillNodes ( IMgaProject *project, IMgaParts* parts );
void fillConnections ( IMgaProject *project, IMgaParts* parts );
Node * findFCO ( IMgaFCO * fco );
void setRoutingPrefs ( Edge * edge );
};
#endif // _GMEGRAPH_H_
--- NEW FILE: Graph.cpp ---
#include "Random.h"
#include "Graph.h"
Graph::Graph()
{
}
Graph::Graph( int nodeNum, int edgeNum )
{
int i,j;
// create nodes
for( i=0; i<nodeNum; ++i )
{
Node * n = new Node(60, 40);
m_nodes.push_back( n );
}
// create random edges
while( true )
{
Node * nodeFrom = m_nodes[Random::nextInt(nodeNum)];
Node * nodeTo = m_nodes[Random::nextInt(nodeNum)];
// check if we already have that edge
for( j=0; j<m_edges.size(); ++j )
{
Edge * e2 = m_edges[j];
if(e2->m_nodeFrom == nodeFrom && e2->m_nodeTo == nodeTo)
break;
}
if( j==m_edges.size() )
{
Edge * e = new Edge( nodeFrom, nodeTo );
m_edges.push_back( e );
nodeFrom->m_edges.push_back( e );
if( nodeFrom != nodeTo )
nodeTo->m_edges.push_back( e );
if( m_edges.size() == edgeNum )
break;
}
}
fillSubGraphField();
}
Graph::~Graph()
{
clear();
}
int Graph::getNumberOfSubGraphs()
{
return m_numberOfSubGraphs;
}
void Graph::fillConnectedToOthersFiled()
{
for( int i=0; i<m_nodes.size(); ++i )
{
Node * n = m_nodes[i];
n->m_connectedToOthers = false;
for( int j=0; j<n->m_edges.size(); ++j )
{
if( n->m_edges[j]->m_nodeFrom != n || n->m_edges[j]->m_nodeTo != n )
{
n->m_connectedToOthers = true;
break;
}
}
}
}
void Graph::fillSubGraphFieldForOneNode( Node * n, int subGraph )
{
n->m_subGraph = subGraph;
for( int i=0; i<n->m_edges.size(); ++i )
{
Node * n2 = n->m_edges[i]->getTopLevelFrom();
if( n2 == n )
n2 = n->m_edges[i]->getTopLevelTo();
if( n2 != n && n2->m_subGraph == -1 )
fillSubGraphFieldForOneNode( n2, subGraph );
}
}
void Graph::fillSubGraphField()
{
int i;
fillConnectedToOthersFiled();
for( i=0; i<m_nodes.size(); ++i )
{
m_nodes[i]->m_subGraph = -1;
m_nodes[i]->m_nodeId = i;
}
m_numberOfSubGraphs = 0;
for( i=0; i<m_nodes.size(); ++i )
{
if( m_nodes[i]->m_subGraph == -1 && m_nodes[i]->m_connectedToOthers )
{
fillSubGraphFieldForOneNode(m_nodes[i],m_numberOfSubGraphs);
m_numberOfSubGraphs++;
}
}
}
void Graph::clear()
{
int i;
for( i=0; i<m_nodes.size(); ++i )
delete m_nodes[i];
for( i=0; i<m_edges.size(); ++i )
delete m_edges[i];
m_nodes.clear();
m_edges.clear();
}
--- NEW FILE: Graph.h ---
#ifndef _GRAPH_H_
#define _GRAPH_H_
#include <vector>
struct Node;
struct Edge;
typedef std::vector<Node*> NodeVec;
typedef std::vector<Edge*> EdgeVec;
struct IMgaFCO;
struct Node
{
Node( int sx, int sy )
{
m_sx = sx;
m_sy = sy;
m_parent = NULL;
m_fco = NULL;
}
Node( Node * parent, int x, int y, int sx, int sy )
{
m_parent = parent;
m_x = x;
m_y = y;
m_sx = sx;
m_sy = sy;
m_fco = NULL;
}
int m_nodeId;
bool m_connectedToOthers;
int m_subGraph; // for graph coloring algorithms
Node * m_parent;
int m_x;
int m_y;
int m_sx;
int m_sy;
NodeVec m_ports;
EdgeVec m_edges;
IMgaFCO * m_fco;
};
struct Edge
{
Edge( Node * nodeFrom, Node * nodeTo )
{
m_nodeFrom = nodeFrom;
m_nodeTo = nodeTo;
cannotStartToEast = false;
cannotStartToEast = false;
cannotStartToWest = false;
cannotStartToNorth = false;
cannotStartToSouth = false;
cannotEndFromEast = false;
cannotEndFromWest = false;
cannotEndFromNorth = false;
cannotEndFromSouth = false;
}
Node * getTopLevelFrom()
{
if( m_nodeFrom == NULL || m_nodeFrom->m_parent == NULL )
return m_nodeFrom;
else
return m_nodeFrom->m_parent;
}
Node * getTopLevelTo()
{
if( m_nodeTo == NULL || m_nodeTo->m_parent == NULL )
return m_nodeTo;
else
return m_nodeTo->m_parent;
}
Node * m_nodeFrom;
Node * m_nodeTo;
bool cannotStartToEast;
bool cannotStartToWest;
bool cannotStartToNorth;
bool cannotStartToSouth;
bool cannotEndFromEast;
bool cannotEndFromWest;
bool cannotEndFromNorth;
bool cannotEndFromSouth;
int x1;
int y1;
int x2;
int y2;
};
class Graph
{
public:
Graph ();
Graph ( int nodeNum, int edgeNum );
virtual ~Graph ();
int getNumberOfSubGraphs ();
//protected:
void fillConnectedToOthersFiled ();
void fillSubGraphFieldForOneNode( Node * n, int subGraph );
void fillSubGraphField ();
void clear();
int m_numberOfSubGraphs;
NodeVec m_nodes;
EdgeVec m_edges;
};
#endif // _GRAPH_H_
--- NEW FILE: LayoutOptimization.cpp ---
#include <cmath>
#include <cfloat>
#include "Random.h"
#include "LayoutOptimization.h"
#include "GAOptimizer.h"
using GAOptimizer::IGenotype;
using GAOptimizer::IProblem;
LayoutOptimizer::LayoutOptimizer( Graph * graph )
{
m_graph = graph;
}
void LayoutOptimizer::optimize( LayoutOptimizerListener * listener, bool startFromScratch )
{
int i,j;
int x = 0;
int m = 100;
for( i=0; i<m_graph->getNumberOfSubGraphs(); ++i )
{
LayoutOptProblem problem( m_graph, i, startFromScratch );
GAOptimizer::Optimizer optimizer;
optimizer.init( &problem, 500, 20 );
LayoutSolution * best;
for( j=0; j<m; ++j )
{
optimizer.step(800);
best = (LayoutSolution*)optimizer.getBest();
if( listener != NULL )
listener->update( (int)(100 * (i*m+j) / double(m_graph->getNumberOfSubGraphs() * m)), best, optimizer.getMaxFitness() );
}
// get best, place it, write back positions to m_graph
best->crop();
best->move( x, 0 );
x += (best->m_xmax - best->m_xmin);
for( j=0; j<best->m_nodes.size(); ++j )
{
best->m_nodes[j].m_node->m_x = best->m_nodes[j].m_x;
best->m_nodes[j].m_node->m_y = best->m_nodes[j].m_y;
}
}
// place not connected nodes
int y = YMARGIN;
for( i=0; i<m_graph->m_nodes.size(); ++i )
{
if( !(m_graph->m_nodes[i]->m_connectedToOthers) )
{
m_graph->m_nodes[i]->m_x = x;
m_graph->m_nodes[i]->m_y = y;
y += m_graph->m_nodes[i]->m_sy + 2 * YMARGIN;
}
}
}
LayoutOptProblem::LayoutOptProblem( Graph * graph, int subGraph, bool startFromScratch )
{
int i,j,k;
m_nodeNum = 0;
m_startFromScratch = startFromScratch;
// calcualte area size, set nodeids in graph, fill m_nodes, m_edges
double area = 0;
for( i=0; i<graph->m_nodes.size(); ++i )
{
Node * n = graph->m_nodes[i];
if( n->m_subGraph == subGraph )
{
area += ((2*XMARGIN+n->m_sx) * (2*YMARGIN+n->m_sy));
n->m_nodeId = m_nodeNum;
//n->m_x = -1;
//n->m_y = -1;
m_nodes.push_back( n );
// add edges
for( j=0; j<n->m_edges.size(); ++j )
{
Edge * edgeToAdd = n->m_edges[j];
// find if the edge already added
for( k=0; k<m_edges.size(); ++k )
if( edgeToAdd == m_edges[k] )
break;
if( k==m_edges.size())
m_edges.push_back( edgeToAdd );
}
m_nodeNum++;
}
}
m_width = (int)(3 * sqrt( area ));
m_height = m_width;
}
IGenotype * LayoutOptProblem::createRandomSolution(int i)
{
LayoutSolution * sol = new LayoutSolution(this);
if( i<2 && !m_startFromScratch)
sol->copyFromGraph();
return sol;
}
double LayoutOptProblem::evaluteSolution( IGenotype * solution )
{
LayoutSolution * sol = (LayoutSolution*)solution;
return sol->getScore();
}
LayoutSolution::LayoutSolution( LayoutOptProblem * problem )
{
m_problem = problem;
m_nodes.resize( problem->m_nodeNum );
for( int i=0; i<problem->m_nodeNum; ++i )
m_nodes[i].m_node = problem->m_nodes[i];
random();
}
void LayoutSolution::derive( GAOptimizer::IGenotype * parent1, GAOptimizer::IGenotype * parent2 )
{
LayoutSolution* p1 = (LayoutSolution*)parent1;
LayoutSolution* p2 = (LayoutSolution*)parent2;
// crossing over
int n = m_nodes.size();
if( Random::nextDouble() < 0.8 )
{
for( int i=0; i<n; ++i )
{
if( Random::nextDouble() < 0.5 )
placeNodeNearPos(i, p1->m_nodes[i].m_x, p1->m_nodes[i].m_y );
else
placeNodeNearPos(i, p2->m_nodes[i].m_x, p2->m_nodes[i].m_y );
}
}
else
{
for( int i=0; i<n; ++i )
placeNodeNearPos(i, p1->m_nodes[i].m_x, p1->m_nodes[i].m_y );
}
// mutation
mutate();
}
void LayoutSolution::random()
{
for( int i=0; i<m_nodes.size(); ++i )
placeNodeToRandomPos(i);
}
void LayoutSolution::copyFromGraph()
{
for( int i=0; i<m_nodes.size(); ++i )
{
int x = m_nodes[i].m_node->m_x;
int y = m_nodes[i].m_node->m_y;
placeNodeNearPos(i, x, y );
}
}
bool LayoutSolution::areConnectionsCrossed( Edge * e1, Edge * e2 )
{
if( e1 == e2 )
return false;
calcEdgeEnds( e1 );
calcEdgeEnds( e2 );
return areLinesCrossed( e1->x1, e1->y1, e1->x2, e1->y2, e2->x1, e2->y1, e2->x2, e2->y2 );
}
bool LayoutSolution::areLinesCrossed( int x1, int y1, int x2, int y2, int xp1, int yp1, int xp2, int yp2 )
{
if( (x1==xp1 && y1==yp1) || (x1==xp2 && y1==yp2) || (x2==xp1 && y2==yp1) || (x2==xp2 && y2==yp2) )
return false;
int diffX = x2-x1;
int diffY = y2-y1;
int diffXp = xp2-xp1;
int diffYp = yp2-yp1;
return((((diffX*yp1-diffY*xp1)<(diffX*y1-diffY*x1))^((diffX*yp2-diffY*xp2)<(diffX*y1-diffY*x1))) &
(((diffXp*y1-diffYp*x1)<(diffXp*yp1-diffYp*xp1))^((diffXp*y2-diffYp*x2)<(diffXp*yp1-diffYp*xp1))));
}
int LayoutSolution::getDirViolations( Edge * e )
{
int violations = 0;
if( e->cannotStartToNorth && e->y2<e->y1+2*YMARGIN )
violations++;
else if( e->cannotEndFromNorth && e->y1<e->y2+2*YMARGIN )
violations++;
if( e->cannotStartToEast && e->x2>e->x1-2*XMARGIN )
violations++;
else if( e->cannotEndFromEast && e->x1>e->x2-2*XMARGIN )
violations++;
if( e->cannotStartToSouth && e->y2>e->y1-2*YMARGIN )
violations++;
else if( e->cannotEndFromSouth && e->y1>e->y2-2*YMARGIN )
violations++;
if( e->cannotStartToWest && e->x2<e->x1+2*XMARGIN )
violations++;
else if( e->cannotEndFromWest && e->x1<e->x2+2*XMARGIN )
violations++;
/*if( e->cannotStartToNorth && e->y2<e->y1+2*YMARGIN )
violations++;
if( e->cannotStartToEast && e->x2>e->x1-2*XMARGIN )
violations++;
if( e->cannotStartToSouth && e->y2>e->y1-2*YMARGIN )
violations++;
if( e->cannotStartToWest && e->x2<e->x1+2*XMARGIN )
violations++;
if( e->cannotEndFromNorth && e->y1<e->y2+2*YMARGIN )
violations++;
if( e->cannotEndFromEast && e->x1>e->x2-2*XMARGIN )
violations++;
if( e->cannotEndFromSouth && e->y1>e->y2-2*YMARGIN )
violations++;
if( e->cannotEndFromWest && e->x1<e->x2+2*XMARGIN )
violations++;*/
return violations;
}
void LayoutSolution::calcBoundingBox()
{
m_xmin = INT_MAX;
m_ymin = INT_MAX;
m_xmax = -INT_MAX;
m_ymax = -INT_MAX;
int n = m_nodes.size();
for( int i=0; i<n; ++i )
{
if( m_nodes[i].m_x-XMARGIN < m_xmin )
m_xmin = m_nodes[i].m_x-XMARGIN;
if( m_nodes[i].m_y-YMARGIN < m_ymin )
m_ymin = m_nodes[i].m_y-YMARGIN;
if( m_nodes[i].m_x+m_nodes[i].m_node->m_sx + XMARGIN > m_xmax )
m_xmax = m_nodes[i].m_x+m_nodes[i].m_node->m_sx + XMARGIN;
if( m_nodes[i].m_y+m_nodes[i].m_node->m_sy + YMARGIN > m_ymax )
m_ymax = m_nodes[i].m_y+m_nodes[i].m_node->m_sy + YMARGIN;
}
}
void LayoutSolution::crop()
{
calcBoundingBox();
move( -m_xmin, -m_ymin );
}
void LayoutSolution::move( int dx, int dy )
{
calcBoundingBox();
int n = m_nodes.size();
for( int i=0; i<n; ++i )
{
m_nodes[i].m_x += dx;
m_nodes[i].m_y += dy;
}
m_xmin += dx;
m_ymin += dy;
m_xmax += dx;
m_ymax += dy;
}
void LayoutSolution::calcEdgeEnds( Edge * e, int& x1, int& y1, int& x2, int& y2 )
{
if( e->m_nodeFrom->m_parent == NULL )
{
x1 = m_nodes[e->m_nodeFrom->m_nodeId].m_x + e->m_nodeFrom->m_sx / 2;
y1 = m_nodes[e->m_nodeFrom->m_nodeId].m_y + e->m_nodeFrom->m_sy / 2;
}
else
{
x1 = m_nodes[e->m_nodeFrom->m_parent->m_nodeId].m_x + e->m_nodeFrom->m_x + e->m_nodeFrom->m_sx / 2;
y1 = m_nodes[e->m_nodeFrom->m_parent->m_nodeId].m_y + e->m_nodeFrom->m_y + e->m_nodeFrom->m_sy / 2;
}
if( e->m_nodeTo->m_parent == NULL )
{
x2 = m_nodes[e->m_nodeTo->m_nodeId].m_x + e->m_nodeTo->m_sx / 2;
y2 = m_nodes[e->m_nodeTo->m_nodeId].m_y + e->m_nodeTo->m_sy / 2;
}
else
{
x2 = m_nodes[e->m_nodeTo->m_parent->m_nodeId].m_x + e->m_nodeTo->m_x + e->m_nodeTo->m_sx / 2;
y2 = m_nodes[e->m_nodeTo->m_parent->m_nodeId].m_y + e->m_nodeTo->m_y + e->m_nodeTo->m_sy / 2;
}
}
void LayoutSolution::calcEdgeEnds( Edge * e )
{
calcEdgeEnds( e, e->x1, e->y1, e->x2, e->y2 );
}
bool LayoutSolution::isNodePlaceable( int node, int x, int y )
{
NodePos& n = m_nodes[node];
// check if out of search region
if( x<XMARGIN || y<YMARGIN || x+n.m_node->m_sx+XMARGIN>=m_problem->m_width
|| y+n.m_node->m_sy+YMARGIN>=m_problem->m_height )
return false;
// check if intersets with others
int x1 = x - XMARGIN;
int y1 = y - YMARGIN;
int sx1 = n.m_node->m_sx + 2 * XMARGIN;
int sy1 = n.m_node->m_sy + 2 * YMARGIN;
for( int i=0; i<m_nodes.size(); ++i )
{
if( i!=node)
{
NodePos& n2 = m_nodes[i];
int x2 = n2.m_x - XMARGIN;
int y2 = n2.m_y - YMARGIN;
int sx2 = n2.m_node->m_sx + 2 * XMARGIN;
int sy2 = n2.m_node->m_sy + 2 * YMARGIN;
if( !((x2 + sx2 <= x1) ||
(y2 + sy2 <= y1) ||
(x2 >= x1 + sx1) ||
(y2 >= y1 + sy1)))
{
return false;
}
}
}
return true;
}
void LayoutSolution::placeNode( int node, int x, int y )
{
m_nodes[node].m_x = x;
m_nodes[node].m_y = y;
}
void LayoutSolution::removeNode( int node )
{
m_nodes[node].m_x = -1;
m_nodes[node].m_y = -1;
}
void LayoutSolution::placeNodeNearPos( int node, int xorg, int yorg )
{
int maxx = m_problem->m_width - m_nodes[node].m_node->m_sx - XMARGIN;
int maxy = m_problem->m_height - m_nodes[node].m_node->m_sy - YMARGIN;
if( xorg<XMARGIN)
xorg = XMARGIN;
if( xorg>=maxx )
xorg = maxx;
if( yorg<YMARGIN)
yorg = YMARGIN;
if( yorg>=maxy )
yorg = maxy;
int x = xorg;
int y = yorg;
double r = 10;
int m = 0;
int n = 0;
while( x<XMARGIN || x>=maxx || y<YMARGIN|| y>=maxy || !isNodePlaceable(node,x,y) )
{
x = (int)(xorg + r * Random::nextGaussian());
y = (int)(yorg + r * Random::nextGaussian());
++n;
if( n>4 )
{
n = 0;
if(r<m_problem->m_width/2)
r*=2;
}
m++;
if( m > 200 )
{
//printf("szivas\n");
return;
}
}
placeNode( node, x, y );
}
void LayoutSolution::placeNodeToRandomPos( int node )
{
placeNodeNearPos( node, XMARGIN+Random::nextInt(m_problem->m_width-m_nodes[node].m_node->m_sx-2*XMARGIN),
YMARGIN+Random::nextInt(m_problem->m_height-m_nodes[node].m_node->m_sy-2*YMARGIN) );
}
void LayoutSolution::randomSwap()
{
int node1 = Random::nextInt(m_nodes.size());
int node2 = Random::nextInt(m_nodes.size());
int x1 = m_nodes[node1].m_x;
int y1 = m_nodes[node1].m_y;
int x2 = m_nodes[node2].m_x;
int y2 = m_nodes[node2].m_y;
removeNode(node1);
removeNode(node2);
placeNodeNearPos( node1, x2, y2 );
placeNodeNearPos( node2, x1, y1 );
}
void LayoutSolution::moveOneToRandomPos()
{
int node = Random::nextInt(m_nodes.size());
removeNode( node );
placeNodeToRandomPos( node );
}
void LayoutSolution::selectRandomNodes( IntSet& nodes )
{
int n = Random::nextInt( m_nodes.size()/2 );
for( int i=0; i<n; ++i )
{
int nodeInd = Random::nextInt( m_nodes.size() );
nodes.insert( nodeInd );
}
}
void LayoutSolution::addSubGraphNodes( Node * act, IntSet& nodes, Node * prohibited, double cutoff )
{
//if( act == prohibited || Random::nextDouble() < cutoff || nodes.find( act->m_nodeId ) != nodes.end() )
if( act == prohibited || nodes.find( act->m_nodeId ) != nodes.end() )
return;
nodes.insert( act->m_nodeId );
for( int i=0; i<act->m_edges.size(); ++i )
{
Edge * e = act->m_edges[i];
Node * n1 = e->getTopLevelFrom();
Node * n2 = e->getTopLevelTo();
if( n1!=act && n1!=prohibited )
addSubGraphNodes( n1, nodes, prohibited, cutoff );
if( n2!=act && n2!=prohibited )
addSubGraphNodes( n2, nodes, prohibited, cutoff );
}
}
void LayoutSolution::selectSubGraph( IntSet& nodes )
{
Edge * edge = m_problem->m_edges[Random::nextInt(m_problem->m_edges.size())];
Node * act;
Node * prohibited;
if( Random::nextDouble() < 0.5 )
{
act = edge->getTopLevelFrom();
prohibited = edge->getTopLevelTo();
}
else
{
prohibited = edge->getTopLevelFrom();
act = edge->getTopLevelTo();
}
double cutoff = 0;
//if( Random::nextDouble() < 0.5 )
// cutoff = 0.5 * Random::nextDouble();
addSubGraphNodes( act, nodes, prohibited, cutoff );
}
void LayoutSolution::moveSome()
{
IntSet nodes;
if( Random::nextDouble() < 0.2 )
selectRandomNodes( nodes );
else;
selectSubGraph( nodes );
int dx, dy;
double r = 1 + 10 * Random::nextDouble();
if( Random::nextDouble() < 0.2 )
r = 200;
if( Random::nextDouble() < 0.333 )
{
dx = (int)(r * Random::nextGaussian());
dy = 0;
}
else if( Random::nextDouble() < 0.5 )
{
dx = 0;
dy = (int)(r * Random::nextGaussian());
}
else
{
dx = (int)(r * Random::nextGaussian());
dy = (int)(r * Random::nextGaussian());
}
IntSet::iterator it;
for( it=nodes.begin(); it!=nodes.end(); ++it )
{
int node = *it;
m_nodes[node].m_tempx = m_nodes[node].m_x + dx;
m_nodes[node].m_tempy = m_nodes[node].m_y + dy;
removeNode( node );
}
for( it=nodes.begin(); it!=nodes.end(); ++it )
{
int node = *it;
placeNodeNearPos( node, m_nodes[node].m_tempx, m_nodes[node].m_tempy );
}
}
void LayoutSolution::moveOne()
{
int nodeInd = Random::nextInt( m_nodes.size() );
double r = 1 + 10 * Random::nextDouble();
if( Random::nextDouble() < 0.2 )
r = 200;
int dx = (int)(r * Random::nextGaussian());
int dy = (int)(r * Random::nextGaussian());
int x = m_nodes[nodeInd].m_x + dx;
int y = m_nodes[nodeInd].m_y + dy;
removeNode( nodeInd );
placeNodeNearPos( nodeInd, x, y );
}
void LayoutSolution::mutate()
{
int r = Random::nextInt(8);
switch( r )
{
case 0:
case 1:
moveOneToRandomPos();
break;
case 2:
case 3:
moveOne();
break;
case 4:
case 5:
moveSome();
break;
case 6:
case 7:
randomSwap();
break;
}
}
double LayoutSolution::getScore()
{
int i,j;
int crossings = 0;
int dirViolations = 0;
double length = 0;
int n = m_problem->m_edges.size();
int m = m_nodes.size();
double weightPointX = 0;
double weightPointY = 0;
for( i=0; i<n; ++i )
{
Edge * e1 = m_problem->m_edges[i];
calcEdgeEnds( e1 );
dirViolations += getDirViolations( e1 );
double dx = (e1->x1 - e1->x2);
double dy = (e1->y1 - e1->y2);
//double d = fabs(dx) + fabs(dy);
double d = sqrt(dx*dx + dy*dy);// + fabs(dx);
//d = pow(d, 2);
length += d;
}
for( i=0; i<n-1; ++i )
{
Edge * e1 = m_problem->m_edges[i];
for( j=i+1; j<n; ++j )
{
Edge * e2 = m_problem->m_edges[j];
if( areConnectionsCrossed( e1, e2 ) )
crossings++;
}
}
return -0.01*length - 1*crossings - 10*dirViolations;
}
--- NEW FILE: LayoutOptimization.h ---
#ifndef _LAYOUTOPTIMIZATION_H_
#define _LAYOUTOPTIMIZATION_H_
#pragma warning( disable : 4786)
#include <set>
#include "GAOptimizer.h"
#include "Graph.h"
#define XMARGIN 50
#define YMARGIN 20
typedef std::vector<int> IntVec;
typedef std::set<int> IntSet;
class LayoutSolution;
class LayoutOptimizerListener
{
public:
virtual void update( int percentage, LayoutSolution * sol, double score ) = 0;
};
class LayoutOptimizer
{
public:
LayoutOptimizer ( Graph * graph );
void optimize ( LayoutOptimizerListener * listener = NULL, bool startFromScratch=true );
private:
Graph * m_graph;
};
class LayoutOptProblem: public GAOptimizer::IProblem
{
public:
LayoutOptProblem ( Graph * graph, int subGraph, bool startFromScratch );
virtual GAOptimizer::IGenotype * createRandomSolution ( int i );
virtual double evaluteSolution ( GAOptimizer::IGenotype * solution );
int getWidth () { return m_width; }
int getHeight () { return m_height; }
EdgeVec& getEdges () { return m_edges; }
private:
bool m_startFromScratch;
NodeVec m_nodes;
EdgeVec m_edges;
int m_nodeNum;
int m_width;
int m_height;
friend class LayoutSolution;
friend class LayoutOptimizer;
};
struct NodePos
{
Node * m_node;
int m_x;
int m_y;
int m_tempx;
int m_tempy;
};
typedef std::vector<NodePos> NodePosVec;
class LayoutSolution: public GAOptimizer::IGenotype
{
public:
LayoutSolution ( LayoutOptProblem * problem );
void derive ( GAOptimizer::IGenotype * parent1,
GAOptimizer::IGenotype * parent2 );
void random ();
void copyFromGraph ();
bool areConnectionsCrossed ( Edge * e1, Edge * e2 );
static bool areLinesCrossed ( int x1, int y1, int x2, int y2, int xp1, int yp1, int xp2, int yp2 );
int getDirViolations ( Edge * e );
double getScore ();
NodePosVec& getNodes () { return m_nodes; }
LayoutOptProblem* getProblem () { return m_problem; }
void calcBoundingBox ();
void crop ();
void move ( int dx, int dy );
void calcEdgeEnds ( Edge * e, int& x1, int& y1, int& x2, int& y2 );
private:
void calcEdgeEnds ( Edge * e );
bool isNodePlaceable ( int node, int x, int y );
void placeNode ( int node, int x, int y );
void removeNode ( int node );
void placeNodeNearPos ( int node, int xorg, int yorg );
void placeNodeToRandomPos ( int node );
void randomSwap ();
void moveOneToRandomPos ();
void selectRandomNodes ( IntSet& nodes );
void addSubGraphNodes ( Node * act, IntSet& nodes, Node * prohibited, double cutoff );
void selectSubGraph ( IntSet& nodes );
void moveSome ();
void moveOne ();
void mutate ();
LayoutOptProblem * m_problem;
NodePosVec m_nodes;
int m_xmin;
int m_ymin;
int m_xmax;
int m_ymax;
friend class LayoutOptimizer;
};
#endif // _LAYOUTOPTIMIZATION_H_
--- NEW FILE: Random.cpp ---
#include <cstdlib>
#include <ctime>
#include <cmath>
#include "Random.h"
bool Random::haveNextNextGaussian = false;
double Random::nextNextGaussian = 0;
void Random::setSeed( int seed )
{
srand(seed);
}
void Random::setRandomSeed()
{
srand( (unsigned)time( NULL ) );
}
double Random::nextDouble()
{
return rand() / double(RAND_MAX+1);
}
int Random::nextInt( int max )
{
return (int)floor(max * nextDouble());
}
double Random::nextGaussian()
{
// See Knuth, ACP, Section 3.4.1 Algorithm C.
if (haveNextNextGaussian)
{
haveNextNextGaussian = false;
return nextNextGaussian;
}
else
{
double v1, v2, s;
do
{
v1 = 2 * nextDouble() - 1; // between -1 and 1
v2 = 2 * nextDouble() - 1; // between -1 and 1
s = v1 * v1 + v2 * v2;
}
while (s >= 1 || s == 0);
double multiplier = sqrt(-2 * log(s)/s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
--- NEW FILE: Random.h ---
#ifndef _RANDOM_H_
#define _RANDOM_H_
class Random
{
public:
static void setSeed ( int seed );
static void setRandomSeed ();
static double nextDouble ();
static int nextInt ( int max );
static double nextGaussian ();
private:
static bool haveNextNextGaussian;
static double nextNextGaussian;
};
#endif // _RANDOM_H_
--- NEW FILE: RawComponent.cpp ---
///////////////////////////////////////////////////////////////////////////
// RawComponent.cpp, the main RAW COM component implementation file
// This is the file (along with its header RawComponent.h)
// that the component implementor is expected to modify in the first place
//
///////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//#include "ComHelp.h"
//#include "GMECOM.h"
#include "ComponentLib.h"
#include "ComponentConfig.h"
#include "RawComponent.h"
#include "CommonSmart.h"
#include "GMEGraph.h"
#include "DlgAutoLayout.h"
// this method is called after all the generic initialization is done
// this should be empty, unless application-specific initialization is needed
STDMETHODIMP RawComponent::Initialize(struct IMgaProject *) {
return S_OK;
}
// this is the obsolete component interface
// this present implementation either tries to call InvokeEx, or returns an error;
STDMETHODIMP RawComponent::Invoke(IMgaProject* gme, IMgaFCOs *models, long param) {
#ifdef SUPPORT_OLD_INVOKE
CComPtr<IMgaFCO> focus;
CComVariant parval = param;
return InvokeEx(gme, focus, selected, parvar);
#else
if(interactive) {
AfxMessageBox("This component does not support the obsolete invoke mechanism");
}
return E_MGA_NOT_SUPPORTED;
#endif
}
// This is the main component method for interpereters and plugins.
// May als be used in case of invokeable addons
STDMETHODIMP RawComponent::InvokeEx( IMgaProject *project, IMgaFCO *currentobj,
IMgaFCOs *selectedobjs, long param) {
COMTRY
{
if(interactive)
{
CComBSTR projname;
CComObjPtr<IMgaTerritory> terr;
COMTHROW(project->CreateTerritory(NULL, PutOut(terr)));
COMTHROW(project->BeginTransaction(terr));
try
{
if(currentobj==NULL)
throw 0;
objtype_enum objType;
COMTHROW(currentobj->get_ObjType(&objType));
if( objType != OBJTYPE_MODEL )
{
AfxMessageBox("AutoLayout can only run on models. Open a model and try again!");
throw 0;
}
CDlgAutoLayout dlg;
dlg.initialzie( project, (IMgaModel*)currentobj );
dlg.DoModal();
COMTHROW( project->CommitTransaction() );
}
catch(...)
{
AfxMessageBox("Valami szar van");
project->AbortTransaction();
}
}
} COMCATCH(;);
}
// GME currently does not use this function
// you only need to implement it if other invokation mechanisms are used
STDMETHODIMP RawComponent::ObjectsInvokeEx( IMgaProject *project, IMgaObject *currentobj, IMgaObjects *selectedobjs, long param) {
if(interactive) {
AfxMessageBox("Tho ObjectsInvoke method is not implemented");
}
return E_MGA_NOT_SUPPORTED;
}
// implement application specific parameter-mechanism in these functions:
STDMETHODIMP RawComponent::get_ComponentParameter(BSTR name, VARIANT *pVal) {
return S_OK;
}
STDMETHODIMP RawComponent::put_ComponentParameter(BSTR name, VARIANT newVal) {
return S_OK;
}
#ifdef GME_ADDON
// these two functions are the main
STDMETHODIMP RawComponent::GlobalEvent(globalevent_enum event) {
if(event == GLOBALEVENT_UNDO) {
AfxMessageBox("UNDO!!");
}
return S_OK;
}
STDMETHODIMP RawComponent::ObjectEvent(IMgaObject * obj, unsigned long eventmask, VARIANT v) {
if(eventmask & OBJEVENT_CREATED) {
CComBSTR objID;
COMTHROW(obj->get_ID(&objID));
AfxMessageBox( "Object created! ObjID: " + CString(objID));
}
return S_OK;
}
#endif
--- NEW FILE: RawComponent.h ---
#ifndef RAWCOMPONENT_H
#define RAWCOMPONENT_H
// Declaration of the main RAW COM component interface class
#ifdef BUILDER_OBJECT_NETWORK
#error This file should only be included in the RAW COM configurations
#endif
class RawComponent {
////////////////////
// Insert your application specific member and method definitions here
public:
RawComponent() { ; }
private:
// Try not to modify the code below this line
////////////////////
public:
#ifdef GME_ADDON
CComPtr<IMgaProject> project; // this is set before Initialize() is called
CComPtr<IMgaAddOn> addon; // this is set before Initialize() is called
#endif
bool interactive;
STDMETHODIMP Initialize(struct IMgaProject *);
STDMETHODIMP Invoke(IMgaProject* gme, IMgaFCOs *models, long param);
STDMETHODIMP InvokeEx( IMgaProject *project, IMgaFCO *currentobj, IMgaFCOs *selectedobjs, long param);
STDMETHODIMP ObjectsInvokeEx( IMgaProject *project, IMgaObject *currentobj, IMgaObjects *selectedobjs, long param);
STDMETHODIMP get_ComponentParameter(BSTR name, VARIANT *pVal);
STDMETHODIMP put_ComponentParameter(BSTR name, VARIANT newVal);
#ifdef GME_ADDON
STDMETHODIMP GlobalEvent(globalevent_enum event);
STDMETHODIMP ObjectEvent(IMgaObject * obj, unsigned long eventmask, VARIANT v);
#endif
};
#endif //RAWCOMPONENT_H
--- NEW FILE: StdAfx.cpp ---
// stdafx.cpp : source file that includes just the standard includes
// stdafx.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
#ifdef _ATL_STATIC_REGISTRY
#include <statreg.h>
#if _ATL_VER < 0x0700
#include <statreg.cpp>
#endif // _ATL_VER < 0x0700
#endif // _ATL_STATIC_REGISTRY
#if _ATL_VER < 0x0700
#include <atlimpl.cpp>
#endif // _ATL_VER < 0x0700
--- NEW FILE: StdAfx.h ---
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#if !defined(AFX_STDAFX_H__C4EFDDFC_C095_4509_B571_632F0986D162__INCLUDED_)
#define AFX_STDAFX_H__C4EFDDFC_C095_4509_B571_632F0986D162__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED
#include <afxwin.h>
#include <afxdisp.h>
#include <afxcmn.h>
#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include <atlcom.h>
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__C4EFDDFC_C095_4509_B571_632F0986D162__INCLUDED)
--- NEW FILE: compicon.ico ---
(This appears to be a binary file; contents omitted.)
--- NEW FILE: component.def ---
; Interpreter.def : Declares the module parameters.
LIBRARY "AutoLayout.DLL"
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
--- NEW FILE: resource.h ---
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Component.rc
//
#define IDS_PROJNAME 100
#define IDD_DIALOG_AUTOLAYOUT 201
#define IDC_BUTTON1 201
#define IDC_BUTTON_GRAPH 202
#define IDC_PROGRESS_OPT 204
#define IDC_LIST_ASPECTS 206
#define IDC_PROGRESS_ASPECT 209
#define IDC_CHECK_STARTFROMSCRATCH 210
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 203
#define _APS_NEXT_COMMAND_VALUE 32768
#define _APS_NEXT_CONTROL_VALUE 211
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
More information about the GME-commit
mailing list