Merge "astobj2: Create function to copy weak proxied objects from container."
[asterisk/asterisk.git] / apps / app_skel.c
index 6fdbebb..e0b8bca 100644 (file)
@@ -33,7 +33,7 @@
  * \addtogroup configuration_file Configuration Files
  */
 
-/*! 
+/*!
  * \page app_skel.conf app_skel.conf
  * \verbinclude app_skel.conf.sample
  */
@@ -45,8 +45,6 @@
 
 #include "asterisk.h"
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
 #include <math.h> /* log10 */
 #include "asterisk/file.h"
 #include "asterisk/channel.h"
@@ -86,6 +84,51 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                from. It shows you the basic structure to create your own Asterisk applications.</para>
                </description>
        </application>
+
+       <configInfo name="app_skel" language="en_US">
+               <configFile name="app_skel.conf">
+                       <configObject name="globals">
+                               <synopsis>Options that apply globally to app_skel</synopsis>
+                               <configOption name="games">
+                                       <synopsis>The number of games a single execution of SkelGuessNumber will play</synopsis>
+                               </configOption>
+                               <configOption name="cheat">
+                                       <synopsis>Should the computer cheat?</synopsis>
+                                       <description><para>If enabled, the computer will ignore winning guesses.</para></description>
+                               </configOption>
+                       </configObject>
+                       <configObject name="sounds">
+                               <synopsis>Prompts for SkelGuessNumber to play</synopsis>
+                               <configOption name="prompt" default="please-enter-your&amp;number&amp;queue-less-than">
+                                       <synopsis>A prompt directing the user to enter a number less than the max number</synopsis>
+                               </configOption>
+                               <configOption name="wrong_guess" default="vm-pls-try-again">
+                                       <synopsis>The sound file to play when a wrong guess is made</synopsis>
+                               </configOption>
+                               <configOption name="right_guess" default="auth-thankyou">
+                                       <synopsis>The sound file to play when a correct guess is made</synopsis>
+                               </configOption>
+                               <configOption name="too_low">
+                                       <synopsis>The sound file to play when a guess is too low</synopsis>
+                               </configOption>
+                               <configOption name="too_high">
+                                       <synopsis>The sound file to play when a guess is too high</synopsis>
+                               </configOption>
+                               <configOption name="lose" default="vm-goodbye">
+                                       <synopsis>The sound file to play when a player loses</synopsis>
+                               </configOption>
+                       </configObject>
+                       <configObject name="level">
+                               <synopsis>Defined levels for the SkelGuessNumber game</synopsis>
+                               <configOption name="max_number">
+                                       <synopsis>The maximum in the range of numbers to guess (1 is the implied minimum)</synopsis>
+                               </configOption>
+                               <configOption name="max_guesses">
+                                       <synopsis>The maximum number of guesses before a game is considered lost</synopsis>
+                               </configOption>
+                       </configObject>
+               </configFile>
+       </configInfo>
  ***/
 
 static char *app = "SkelGuessNumber";
@@ -128,7 +171,7 @@ struct skel_level_state {
 };
 
 /*! \brief Object to hold level config information.
- * \note This object should hold a reference to an an object that holds state across reloads.
+ * \note This object should hold a reference to an object that holds state across reloads.
  * The other fields are just examples of the kind of data that might be stored in an level.
  */
 struct skel_level {
@@ -148,7 +191,7 @@ struct skel_level {
  * the running game.
  */
 struct skel_current_game {
-       uint32_t total_games;          /*! The total number of games for this call to to the app */
+       uint32_t total_games;          /*! The total number of games for this call to the app */
        uint32_t games_left;           /*! How many games are left to play in this set */
        uint32_t cheat;                /*! Whether or not cheating was enabled for the game */
        struct skel_level *level_info; /*! The level information for the running game */
@@ -197,9 +240,10 @@ static void *skel_level_find(struct ao2_container *tmp_container, const char *ca
 /*! \brief An aco_type structure to link the "general" category to the skel_global_config type */
 static struct aco_type global_option = {
        .type = ACO_GLOBAL,
+       .name = "globals",
        .item_offset = offsetof(struct skel_config, global),
-       .category_match = ACO_WHITELIST,
-       .category = "^general$",
+       .category_match = ACO_WHITELIST_EXACT,
+       .category = "general",
 };
 
 struct aco_type *global_options[] = ACO_TYPES(&global_option);
@@ -207,18 +251,26 @@ struct aco_type *global_options[] = ACO_TYPES(&global_option);
 /*! \brief An aco_type structure to link the "sounds" category to the skel_global_config type */
 static struct aco_type sound_option = {
        .type = ACO_GLOBAL,
+       .name = "sounds",
        .item_offset = offsetof(struct skel_config, global),
-       .category_match = ACO_WHITELIST,
-       .category = "^sounds$",
+       .category_match = ACO_WHITELIST_EXACT,
+       .category = "sounds",
 };
 
 struct aco_type *sound_options[] = ACO_TYPES(&sound_option);
 
+static const char *level_categories[] = {
+       "general",
+       "sounds",
+       NULL,
+};
+
 /*! \brief An aco_type structure to link the everything but the "general" and "sounds" categories to the skel_level type */
 static struct aco_type level_option = {
        .type = ACO_ITEM,
-       .category_match = ACO_BLACKLIST,
-       .category = "^(general|sounds)$",
+       .name = "level",
+       .category_match = ACO_BLACKLIST_ARRAY,
+       .category = (const char *)level_categories,
        .item_alloc = skel_level_alloc,
        .item_find = skel_level_find,
        .item_offset = offsetof(struct skel_config, levels),
@@ -528,7 +580,9 @@ static void *skel_config_alloc(void)
                goto error;
        }
 
-       if (!(cfg->levels = ao2_container_alloc(LEVEL_BUCKETS, skel_level_hash, skel_level_cmp))) {
+       cfg->levels = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, LEVEL_BUCKETS,
+               skel_level_hash, NULL, skel_level_cmp);
+       if (!cfg->levels) {
                goto error;
        }
 
@@ -654,6 +708,7 @@ static int unload_module(void)
        ast_cli_unregister_multiple(skel_cli, ARRAY_LEN(skel_cli));
        aco_info_destroy(&cfg_info);
        ao2_global_obj_release(globals);
+       ao2_cleanup(games);
        return ast_unregister_application(app);
 }
 
@@ -663,8 +718,8 @@ static int unload_module(void)
  * Module loading including tests for configuration or dependencies.
  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
- * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the 
- * configuration file or other non-critical problem return 
+ * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
+ * configuration file or other non-critical problem return
  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
  */
 static int load_module(void)
@@ -672,7 +727,9 @@ static int load_module(void)
        if (aco_info_init(&cfg_info)) {
                goto error;
        }
-       if (!(games = ao2_container_alloc(1, NULL, NULL))) {
+
+       games = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
+       if (!games) {
                goto error;
        }
 
@@ -690,7 +747,7 @@ static int load_module(void)
 
        /* Level options */
        aco_option_register(&cfg_info, "max_number", ACO_EXACT, level_options, NULL, OPT_UINT_T, 0, FLDSET(struct skel_level, max_num));
-       aco_option_register(&cfg_info, "max_guesses", ACO_EXACT, level_options, NULL, OPT_UINT_T, 1, FLDSET(struct skel_level, max_guesses));
+       aco_option_register(&cfg_info, "max_guesses", ACO_EXACT, level_options, NULL, OPT_UINT_T, 0, FLDSET(struct skel_level, max_guesses));
 
        if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
                goto error;
@@ -708,9 +765,9 @@ error:
        return AST_MODULE_LOAD_DECLINE;
 }
 
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Skeleton (sample) Application",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Skeleton (sample) Application",
+       .support_level = AST_MODULE_SUPPORT_CORE,
        .load = load_module,
        .unload = unload_module,
        .reload = reload_module,
-       .load_pri = AST_MODPRI_DEFAULT,
 );