comparison mcabber/doc/HOWTO_modules.txt @ 1752:4a7c7900f600

Update HOWTO
author Myhailo Danylenko <isbear@ukrpost.net>
date Sat, 13 Mar 2010 12:35:15 +0200
parents 5093b5ca1572
children d8442bcb33b7
comparison
equal deleted inserted replaced
1751:c25f95b98377 1752:4a7c7900f600
15 #include <mcabber/modules.h> 15 #include <mcabber/modules.h>
16 16
17 typedef void (*module_init_t)(void); 17 typedef void (*module_init_t)(void);
18 typedef void (*module_uninit_t)(void); 18 typedef void (*module_uninit_t)(void);
19 19
20 typedef struct { 20 typedef struct module_info_struct module_info_t;
21 const gchar *mcabber_version; 21 struct module_info_struct {
22 const gchar *branch;
22 module_init_t init; 23 module_init_t init;
23 module_uninit_t uninit; 24 module_uninit_t uninit;
24 const gchar **requires; 25 const gchar **requires;
25 } module_info_t; 26 guint api;
27 const gchar *version;
28 const gchar *description;
29 module_info_t *next;
30 };
26 -------------------------------------------------------- 31 --------------------------------------------------------
27 32
28 Callbacks init and uninit will be called after module 33 Callbacks init and uninit will be called after module
29 and it's dependencies loading. 'requires' should contain 34 and it's dependencies loading. 'requires' can contain a
30 NULL-terminated list of module names, that should be loaded 35 NULL-terminated list of module names, that should be loaded
31 before this. 'mcabber_version' is required and should contain 36 before this. 'branch' and 'api' are required and should
32 mcabber version, that this module is designed to work with. 37 contain mcabber branch and api version, that this module is
33 Three other fields may be NULL. 38 designed to work with. For these values see ChangeLog.api.
39 'version' and 'description' fields are optional and just
40 provide user with additional information about module.
41 'description' field can contain newlines. 'next' field can
42 contain pointer to the next struct with another branch of
43 mcabber, if your module can work with multiple branches.
34 44
35 To load modules, mcabber uses glib's GModule, thus, in your 45 To load modules, mcabber uses glib's GModule, thus, in your
36 module you can also use functions 46 module you can also use functions
37 47
38 -------------------------------------------------------- 48 --------------------------------------------------------
74 - check if module is present, and if present just 84 - check if module is present, and if present just
75 increase it's reference count 85 increase it's reference count
76 - load .so via glib (and call g_module_check_init, if 86 - load .so via glib (and call g_module_check_init, if
77 present) 87 present)
78 - check for information structure presence 88 - check for information structure presence
79 - check target mcabber version compatibility 89 - find suitable branch and check api version
90 compatibility
80 - load modules, that this module requires (note, that 91 - load modules, that this module requires (note, that
81 dependency problems will be reported as error 92 dependency problems will be reported as error
82 invariably, force flag have no effect on this check) 93 invariably, force flag have no effect on this check)
83 - module placed into a list of modules 94 - module placed into a list of modules
84 - module init routine is called 95 - module init routine is called
319 { 330 {
320 scr_LogPrint (LPRINT_NORMAL, "Bye, World!"); 331 scr_LogPrint (LPRINT_NORMAL, "Bye, World!");
321 } 332 }
322 333
323 module_info_t info_hello = { 334 module_info_t info_hello = {
324 .mcabber_version = "0.10.0", 335 .branch = "dev",
336 .api = 1,
325 .requires = NULL, 337 .requires = NULL,
326 .init = hello_init, 338 .init = hello_init,
327 .uninit = hello_uninit, 339 .uninit = hello_uninit,
340 .version = "0.0.1",
341 .description = "Hello world module\n"
342 "(as well as bye world module)",
343 .next = NULL,
328 }; 344 };
329 345
330 /* The End */ 346 /* The End */
331 -------------------------------------------------------- 347 --------------------------------------------------------
332 348
382 { 398 {
383 cmd_del ("hello"); 399 cmd_del ("hello");
384 } 400 }
385 401
386 module_info_t hello_info = { 402 module_info_t hello_info = {
387 .mcabber_version = "0.10.0", 403 .branch = "dev",
404 .api = 1,
388 .requires = NULL, 405 .requires = NULL,
389 .init = hello_init, 406 .init = hello_init,
390 .uninit = hello_uninit, 407 .uninit = hello_uninit,
408 .version = "0.0.2",
409 .description = "Hello world module\n"
410 "Provides command /hello",
411 .next = NULL,
391 } 412 }
392 413
393 /* The End */ 414 /* The End */
394 -------------------------------------------------------- 415 --------------------------------------------------------
395 416
452 compl_del_category (hello_cid); 473 compl_del_category (hello_cid);
453 cmd_del ("hello"); 474 cmd_del ("hello");
454 } 475 }
455 476
456 module_info_t hello_info = { 477 module_info_t hello_info = {
457 .mcabber_version = "0.10.0", 478 .branch = "dev",
479 .api = 1,
458 .requires = NULL, 480 .requires = NULL,
459 .init = hello_init, 481 .init = hello_init,
460 .uninit = hello_uninit, 482 .uninit = hello_uninit,
483 .version = "0.0.3",
484 .description = "Hello world module"
485 "Provides command /hello with completion",
486 .next = NULL,
461 } 487 }
462 488
463 /* The End */ 489 /* The End */
464 -------------------------------------------------------- 490 --------------------------------------------------------
465 491
559 if (beep_cid) 585 if (beep_cid)
560 compl_del_category (beep_cid); 586 compl_del_category (beep_cid);
561 } 587 }
562 588
563 module_info_t beep_info = { 589 module_info_t beep_info = {
564 .mcabber_version = "0.10.0", 590 .branch = "dev",
591 .api = 1,
565 .requires = NULL, 592 .requires = NULL,
566 .init = beep_init, 593 .init = beep_init,
567 .uninit = beep_uninit, 594 .uninit = beep_uninit,
595 .version = "0.0.1",
596 .description = "Simple beeper module\n"
597 "Recognizes option beep_enable\n"
598 "Provides command /beep",
599 .next = NULL,
568 } 600 }
569 601
570 /* The End */ 602 /* The End */
571 -------------------------------------------------------- 603 --------------------------------------------------------
572 604
609 #include <mcabber/modules.h> 641 #include <mcabber/modules.h>
610 642
611 const gchar *a_deps[] = { "b", "c", NULL }; 643 const gchar *a_deps[] = { "b", "c", NULL };
612 644
613 module_info_t info_a = { 645 module_info_t info_a = {
614 .mcabber_version = "0.10.0", 646 .branch = "dev",
647 .api = 1,
615 .requires = a_deps, 648 .requires = a_deps,
616 .init = a_init, 649 .init = a_init,
617 .uninit = a_uninit, 650 .uninit = a_uninit,
651 .version = NULL,
652 .description = NULL,
653 .next = NULL,
618 }; 654 };
619 -------------------------------------------------------- 655 --------------------------------------------------------
620 656
621 If your module needs to "authenticate" mcabber version 657 If your module needs to "authenticate" mcabber version
622 too, this can be done in g_module_check_init: 658 too, this can be done in g_module_check_init:
624 -------------------------------------------------------- 660 --------------------------------------------------------
625 #include <glib.h> 661 #include <glib.h>
626 #include <gmodule.h> 662 #include <gmodule.h>
627 663
628 #include <mcabber/main.h> 664 #include <mcabber/main.h>
665 #include <mcabber/modules.h>
629 666
630 const gchar *g_module_check_init (GModule *module) 667 const gchar *g_module_check_init (GModule *module)
631 { 668 {
632 char *ver = mcabber_version (); 669 char *ver = mcabber_version ();
633
634 // ver now contains version in format 670 // ver now contains version in format
635 // X.X.X[-xxx][ (XXXXXXXXX)] 671 // X.X.X[-xxx][ (XXXXXXXXXXXXX)]
672 const gchar *branch = mcabber_branch;
673 guint api = mcabber_api_version;
674 const gchar *error = NULL;
675
636 if (...) 676 if (...)
637 return "Incompatible mcabber version"; 677 error = "Incompatible mcabber version";
638 678
639 g_free (ver); 679 g_free (ver);
640 return NULL; 680 return error;
641 } 681 }
642 -------------------------------------------------------- 682 --------------------------------------------------------
643 683
644 Also you can use glib check_init routine to modify 684 Also you can use glib check_init routine to modify
645 module information, that will be checked by mcabber, 685 module information, that will be checked by mcabber,
646 eg. if you want your module to always pass mcabber 686 eg. if you want your module to always pass mcabber
647 version check, you can assign version, obtained from 687 version check, you can assign branch information,
648 mcabber_version() to corresponding field in your struct. 688 obtained from mcabber_... variables to corresponding
689 fields in your struct.
649 Or you can modify your module's dependencies, though 690 Or you can modify your module's dependencies, though
650 direct module_load() will have the same effect, and 691 direct module_load() will have the same effect, and
651 can be used for optional dependencies, that your module 692 can be used for optional dependencies, that your module
652 can work without. 693 can still work without.
653 694
654 Note: remember, that g_module_check_init will be always 695 Note: remember, that g_module_check_init will be always
655 called, even if later module will not pass checks, thus: 696 called, even if later module will not pass checks, thus:
656 - do not use functions from other modules there; 697 - do not use functions from other modules there;
657 - provide g_module_unload to undo anything, check_init 698 - provide g_module_unload to undo anything, check_init
689 a more suitable version of text in question). 730 a more suitable version of text in question).
690 731
691 -- Myhailo Danylenko 732 -- Myhailo Danylenko
692 -- mailto:isbear@ukrpost.net 733 -- mailto:isbear@ukrpost.net
693 -- xmpp:isbear@unixzone.org.ua 734 -- xmpp:isbear@unixzone.org.ua
694 -- Thu, 04 Mar 2010 09:32:38 +0200 735 -- Sat, 13 Mar 2010 12:18:17 +0200
695 736