home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Programming / MR_Classes / Dev / Source / supermodel / model_SuperModel.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-04  |  8.2 KB  |  354 lines

  1. //#define DEBUG
  2. #include <debug.h>
  3.  
  4. #include <tagitemmacros.h>
  5.  
  6. #include "supermodel.h"
  7. #include "protos.h"
  8.  
  9. #include <string.h>
  10.  
  11. #include <classes/supermodel.h>
  12.  
  13. #include <clib/extras/string_protos.h>
  14. #include <clib/extras/utility_protos.h>
  15. #include <clib/alib_protos.h>
  16.  
  17. #include <exec/memory.h>
  18.  
  19. #include <intuition/classusr.h>
  20. #include <intuition/classes.h>
  21. #include <intuition/icclass.h>
  22.  
  23. #include <proto/dos.h>
  24. #include <proto/utility.h>
  25. #include <proto/intuition.h>
  26.  
  27. #include <proto/exec.h>
  28.  
  29.  
  30. ULONG SuperNotifyA(Class *CL, Object *O, struct opUpdate *M, struct TagItem *TagList);
  31. void UpdateCachedStrings(struct SuperModelData *data, struct TagItem *NewTags);
  32. void FreeCachedStrings(struct SuperModelData *data);
  33.  
  34. Class *SuperModelClass;
  35.  
  36.  
  37. BOOL i_SuperModelInit(void)
  38. {
  39.   if(i_SuperICInit())
  40.   {
  41.     if(SuperModelClass=i_MakeClass(0,(STRPTR)"modelclass",0,sizeof(struct SuperModelData), 0, SuperModel_Dispatch)) 
  42.     {
  43.       return(1);
  44.     }
  45.     i_SuperICTerm();    
  46.   }
  47.   return(0);
  48. }
  49.  
  50.  
  51.  
  52.  
  53. void i_SuperModelTerm(void)
  54. {
  55.   i_SuperICTerm();    
  56.   if(SuperModelClass)
  57.   {
  58.     FreeClass(SuperModelClass);
  59.     SuperModelClass=0;
  60.   }
  61. }
  62.  
  63. /****** supermodel.class/SM_NewSuperModel ******************************************
  64. *
  65. *   NAME
  66. *       SM_NewSuperModel -- Allocate SuperModel object
  67. *
  68. *   SYNOPSIS
  69. *       model = SM_NewSuperModel( Tag1, Data1, TAg2, ...)
  70. *
  71. *       Object *SM_NewSuperModel(Tag Tags, ...);
  72. *
  73. *   FUNCTION
  74. *       Allocate model object.
  75. *
  76. *   INPUTS
  77. *       Tags
  78. *
  79. *   RESULT
  80. *
  81. *   EXAMPLE
  82. *
  83. *   NOTES
  84. *       DisposeObject() returned model when done.
  85. *
  86. *       Before targeted objects (ie gadgets) are freed you must either:
  87. *       1. Dispose() the SuperModel object, which also Dispose()s all
  88. *           SuperIC objects.
  89. *       2. SetAttr() ICA_TARGET to NULL on every SuperIC object.
  90. *       SuperIC objects need to clear the ICA_MAP and ICA_TARGET settings 
  91. *       of it's targetted object.  If the target object nolonger exists,
  92. *       expect bad things to happen.
  93. *
  94. *   BUGS
  95. *
  96. *   SEE ALSO
  97. *
  98. ******************************************************************************
  99. *
  100. */
  101.  
  102.  
  103. Object  __asm *LIB_SM_NewSuperModelA(register __a0 struct TagItem  *TagList)
  104. {
  105.   return(NewObjectA(SuperModelClass, 0, (APTR)TagList));
  106. }
  107.  
  108.  
  109. ULONG SuperModel_Set(Class *CL, Object *O, struct opSet *Set);
  110.  
  111. ULONG __asm __saveds SuperModel_Dispatch(register __a0 Class *CL, register __a2 Object *O, register __a1 Msg M)
  112. {
  113.   ULONG retval=0;
  114.   struct SuperModelData *data;
  115.  
  116.   data=INST_DATA(CL,O);
  117.  
  118.   switch(M->MethodID)
  119.   {
  120.     case OM_NEW:
  121.       if(O=(APTR)DoSuperMethodA(CL,O,M))
  122.       {
  123.         data=INST_DATA(CL,O);
  124.         if(data->CachedStringTags=SMTAG_AllocTags(50))
  125.         {
  126.           NewList(&data->Members);
  127.           SuperModel_Set(CL,O,(APTR)M);
  128.           retval=(ULONG)O;
  129.         }
  130.         else
  131.         {
  132.           DoSuperMethod(CL,O,OM_DISPOSE);
  133.           retval=0;
  134.         }
  135.       } 
  136.       break;
  137.       
  138.     case OM_DISPOSE://                                                                                 (44.1.7) (08/04/00)
  139.       {//                                                                                              (44.1.7) (08/04/00)
  140.         FreeCachedStrings(data);//                                                                     (44.1.7) (08/04/00)
  141.       }
  142.       break;
  143.  
  144.     case OM_ADDMEMBER:
  145.       {
  146.         struct opMember *m;
  147.         Object *o;
  148.         
  149.         m=(APTR)M;
  150.         o=m->opam_Object;
  151.         
  152.         if(SM_IsMemberOf(o, SuperICClass,0))
  153.         {
  154.           SetAttrs((Object *)o, SICA_Model, O, TAG_DONE);
  155.         }
  156.         retval=DoSuperMethodA(CL,O,M);
  157.       }
  158.       break;
  159.       
  160.     case OM_REMMEMBER:
  161.         //DKP("OM_REMMEMBER\n");
  162.       {
  163.         struct opMember *m;
  164.         Object *o;
  165.         
  166.         m=(APTR)M;
  167.         o=m->opam_Object;
  168.         
  169.         if(SM_IsMemberOf(o, SuperICClass,0))
  170.         {
  171.           SetAttrs((Object *)o, SICA_Model, 0, TAG_DONE);
  172.         }
  173.         retval=DoSuperMethodA(CL,O,M);
  174.       }
  175.       break;
  176.  
  177. /*  Do real Notify  */
  178.     case SMM_PRIVATE0:
  179.       {
  180.         struct opUpdate u,*uu;
  181.         
  182.         uu=(APTR)M;
  183.         
  184.         u=*uu;
  185.         
  186.         UpdateCachedStrings(data,u.opu_AttrList);
  187.         
  188.         u.MethodID=OM_NOTIFY;
  189.         
  190.         retval=DoSuperMethodA(CL,O,(Msg)&u);
  191.       }
  192.       break;
  193.       
  194.     case OM_SET:
  195.     case OM_UPDATE:
  196.       //DKP("OM_SET/UPDATE\n");
  197.       if(data->GlueFunc)
  198.       {
  199.         struct opUpdate u,*uu;
  200.         struct smGlueData gd;
  201.         struct TagItem *mytags;
  202.         
  203.         uu=(APTR)M;
  204.         
  205.         u.MethodID      =uu->MethodID;
  206.         u.opu_AttrList  =uu->opu_AttrList;
  207.         u.opu_GInfo     =uu->opu_GInfo;
  208.         if(u.MethodID==OM_UPDATE)
  209.         {
  210.           u.opu_Flags=uu->opu_Flags;
  211.         }
  212.         
  213.         if(mytags = u.opu_AttrList = SMTAG_AllocTags(50))
  214.         {
  215.           SMTAG_AddTagsA(u.opu_AttrList, uu->opu_AttrList);
  216.           
  217. //        retval=data->GlueFunc(CL, O, (APTR)&u, data->UserData, data->A6);
  218.  
  219.           gd.ModelCL    =CL;
  220.           gd.ModelObject=O;
  221.           gd.Update     =&u;
  222.         
  223.           retval=data->GlueFunc(&gd, u.opu_AttrList, (APTR)data->UserData, data->A6);
  224.         
  225.           SMTAG_FreeTags(mytags);//                                                                    (44.1.1) (08/04/00)//  (44.1.2) (08/04/00)
  226.         }
  227.       }
  228.       else
  229.       {
  230.         retval=DoSuperMethodA(CL,O,(APTR)M);
  231.       }
  232.       
  233.       retval+=SuperModel_Set(CL,O,(APTR)M);
  234.       
  235.       break;
  236.       
  237.     default:
  238.       retval=DoSuperMethodA(CL,O,M);
  239.   }
  240.  
  241.   return(retval);
  242. }
  243.  
  244. ULONG SuperModel_Set(Class *CL, Object *O, struct opSet *Set)
  245. {
  246.   struct SuperModelData *data;
  247.   struct TagItem *tag, *tstate;
  248.   ULONG d,retval=0,c=0;
  249.  
  250.   data=INST_DATA(CL,O);
  251.  
  252.   tstate=Set->ops_AttrList;
  253.   
  254.   while(tag=NextTagItem(&tstate))
  255.   {
  256.     c++;
  257.     d=tag->ti_Data;
  258.     switch(tag->ti_Tag)
  259.     {
  260.       case SMA_AddMember:
  261.         DoMethod(O, OM_ADDMEMBER, d);
  262.         c--;
  263.         break;
  264.       
  265.       case SMA_RemMember:
  266.         DoMethod(O, OM_REMMEMBER, d);
  267.         c--;
  268.         break;
  269.  
  270.       case ICA_TARGET:
  271.       case ICA_MAP:
  272.         c--;
  273.         break;
  274.       
  275.       case SMA_GlueFunc:
  276.         data->GlueFunc=d;
  277.         c--;
  278.         break;
  279.       case SMA_GlueFuncA6:
  280.         data->A6=d;
  281.         c--;
  282.         break;
  283.  
  284.       case SMA_GlueFuncUserData:
  285.         data->UserData=(APTR)d;
  286.         c--;
  287.         break;
  288.  
  289.       case SMA_CacheStringTag://                                                                       (44.1.3) (08/04/00)
  290. //        DKP("SMA_CacheStringTag %lx\n",d);//                                                         (44.1.3) (08/04/00)
  291.         SMTAG_AddTag(data->CachedStringTags, d, AllocVec(258,MEMF_PUBLIC));//                          (44.1.3) (08/04/00)
  292.         c--;//                                                                                         (44.1.3) (08/04/00)
  293.         break;//                                                                                       (44.1.3) (08/04/00)
  294.     }
  295.   }
  296.   
  297.   if(c)
  298.   {
  299. //    retval=SuperNotifyA(CL, O, (APTR)Set, Set->ops_AttrList);
  300.   }
  301.   
  302.   return(retval);
  303. }
  304.  
  305.  
  306.  
  307. ULONG SuperNotifyA(Class *CL, Object *O, struct opUpdate *M, struct TagItem *TagList)
  308. {
  309.   return(DoSuperMethod(CL,O,OM_NOTIFY, TagList, M->opu_GInfo, ((M->MethodID == OM_UPDATE)?(M->opu_Flags): 0)));
  310. }
  311.  
  312.  
  313. void UpdateCachedStrings(struct SuperModelData *data, struct TagItem *NewTags)//                       (44.1.4) (08/04/00)//  (44.1.5) (08/04/00)
  314. {
  315.   struct TagItem *tag, *tstate, *nt;
  316.  
  317. //  DKP("UpdateCacheStrings\n");
  318.   
  319.   ProcessTagList(data->CachedStringTags, tag, tstate)
  320.   {
  321. //    DKP("Tag %08lx\n", tag->ti_Tag);
  322.     
  323.     if(nt=FindTagItem(tag->ti_Tag, NewTags))
  324.     {
  325. //      DKP("Updating Tag\n");
  326.       
  327.       /* unload old string */
  328.       if(tag->ti_Data)
  329.       {
  330.         UBYTE *d;
  331.         
  332.         d=(UBYTE *)tag->ti_Data;
  333.         strncpy(d, (char *)nt->ti_Data, 257);
  334.         d[257]=0;
  335.         /* make new tags reference new copy of string */
  336.         nt->ti_Data=(ULONG)d;
  337. //        DKP("nv %ls\n",d);
  338.       }
  339.     }
  340.   }
  341. }
  342.  
  343.  
  344. void FreeCachedStrings(struct SuperModelData *data)//                                                  (44.1.6) (08/04/00)
  345. {
  346.   struct TagItem *tag, *tstate;
  347.   
  348.   ProcessTagList(data->CachedStringTags, tag, tstate)
  349.   {
  350.     FreeVec((APTR)tag->ti_Data);
  351.     tag->ti_Data=0;
  352.   }
  353. }
  354.