Difference between revisions of "Code::Blocks SDK events"

From CodeBlocks
Jump to: navigation, search
m (add new category)
m (Subscribing to events: add rev)
Line 18: Line 18:
  
 
=== Subscribing to events ===
 
=== Subscribing to events ===
Up until July 6th (2007), Code::Blocks events were handled like other wxWidgets events: by declaring an event table in your class that should handle them and adding relevant event table entries.
+
Up until July 6th (2007) rev4233, Code::Blocks events were handled like other wxWidgets events: by declaring an event table in your class that should handle them and adding relevant event table entries.
  
But the event system changed radically on July 6th (2007), in order to battle some shortcomings of the wxWidgets event system (at least for our usage). While designing the new system, great attention has been paid so that plugin writers have to do minimum changes to convert their code.
+
But the event system changed radically on July 6th (2007) rev4234, in order to battle some shortcomings of the wxWidgets event system (at least for our usage). While designing the new system, great attention has been paid so that plugin writers have to do minimum changes to convert their code.
  
 
The class that handles all event registrations is the central class in Code::Blocks which you use if you want to do anything with the Code::Blocks SDK: <tt>Manager</tt>. Let's see by example how would a class (e.g. <tt>SomePlugin</tt>) subscribe for the cbEVT_EDITOR_SAVE event (fired when an editor's contents are saved):
 
The class that handles all event registrations is the central class in Code::Blocks which you use if you want to do anything with the Code::Blocks SDK: <tt>Manager</tt>. Let's see by example how would a class (e.g. <tt>SomePlugin</tt>) subscribe for the cbEVT_EDITOR_SAVE event (fired when an editor's contents are saved):
Line 41: Line 41:
  
 
'''Important note:''' For various reasons, cbEVT_PIPEDPROCESS* and cbEVT_THREADEDTASK* events should still be bound using the old way (i.e. by adding event table entries). If this is changed in the future, this article will be updated accordingly.
 
'''Important note:''' For various reasons, cbEVT_PIPEDPROCESS* and cbEVT_THREADEDTASK* events should still be bound using the old way (i.e. by adding event table entries). If this is changed in the future, this article will be updated accordingly.
 
 
  
 
=== Unsubscribing from events ===
 
=== Unsubscribing from events ===

Revision as of 05:09, 20 June 2012

During a Code::Blocks session, many things are happening: projects/files loading, closing, activating, saving, etc. These are interesting things that happen and various parts of Code::Blocks and its plugins are interested in them. The Code::Blocks SDK provides functions that allow a part of the code to be "subscribed" to these events (i.e. be notified when they happen). This is what we'll look at in this article.

Note: since mid-November 2007, loggers registration is handled with events too.


Available events

There are many event constants defined for the interesting events that happens inside Code::Blocks. These constants are defined in include/sdk_events.h and listed at the bottom of this page.

Also note that there 4 different event categories:

  • Logging system related (CodeBlocksLogEvent)
  • View layout related (CodeBlocksLayoutEvent)
  • Docking system related (CodeBlocksDockEvent)
  • and everything else (CodeBlocksEvent)

Subscribing to events

Up until July 6th (2007) rev4233, Code::Blocks events were handled like other wxWidgets events: by declaring an event table in your class that should handle them and adding relevant event table entries.

But the event system changed radically on July 6th (2007) rev4234, in order to battle some shortcomings of the wxWidgets event system (at least for our usage). While designing the new system, great attention has been paid so that plugin writers have to do minimum changes to convert their code.

The class that handles all event registrations is the central class in Code::Blocks which you use if you want to do anything with the Code::Blocks SDK: Manager. Let's see by example how would a class (e.g. SomePlugin) subscribe for the cbEVT_EDITOR_SAVE event (fired when an editor's contents are saved):

// assuming an existing member function:
// void SomePlugin::OnEditorSaved(CodeBlocksEvent& event);

Manager::Get()->RegisterEventSink(cbEVT_EDITOR_SAVE, new cbEventFunctor<SomePlugin, CodeBlocksEvent>(this, &SomePlugin::OnEditorSaved));

Seems difficult? It isn't, if you realize what the second argument to Manager::RegisterEventSink does.

cbEventFunctor is a class that encapsulates a this-pointer call. It is like a C function pointer except that it works with class instances (i.e. a member-function pointer). For obvious reasons it is a template class, taking two template arguments: the first is the class' name and the second is the type of the event the member function handles.

The constructor of cbEventFunctor takes two arguments: first is the class instance (we use the this pointer) and the second is the address of the member function.

And that's it. After using the above code, the defined function will be called-back on each editor saving :).


Important note: For various reasons, cbEVT_PIPEDPROCESS* and cbEVT_THREADEDTASK* events should still be bound using the old way (i.e. by adding event table entries). If this is changed in the future, this article will be updated accordingly.

Unsubscribing from events

Usually there is no need to unsubscribe from event notifications. A plugin, for example, is automatically removed from all event notifications when it is detached (deactivated, unloaded, uninstalled).

But if you really think you need to unsubscribe from events, there is a function to do that: Manager::Get()->RemoveAllEventSinksFor(void* owner). As the sole argument, pass the instance that you registered the events in the first place.

Notice that this function will remove all event notifications for the specified instance. There is no way to remove event notifications selectively. It's an all-or-nothing deal...


When to register/unregister for event notifications?

In plugins, event notifications should be registered in OnAttach(). As mentioned above, there is no need to unregister anything in OnDetach() because it is automatically done by Code::Blocks.

For code other than plugins, register whenever you think is better (depends on the actual code).

Also notice that Code::Blocks removes all registrations on shut down, so don't even think that we have memory leaks in that part ;).


Any examples?

If the example provided above is not enough, browse through the sources of the core/contrib Code::Blocks plugins. A few of them register for events: just search the code for RegisterEventSink. But it really is nothing difficult: just remove the event handlers from the class's event table and register with this new way.

Try using the DisplayEvents plugin if there is any difficulty determining which events to register.

List of Available Code::Blocks Events

Events that must be registered with RegisterEventSink

app events

  • cbEVT_APP_STARTUP_DONE
  • cbEVT_APP_START_SHUTDOWN
  • cbEVT_APP_UPDATE_TITLE (removed)

plugin events (CodeBlocksEvent)

  • cbEVT_PLUGIN_ATTACHED
  • cbEVT_PLUGIN_RELEASED
  • cbEVT_PLUGIN_INSTALLED
  • cbEVT_PLUGIN_UNINSTALLED

editor events (CodeBlocksEvent)

  • cbEVT_EDITOR_CLOSE
  • cbEVT_EDITOR_OPEN
  • cbEVT_EDITOR_ACTIVATED
  • cbEVT_EDITOR_DEACTIVATED
  • cbEVT_EDITOR_SAVE
  • cbEVT_EDITOR_MODIFIED
  • cbEVT_EDITOR_TOOLTIP
  • cbEVT_EDITOR_TOOLTIP_CANCEL
  • cbEVT_EDITOR_BREAKPOINT_ADD
  • cbEVT_EDITOR_BREAKPOINT_EDIT
  • cbEVT_EDITOR_BREAKPOINT_DELETE
  • cbEVT_EDITOR_UPDATE_UI
  • cbEVT_EDITOR_SWITCHED

project events (CodeBlocksEvent)

  • cbEVT_PROJECT_CLOSE
  • cbEVT_PROJECT_OPEN
  • cbEVT_PROJECT_SAVE
  • cbEVT_PROJECT_ACTIVATE
  • cbEVT_PROJECT_BEGIN_ADD_FILES
  • cbEVT_PROJECT_END_ADD_FILES
  • cbEVT_PROJECT_BEGIN_REMOVE_FILES
  • cbEVT_PROJECT_END_REMOVE_FILES
  • cbEVT_PROJECT_FILE_ADDED
  • cbEVT_PROJECT_FILE_REMOVED
  • cbEVT_PROJECT_POPUP_MENU
  • cbEVT_PROJECT_TARGETS_MODIFIED
  • cbEVT_PROJECT_RENAMED
  • cbEVT_PROJECT_FILE_CHANGED
  • cbEVT_CLEAN_PROJECT_STARTED
  • cbEVT_WORKSPACE_CHANGED
  • cbEVT_CLEAN_WORKSPACE_STARTED

main menubar creation (CodeBlocksEvent)

  • cbEVT_MENUBAR_CREATE_BEGIN: app notifies that the menubar is started being (re)created
  • cbEVT_MENUBAR_CREATE_END: app notifies that the menubar (re)creation ended

compiler-related events (CodeBlocksEvent)

  • cbEVT_COMPILER_STARTED
  • cbEVT_COMPILER_FINISHED

debugger-related events (CodeBlocksEvent)

  • cbEVT_DEBUGGER_STARTED
  • cbEVT_DEBUGGER_PAUSED
  • cbEVT_DEBUGGER_FINISHED

logging-system related events (CodeBlocksLogEvent)

  • cbEVT_ADD_LOG_WINDOW: add a log window
  • cbEVT_REMOVE_LOG_WINDOW: remove a log window
  • cbEVT_SWITCH_TO_LOG_WINDOW: switch to a log window (make it visible)
  • cbEVT_SHOW_LOG_MANAGER: show log manager
  • cbEVT_HIDE_LOG_MANAGER: hide log manager
  • cbEVT_LOCK_LOG_MANAGER: "lock" it (used with auto-hiding functionality)
  • cbEVT_UNLOCK_LOG_MANAGER: "unlock" it (used with auto-hiding functionality)


dockable windows (CodeBlocksDockEvent)

  • cbEVT_ADD_DOCK_WINDOW: request app to add and manage a docked window
  • cbEVT_REMOVE_DOCK_WINDOW: request app to stop managing a docked window
  • cbEVT_SHOW_DOCK_WINDOW: request app to show a docked window
  • cbEVT_HIDE_DOCK_WINDOW: request app to hide a docked window
  • cbEVT_DOCK_WINDOW_VISIBILITY: app notifies that a docked window has been hidden/shown to actually find out its state use IsWindowReallyShown(event.pWindow);

layout related events (CodeBlocksLayoutEvent)

  • cbEVT_SWITCH_VIEW_LAYOUT: request app to switch view layout
  • cbEVT_SWITCHED_VIEW_LAYOUT: app notifies that a new layout has been applied

Events processed on wxWidgets event tables and not registered using RegisterEventSink

pipedprocess events (CodeBlocksEvent)

  • cbEVT_PIPEDPROCESS_STDOUT
  • cbEVT_PIPEDPROCESS_STDERR
  • cbEVT_PIPEDPROCESS_TERMINATED

thread-pool events (CodeBlocksEvent)

  • cbEVT_THREADTASK_STARTED
  • cbEVT_THREADTASK_ENDED
  • cbEVT_THREADTASK_ALLDONE


Mandrav 10:31, 23 November 2007 (UTC)