redcar 0.3.1dev → 0.3.2dev
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +34 -1
- data/README.md +2 -1
- data/ROADMAP.md +13 -45
- data/Rakefile +15 -14
- data/bin/redcar +4 -1
- data/lib/plugin_manager/README.md +61 -0
- data/lib/plugin_manager/Rakefile +55 -0
- data/lib/plugin_manager/bin/plugin_manager +4 -0
- data/lib/plugin_manager/lib/plugin_manager.rb +107 -0
- data/lib/plugin_manager/lib/plugin_manager/definition_builder.rb +37 -0
- data/lib/plugin_manager/lib/plugin_manager/plugin.rb +9 -0
- data/lib/plugin_manager/lib/plugin_manager/plugin_definition.rb +50 -0
- data/lib/plugin_manager/plugin_manager.gemspec +33 -0
- data/lib/plugin_manager/spec/fixtures/error_in_definition/core/plugin.rb +2 -0
- data/lib/plugin_manager/spec/fixtures/error_in_plugin/core/core.rb +4 -0
- data/lib/plugin_manager/spec/fixtures/error_in_plugin/core/plugin.rb +7 -0
- data/lib/plugin_manager/spec/fixtures/example/core/core.rb +20 -0
- data/lib/plugin_manager/spec/fixtures/example/core/plugin.rb +7 -0
- data/lib/plugin_manager/spec/fixtures/example/debug/debug.rb +6 -0
- data/lib/plugin_manager/spec/fixtures/example/debug/plugin.rb +8 -0
- data/lib/plugin_manager/spec/fixtures/example/extras/extras.rb +6 -0
- data/lib/plugin_manager/spec/fixtures/example/extras/plugin.rb +8 -0
- data/lib/plugin_manager/spec/fixtures/two_versions1/core/core.rb +20 -0
- data/lib/plugin_manager/spec/fixtures/two_versions1/core/plugin.rb +7 -0
- data/lib/plugin_manager/spec/fixtures/two_versions1/core2/core.rb +20 -0
- data/lib/plugin_manager/spec/fixtures/two_versions1/core2/plugin.rb +7 -0
- data/lib/plugin_manager/spec/fixtures/two_versions2/core/core.rb +20 -0
- data/lib/plugin_manager/spec/fixtures/two_versions2/core/plugin.rb +7 -0
- data/lib/plugin_manager/spec/fixtures/two_versions2/core2/core.rb +20 -0
- data/lib/plugin_manager/spec/fixtures/two_versions2/core2/plugin.rb +8 -0
- data/lib/plugin_manager/spec/fixtures/unmet_dependencies1/core/core.rb +10 -0
- data/lib/plugin_manager/spec/fixtures/unmet_dependencies1/core/plugin.rb +7 -0
- data/lib/plugin_manager/spec/fixtures/unmet_dependencies1/debug/debug.rb +6 -0
- data/lib/plugin_manager/spec/fixtures/unmet_dependencies1/debug/plugin.rb +8 -0
- data/lib/plugin_manager/spec/fixtures/unmet_dependencies2/core/core.rb +10 -0
- data/lib/plugin_manager/spec/fixtures/unmet_dependencies2/core/plugin.rb +7 -0
- data/lib/plugin_manager/spec/fixtures/unmet_dependencies2/debug/debug.rb +6 -0
- data/lib/plugin_manager/spec/fixtures/unmet_dependencies2/debug/plugin.rb +8 -0
- data/lib/plugin_manager/spec/plugin_manager_spec.rb +208 -0
- data/lib/plugin_manager/spec/spec_helper.rb +3 -0
- data/lib/redcar.rb +8 -3
- data/lib/redcar/boot.rb +59 -56
- data/lib/redcar/installer.rb +1 -1
- data/lib/redcar/instance_exec.rb +25 -0
- data/lib/redcar/runner.rb +5 -1
- data/lib/redcar/usage.rb +5 -1
- data/plugins/application/icons/close.png +0 -0
- data/plugins/application/lib/application.rb +61 -28
- data/plugins/application/lib/application/clipboard.rb +71 -0
- data/plugins/application/lib/application/dialog.rb +63 -0
- data/plugins/application/lib/application/menu.rb +32 -1
- data/plugins/application/lib/application/menu/builder.rb +10 -4
- data/plugins/application/lib/application/menu/item.rb +16 -3
- data/plugins/application/lib/application/notebook.rb +5 -0
- data/plugins/application/lib/application/speedbar.rb +73 -0
- data/plugins/application/lib/application/window.rb +25 -0
- data/plugins/application/plugin.rb +8 -0
- data/plugins/application/spec/application/clipboard_spec.rb +36 -0
- data/plugins/application/spec/application/menu_spec.rb +73 -1
- data/plugins/application/spec/application/speedbar_spec.rb +46 -0
- data/plugins/application/spec/spec_helper.rb +1 -1
- data/plugins/application_swt/lib/application_swt.rb +18 -11
- data/plugins/application_swt/lib/application_swt/clipboard.rb +42 -0
- data/plugins/application_swt/lib/application_swt/dialog_adapter.rb +68 -0
- data/plugins/application_swt/lib/application_swt/dialogs/filter_list_dialog_controller.rb +1 -1
- data/plugins/application_swt/lib/application_swt/html_tab.rb +32 -0
- data/plugins/application_swt/lib/application_swt/menu.rb +57 -21
- data/plugins/application_swt/lib/application_swt/menu/binding_translator.rb +39 -2
- data/plugins/application_swt/lib/application_swt/notebook.rb +5 -0
- data/plugins/application_swt/lib/application_swt/speedbar.rb +187 -0
- data/plugins/application_swt/lib/application_swt/swt_wrapper.rb +24 -1
- data/plugins/application_swt/lib/application_swt/window.rb +33 -3
- data/plugins/application_swt/plugin.rb +8 -0
- data/plugins/application_swt/spec/spec_helper.rb +1 -1
- data/plugins/auto_completer/features/auto_complete.feature +65 -0
- data/plugins/auto_completer/features/step_definitions/auto_complete_steps.rb +4 -0
- data/plugins/auto_completer/features/support/env.rb +4 -0
- data/plugins/auto_completer/lib/auto_completer.rb +99 -0
- data/plugins/auto_completer/lib/auto_completer/document_controller.rb +52 -0
- data/plugins/auto_completer/lib/auto_completer/word_iterator.rb +48 -0
- data/plugins/auto_completer/lib/auto_completer/word_list.rb +40 -0
- data/plugins/auto_completer/plugin.rb +10 -0
- data/plugins/auto_indenter/lib/auto_indenter.rb +1 -1
- data/plugins/auto_indenter/lib/auto_indenter/document_controller.rb +1 -1
- data/plugins/auto_indenter/plugin.rb +8 -0
- data/plugins/core/lib/core.rb +6 -30
- data/plugins/core/lib/core/gui.rb +7 -2
- data/plugins/core/lib/core/logger.rb +7 -4
- data/plugins/core/lib/core/plugin/storage.rb +15 -5
- data/plugins/core/plugin.rb +7 -0
- data/plugins/core/spec/core/storage_spec.rb +0 -9
- data/plugins/edit_view/features/cut_and_paste.feature +45 -0
- data/plugins/edit_view/features/step_definitions/editing_steps.rb +22 -0
- data/plugins/edit_view/features/step_definitions/key_steps.rb +1 -1
- data/plugins/edit_view/features/step_definitions/notebook_steps.rb +1 -1
- data/plugins/edit_view/features/step_definitions/tab_steps.rb +2 -0
- data/plugins/edit_view/features/step_definitions/window_steps.rb +1 -1
- data/plugins/edit_view/features/support/env.rb +2 -2
- data/plugins/edit_view/lib/edit_view.rb +24 -13
- data/plugins/edit_view/lib/edit_view/document.rb +233 -15
- data/plugins/edit_view/lib/edit_view/edit_tab.rb +2 -2
- data/plugins/edit_view/plugin.rb +9 -0
- data/plugins/edit_view/spec/spec_helper.rb +1 -1
- data/plugins/edit_view_swt/lib/edit_view_swt.rb +37 -8
- data/plugins/edit_view_swt/lib/edit_view_swt/document.rb +59 -24
- data/plugins/edit_view_swt/lib/edit_view_swt/word_movement.rb +66 -0
- data/plugins/edit_view_swt/plugin.rb +9 -0
- data/plugins/edit_view_swt/spec/edit_view_swt/word_movement_spec.rb +29 -0
- data/plugins/edit_view_swt/spec/spec_helper.rb +6 -0
- data/plugins/html_view/assets/blueprint/ie.css +35 -0
- data/plugins/html_view/assets/blueprint/print.css +29 -0
- data/plugins/html_view/assets/blueprint/screen.css +257 -0
- data/plugins/html_view/assets/blueprint/src/forms.css +65 -0
- data/plugins/html_view/assets/blueprint/src/grid.css +281 -0
- data/plugins/html_view/assets/blueprint/src/grid.png +0 -0
- data/plugins/html_view/assets/blueprint/src/ie.css +76 -0
- data/plugins/html_view/assets/blueprint/src/print.css +85 -0
- data/plugins/html_view/assets/blueprint/src/reset.css +38 -0
- data/plugins/html_view/assets/blueprint/src/typography.css +106 -0
- data/plugins/html_view/assets/jquery-1.4.min.js +151 -0
- data/plugins/html_view/assets/redcar.css +12 -0
- data/plugins/html_view/lib/html_controller.rb +5 -0
- data/plugins/html_view/lib/html_view.rb +47 -0
- data/plugins/html_view/lib/html_view/html_tab.rb +16 -0
- data/plugins/html_view/plugin.rb +12 -0
- data/plugins/my_plugin/lib/my_plugin.rb +55 -0
- data/plugins/my_plugin/plugin.rb +8 -0
- data/plugins/plugin_manager_ui/lib/plugin_manager_ui.rb +62 -0
- data/plugins/plugin_manager_ui/plugin.rb +12 -0
- data/plugins/plugin_manager_ui/views/index.html.erb +31 -0
- data/plugins/project/lib/project.rb +27 -13
- data/plugins/project/lib/project/find_file_dialog.rb +25 -19
- data/plugins/project/plugin.rb +8 -0
- data/plugins/project/spec/spec_helper.rb +1 -1
- data/plugins/redcar/plugin.rb +13 -0
- data/plugins/redcar/redcar.rb +249 -8
- data/plugins/repl/lib/repl.rb +22 -14
- data/plugins/repl/plugin.rb +8 -0
- data/plugins/repl/spec/spec_helper.rb +1 -1
- data/plugins/tree/plugin.rb +9 -0
- data/plugins/tree/spec/spec_helper.rb +1 -1
- data/plugins/tree_view_swt/plugin.rb +9 -0
- data/textmate/Bundles/Apache.tmbundle/Syntaxes/Apache.plist +544 -0
- data/textmate/Bundles/Apache.tmbundle/Syntaxes/mod_perl.tmLanguage +120 -0
- data/textmate/Bundles/Blogging.tmbundle/Syntaxes/Blog___HTML__.plist +88 -0
- data/textmate/Bundles/Blogging.tmbundle/Syntaxes/Blog___Markdown__.plist +89 -0
- data/textmate/Bundles/Blogging.tmbundle/Syntaxes/Blog___Text__.plist +74 -0
- data/textmate/Bundles/Blogging.tmbundle/Syntaxes/Blog___Textile__.plist +74 -0
- data/textmate/Bundles/Bundle Development.tmbundle/Syntaxes/LanguageGrammar.tmLanguage +1829 -0
- data/textmate/Bundles/C Sharp.tmbundle/Syntaxes/Build.tmLanguage +142 -0
- data/textmate/Bundles/C Sharp.tmbundle/Syntaxes/C__.tmLanguage +524 -0
- data/textmate/Bundles/C++ Qt.tmbundle/Syntaxes/Qt_C____.tmLanguage +62 -0
- data/textmate/Bundles/C++ Qt.tmbundle/Syntaxes/qmake_Project.tmLanguage +308 -0
- data/textmate/Bundles/C.tmbundle/Syntaxes/C.plist +90 -48
- data/textmate/Bundles/Clojure.tmbundle/Syntaxes/Clojure.tmLanguage +427 -0
- data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/Cucumber_Plain_Text_Feature.tmLanguage +106 -13
- data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/Cucumber_Steps.tmLanguage +177 -2
- data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/plaintext_template.erb +109 -17
- data/textmate/Bundles/D.tmbundle/Syntaxes/D.tmLanguage +908 -0
- data/textmate/Bundles/Diff.tmbundle/Syntaxes/Diff.plist +229 -0
- data/textmate/Bundles/DokuWiki.tmbundle/Syntaxes/DokuWiki.tmLanguage +649 -0
- data/textmate/Bundles/F-Script.tmbundle/Syntaxes/F__Script.plist +219 -0
- data/textmate/Bundles/Haskell.tmbundle/Syntaxes/Haskell.plist +646 -0
- data/textmate/Bundles/Haskell.tmbundle/Syntaxes/Literate_Haskell.plist +90 -0
- data/textmate/Bundles/Io.tmbundle/Syntaxes/Io.plist +225 -0
- data/textmate/Bundles/JSON.tmbundle/Syntaxes/JSON.tmLanguage +285 -0
- data/textmate/Bundles/JavaScript Prototype & Script_aculo_us.tmbundle/Syntaxes/JavaScript____Prototype.tmLanguage +193 -0
- data/textmate/Bundles/JavaScript Prototype & Script_aculo_us.tmbundle/Syntaxes/JavaScript____Prototype_Bracketed.tmLanguage +394 -0
- data/textmate/Bundles/JavaScript jQuery.tmbundle/Syntaxes/jQuery___JavaScript__.tmLanguage +440 -0
- data/textmate/Bundles/JavaScript.tmbundle/Syntaxes/JavaScript.plist +712 -0
- data/textmate/Bundles/Latex.tmbundle/Syntaxes/Bibtex.plist +406 -0
- data/textmate/Bundles/Latex.tmbundle/Syntaxes/LaTeX.plist +1601 -0
- data/textmate/Bundles/Latex.tmbundle/Syntaxes/LaTeX_Beamer.plist +106 -0
- data/textmate/Bundles/Latex.tmbundle/Syntaxes/LaTeX_Log.plist +141 -0
- data/textmate/Bundles/Latex.tmbundle/Syntaxes/LaTeX_Memoir.tmLanguage +165 -0
- data/textmate/Bundles/Latex.tmbundle/Syntaxes/TeX.plist +246 -0
- data/textmate/Bundles/Latex.tmbundle/Syntaxes/TeX_Math.plist +132 -0
- data/textmate/Bundles/Lisp.tmbundle/Syntaxes/Lisp.plist +160 -0
- data/textmate/Bundles/Makefile.tmbundle/Syntaxes/Makefile.plist +103 -0
- data/textmate/Bundles/Markdown.tmbundle/Syntaxes/Markdown.plist +1192 -0
- data/textmate/Bundles/Markdown.tmbundle/Syntaxes/MultiMarkdown.tmLanguage +80 -0
- data/textmate/Bundles/PHP.tmbundle/Syntaxes/PHP.plist +3481 -0
- data/textmate/Bundles/Perl HTML-Template.tmbundle/Syntaxes/Perl_HTML__Template.tmLanguage +217 -0
- data/textmate/Bundles/Perl Template Toolkit.tmbundle/Syntaxes/HTML___Template_Toolkit__.tmLanguage +339 -0
- data/textmate/Bundles/Postscript.tmbundle/Syntaxes/Postscript.tmLanguage +321 -0
- data/textmate/Bundles/Processing.tmbundle/Syntaxes/Processing.plist +296 -0
- data/textmate/Bundles/Property List.tmbundle/Syntaxes/Property_List.tmLanguage +1650 -0
- data/textmate/Bundles/Python Django Templates.tmbundle/Syntaxes/HTML___Django__.tmLanguage +104 -0
- data/textmate/Bundles/Python Django.tmbundle/Syntaxes/Python_Django.tmLanguage +57 -0
- data/textmate/Bundles/Python.tmbundle/Syntaxes/Python.tmLanguage +3016 -0
- data/textmate/Bundles/Python.tmbundle/Syntaxes/Regular_Expressions___Python__.tmLanguage +299 -0
- data/textmate/Bundles/Rez.tmbundle/Syntaxes/Rez.plist +219 -0
- data/textmate/Bundles/Ruby Haml.tmbundle/Syntaxes/Ruby_Haml.tmLanguage +403 -0
- data/textmate/Bundles/Ruby RSpec.tmbundle/Syntaxes/RSpec.tmLanguage +142 -0
- data/textmate/Bundles/Ruby.tmbundle/Syntaxes/Ruby.plist +139 -49
- data/textmate/Bundles/SQL.tmbundle/Syntaxes/SQL.plist +705 -0
- data/textmate/Bundles/SSH-Config.tmbundle/Syntaxes/SSH__Config.tmLanguage +88 -0
- data/textmate/Bundles/Scala.tmbundle/Syntaxes/Scala.tmLanguage +609 -0
- data/textmate/Bundles/Scala.tmbundle/Syntaxes/Scala_Properties.tmLanguage +54 -0
- data/textmate/Bundles/ShellScript.tmbundle/Syntaxes/Shell__Unix__Generic.plist +1855 -0
- data/textmate/Bundles/Tabular.tmbundle/Syntaxes/CSV.tmLanguage +178 -0
- data/textmate/Bundles/Tabular.tmbundle/Syntaxes/TSV.tmLanguage +135 -0
- data/textmate/Bundles/TextMate.tmbundle/Syntaxes/Regular_Expressions___Oniguruma__.tmLanguage +295 -0
- data/textmate/Bundles/TextMate.tmbundle/Syntaxes/Release_Notes.tmLanguage +126 -0
- data/textmate/Bundles/Textile.tmbundle/Syntaxes/Textile.plist +490 -0
- data/textmate/Bundles/Thrift.tmbundle/Syntaxes/Thrift.tmLanguage +1024 -0
- data/textmate/Bundles/XML.tmbundle/Syntaxes/XML.plist +576 -0
- data/textmate/Bundles/XML.tmbundle/Syntaxes/XSL.plist +157 -0
- data/textmate/Bundles/YAML.tmbundle/Syntaxes/YAML.plist +466 -0
- data/textmate/Themes/Django.tmTheme +436 -0
- metadata +371 -325
- data/config/default.yaml +0 -15
- data/lib/freebase2/README.txt +0 -47
- data/lib/freebase2/bin/default.yaml +0 -15
- data/lib/freebase2/bin/install.rb +0 -42
- data/lib/freebase2/bin/run.rb +0 -48
- data/lib/freebase2/lib/freebase/configuration.rb +0 -535
- data/lib/freebase2/lib/freebase/core.rb +0 -197
- data/lib/freebase2/lib/freebase/databus.rb +0 -1128
- data/lib/freebase2/lib/freebase/freebase.rb +0 -60
- data/lib/freebase2/lib/freebase/logger.rb +0 -117
- data/lib/freebase2/lib/freebase/plugin.rb +0 -384
- data/lib/freebase2/lib/freebase/properties.rb +0 -130
- data/lib/freebase2/lib/freebase/readers.rb +0 -328
- data/lib/freebase2/notes +0 -61
- data/lib/freebase2/plugins/raa_webrick/httpd.rb +0 -125
- data/lib/freebase2/plugins/raa_webrick/plugin.yaml +0 -7
- data/lib/freebase2/plugins/raa_webrick/web_root/test.html +0 -5
- data/lib/freebase2/plugins/raa_webrick/webserver.yaml +0 -6
- data/lib/freebase2/plugins/raa_xmlrpc4r/plugin.xml +0 -8
- data/lib/freebase2/plugins/raa_xmlrpc4r/rpcd.rb +0 -54
- data/lib/freebase2/regress/README +0 -1
- data/lib/little_plugger/History.txt +0 -20
- data/lib/little_plugger/Rakefile +0 -34
- data/lib/little_plugger/lib/little-plugger.rb +0 -323
- data/lib/little_plugger/spec/little-plugger_spec.rb +0 -26
- data/lib/little_plugger/spec/spec_helper.rb +0 -16
- data/lib/logging/History.txt +0 -240
- data/lib/logging/Rakefile +0 -37
- data/lib/logging/data/bad_logging_1.rb +0 -13
- data/lib/logging/data/bad_logging_2.rb +0 -21
- data/lib/logging/data/logging.rb +0 -42
- data/lib/logging/data/logging.yaml +0 -63
- data/lib/logging/data/simple_logging.rb +0 -13
- data/lib/logging/examples/appenders.rb +0 -47
- data/lib/logging/examples/classes.rb +0 -41
- data/lib/logging/examples/consolidation.rb +0 -83
- data/lib/logging/examples/formatting.rb +0 -51
- data/lib/logging/examples/hierarchies.rb +0 -73
- data/lib/logging/examples/layouts.rb +0 -48
- data/lib/logging/examples/loggers.rb +0 -29
- data/lib/logging/examples/names.rb +0 -43
- data/lib/logging/examples/simple.rb +0 -17
- data/lib/logging/lib/logging.rb +0 -501
- data/lib/logging/lib/logging/appender.rb +0 -251
- data/lib/logging/lib/logging/appenders.rb +0 -131
- data/lib/logging/lib/logging/appenders/buffering.rb +0 -168
- data/lib/logging/lib/logging/appenders/console.rb +0 -60
- data/lib/logging/lib/logging/appenders/email.rb +0 -75
- data/lib/logging/lib/logging/appenders/file.rb +0 -58
- data/lib/logging/lib/logging/appenders/growl.rb +0 -197
- data/lib/logging/lib/logging/appenders/io.rb +0 -69
- data/lib/logging/lib/logging/appenders/rolling_file.rb +0 -293
- data/lib/logging/lib/logging/appenders/string_io.rb +0 -68
- data/lib/logging/lib/logging/appenders/syslog.rb +0 -194
- data/lib/logging/lib/logging/config/configurator.rb +0 -188
- data/lib/logging/lib/logging/config/yaml_configurator.rb +0 -191
- data/lib/logging/lib/logging/layout.rb +0 -117
- data/lib/logging/lib/logging/layouts.rb +0 -47
- data/lib/logging/lib/logging/layouts/basic.rb +0 -32
- data/lib/logging/lib/logging/layouts/parseable.rb +0 -211
- data/lib/logging/lib/logging/layouts/pattern.rb +0 -311
- data/lib/logging/lib/logging/log_event.rb +0 -45
- data/lib/logging/lib/logging/logger.rb +0 -503
- data/lib/logging/lib/logging/repository.rb +0 -232
- data/lib/logging/lib/logging/root_logger.rb +0 -61
- data/lib/logging/lib/logging/stats.rb +0 -278
- data/lib/logging/lib/logging/utils.rb +0 -153
- data/lib/logging/lib/spec/logging_helper.rb +0 -34
- data/lib/logging/test/appenders/test_buffered_io.rb +0 -176
- data/lib/logging/test/appenders/test_console.rb +0 -66
- data/lib/logging/test/appenders/test_email.rb +0 -170
- data/lib/logging/test/appenders/test_file.rb +0 -95
- data/lib/logging/test/appenders/test_growl.rb +0 -127
- data/lib/logging/test/appenders/test_io.rb +0 -129
- data/lib/logging/test/appenders/test_rolling_file.rb +0 -200
- data/lib/logging/test/appenders/test_syslog.rb +0 -194
- data/lib/logging/test/benchmark.rb +0 -86
- data/lib/logging/test/config/test_configurator.rb +0 -70
- data/lib/logging/test/config/test_yaml_configurator.rb +0 -40
- data/lib/logging/test/layouts/test_basic.rb +0 -42
- data/lib/logging/test/layouts/test_json.rb +0 -112
- data/lib/logging/test/layouts/test_pattern.rb +0 -198
- data/lib/logging/test/layouts/test_yaml.rb +0 -121
- data/lib/logging/test/setup.rb +0 -44
- data/lib/logging/test/test_appender.rb +0 -152
- data/lib/logging/test/test_consolidate.rb +0 -46
- data/lib/logging/test/test_layout.rb +0 -110
- data/lib/logging/test/test_log_event.rb +0 -80
- data/lib/logging/test/test_logger.rb +0 -699
- data/lib/logging/test/test_logging.rb +0 -267
- data/lib/logging/test/test_repository.rb +0 -158
- data/lib/logging/test/test_root_logger.rb +0 -81
- data/lib/logging/test/test_stats.rb +0 -274
- data/lib/logging/test/test_utils.rb +0 -116
- data/plugins/application/plugin.yaml +0 -11
- data/plugins/application_swt/plugin.yaml +0 -11
- data/plugins/auto_indenter/plugin.yaml +0 -12
- data/plugins/core/plugin.yaml +0 -7
- data/plugins/edit_view/plugin.yaml +0 -14
- data/plugins/edit_view_swt/plugin.yaml +0 -14
- data/plugins/project/plugin.yaml +0 -12
- data/plugins/redcar/plugin.yaml +0 -18
- data/plugins/repl/plugin.yaml +0 -12
- data/plugins/tree/plugin.yaml +0 -14
- data/plugins/tree_view_swt/plugin.yaml +0 -14
@@ -1,197 +0,0 @@
|
|
1
|
-
# Purpose: FreeBASE Core module. Starts all plugins
|
2
|
-
#
|
3
|
-
# $Id: core.rb,v 1.4 2004/10/14 20:54:34 ljulliar Exp $
|
4
|
-
#
|
5
|
-
# Authors: Rich Kilmer <rich@infoether.com>
|
6
|
-
# Contributors:
|
7
|
-
# - Laurent Julliard <laurent AT moldus DOT org)
|
8
|
-
#
|
9
|
-
# This file is part of the FreeRIDE project
|
10
|
-
#
|
11
|
-
# This application is free software; you can redistribute it and/or
|
12
|
-
# modify it under the terms of the Ruby license defined in the
|
13
|
-
# COPYING file.
|
14
|
-
#
|
15
|
-
# Copyright (c) 2001 Rich Kilmer. All rights reserved.
|
16
|
-
#
|
17
|
-
|
18
|
-
require 'rbconfig'
|
19
|
-
|
20
|
-
module FreeBASE
|
21
|
-
|
22
|
-
##
|
23
|
-
# The Core class starts the FreeBASE service that manages
|
24
|
-
# the installed plugins.
|
25
|
-
#
|
26
|
-
class Core
|
27
|
-
|
28
|
-
include Config
|
29
|
-
|
30
|
-
# The master bus FreeBASE::DataBus
|
31
|
-
attr_reader :bus
|
32
|
-
|
33
|
-
# The logger utility
|
34
|
-
attr_reader :log
|
35
|
-
|
36
|
-
##
|
37
|
-
# Constructs a new Core, loads the setup.rb, and loads the plugins
|
38
|
-
#
|
39
|
-
def initialize(propertiesFile, defaultPropertiesFile, options = {})
|
40
|
-
@propertiesFile = propertiesFile
|
41
|
-
@defaultPropertiesFile = defaultPropertiesFile
|
42
|
-
init_bus
|
43
|
-
load_properties
|
44
|
-
load_setup
|
45
|
-
end
|
46
|
-
|
47
|
-
##
|
48
|
-
# Starts the Core service. This method blocks until shutdown.
|
49
|
-
#
|
50
|
-
def startup(options={})
|
51
|
-
# push all plugin paths into the require path. Prepend codebase
|
52
|
-
# if it's a relative path
|
53
|
-
@properties["config/plugin_path"].split(";").each do |path|
|
54
|
-
path = File.join($FR_CODEBASE,path) unless File.absolute_path?(path)
|
55
|
-
$:.push path
|
56
|
-
end
|
57
|
-
@bus["/log/info"] << "--- #{@properties['config/product_name']} Started on #{Time.now.to_s}"
|
58
|
-
@bus["/system/state/all_plugins_loaded"].data = false
|
59
|
-
@plugin_config = Configuration.new(self, @properties["config/plugin_path"])
|
60
|
-
if options[:require_only]
|
61
|
-
@plugin_config.require_plugins
|
62
|
-
else
|
63
|
-
@plugin_config.load_plugins
|
64
|
-
@plugin_config.start_plugins unless options[:load_only]
|
65
|
-
end
|
66
|
-
@bus["/system/state/all_plugins_loaded"].data = true
|
67
|
-
@core_thread = Thread.current
|
68
|
-
end
|
69
|
-
|
70
|
-
def load_plugins
|
71
|
-
startup(:load_only => true)
|
72
|
-
end
|
73
|
-
|
74
|
-
def require_files
|
75
|
-
startup(:require_only => true)
|
76
|
-
end
|
77
|
-
|
78
|
-
##
|
79
|
-
# Shuts down the system by notifying each installed plugin via
|
80
|
-
# publishing the Core instance to the local plugin bus ['/command/shutdown']
|
81
|
-
# Shutdown stops if requested by a plugin to abort.
|
82
|
-
#
|
83
|
-
def shutdown
|
84
|
-
@plugin_config.stop_plugins
|
85
|
-
@plugin_config.unload_plugins
|
86
|
-
@bus["/system/state/all_plugins_loaded"].data = false;
|
87
|
-
@bus["/log/info"] << "--- Shutting down #{@properties['config/product_name']} on #{Time.now.to_s}"
|
88
|
-
@core_thread.wakeup if @core_thread.stop?
|
89
|
-
end
|
90
|
-
|
91
|
-
|
92
|
-
private
|
93
|
-
|
94
|
-
def init_bus
|
95
|
-
@bus = DataBus.new
|
96
|
-
# Publishing an integer to this location will shut down FreeBASE in that many seconds
|
97
|
-
@bus["/system/shutdown"].validate_with("Specify number of seconds") do |args|
|
98
|
-
args.size==1 and args[0].respond_to? "to_i" # validate convertable to integer
|
99
|
-
end
|
100
|
-
@bus["/system/shutdown"].set_proc do |seconds|
|
101
|
-
Thread.new do
|
102
|
-
puts "Shutdown in #{seconds.to_i} seconds..."
|
103
|
-
sleep seconds.to_i
|
104
|
-
shutdown
|
105
|
-
end
|
106
|
-
true
|
107
|
-
end
|
108
|
-
|
109
|
-
@bus["/system/test"].set_proc do
|
110
|
-
require 'test/unit'
|
111
|
-
|
112
|
-
# we do not want the tests to run on exit:
|
113
|
-
Test::Unit.run = false
|
114
|
-
|
115
|
-
suite = Test::Unit::TestSuite.new()
|
116
|
-
|
117
|
-
@bus["/plugins/"].children.each do |plugin_slot|
|
118
|
-
if plugin_slot["actions"].children.map{|c| c.name}.include? "test"
|
119
|
-
plugin = plugin_slot.data
|
120
|
-
plugin.plugin_configuration.tests.each do |test_info|
|
121
|
-
plugin.require_testcase(test_info["path"])
|
122
|
-
suite << eval(test_info["testcase"]).suite
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
require 'test/unit/ui/console/testrunner'
|
128
|
-
|
129
|
-
begin
|
130
|
-
Test::Unit::UI::Console::TestRunner.new(suite).start
|
131
|
-
rescue Object => e
|
132
|
-
puts e
|
133
|
-
puts e.message
|
134
|
-
puts e.backtrace
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
# Set up logger
|
139
|
-
@bus["log/info"].queue
|
140
|
-
@bus["log/error"].queue
|
141
|
-
@bus["log/debug"].queue
|
142
|
-
@bus["log"].subscribe do |event, slot|
|
143
|
-
if event == :notify_queue_join and slot.name != "log"
|
144
|
-
@bus["log"].call(slot.name, slot.queue.leave) if @bus["log"].is_proc_slot?
|
145
|
-
slot.queue.leave if slot.queue.count > 500
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
##
|
151
|
-
# Loads the setup.rb file by eval'ing the contents into this instance
|
152
|
-
#
|
153
|
-
def load_setup
|
154
|
-
setupFile = @properties["config/setup_file"]
|
155
|
-
return unless (setupFile and File.exist?(setupFile))
|
156
|
-
file = File.new(setupFile)
|
157
|
-
setup = file.read
|
158
|
-
file.close
|
159
|
-
instance_eval(setup)
|
160
|
-
end
|
161
|
-
|
162
|
-
##
|
163
|
-
# Builds the default properties file if it does not exist
|
164
|
-
#
|
165
|
-
def load_properties
|
166
|
-
unless Properties.exist?(@propertiesFile)
|
167
|
-
Properties.copy(@defaultPropertiesFile, @propertiesFile)
|
168
|
-
@properties = Properties.new("Core configuration file",
|
169
|
-
"1.0",
|
170
|
-
@bus["/system/properties"],
|
171
|
-
@propertiesFile)
|
172
|
-
@properties["version/major"] = Redcar::VERSION_MAJOR
|
173
|
-
@properties["version/minor"] = Redcar::VERSION_MINOR
|
174
|
-
@properties["version/release"] = Redcar::VERSION_RELEASE
|
175
|
-
else
|
176
|
-
@properties = Properties.new("Core configuration file",
|
177
|
-
"1.0",
|
178
|
-
@bus["/system/properties"],
|
179
|
-
@propertiesFile)
|
180
|
-
was_version = [@properties["version/major"],@properties["version/minor"],@properties["version/release"]].join('.')
|
181
|
-
is_version = [Redcar::VERSION_MAJOR, Redcar::VERSION_MINOR, Redcar::VERSION_RELEASE].join('.')
|
182
|
-
|
183
|
-
if (is_version < was_version)
|
184
|
-
puts "="*70
|
185
|
-
puts "WARNING!! You are running an old version of #{$FREEBASE_APPLICATION} (#{is_version}) against #{$FREEBASE_APPLICATION} configuration files created with a newer version (#{was_version}). This may cause serious troubles including #{$FREEBASE_APPLICATION} crashes."
|
186
|
-
puts "="*70
|
187
|
-
else
|
188
|
-
@properties["version/major"] = Redcar::VERSION_MAJOR
|
189
|
-
@properties["version/minor"] = Redcar::VERSION_MINOR
|
190
|
-
@properties["version/release"] = Redcar::VERSION_RELEASE
|
191
|
-
end
|
192
|
-
end
|
193
|
-
@properties['config/codebase'] = $FR_CODEBASE
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
end
|
@@ -1,1128 +0,0 @@
|
|
1
|
-
# Purpose: FreeBASE Databus. A publish/subscribe hierarchical system.
|
2
|
-
#
|
3
|
-
# $Id: databus.rb,v 1.6 2006/06/04 05:50:00 curthibbs Exp $
|
4
|
-
#
|
5
|
-
# Authors: Rich Kilmer <rich@infoether.com>
|
6
|
-
# based on an original design by Curt Hibbs <curt@hibbs.com>
|
7
|
-
# Contributors:
|
8
|
-
#
|
9
|
-
# This file is part of the FreeRIDE project
|
10
|
-
#
|
11
|
-
# This application is free software; you can redistribute it and/or
|
12
|
-
# modify it under the terms of the Ruby license defined in the
|
13
|
-
# COPYING file.
|
14
|
-
#
|
15
|
-
# Copyright (c) 2001 Rich Kilmer. All rights reserved.
|
16
|
-
#
|
17
|
-
|
18
|
-
require 'thread'
|
19
|
-
|
20
|
-
module FreeBASE
|
21
|
-
module DataBusHelper
|
22
|
-
def self.included(klass)
|
23
|
-
klass.send(:extend, self)
|
24
|
-
end
|
25
|
-
|
26
|
-
def bus(arg=nil, safe=false)
|
27
|
-
if safe
|
28
|
-
bits = arg.split("/")[1..-1]
|
29
|
-
path = "/"
|
30
|
-
bits.length.times do |i|
|
31
|
-
if $BUS[path].has_child? bits[i]
|
32
|
-
path += "/"+bits[i]
|
33
|
-
else
|
34
|
-
return nil
|
35
|
-
end
|
36
|
-
end
|
37
|
-
$BUS[arg]
|
38
|
-
else
|
39
|
-
if arg
|
40
|
-
$BUS[arg]
|
41
|
-
else
|
42
|
-
$BUS
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
##
|
49
|
-
# The DataBus class is used to manage a publish/subscribe system
|
50
|
-
# Usage::
|
51
|
-
#
|
52
|
-
# class SubscriptionTest
|
53
|
-
# def databus_notify(event, slot)
|
54
|
-
# puts "Tester Class got #{slot.data}"
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# databus = FreeBASE::DataBus.new
|
59
|
-
# st = SubscriptionTest.new
|
60
|
-
# databus["/foo/bar"].subscribe(st)
|
61
|
-
# id = databus["/foo/bar"].subscribe {|event, slot| puts "Block got #{slot.data}" }
|
62
|
-
# databus["/foo/bar"].data = "data :-)" #=> publishes data
|
63
|
-
# databus["/foo/bar"].unsubscribe(id)
|
64
|
-
# databus["/foo/bar"].unsubscribe(st)
|
65
|
-
# databus["/foo/bar/int"].validate("Does not implement to_i") { | value | value.respond_to? "to_i" }
|
66
|
-
# databus["/foo/bar/int"].data = Hash.new #=> raises Does not implement to_i
|
67
|
-
#
|
68
|
-
# stack, data, proc, queue
|
69
|
-
#
|
70
|
-
class DataBus
|
71
|
-
|
72
|
-
SEPARATOR = 47; # 47 is ASCII for /
|
73
|
-
|
74
|
-
SUBSCRIBER = 0
|
75
|
-
EVENT = 1
|
76
|
-
SLOT = 2
|
77
|
-
|
78
|
-
# True to enable validating values in slots, default=true
|
79
|
-
attr_accessor :validation_enabled
|
80
|
-
|
81
|
-
# True if notify method propagates to parent.notify, default=true
|
82
|
-
attr_accessor :propagate_notifications
|
83
|
-
|
84
|
-
# The root of this DataBus
|
85
|
-
attr_reader :root
|
86
|
-
|
87
|
-
# The parent slot
|
88
|
-
attr_reader :parent
|
89
|
-
|
90
|
-
attr_reader :state
|
91
|
-
|
92
|
-
attr_reader :notification_thread
|
93
|
-
|
94
|
-
##
|
95
|
-
# Constructs a DataBus
|
96
|
-
#
|
97
|
-
def initialize
|
98
|
-
@root = Slot.new("", nil, self)
|
99
|
-
@notification_queue = []
|
100
|
-
@idCount = 0
|
101
|
-
@validation_enabled = true
|
102
|
-
@propagate_notifications = true
|
103
|
-
|
104
|
-
# If only one bus, last created is available through $BUS and Object#bus:
|
105
|
-
$BUS = self
|
106
|
-
#start
|
107
|
-
end
|
108
|
-
|
109
|
-
##
|
110
|
-
# Place a notification event into the queue to be delivered asynchronously
|
111
|
-
#
|
112
|
-
# to:: [Proc | #databus_notify] The object to deliver the event to
|
113
|
-
# event:: [Symbol] The event symbol
|
114
|
-
# slot:: [DataBus::Slot] The slot that the event occurred at
|
115
|
-
#
|
116
|
-
def queue_notification(to, event, slot)
|
117
|
-
@notification_queue << [to, event, slot]
|
118
|
-
@notification_thread.wakeup if @notification_thread.stop?
|
119
|
-
end
|
120
|
-
|
121
|
-
##
|
122
|
-
# Starts the asynchronous notification queue
|
123
|
-
#
|
124
|
-
def start
|
125
|
-
@notification_thread = Thread.new {
|
126
|
-
loop do
|
127
|
-
while notification = @notification_queue.shift
|
128
|
-
if notification[SUBSCRIBER].kind_of? Proc
|
129
|
-
notification[SUBSCRIBER].call(notification[EVENT], notification[SLOT])
|
130
|
-
else
|
131
|
-
notification[SUBSCRIBER].databus_notify(notification[EVENT], notification[SLOT])
|
132
|
-
end
|
133
|
-
end
|
134
|
-
sleep unless @notification_queue.size > 0
|
135
|
-
end
|
136
|
-
}
|
137
|
-
end
|
138
|
-
|
139
|
-
##
|
140
|
-
# Navigates to a path (relative) to the root
|
141
|
-
#
|
142
|
-
# path:: [String] The path (i.e. /foo/bar or foo/bar)
|
143
|
-
# return:: [FreeBASE::DataBus::Slot] The new or existing slot
|
144
|
-
# see:: FreeBASE::DataBus::Slot#[]
|
145
|
-
#
|
146
|
-
def [](path)
|
147
|
-
@root[path]
|
148
|
-
end
|
149
|
-
|
150
|
-
##
|
151
|
-
# Incremented subscriber id counter
|
152
|
-
#
|
153
|
-
# return:: [Integer] unique id (incremented)
|
154
|
-
#
|
155
|
-
def idCount
|
156
|
-
@idCount = @idCount + 1
|
157
|
-
end
|
158
|
-
|
159
|
-
##
|
160
|
-
# The LinkSlot class represents a slot that is a logical link
|
161
|
-
# to another slot in the databus
|
162
|
-
#
|
163
|
-
class LinkSlot
|
164
|
-
attr_reader :path, :parent, :name
|
165
|
-
|
166
|
-
##
|
167
|
-
# Constructs a new link slot with the given name and parent
|
168
|
-
# linked to the supplied slot
|
169
|
-
#
|
170
|
-
# name:: [String] the name of this link slot
|
171
|
-
# parent:: [FreeBASE::DataBus::Slot] The parent of this slot
|
172
|
-
# link:: [FreeBASE::DataBus::Slot] The slot to link to
|
173
|
-
#
|
174
|
-
def initialize(name, parent, link)
|
175
|
-
@name = name
|
176
|
-
@parent = parent
|
177
|
-
@path = parent.nil? ? "/" : "#{parent.path}#{name}/"
|
178
|
-
@link = link
|
179
|
-
end
|
180
|
-
|
181
|
-
##
|
182
|
-
# Unlinks this slot from the parent
|
183
|
-
#
|
184
|
-
def unlink
|
185
|
-
@parent.unlink(self)
|
186
|
-
end
|
187
|
-
|
188
|
-
##
|
189
|
-
# Unlinks if pruning link slot, otherwise forwards to linked slot
|
190
|
-
#
|
191
|
-
# name:: [String=nil] The name of the slot to unlink
|
192
|
-
#
|
193
|
-
def prune(name=nil)
|
194
|
-
unlink unless name
|
195
|
-
@link.prune(name) if name
|
196
|
-
end
|
197
|
-
|
198
|
-
##
|
199
|
-
# Returns if this slot is a link slot
|
200
|
-
#
|
201
|
-
# return:: [Boolean] True for all LinkSlot instances
|
202
|
-
#
|
203
|
-
def is_link_slot?
|
204
|
-
return true
|
205
|
-
end
|
206
|
-
|
207
|
-
##
|
208
|
-
# Forward all unhandled calls to the linked slot
|
209
|
-
#
|
210
|
-
def method_missing(meth, *attrs, &block)
|
211
|
-
@link.send(meth, *attrs, &block)
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
##
|
216
|
-
# The Slot class represents a subscribe and/or publish node
|
217
|
-
#
|
218
|
-
class Slot
|
219
|
-
DATA = "data_slot"
|
220
|
-
QUEUE = "queue_slot"
|
221
|
-
STACK = "stack_slot"
|
222
|
-
PROC = "proc_slot"
|
223
|
-
MAP = "map_slot"
|
224
|
-
|
225
|
-
# True if notify method propagates to parent.notify, default=true
|
226
|
-
attr_accessor :propagate_notifications
|
227
|
-
|
228
|
-
attr_reader :path, :parent, :name, :attrs
|
229
|
-
|
230
|
-
##
|
231
|
-
# Creates a new Slot
|
232
|
-
#
|
233
|
-
# name:: [String] The name of the slot
|
234
|
-
# parent:: [Slot | Databus] The parent slot (or nil if root
|
235
|
-
# databus:: [Databus] The databus instance
|
236
|
-
#
|
237
|
-
def initialize(name, parent, databus)
|
238
|
-
@name = name
|
239
|
-
@parent = parent
|
240
|
-
@path = parent.nil? ? "/" : "#{parent.path}#{name}/"
|
241
|
-
@databus = databus
|
242
|
-
@slots = Hash.new
|
243
|
-
@subscribers = Hash.new
|
244
|
-
@propagate_notifications = true
|
245
|
-
notify(:notify_slot_add)
|
246
|
-
end
|
247
|
-
|
248
|
-
##
|
249
|
-
# Returns if this slot is the root slot
|
250
|
-
#
|
251
|
-
# return:: [Boolean] true if this slot is root
|
252
|
-
#
|
253
|
-
def root?
|
254
|
-
return true if self==@databus.root
|
255
|
-
end
|
256
|
-
|
257
|
-
##
|
258
|
-
# Sets this slots active manager
|
259
|
-
#
|
260
|
-
# manager:: [Object] The object to manager this slot
|
261
|
-
# raise:: [RuntimeException] If this slot is alread managed
|
262
|
-
#
|
263
|
-
def manager=(manager)
|
264
|
-
raise "Slot #{@path} already has an active manager: #{@manager}" if @manager
|
265
|
-
@manager = manager
|
266
|
-
notify(:notify_slot_managed)
|
267
|
-
end
|
268
|
-
|
269
|
-
##
|
270
|
-
# Returns the manager of this slot (or its parent manager if
|
271
|
-
# this slot does not have a manager
|
272
|
-
#
|
273
|
-
# return:: [Object] The manager of this slot or nil
|
274
|
-
#
|
275
|
-
def manager
|
276
|
-
return @manager if @manager or root?
|
277
|
-
return @parent.manager
|
278
|
-
end
|
279
|
-
|
280
|
-
##
|
281
|
-
# Determines if this slot has an active manager registered
|
282
|
-
# on it. This does not access the parent's manager if one
|
283
|
-
# is not set on this slot (as does the _manager method.
|
284
|
-
#
|
285
|
-
# return:: [Boolean] True if this slot has an active manager
|
286
|
-
#
|
287
|
-
def managed?
|
288
|
-
return @manager ? true : false
|
289
|
-
end
|
290
|
-
|
291
|
-
##
|
292
|
-
# Checks if this slot has a child slot of the given name
|
293
|
-
#
|
294
|
-
# name:: [String] The name of the child slot
|
295
|
-
# return:: [Boolean] True if child slot exists, otherwise false
|
296
|
-
#
|
297
|
-
def has_child?(name=nil)
|
298
|
-
unless name
|
299
|
-
return true if @slots.size > 0
|
300
|
-
return false
|
301
|
-
end
|
302
|
-
return @slots.has_key?(name)
|
303
|
-
end
|
304
|
-
|
305
|
-
##
|
306
|
-
# Returns all the children of this slot.
|
307
|
-
#
|
308
|
-
def children
|
309
|
-
c = []
|
310
|
-
self.each_slot {|slot| c << slot }
|
311
|
-
c
|
312
|
-
end
|
313
|
-
|
314
|
-
##
|
315
|
-
# Navigates to a path (relative) to the current object (with DataBus as root)
|
316
|
-
#
|
317
|
-
# path:: [String] The path (i.e. /foo/bar or foo/bar)
|
318
|
-
# return:: [FreeBASE::DataBus::Slot] The new or existing slot
|
319
|
-
#
|
320
|
-
def [](path)
|
321
|
-
path = path.split("/") if path.kind_of? String
|
322
|
-
while path.first == "." # ignore single dot ./foo
|
323
|
-
path.shift
|
324
|
-
end
|
325
|
-
subslot = path.shift
|
326
|
-
unless root?
|
327
|
-
return @databus.root[path] if subslot == "" # started at root /foo
|
328
|
-
return parent[path] if subslot==".." # parent ../foo
|
329
|
-
end
|
330
|
-
while subslot=="" # get rid of multi-slashes ///foo
|
331
|
-
subslot = path.shift
|
332
|
-
end
|
333
|
-
return self unless subslot # path now empty...return self
|
334
|
-
unless (child = @slots[subslot]) # is child a defined ?
|
335
|
-
child = @slots[subslot]= Slot.new(subslot, self, @databus) # build new one
|
336
|
-
end
|
337
|
-
while path.first=="" # get rid of multi-slashes foo///bar
|
338
|
-
path.shift
|
339
|
-
end
|
340
|
-
return child if path.empty?
|
341
|
-
return child[path]
|
342
|
-
end
|
343
|
-
|
344
|
-
##
|
345
|
-
# Prunes (removes) this slot (and all child slots)
|
346
|
-
#
|
347
|
-
# name:: [String=nil] The name of the child slot (nil == current slot)
|
348
|
-
# notification: :notify_slot_prune
|
349
|
-
#
|
350
|
-
def prune(name=nil)
|
351
|
-
if name and @slots[name]
|
352
|
-
@slots[name].notify(:notify_slot_prune)
|
353
|
-
@slots.delete(name)
|
354
|
-
return
|
355
|
-
end
|
356
|
-
raise "Cannot prune root slot" if root?
|
357
|
-
@slots.values.each {|slot| slot.prune}
|
358
|
-
@parent.prune(@name)
|
359
|
-
end
|
360
|
-
|
361
|
-
##
|
362
|
-
# Iterates over the sub-slots and link slots
|
363
|
-
#
|
364
|
-
# recurse:: [Boolean=false] if true, recurses all child slots
|
365
|
-
# yeild:: [FreeBASE::DataBus::Slot] The child slot
|
366
|
-
#
|
367
|
-
def each_slot(recurse=false, &block)
|
368
|
-
return unless block_given?
|
369
|
-
@slots.keys.sort.each do |name|
|
370
|
-
slot = @slots[name]
|
371
|
-
yield slot
|
372
|
-
slot.each_slot(recurse, &block) if recurse
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
##
|
377
|
-
# Links a child slot name to another slot in the databus
|
378
|
-
#
|
379
|
-
# child_name:: [String] The name of the child
|
380
|
-
# destination:: [String | FreeBASE::DataBus::Slot] The destination of the link
|
381
|
-
#
|
382
|
-
def link(child_name, destination)
|
383
|
-
destination = self[destination] if destination.kind_of? String
|
384
|
-
raise "Can only link to a DataBus::Slot" unless destination.kind_of? Slot
|
385
|
-
child = LinkSlot.new(child_name, self, destination)
|
386
|
-
@slots[child_name] = child
|
387
|
-
notify(:notify_slot_link, child)
|
388
|
-
child
|
389
|
-
end
|
390
|
-
|
391
|
-
##
|
392
|
-
# Unlinks a child slot name to another slot in the databus
|
393
|
-
#
|
394
|
-
# child:: [String] The name of the child
|
395
|
-
#
|
396
|
-
def unlink(child)
|
397
|
-
return unless child
|
398
|
-
child = child.name unless child.kind_of? String
|
399
|
-
child = @slots.delete(child)
|
400
|
-
notify(:notify_slot_unlink, child) if child
|
401
|
-
end
|
402
|
-
|
403
|
-
##
|
404
|
-
# Returns if this slot is a link slot
|
405
|
-
#
|
406
|
-
# return:: [Boolean] True is the slot is a link
|
407
|
-
#
|
408
|
-
def is_link_slot?
|
409
|
-
return false
|
410
|
-
end
|
411
|
-
|
412
|
-
##
|
413
|
-
# Make the slot a Data slot and set the value of the data.
|
414
|
-
# notification :notify_data_set
|
415
|
-
#
|
416
|
-
# object:: [Object] The object to store in the slot
|
417
|
-
# raise:: [RuntimeException] If there is a validator and it fails to validate the object
|
418
|
-
# raise:: [RuntimeException] If this slot is not a Data slot
|
419
|
-
#
|
420
|
-
def data=(object)
|
421
|
-
check_type(DATA)
|
422
|
-
validate(object)
|
423
|
-
@data = object
|
424
|
-
notify(:notify_data_set)
|
425
|
-
end
|
426
|
-
|
427
|
-
##
|
428
|
-
# Retrieves the value of the data object if this is a Data slot
|
429
|
-
#
|
430
|
-
# return:: [Object] The object stored in the slot
|
431
|
-
# raise:: [RuntimeException] If this slot is not a Data slot
|
432
|
-
#
|
433
|
-
def data
|
434
|
-
check_type(DATA)
|
435
|
-
return @data
|
436
|
-
end
|
437
|
-
alias_method :value, :data
|
438
|
-
|
439
|
-
##
|
440
|
-
# Checks is this is a Data slot
|
441
|
-
#
|
442
|
-
# return:: [Boolean] true if this is a Data slot
|
443
|
-
#
|
444
|
-
def is_data_slot?
|
445
|
-
return @type==DATA
|
446
|
-
end
|
447
|
-
|
448
|
-
##
|
449
|
-
# calls queue.join if this is a queue slot
|
450
|
-
#
|
451
|
-
def join(object)
|
452
|
-
return self.queue.join(object)
|
453
|
-
end
|
454
|
-
|
455
|
-
##
|
456
|
-
# calls queue.join if this is a queue slot
|
457
|
-
#
|
458
|
-
def <<(object)
|
459
|
-
return self.queue << object
|
460
|
-
end
|
461
|
-
|
462
|
-
##
|
463
|
-
# calls queue.leave is this is a queue slot
|
464
|
-
#
|
465
|
-
def leave
|
466
|
-
return self.queue.leave
|
467
|
-
end
|
468
|
-
|
469
|
-
##
|
470
|
-
# calls stack.push if this is a stack slot
|
471
|
-
#
|
472
|
-
def push(object)
|
473
|
-
return self.stack.push(object)
|
474
|
-
end
|
475
|
-
|
476
|
-
##
|
477
|
-
# calls stack.pop if this is a stack slot
|
478
|
-
#
|
479
|
-
def pop
|
480
|
-
return self.stack.pop
|
481
|
-
end
|
482
|
-
|
483
|
-
##
|
484
|
-
# calls map.put if this is a map slot
|
485
|
-
#
|
486
|
-
def put(key, value)
|
487
|
-
return self.map.put(key,value)
|
488
|
-
end
|
489
|
-
|
490
|
-
##
|
491
|
-
# calls map.get if this is a map slot
|
492
|
-
#
|
493
|
-
def get(key)
|
494
|
-
return self.map.get(key)
|
495
|
-
end
|
496
|
-
|
497
|
-
##
|
498
|
-
# removes a key if this is a map slot
|
499
|
-
#
|
500
|
-
def remove(key)
|
501
|
-
return self.map.remove
|
502
|
-
end
|
503
|
-
|
504
|
-
##
|
505
|
-
# Clears the stack or queue or map depending on the slot type
|
506
|
-
#
|
507
|
-
def clear
|
508
|
-
return self.queue.clear if is_queue_slot?
|
509
|
-
return self.stack.clear if is_stack_slot?
|
510
|
-
return self.map.clear if is_map_slot?
|
511
|
-
end
|
512
|
-
|
513
|
-
##
|
514
|
-
# Return the number of objects in the stack or queue
|
515
|
-
#
|
516
|
-
# return:: [Integer] The number of objects
|
517
|
-
#
|
518
|
-
def count
|
519
|
-
return self.queue.count if is_queue_slot?
|
520
|
-
return self.stack.count if is_stack_slot?
|
521
|
-
return self.map.count if is_map_slot?
|
522
|
-
end
|
523
|
-
|
524
|
-
##
|
525
|
-
# Retrieves the Queue object if this is a Queue slot
|
526
|
-
#
|
527
|
-
# return:: [FreeBASE::DataBus::Queue] The queue object of this slot
|
528
|
-
# raise:: [RuntimeException] If this slot is not a Queue slot
|
529
|
-
#
|
530
|
-
def queue
|
531
|
-
check_type(QUEUE)
|
532
|
-
@queue = Queue.new(self) unless @queue
|
533
|
-
return @queue
|
534
|
-
end
|
535
|
-
|
536
|
-
##
|
537
|
-
# Checks if this is a Queue slot
|
538
|
-
#
|
539
|
-
# return:: [Boolean] true if this is a Queue slot
|
540
|
-
#
|
541
|
-
def is_queue_slot?
|
542
|
-
return @type==QUEUE
|
543
|
-
end
|
544
|
-
|
545
|
-
##
|
546
|
-
# Retrieves the Stack object if this is a Stack slot
|
547
|
-
#
|
548
|
-
# return:: [FreeBASE::DataBus::Stack] The Stack object of this slot
|
549
|
-
# raise:: [RuntimeException] If this slot is not a Stack slot
|
550
|
-
#
|
551
|
-
def stack
|
552
|
-
check_type(STACK)
|
553
|
-
@stack = Stack.new(self) unless @stack
|
554
|
-
return @stack
|
555
|
-
end
|
556
|
-
|
557
|
-
##
|
558
|
-
# Checks if this is a Stack slot
|
559
|
-
#
|
560
|
-
# return:: [Boolean] true if this is a Stack slot
|
561
|
-
#
|
562
|
-
def is_stack_slot?
|
563
|
-
return @type==STACK
|
564
|
-
end
|
565
|
-
|
566
|
-
##
|
567
|
-
# Retrieves the ProcWrapper object if this is a queue slot
|
568
|
-
#
|
569
|
-
# return:: [FreeBASE::DataBus::ProcWrapper] The ProcWrapper object of this Proc slot
|
570
|
-
# raise:: [RuntimeException] If this slot is not a Proc slot
|
571
|
-
#
|
572
|
-
def proc
|
573
|
-
check_type(PROC)
|
574
|
-
@proc = ProcWrapper.new(self) unless @proc
|
575
|
-
return @proc
|
576
|
-
end
|
577
|
-
|
578
|
-
##
|
579
|
-
# Checks if this is a Proc slot
|
580
|
-
#
|
581
|
-
# return:: [Boolean] true if this is a Proc slot
|
582
|
-
#
|
583
|
-
def is_proc_slot?
|
584
|
-
return @type==PROC
|
585
|
-
end
|
586
|
-
|
587
|
-
##
|
588
|
-
# calls proc.set_proc if this is a proc slot
|
589
|
-
#
|
590
|
-
def set_proc(proc=nil, &block)
|
591
|
-
self.proc.set_proc(proc, &block)
|
592
|
-
end
|
593
|
-
|
594
|
-
##
|
595
|
-
# calls proc.call if this is a proc slot (invoke is an alias)
|
596
|
-
#
|
597
|
-
def call(*args, &block)
|
598
|
-
return self.proc.call(*args, &block)
|
599
|
-
end
|
600
|
-
alias_method :invoke, :call
|
601
|
-
|
602
|
-
##
|
603
|
-
# Retrieves the Map object if this is a hash slot
|
604
|
-
#
|
605
|
-
# return:: [FreeBASE::DataBus::Map] The HashWrapper object of this Hash slot
|
606
|
-
# raise:: [RuntimeException] If this slot is not a Hash slot
|
607
|
-
#
|
608
|
-
def map
|
609
|
-
check_type(MAP)
|
610
|
-
@map = Map.new(self) unless @map
|
611
|
-
return @map
|
612
|
-
end
|
613
|
-
|
614
|
-
##
|
615
|
-
# Checks if this is a map slot
|
616
|
-
#
|
617
|
-
# return:: [Boolean] true if this is a map slot
|
618
|
-
#
|
619
|
-
def is_map_slot?
|
620
|
-
return @type==MAP
|
621
|
-
end
|
622
|
-
|
623
|
-
##
|
624
|
-
# Checks to see if the type of slot is as specified. If the type is not defined, the
|
625
|
-
# type is set to the supplied type.
|
626
|
-
#
|
627
|
-
# type:: [String] The type of slot
|
628
|
-
# raise:: [RuntimeException] If the slot is of a different type that what is supplied
|
629
|
-
#
|
630
|
-
def check_type(type)
|
631
|
-
return if @type == type
|
632
|
-
raise "Slot #{path} cannot be set as a #{type} because its already a #{@type}" if @type
|
633
|
-
@type = type
|
634
|
-
end
|
635
|
-
|
636
|
-
private :check_type
|
637
|
-
|
638
|
-
##
|
639
|
-
# Sends out a notification to subscribers of this slot. If this slot
|
640
|
-
# has a parent, the notification is propagated to the parent's notify method
|
641
|
-
# until the root slot is reached.
|
642
|
-
#
|
643
|
-
# event:: [Symbol] The event (:notify_obj_action)
|
644
|
-
# slot:: [Slot=self] The slot that has the action on it
|
645
|
-
#
|
646
|
-
def notify(event, slot = self)
|
647
|
-
if @subscribers.size > 0
|
648
|
-
@subscribers.each_value do |subscriber|
|
649
|
-
#@databus.queue_notification(subscriber, event, slot)
|
650
|
-
if subscriber.kind_of? Proc
|
651
|
-
subscriber.call(event, slot)
|
652
|
-
else
|
653
|
-
subscriber.databus_notify(event, slot)
|
654
|
-
end
|
655
|
-
end
|
656
|
-
end
|
657
|
-
@parent.notify(event, slot) if @propagate_notifications && @databus.propagate_notifications && @parent
|
658
|
-
end
|
659
|
-
|
660
|
-
##
|
661
|
-
# Returns the subscribers to this slot (as a hash).
|
662
|
-
#
|
663
|
-
def subscribers
|
664
|
-
return @subscribers
|
665
|
-
end
|
666
|
-
|
667
|
-
##
|
668
|
-
# If a validator is set on this slot, it is called with the
|
669
|
-
# data object
|
670
|
-
#
|
671
|
-
# object:: [Object] The object to validate against
|
672
|
-
# raise:: [RuntimeException] If validator fails
|
673
|
-
#
|
674
|
-
def validate(object)
|
675
|
-
if @databus.validation_enabled and @validator
|
676
|
-
raise@validatorError unless @validator.call(object)
|
677
|
-
end
|
678
|
-
end
|
679
|
-
|
680
|
-
##
|
681
|
-
# The Subscription class is used to hold the slot so
|
682
|
-
# that one can cancel with the object.
|
683
|
-
#
|
684
|
-
# subscription = @databus['slot'].subscribe { |event, slot| ... }
|
685
|
-
# subscription.cancel
|
686
|
-
#
|
687
|
-
class Subscription
|
688
|
-
def initialize(slot)
|
689
|
-
@slot = slot
|
690
|
-
end
|
691
|
-
|
692
|
-
##
|
693
|
-
# Cancel this subscription
|
694
|
-
#
|
695
|
-
def cancel
|
696
|
-
@slot.unsubscribe(self)
|
697
|
-
end
|
698
|
-
end
|
699
|
-
|
700
|
-
##
|
701
|
-
# Subscribe to this slot
|
702
|
-
#
|
703
|
-
# subscriber:: [Object_databus_notify] The object to process the slot (response w/databus_notify(message, slot)
|
704
|
-
# &block:: [Block |message, slot|] The block to process the slot
|
705
|
-
# return:: [Object] The subscription ID (used for unsubscribe)
|
706
|
-
#
|
707
|
-
def subscribe(subscriber=nil, &block)
|
708
|
-
if subscriber
|
709
|
-
unless subscriber.respond_to?("databus_notify")
|
710
|
-
raise "Subscribers must impliment the databus_notify method"
|
711
|
-
end
|
712
|
-
@subscribers[subscriber] = subscriber
|
713
|
-
return subscriber
|
714
|
-
else
|
715
|
-
subscription = Subscription.new(self)
|
716
|
-
@subscribers[subscription] = Proc.new(&block)
|
717
|
-
return subscription
|
718
|
-
end
|
719
|
-
end
|
720
|
-
|
721
|
-
##
|
722
|
-
# Unsubscribes to this slot
|
723
|
-
#
|
724
|
-
# subscriber:: [Object] The id returned from subscribe
|
725
|
-
#
|
726
|
-
def unsubscribe(subscriber)
|
727
|
-
@subscribers.delete(subscriber)
|
728
|
-
end
|
729
|
-
|
730
|
-
##
|
731
|
-
# Dumps (puts) the subscriber list
|
732
|
-
#
|
733
|
-
def dump(array = nil)
|
734
|
-
if array
|
735
|
-
first = false
|
736
|
-
else
|
737
|
-
first = true
|
738
|
-
array = []
|
739
|
-
end
|
740
|
-
array << "Slot #{@path} [type='#{@type}', data='#{@data}', manager='#{@manager.class}']" if @type
|
741
|
-
@slots.each_value {|slot| slot.dump(array)}
|
742
|
-
array.each {|slot| puts slot} if first
|
743
|
-
end
|
744
|
-
|
745
|
-
##
|
746
|
-
# Sets the validator for this slot
|
747
|
-
#
|
748
|
-
# validatorError:: [String=""] The error string to display if failure occurs
|
749
|
-
# &block:: [Block |object|] The block to process the published object. Must return true if object is valid.
|
750
|
-
#
|
751
|
-
def validate_with(validatorError="", &block)
|
752
|
-
@validator = block
|
753
|
-
@validatorError = "Object published into #{@path} did not pass validator: #{validatorError}"
|
754
|
-
end
|
755
|
-
|
756
|
-
##
|
757
|
-
# Overrides method_missing to be able to set attributes using the following
|
758
|
-
# syntax:
|
759
|
-
# get:: slot.attr_<name> to get an attribute vulue
|
760
|
-
# set:: slot.attr_<name>=value to set and attribute value
|
761
|
-
#
|
762
|
-
def method_missing(methId, *args, &block)
|
763
|
-
tag = methId.id2name
|
764
|
-
if tag[0..4]=="attr_"
|
765
|
-
@attrs ||= {}
|
766
|
-
if tag[-1]==61 # 'attr_???='
|
767
|
-
attrname = tag[5..-2]
|
768
|
-
case attrname
|
769
|
-
when "parent", "name", "path"
|
770
|
-
raise "Attribute set by constructor"
|
771
|
-
else
|
772
|
-
@attrs[attrname] = args[0]
|
773
|
-
notify(:notify_attribute_set, self)
|
774
|
-
end
|
775
|
-
return
|
776
|
-
else
|
777
|
-
attrname = tag[5..-1]
|
778
|
-
case attrname
|
779
|
-
when "parent"
|
780
|
-
return @parent
|
781
|
-
when "name"
|
782
|
-
return @name
|
783
|
-
when "path"
|
784
|
-
return @path
|
785
|
-
else
|
786
|
-
return @attrs[attrname]
|
787
|
-
end
|
788
|
-
end
|
789
|
-
end
|
790
|
-
super
|
791
|
-
end
|
792
|
-
|
793
|
-
end
|
794
|
-
|
795
|
-
##
|
796
|
-
# The Queue class represents a FIFO list for Slots that may need
|
797
|
-
# to manage such data (such as User Interface event propagation).
|
798
|
-
#
|
799
|
-
class Queue
|
800
|
-
|
801
|
-
##
|
802
|
-
# Create the Queue object
|
803
|
-
#
|
804
|
-
# slot:: [FreeBASE::DataBus::Slot] The slot this queue belongs to.
|
805
|
-
#
|
806
|
-
def initialize(slot)
|
807
|
-
@slot = slot
|
808
|
-
@queue = []
|
809
|
-
end
|
810
|
-
|
811
|
-
##
|
812
|
-
# Have the object join the queue
|
813
|
-
# notification :notify_queue_join
|
814
|
-
#
|
815
|
-
# object:: [Object] The object to place in the queue
|
816
|
-
#
|
817
|
-
def join(object)
|
818
|
-
@slot.validate(object)
|
819
|
-
@queue << object
|
820
|
-
@slot.notify(:notify_queue_join)
|
821
|
-
end
|
822
|
-
|
823
|
-
##
|
824
|
-
# Same as _join(object)
|
825
|
-
#
|
826
|
-
def <<(object)
|
827
|
-
join(object)
|
828
|
-
end
|
829
|
-
|
830
|
-
##
|
831
|
-
# Have the first object leave the queue
|
832
|
-
# notification :notify_queue_leave
|
833
|
-
#
|
834
|
-
# return:: [Object] The first object in the queue or nil
|
835
|
-
#
|
836
|
-
def leave
|
837
|
-
result = @queue.shift
|
838
|
-
@slot.notify(:notify_queue_leave)
|
839
|
-
return result
|
840
|
-
end
|
841
|
-
|
842
|
-
##
|
843
|
-
# Return the number of objects in the stack
|
844
|
-
#
|
845
|
-
# return:: [Integer] The number of objects
|
846
|
-
#
|
847
|
-
def count
|
848
|
-
return @queue.size
|
849
|
-
end
|
850
|
-
|
851
|
-
##
|
852
|
-
# Clear all objects from the queue
|
853
|
-
# notification :notify_queue_clear
|
854
|
-
#
|
855
|
-
def clear
|
856
|
-
@queue.clear
|
857
|
-
@slot.notify(:notify_queue_clear)
|
858
|
-
end
|
859
|
-
|
860
|
-
##
|
861
|
-
# Return a given element in the queue. Leave it in place
|
862
|
-
# notification :none
|
863
|
-
# return: the value of the element at index
|
864
|
-
def [] (index)
|
865
|
-
@queue[index]
|
866
|
-
end
|
867
|
-
|
868
|
-
end
|
869
|
-
|
870
|
-
##
|
871
|
-
# The Stack class represents a LIFO list for Slots that may need
|
872
|
-
# to manage such data.
|
873
|
-
#
|
874
|
-
class Stack
|
875
|
-
|
876
|
-
##
|
877
|
-
# Create the Stack object
|
878
|
-
#
|
879
|
-
# slot:: [FreeBASE::DataBus::Slot] The slot this queue belongs to.
|
880
|
-
#
|
881
|
-
def initialize(slot)
|
882
|
-
@slot = slot
|
883
|
-
@stack = []
|
884
|
-
end
|
885
|
-
|
886
|
-
##
|
887
|
-
# Push an object onto the stack.
|
888
|
-
# notification :notify_stack_push
|
889
|
-
#
|
890
|
-
# object:: [Object] The object to push on the stack
|
891
|
-
#
|
892
|
-
def push(object)
|
893
|
-
@slot.validate(object)
|
894
|
-
@stack.push object
|
895
|
-
@slot.notify(:notify_stack_push)
|
896
|
-
end
|
897
|
-
|
898
|
-
##
|
899
|
-
# Pop an object off the stack.
|
900
|
-
# notification :notify_stack_pop
|
901
|
-
#
|
902
|
-
# return:: [Object] The object to popped from the stack
|
903
|
-
#
|
904
|
-
def pop
|
905
|
-
result = @stack.pop
|
906
|
-
@slot.notify(:notify_stack_pop)
|
907
|
-
return result
|
908
|
-
end
|
909
|
-
|
910
|
-
##
|
911
|
-
# Return the number of objects in the stack
|
912
|
-
#
|
913
|
-
# return:: [Integer] The number of objects
|
914
|
-
#
|
915
|
-
def count
|
916
|
-
return @stack.size
|
917
|
-
end
|
918
|
-
|
919
|
-
##
|
920
|
-
# Clear all objects from the stack
|
921
|
-
# notification :notify_stack_clear
|
922
|
-
#
|
923
|
-
def clear
|
924
|
-
@stack.clear
|
925
|
-
end
|
926
|
-
|
927
|
-
##
|
928
|
-
# Return a given element in the stack. Leave it in place
|
929
|
-
# notification :none
|
930
|
-
# return: the value of the element at index
|
931
|
-
def [] (index)
|
932
|
-
@queue[index]
|
933
|
-
end
|
934
|
-
|
935
|
-
end
|
936
|
-
|
937
|
-
##
|
938
|
-
# The ProcWrapper holds the Proc object for the Proc slot
|
939
|
-
#
|
940
|
-
# Usage::
|
941
|
-
# p = ProcWrapper.new(self)
|
942
|
-
# p.set {|p1, p2| puts p1,p2}
|
943
|
-
# p.call("one", "two") #=> "one"\n"two"
|
944
|
-
#
|
945
|
-
class ProcWrapper
|
946
|
-
|
947
|
-
##
|
948
|
-
# Create the ProcWrapper object
|
949
|
-
#
|
950
|
-
# slot:: [FreeBASE::DataBus::Slot] The slot this proc wrapper belongs to.
|
951
|
-
#
|
952
|
-
def initialize(slot)
|
953
|
-
@slot = slot
|
954
|
-
end
|
955
|
-
|
956
|
-
##
|
957
|
-
# Sets the proc
|
958
|
-
#
|
959
|
-
# proc:: [Proc = nil] The (optional) Proc to store
|
960
|
-
# &block:: [Block] The block to store
|
961
|
-
#
|
962
|
-
def set_proc(proc=nil, &block)
|
963
|
-
block = proc if proc
|
964
|
-
@proc = block
|
965
|
-
@slot.notify(:notify_proc_set)
|
966
|
-
end
|
967
|
-
|
968
|
-
##
|
969
|
-
# Gets the proc
|
970
|
-
#
|
971
|
-
# return:: [Proc] The proc stored in this slot
|
972
|
-
#
|
973
|
-
def get_proc
|
974
|
-
return @proc
|
975
|
-
end
|
976
|
-
|
977
|
-
##
|
978
|
-
# Calls the stored proc.
|
979
|
-
# nofication :notify_proc_call
|
980
|
-
#
|
981
|
-
# *args:: [*Array] The calling param array
|
982
|
-
# return:: [Object] The result of the proc
|
983
|
-
# raise:: [RuntimeException] If validator is enabled and the supplied args fail validation
|
984
|
-
#
|
985
|
-
def call(*args)
|
986
|
-
@slot.validate(args)
|
987
|
-
result = nil
|
988
|
-
result = @proc.call(*args) if @proc
|
989
|
-
@slot.notify(:notify_proc_call)
|
990
|
-
return result
|
991
|
-
end
|
992
|
-
end
|
993
|
-
|
994
|
-
##
|
995
|
-
# The Map holds the Hash object for the Hash slot
|
996
|
-
#
|
997
|
-
# Usage::
|
998
|
-
# p = HashWrapper.new(self)
|
999
|
-
# p.put(key, value)
|
1000
|
-
# p.get(key) #=> value
|
1001
|
-
#
|
1002
|
-
class Map
|
1003
|
-
##
|
1004
|
-
# Create the Map object
|
1005
|
-
#
|
1006
|
-
# slot:: [FreeBASE::DataBus::Slot] The slot this proc wrapper belongs to.
|
1007
|
-
#
|
1008
|
-
def initialize(slot)
|
1009
|
-
@slot = slot
|
1010
|
-
@map = {}
|
1011
|
-
end
|
1012
|
-
|
1013
|
-
##
|
1014
|
-
# Sets the hash
|
1015
|
-
#
|
1016
|
-
# hash:: [Hash] The Hash to store
|
1017
|
-
#
|
1018
|
-
def map=(hash)
|
1019
|
-
@map=hash
|
1020
|
-
@slot.notify(:notify_map_set)
|
1021
|
-
end
|
1022
|
-
|
1023
|
-
##
|
1024
|
-
# Clears the hash
|
1025
|
-
#
|
1026
|
-
def clear()
|
1027
|
-
@map = {}
|
1028
|
-
@slot.notify(:notify_map_cleared)
|
1029
|
-
end
|
1030
|
-
|
1031
|
-
##
|
1032
|
-
# Removes an item from the hash
|
1033
|
-
#
|
1034
|
-
# key:: [key] The key to remove
|
1035
|
-
#
|
1036
|
-
def remove(key)
|
1037
|
-
@map.delete(key)
|
1038
|
-
@slot.notify(:notify_map_remove)
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
##
|
1042
|
-
# Gets the value
|
1043
|
-
#
|
1044
|
-
# key:: [Object] The key
|
1045
|
-
# return:: [Object] The value of the specified key
|
1046
|
-
#
|
1047
|
-
def get(key)
|
1048
|
-
return @map[key]
|
1049
|
-
end
|
1050
|
-
|
1051
|
-
##
|
1052
|
-
# Sets the value of the supplied key
|
1053
|
-
#
|
1054
|
-
# key:: [Object] The key
|
1055
|
-
# value:: [Object] The value
|
1056
|
-
#
|
1057
|
-
def put(key, value)
|
1058
|
-
@map[key]=value
|
1059
|
-
@slot.notify(:notify_map_put)
|
1060
|
-
end
|
1061
|
-
|
1062
|
-
##
|
1063
|
-
# Returns if the map slot contains the given key
|
1064
|
-
#
|
1065
|
-
# key:: [Object] The key
|
1066
|
-
# return:: [Boolean] true if the map has the key, otherwise false
|
1067
|
-
#
|
1068
|
-
def has_key?(key)
|
1069
|
-
return @map.has_key?(key)
|
1070
|
-
end
|
1071
|
-
|
1072
|
-
##
|
1073
|
-
# Return the number of objects in the hash
|
1074
|
-
#
|
1075
|
-
# return:: [Integer] The number of objects
|
1076
|
-
#
|
1077
|
-
def count
|
1078
|
-
return @map.size
|
1079
|
-
end
|
1080
|
-
|
1081
|
-
end
|
1082
|
-
|
1083
|
-
##
|
1084
|
-
# The Adapter is a helper class that allows for connecting slot
|
1085
|
-
# values together (in a Thread-safe way) so that changes to
|
1086
|
-
# one (or more) slots would result in automatic updates to
|
1087
|
-
# other slots
|
1088
|
-
#
|
1089
|
-
class Adapter
|
1090
|
-
|
1091
|
-
##
|
1092
|
-
# Construct an Adapter object and subscribes to the supplied slots.
|
1093
|
-
#
|
1094
|
-
# slots:: [Array of FreeBASE::DataBus::Slot] The slots that the supplied block needs to manage
|
1095
|
-
# &block:: [Block | msg, slot |] The block to process the slot changes
|
1096
|
-
#
|
1097
|
-
def initialize(slots, &block)
|
1098
|
-
block = proc if proc
|
1099
|
-
slots.each {|slot| slot.subscribe(self)}
|
1100
|
-
@proc = block
|
1101
|
-
@thread_queue = []
|
1102
|
-
end
|
1103
|
-
|
1104
|
-
##
|
1105
|
-
# Called from databus when slots are updated. This method
|
1106
|
-
# queues calling threads to ensure only a single thread updating
|
1107
|
-
# at the same time.
|
1108
|
-
#
|
1109
|
-
# msg:: [Symbol] the message symbol
|
1110
|
-
# slot:: [FreeBASE::DataBus::Slot] the slot that was updated
|
1111
|
-
#
|
1112
|
-
def databus_notify(msg, slot)
|
1113
|
-
return if @current_thread == Thread.current
|
1114
|
-
if @current_thread
|
1115
|
-
@thread_queue << Thread.current
|
1116
|
-
Thread.current.stop
|
1117
|
-
end
|
1118
|
-
@current_thread = Thread.current
|
1119
|
-
@proc.call(msg, slot)
|
1120
|
-
@current_thread = nil
|
1121
|
-
@thread_queue.shift.wake if @thread_queue.size>0
|
1122
|
-
end
|
1123
|
-
end
|
1124
|
-
|
1125
|
-
|
1126
|
-
end
|
1127
|
-
end
|
1128
|
-
|