Code::Blocks  SVN r11506
editor_hooks.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  *
5  * $Revision: 9753 $
6  * $Id: editor_hooks.cpp 9753 2014-04-15 05:12:55Z ollydbg $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/sdk/editor_hooks.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 
12 #ifndef CB_PRECOMP
13  #include "cbeditor.h"
14  #include "cbplugin.h"
15 #endif
16 
17 
18 #include "editor_hooks.h"
19 
20 #ifdef EDITOR_HOOK_PERFORMANCE_MEASURE
21  //put these include directive after #include "editor_hooks.h", as the macro may
22  //defined in the header file
23  #include <cxxabi.h> // demangle C++ names
24  #include <cstdlib> // free the memory created by abi::__cxa_demangle
25 #endif // EDITOR_HOOK_PERFORMANCE_MEASURE
26 
27 #include "wx/wxscintilla.h"
28 
29 #include <map>
30 
31 
32 #ifdef EDITOR_HOOK_PERFORMANCE_MEASURE
33 // this function is only used in performance hook
34 static wxString GetScintillaEventName(wxEventType type)
35 {
36  wxString name;
37  if (type == wxEVT_SCI_CHANGE) name = _T("wxEVT_SCI_CHANGE");
38  else if (type == wxEVT_SCI_STYLENEEDED) name = _T("wxEVT_SCI_STYLENEEDED");
39  else if (type == wxEVT_SCI_CHARADDED) name = _T("wxEVT_SCI_CHARADDED");
40  else if (type == wxEVT_SCI_SAVEPOINTREACHED) name = _T("wxEVT_SCI_SAVEPOINTREACHED");
41  else if (type == wxEVT_SCI_SAVEPOINTLEFT) name = _T("wxEVT_SCI_SAVEPOINTLEFT");
42  else if (type == wxEVT_SCI_ROMODIFYATTEMPT) name = _T("wxEVT_SCI_ROMODIFYATTEMPT");
43  else if (type == wxEVT_SCI_KEY) name = _T("wxEVT_SCI_KEY");
44  else if (type == wxEVT_SCI_DOUBLECLICK) name = _T("wxEVT_SCI_DOUBLECLICK");
45  else if (type == wxEVT_SCI_UPDATEUI) name = _T("wxEVT_SCI_UPDATEUI");
46  else if (type == wxEVT_SCI_MODIFIED) name = _T("wxEVT_SCI_MODIFIED");
47  else if (type == wxEVT_SCI_MACRORECORD) name = _T("wxEVT_SCI_MACRORECORD");
48  else if (type == wxEVT_SCI_MARGINCLICK) name = _T("wxEVT_SCI_MARGINCLICK");
49  else if (type == wxEVT_SCI_NEEDSHOWN) name = _T("wxEVT_SCI_NEEDSHOWN");
50  else if (type == wxEVT_SCI_PAINTED) name = _T("wxEVT_SCI_PAINTED");
51  else if (type == wxEVT_SCI_USERLISTSELECTION) name = _T("wxEVT_SCI_USERLISTSELECTION");
52  else if (type == wxEVT_SCI_URIDROPPED) name = _T("wxEVT_SCI_URIDROPPED");
53  else if (type == wxEVT_SCI_DWELLSTART) name = _T("wxEVT_SCI_DWELLSTART");
54  else if (type == wxEVT_SCI_DWELLEND) name = _T("wxEVT_SCI_DWELLEND");
55  else if (type == wxEVT_SCI_START_DRAG) name = _T("wxEVT_SCI_START_DRAG");
56  else if (type == wxEVT_SCI_DRAG_OVER) name = _T("wxEVT_SCI_DRAG_OVER");
57  else if (type == wxEVT_SCI_DO_DROP) name = _T("wxEVT_SCI_DO_DROP");
58  else if (type == wxEVT_SCI_ZOOM) name = _T("wxEVT_SCI_ZOOM");
59  else if (type == wxEVT_SCI_HOTSPOT_CLICK) name = _T("wxEVT_SCI_HOTSPOT_CLICK");
60  else if (type == wxEVT_SCI_HOTSPOT_DCLICK) name = _T("wxEVT_SCI_HOTSPOT_DCLICK");
61  else if (type == wxEVT_SCI_CALLTIP_CLICK) name = _T("wxEVT_SCI_CALLTIP_CLICK");
62  else if (type == wxEVT_SCI_AUTOCOMP_SELECTION) name = _T("wxEVT_SCI_AUTOCOMP_SELECTION");
63  else if (type == wxEVT_SCI_INDICATOR_CLICK) name = _T("wxEVT_SCI_INDICATOR_CLICK");
64  else if (type == wxEVT_SCI_INDICATOR_RELEASE) name = _T("wxEVT_SCI_INDICATOR_RELEASE");
65  else name = _T("unknown wxEVT_SCI_EVENT");
66 
67  return name;
68 }
69 #endif // EDITOR_HOOK_PERFORMANCE_MEASURE
70 
71 namespace EditorHooks
72 {
73  typedef std::map<int, HookFunctorBase*> HookFunctorsMap;
74  static HookFunctorsMap s_HookFunctorsMap;
75  static int s_UniqueID = 0;
76 }
77 
79 {
80  for (HookFunctorsMap::iterator it = s_HookFunctorsMap.begin(); it != s_HookFunctorsMap.end(); ++it)
81  {
82  if (it->second == functor)
83  return it->first;
84  }
85  s_HookFunctorsMap[s_UniqueID] = functor;
86  return s_UniqueID++;
87 }
88 
90 {
91  HookFunctorsMap::iterator it = s_HookFunctorsMap.find(id);
92  if (it != s_HookFunctorsMap.end())
93  {
94  EditorHooks::HookFunctorBase* functor = it->second;
95  s_HookFunctorsMap.erase(it);
96  if (deleteHook)
97  {
98  delete functor;
99  return nullptr;
100  }
101  return functor;
102  }
103  return nullptr;
104 }
105 
107 {
108  return s_HookFunctorsMap.size() != 0;
109 }
110 
112 {
113  for (HookFunctorsMap::iterator it = s_HookFunctorsMap.begin(); it != s_HookFunctorsMap.end(); ++it)
114  {
115  EditorHooks::HookFunctorBase* functor = it->second;
116  if (functor)
117  {
118 #ifdef EDITOR_HOOK_PERFORMANCE_MEASURE
119  wxStopWatch sw;
120 #endif // EDITOR_HOOK_PERFORMANCE_MEASURE
121 
122  functor->Call(editor, event);
123 
124 #ifdef EDITOR_HOOK_PERFORMANCE_MEASURE
125  if(sw.Time() < 10) // only print a handler run longer than 10 ms
126  continue;
127 
128  const char *p = functor->GetTypeName();
129  int status;
130  char *realname;
131  realname = abi::__cxa_demangle(p, 0, 0, &status);
132  wxString txt;
133  // if the demangled C++ function name success, then realname is not NULL
134  if (realname != 0)
135  {
136  txt = wxString::FromUTF8(realname);
137  free(realname);
138  }
139  else
140  txt = wxString::FromUTF8(p); // show the mangled(original) name
141 
142  wxEventType type = event.GetEventType();
143  txt << GetScintillaEventName(type);
144  Manager::Get()->GetLogManager()->DebugLog(F(wxT("%s take %ld ms"), txt.wx_str(), sw.Time()));
145 #endif // EDITOR_HOOK_PERFORMANCE_MEASURE
146  }
147 
148  }
149 }
150 
151 namespace EditorHooks
152 {
154  m_plugin(plugin){}
155 
157  {
158  m_plugin->OnEditorHook(editor, event);
159  }
160 }
Provides static functions to add hooks to the editor modification operations.
Definition: editor_hooks.h:23
wxString F(const wxChar *msg,...)
sprintf-like function
Definition: logmanager.h:20
virtual void OnEditorHook(cbEditor *editor, wxScintillaEvent &event) const =0
When this is called, the smartIndent mechanism must get to work ;).
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
cbSmartIndentEditorHookFunctor(cbSmartIndentPlugin *plugin)
ctor.
DLLIMPORT bool HasRegisteredHooks()
Are there any hooks registered?
long Time() const
#define _T(string)
#define wxT(string)
static int s_UniqueID
std::map< int, HookFunctorBase * > HookFunctorsMap
static wxString FromUTF8(const char *s)
LogManager * GetLogManager() const
Definition: manager.cpp:439
const wxStringCharType * wx_str() const
void Call(cbEditor *editor, wxScintillaEvent &event) const override
Needs to be implemented by the plugin to act(smart indent) accordingly.
Abstract base hook functor interface.
Definition: editor_hooks.h:26
A file editor.
Definition: cbeditor.h:43
virtual void Call(cbEditor *, wxScintillaEvent &) const =0
void DebugLog(const wxString &msg, Logger::level lv=Logger::info)
Definition: logmanager.h:146
DLLIMPORT HookFunctorBase * UnregisterHook(int id, bool deleteHook=true)
Unregister a previously registered project loading/saving hook.
int wxEventType
static HookFunctorsMap s_HookFunctorsMap
DLLIMPORT void CallHooks(cbEditor *editor, wxScintillaEvent &event)
Call all registered hooks using the supplied parameters.
DLLIMPORT int RegisterHook(HookFunctorBase *functor)
Register a project loading/saving hook.