diff options
author | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
---|---|---|
committer | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
commit | 526b5580dabbfed7cfe5439dc3a90ec727f563c2 (patch) | |
tree | 22b1af92348785daad16714ee5e2b633017e0e48 /apps/plugins/pdbox/PDa/src/m_obj.c | |
parent | 4f2dfcc01b260d946044ef2b6af5fe36cb772c8d (diff) | |
download | rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.tar.gz rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.zip |
Cut the files in half and it might work better (note to self: check your tree is really clean before patching)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21070 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/m_obj.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/m_obj.c | 697 |
1 files changed, 0 insertions, 697 deletions
diff --git a/apps/plugins/pdbox/PDa/src/m_obj.c b/apps/plugins/pdbox/PDa/src/m_obj.c index d53da5722e..785fd240bf 100644 --- a/apps/plugins/pdbox/PDa/src/m_obj.c +++ b/apps/plugins/pdbox/PDa/src/m_obj.c | |||
@@ -695,700 +695,3 @@ int outlet_getsignalindex(t_outlet *x) | |||
695 | return (n); | 695 | return (n); |
696 | } | 696 | } |
697 | 697 | ||
698 | /* Copyright (c) 1997-1999 Miller Puckette. | ||
699 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
700 | * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ | ||
701 | |||
702 | /* this file handles Max-style patchable objects, i.e., objects which | ||
703 | can interconnect via inlets and outlets; also, the (terse) generic | ||
704 | behavior for "gobjs" appears at the end of this file. */ | ||
705 | |||
706 | #include "m_pd.h" | ||
707 | #include "m_imp.h" | ||
708 | |||
709 | union inletunion | ||
710 | { | ||
711 | t_symbol *iu_symto; | ||
712 | t_gpointer *iu_pointerslot; | ||
713 | t_float *iu_floatslot; | ||
714 | t_symbol **iu_symslot; | ||
715 | t_sample iu_floatsignalvalue; | ||
716 | }; | ||
717 | |||
718 | struct _inlet | ||
719 | { | ||
720 | t_pd i_pd; | ||
721 | struct _inlet *i_next; | ||
722 | t_object *i_owner; | ||
723 | t_pd *i_dest; | ||
724 | t_symbol *i_symfrom; | ||
725 | union inletunion i_un; | ||
726 | }; | ||
727 | |||
728 | #define i_symto i_un.iu_symto | ||
729 | #define i_pointerslot i_un.iu_pointerslot | ||
730 | #define i_floatslot i_un.iu_floatslot | ||
731 | #define i_symslot i_un.iu_symslot | ||
732 | |||
733 | static t_class *inlet_class, *pointerinlet_class, *floatinlet_class, | ||
734 | *symbolinlet_class; | ||
735 | |||
736 | #define ISINLET(pd) ((*(pd) == inlet_class) || \ | ||
737 | (*(pd) == pointerinlet_class) || \ | ||
738 | (*(pd) == floatinlet_class) || \ | ||
739 | (*(pd) == symbolinlet_class)) | ||
740 | |||
741 | /* --------------------- generic inlets ala max ------------------ */ | ||
742 | |||
743 | t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1, t_symbol *s2) | ||
744 | { | ||
745 | t_inlet *x = (t_inlet *)pd_new(inlet_class), *y, *y2; | ||
746 | x->i_owner = owner; | ||
747 | x->i_dest = dest; | ||
748 | if (s1 == &s_signal) | ||
749 | x->i_un.iu_floatsignalvalue = 0; | ||
750 | else x->i_symto = s2; | ||
751 | x->i_symfrom = s1; | ||
752 | x->i_next = 0; | ||
753 | if (y = owner->ob_inlet) | ||
754 | { | ||
755 | while (y2 = y->i_next) y = y2; | ||
756 | y->i_next = x; | ||
757 | } | ||
758 | else owner->ob_inlet = x; | ||
759 | return (x); | ||
760 | } | ||
761 | |||
762 | static void inlet_wrong(t_inlet *x, t_symbol *s) | ||
763 | { | ||
764 | pd_error(x->i_owner, "inlet: expected '%s' but got '%s'", | ||
765 | x->i_symfrom->s_name, s->s_name); | ||
766 | } | ||
767 | |||
768 | /* LATER figure out how to make these efficient: */ | ||
769 | static void inlet_bang(t_inlet *x) | ||
770 | { | ||
771 | if (x->i_symfrom == &s_bang) | ||
772 | pd_vmess(x->i_dest, x->i_symto, ""); | ||
773 | else if (!x->i_symfrom) pd_bang(x->i_dest); | ||
774 | else inlet_wrong(x, &s_bang); | ||
775 | } | ||
776 | |||
777 | static void inlet_pointer(t_inlet *x, t_gpointer *gp) | ||
778 | { | ||
779 | if (x->i_symfrom == &s_pointer) | ||
780 | pd_vmess(x->i_dest, x->i_symto, "p", gp); | ||
781 | else if (!x->i_symfrom) pd_pointer(x->i_dest, gp); | ||
782 | else inlet_wrong(x, &s_pointer); | ||
783 | } | ||
784 | |||
785 | static void inlet_float(t_inlet *x, t_float f) | ||
786 | { | ||
787 | if (x->i_symfrom == &s_float) | ||
788 | pd_vmess(x->i_dest, x->i_symto, "f", (t_floatarg)f); | ||
789 | else if (x->i_symfrom == &s_signal) | ||
790 | x->i_un.iu_floatsignalvalue = ftofix(f); | ||
791 | else if (!x->i_symfrom) | ||
792 | pd_float(x->i_dest, f); | ||
793 | else inlet_wrong(x, &s_float); | ||
794 | } | ||
795 | |||
796 | static void inlet_symbol(t_inlet *x, t_symbol *s) | ||
797 | { | ||
798 | if (x->i_symfrom == &s_symbol) | ||
799 | pd_vmess(x->i_dest, x->i_symto, "s", s); | ||
800 | else if (!x->i_symfrom) pd_symbol(x->i_dest, s); | ||
801 | else inlet_wrong(x, &s_symbol); | ||
802 | } | ||
803 | |||
804 | static void inlet_list(t_inlet *x, t_symbol *s, int argc, t_atom *argv) | ||
805 | { | ||
806 | t_atom at; | ||
807 | if (x->i_symfrom == &s_list || x->i_symfrom == &s_float | ||
808 | || x->i_symfrom == &s_symbol || x->i_symfrom == &s_pointer) | ||
809 | typedmess(x->i_dest, x->i_symto, argc, argv); | ||
810 | else if (!x->i_symfrom) pd_list(x->i_dest, s, argc, argv); | ||
811 | else inlet_wrong(x, &s_list); | ||
812 | } | ||
813 | |||
814 | static void inlet_anything(t_inlet *x, t_symbol *s, int argc, t_atom *argv) | ||
815 | { | ||
816 | if (x->i_symfrom == s) | ||
817 | typedmess(x->i_dest, x->i_symto, argc, argv); | ||
818 | else if (!x->i_symfrom) | ||
819 | typedmess(x->i_dest, s, argc, argv); | ||
820 | else inlet_wrong(x, s); | ||
821 | } | ||
822 | |||
823 | void inlet_free(t_inlet *x) | ||
824 | { | ||
825 | t_object *y = x->i_owner; | ||
826 | t_inlet *x2; | ||
827 | if (y->ob_inlet == x) y->ob_inlet = x->i_next; | ||
828 | else for (x2 = y->ob_inlet; x2; x2 = x2->i_next) | ||
829 | if (x2->i_next == x) | ||
830 | { | ||
831 | x2->i_next = x->i_next; | ||
832 | break; | ||
833 | } | ||
834 | t_freebytes(x, sizeof(*x)); | ||
835 | } | ||
836 | |||
837 | /* ----- pointerinlets, floatinlets, syminlets: optimized inlets ------- */ | ||
838 | |||
839 | static void pointerinlet_pointer(t_inlet *x, t_gpointer *gp) | ||
840 | { | ||
841 | gpointer_unset(x->i_pointerslot); | ||
842 | *(x->i_pointerslot) = *gp; | ||
843 | if (gp->gp_stub) gp->gp_stub->gs_refcount++; | ||
844 | } | ||
845 | |||
846 | t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp) | ||
847 | { | ||
848 | t_inlet *x = (t_inlet *)pd_new(pointerinlet_class), *y, *y2; | ||
849 | x->i_owner = owner; | ||
850 | x->i_dest = 0; | ||
851 | x->i_symfrom = &s_pointer; | ||
852 | x->i_pointerslot = gp; | ||
853 | x->i_next = 0; | ||
854 | if (y = owner->ob_inlet) | ||
855 | { | ||
856 | while (y2 = y->i_next) y = y2; | ||
857 | y->i_next = x; | ||
858 | } | ||
859 | else owner->ob_inlet = x; | ||
860 | return (x); | ||
861 | } | ||
862 | |||
863 | static void floatinlet_float(t_inlet *x, t_float f) | ||
864 | { | ||
865 | *(x->i_floatslot) = f; | ||
866 | } | ||
867 | |||
868 | t_inlet *floatinlet_new(t_object *owner, t_float *fp) | ||
869 | { | ||
870 | t_inlet *x = (t_inlet *)pd_new(floatinlet_class), *y, *y2; | ||
871 | x->i_owner = owner; | ||
872 | x->i_dest = 0; | ||
873 | x->i_symfrom = &s_float; | ||
874 | x->i_floatslot = fp; | ||
875 | x->i_next = 0; | ||
876 | if (y = owner->ob_inlet) | ||
877 | { | ||
878 | while (y2 = y->i_next) y = y2; | ||
879 | y->i_next = x; | ||
880 | } | ||
881 | else owner->ob_inlet = x; | ||
882 | return (x); | ||
883 | } | ||
884 | |||
885 | static void symbolinlet_symbol(t_inlet *x, t_symbol *s) | ||
886 | { | ||
887 | *(x->i_symslot) = s; | ||
888 | } | ||
889 | |||
890 | t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp) | ||
891 | { | ||
892 | t_inlet *x = (t_inlet *)pd_new(symbolinlet_class), *y, *y2; | ||
893 | x->i_owner = owner; | ||
894 | x->i_dest = 0; | ||
895 | x->i_symfrom = &s_symbol; | ||
896 | x->i_symslot = sp; | ||
897 | x->i_next = 0; | ||
898 | if (y = owner->ob_inlet) | ||
899 | { | ||
900 | while (y2 = y->i_next) y = y2; | ||
901 | y->i_next = x; | ||
902 | } | ||
903 | else owner->ob_inlet = x; | ||
904 | return (x); | ||
905 | } | ||
906 | |||
907 | /* ---------------------- routine to handle lists ---------------------- */ | ||
908 | |||
909 | /* objects interpret lists by feeding them to the individual inlets. | ||
910 | Before you call this check that the object doesn't have a more | ||
911 | specific way to handle lists. */ | ||
912 | void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv) | ||
913 | { | ||
914 | t_atom *ap; | ||
915 | int count; | ||
916 | t_inlet *ip = ((t_object *)x)->ob_inlet; | ||
917 | if (!argc) return; | ||
918 | for (count = argc-1, ap = argv+1; ip && count--; ap++, ip = ip->i_next) | ||
919 | { | ||
920 | if (ap->a_type == A_POINTER) pd_pointer(&ip->i_pd, ap->a_w.w_gpointer); | ||
921 | else if (ap->a_type == A_FLOAT) pd_float(&ip->i_pd, ap->a_w.w_float); | ||
922 | else pd_symbol(&ip->i_pd, ap->a_w.w_symbol); | ||
923 | } | ||
924 | if (argv->a_type == A_POINTER) pd_pointer(&x->ob_pd, argv->a_w.w_gpointer); | ||
925 | else if (argv->a_type == A_FLOAT) pd_float(&x->ob_pd, argv->a_w.w_float); | ||
926 | else pd_symbol(&x->ob_pd, argv->a_w.w_symbol); | ||
927 | } | ||
928 | |||
929 | void obj_init(void) | ||
930 | { | ||
931 | inlet_class = class_new(gensym("inlet"), 0, 0, | ||
932 | sizeof(t_inlet), CLASS_PD, 0); | ||
933 | class_addbang(inlet_class, inlet_bang); | ||
934 | class_addpointer(inlet_class, inlet_pointer); | ||
935 | class_addfloat(inlet_class, inlet_float); | ||
936 | class_addsymbol(inlet_class, inlet_symbol); | ||
937 | class_addlist(inlet_class, inlet_list); | ||
938 | class_addanything(inlet_class, inlet_anything); | ||
939 | |||
940 | pointerinlet_class = class_new(gensym("inlet"), 0, 0, | ||
941 | sizeof(t_inlet), CLASS_PD, 0); | ||
942 | class_addpointer(pointerinlet_class, pointerinlet_pointer); | ||
943 | |||
944 | floatinlet_class = class_new(gensym("inlet"), 0, 0, | ||
945 | sizeof(t_inlet), CLASS_PD, 0); | ||
946 | class_addfloat(floatinlet_class, (t_method)floatinlet_float); | ||
947 | |||
948 | symbolinlet_class = class_new(gensym("inlet"), 0, 0, | ||
949 | sizeof(t_inlet), CLASS_PD, 0); | ||
950 | class_addsymbol(symbolinlet_class, symbolinlet_symbol); | ||
951 | |||
952 | } | ||
953 | |||
954 | /* --------------------------- outlets ------------------------------ */ | ||
955 | |||
956 | static char *stacklimit, *topstack; | ||
957 | #define STACKSIZE 1000000 | ||
958 | static int outlet_eventno; | ||
959 | |||
960 | /* set a stack limit (on each incoming event that can set off messages) | ||
961 | for the outlet functions to check to prevent stack overflow from message | ||
962 | recursion */ | ||
963 | void outlet_setstacklim(void) | ||
964 | { | ||
965 | char c; | ||
966 | topstack = &c; | ||
967 | stacklimit = (&c) - STACKSIZE; | ||
968 | outlet_eventno++; | ||
969 | } | ||
970 | |||
971 | /* get a number unique to the (clock, MIDI, GUI, etc.) event we're on */ | ||
972 | int sched_geteventno( void) | ||
973 | { | ||
974 | return (outlet_eventno); | ||
975 | } | ||
976 | |||
977 | struct _outconnect | ||
978 | { | ||
979 | struct _outconnect *oc_next; | ||
980 | t_pd *oc_to; | ||
981 | }; | ||
982 | |||
983 | struct _outlet | ||
984 | { | ||
985 | t_object *o_owner; | ||
986 | struct _outlet *o_next; | ||
987 | t_outconnect *o_connections; | ||
988 | t_symbol *o_sym; | ||
989 | }; | ||
990 | |||
991 | t_outlet *outlet_new(t_object *owner, t_symbol *s) | ||
992 | { | ||
993 | t_outlet *x = (t_outlet *)getbytes(sizeof(*x)), *y, *y2; | ||
994 | x->o_owner = owner; | ||
995 | x->o_next = 0; | ||
996 | if (y = owner->ob_outlet) | ||
997 | { | ||
998 | while (y2 = y->o_next) y = y2; | ||
999 | y->o_next = x; | ||
1000 | } | ||
1001 | else owner->ob_outlet = x; | ||
1002 | x->o_connections = 0; | ||
1003 | x->o_sym = s; | ||
1004 | return (x); | ||
1005 | } | ||
1006 | |||
1007 | static void outlet_stackerror(t_outlet *x) | ||
1008 | { | ||
1009 | pd_error(x->o_owner, "stack overflow"); | ||
1010 | stacklimit = topstack; | ||
1011 | } | ||
1012 | |||
1013 | void outlet_bang(t_outlet *x) | ||
1014 | { | ||
1015 | t_outconnect *oc; | ||
1016 | char c; | ||
1017 | if (&c < stacklimit) | ||
1018 | outlet_stackerror(x); | ||
1019 | else for (oc = x->o_connections; oc; oc = oc->oc_next) | ||
1020 | pd_bang(oc->oc_to); | ||
1021 | } | ||
1022 | |||
1023 | void outlet_pointer(t_outlet *x, t_gpointer *gp) | ||
1024 | { | ||
1025 | t_outconnect *oc; | ||
1026 | t_gpointer gpointer; | ||
1027 | char c; | ||
1028 | if (&c < stacklimit) | ||
1029 | outlet_stackerror(x); | ||
1030 | else | ||
1031 | { | ||
1032 | #if 0 | ||
1033 | gpointer_copy(gp, &gpointer); | ||
1034 | for (oc = x->o_connections; oc; oc = oc->oc_next) | ||
1035 | pd_pointer(oc->oc_to, &gpointer); | ||
1036 | gpointer_unset(&gpointer); | ||
1037 | #else | ||
1038 | gpointer = *gp; | ||
1039 | for (oc = x->o_connections; oc; oc = oc->oc_next) | ||
1040 | pd_pointer(oc->oc_to, &gpointer); | ||
1041 | #endif | ||
1042 | } | ||
1043 | } | ||
1044 | |||
1045 | void outlet_float(t_outlet *x, t_float f) | ||
1046 | { | ||
1047 | t_outconnect *oc; | ||
1048 | char c; | ||
1049 | if (&c < stacklimit) | ||
1050 | outlet_stackerror(x); | ||
1051 | else for (oc = x->o_connections; oc; oc = oc->oc_next) | ||
1052 | pd_float(oc->oc_to, f); | ||
1053 | } | ||
1054 | |||
1055 | void outlet_symbol(t_outlet *x, t_symbol *s) | ||
1056 | { | ||
1057 | t_outconnect *oc; | ||
1058 | char c; | ||
1059 | if (&c < stacklimit) | ||
1060 | outlet_stackerror(x); | ||
1061 | else for (oc = x->o_connections; oc; oc = oc->oc_next) | ||
1062 | pd_symbol(oc->oc_to, s); | ||
1063 | } | ||
1064 | |||
1065 | void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv) | ||
1066 | { | ||
1067 | t_outconnect *oc; | ||
1068 | char c; | ||
1069 | if (&c < stacklimit) | ||
1070 | outlet_stackerror(x); | ||
1071 | else for (oc = x->o_connections; oc; oc = oc->oc_next) | ||
1072 | pd_list(oc->oc_to, s, argc, argv); | ||
1073 | } | ||
1074 | |||
1075 | void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv) | ||
1076 | { | ||
1077 | t_outconnect *oc; | ||
1078 | char c; | ||
1079 | if (&c < stacklimit) | ||
1080 | outlet_stackerror(x); | ||
1081 | else for (oc = x->o_connections; oc; oc = oc->oc_next) | ||
1082 | typedmess(oc->oc_to, s, argc, argv); | ||
1083 | } | ||
1084 | |||
1085 | /* get the outlet's declared symbol */ | ||
1086 | t_symbol *outlet_getsymbol(t_outlet *x) | ||
1087 | { | ||
1088 | return (x->o_sym); | ||
1089 | } | ||
1090 | |||
1091 | void outlet_free(t_outlet *x) | ||
1092 | { | ||
1093 | t_object *y = x->o_owner; | ||
1094 | t_outlet *x2; | ||
1095 | if (y->ob_outlet == x) y->ob_outlet = x->o_next; | ||
1096 | else for (x2 = y->ob_outlet; x2; x2 = x2->o_next) | ||
1097 | if (x2->o_next == x) | ||
1098 | { | ||
1099 | x2->o_next = x->o_next; | ||
1100 | break; | ||
1101 | } | ||
1102 | t_freebytes(x, sizeof(*x)); | ||
1103 | } | ||
1104 | |||
1105 | t_outconnect *obj_connect(t_object *source, int outno, | ||
1106 | t_object *sink, int inno) | ||
1107 | { | ||
1108 | t_inlet *i; | ||
1109 | t_outlet *o; | ||
1110 | t_pd *to; | ||
1111 | t_outconnect *oc, *oc2; | ||
1112 | |||
1113 | for (o = source->ob_outlet; o && outno; o = o->o_next, outno--) ; | ||
1114 | if (!o) return (0); | ||
1115 | |||
1116 | if (sink->ob_pd->c_firstin) | ||
1117 | { | ||
1118 | if (!inno) | ||
1119 | { | ||
1120 | to = &sink->ob_pd; | ||
1121 | goto doit; | ||
1122 | } | ||
1123 | else inno--; | ||
1124 | } | ||
1125 | for (i = sink->ob_inlet; i && inno; i = i->i_next, inno--) ; | ||
1126 | if (!i) return (0); | ||
1127 | to = &i->i_pd; | ||
1128 | doit: | ||
1129 | oc = (t_outconnect *)t_getbytes(sizeof(*oc)); | ||
1130 | oc->oc_next = 0; | ||
1131 | oc->oc_to = to; | ||
1132 | /* append it to the end of the list */ | ||
1133 | /* LATER we might cache the last "oc" to make this faster. */ | ||
1134 | if ((oc2 = o->o_connections)) | ||
1135 | { | ||
1136 | while (oc2->oc_next) oc2 = oc2->oc_next; | ||
1137 | oc2->oc_next = oc; | ||
1138 | } | ||
1139 | else o->o_connections = oc; | ||
1140 | if (o->o_sym == &s_signal) canvas_update_dsp(); | ||
1141 | |||
1142 | return (oc); | ||
1143 | } | ||
1144 | |||
1145 | void obj_disconnect(t_object *source, int outno, t_object *sink, int inno) | ||
1146 | { | ||
1147 | t_inlet *i; | ||
1148 | t_outlet *o; | ||
1149 | t_pd *to; | ||
1150 | t_outconnect *oc, *oc2; | ||
1151 | |||
1152 | for (o = source->ob_outlet; o && outno; o = o->o_next, outno--) | ||
1153 | if (!o) return; | ||
1154 | if (sink->ob_pd->c_firstin) | ||
1155 | { | ||
1156 | if (!inno) | ||
1157 | { | ||
1158 | to = &sink->ob_pd; | ||
1159 | goto doit; | ||
1160 | } | ||
1161 | else inno--; | ||
1162 | } | ||
1163 | for (i = sink->ob_inlet; i && inno; i = i->i_next, inno--) ; | ||
1164 | if (!i) return; | ||
1165 | to = &i->i_pd; | ||
1166 | doit: | ||
1167 | if (!(oc = o->o_connections)) return; | ||
1168 | if (oc->oc_to == to) | ||
1169 | { | ||
1170 | o->o_connections = oc->oc_next; | ||
1171 | freebytes(oc, sizeof(*oc)); | ||
1172 | goto done; | ||
1173 | } | ||
1174 | while (oc2 = oc->oc_next) | ||
1175 | { | ||
1176 | if (oc2->oc_to == to) | ||
1177 | { | ||
1178 | oc->oc_next = oc2->oc_next; | ||
1179 | freebytes(oc2, sizeof(*oc2)); | ||
1180 | goto done; | ||
1181 | } | ||
1182 | oc = oc2; | ||
1183 | } | ||
1184 | done: | ||
1185 | if (o->o_sym == &s_signal) canvas_update_dsp(); | ||
1186 | } | ||
1187 | |||
1188 | /* ------ traversal routines for code that can't see our structures ------ */ | ||
1189 | |||
1190 | int obj_noutlets(t_object *x) | ||
1191 | { | ||
1192 | int n; | ||
1193 | t_outlet *o; | ||
1194 | for (o = x->ob_outlet, n = 0; o; o = o->o_next) n++; | ||
1195 | return (n); | ||
1196 | } | ||
1197 | |||
1198 | int obj_ninlets(t_object *x) | ||
1199 | { | ||
1200 | int n; | ||
1201 | t_inlet *i; | ||
1202 | for (i = x->ob_inlet, n = 0; i; i = i->i_next) n++; | ||
1203 | if (x->ob_pd->c_firstin) n++; | ||
1204 | return (n); | ||
1205 | } | ||
1206 | |||
1207 | t_outconnect *obj_starttraverseoutlet(t_object *x, t_outlet **op, int nout) | ||
1208 | { | ||
1209 | t_outlet *o = x->ob_outlet; | ||
1210 | while (nout-- && o) o = o->o_next; | ||
1211 | *op = o; | ||
1212 | if (o) return (o->o_connections); | ||
1213 | else return (0); | ||
1214 | } | ||
1215 | |||
1216 | t_outconnect *obj_nexttraverseoutlet(t_outconnect *lastconnect, | ||
1217 | t_object **destp, t_inlet **inletp, int *whichp) | ||
1218 | { | ||
1219 | t_pd *y; | ||
1220 | y = lastconnect->oc_to; | ||
1221 | if (ISINLET(y)) | ||
1222 | { | ||
1223 | int n; | ||
1224 | t_inlet *i = (t_inlet *)y, *i2; | ||
1225 | t_object *dest = i->i_owner; | ||
1226 | for (n = dest->ob_pd->c_firstin, i2 = dest->ob_inlet; | ||
1227 | i2 && i2 != i; i2 = i2->i_next) n++; | ||
1228 | *whichp = n; | ||
1229 | *destp = dest; | ||
1230 | *inletp = i; | ||
1231 | } | ||
1232 | else | ||
1233 | { | ||
1234 | *whichp = 0; | ||
1235 | *inletp = 0; | ||
1236 | *destp = ((t_object *)y); | ||
1237 | } | ||
1238 | return (lastconnect->oc_next); | ||
1239 | } | ||
1240 | |||
1241 | /* this one checks that a pd is indeed a patchable object, and returns | ||
1242 | it, correctly typed, or zero if the check failed. */ | ||
1243 | t_object *pd_checkobject(t_pd *x) | ||
1244 | { | ||
1245 | if ((*x)->c_patchable) return ((t_object *)x); | ||
1246 | else return (0); | ||
1247 | } | ||
1248 | |||
1249 | /* move an inlet or outlet to the head of the list */ | ||
1250 | void obj_moveinletfirst(t_object *x, t_inlet *i) | ||
1251 | { | ||
1252 | t_inlet *i2; | ||
1253 | if (x->ob_inlet == i) return; | ||
1254 | else for (i2 = x->ob_inlet; i2; i2 = i2->i_next) | ||
1255 | if (i2->i_next == i) | ||
1256 | { | ||
1257 | i2->i_next = i->i_next; | ||
1258 | i->i_next = x->ob_inlet; | ||
1259 | x->ob_inlet = i; | ||
1260 | return; | ||
1261 | } | ||
1262 | } | ||
1263 | |||
1264 | void obj_moveoutletfirst(t_object *x, t_outlet *o) | ||
1265 | { | ||
1266 | t_outlet *o2; | ||
1267 | if (x->ob_outlet == o) return; | ||
1268 | else for (o2 = x->ob_outlet; o2; o2 = o2->o_next) | ||
1269 | if (o2->o_next == o) | ||
1270 | { | ||
1271 | o2->o_next = o->o_next; | ||
1272 | o->o_next = x->ob_outlet; | ||
1273 | x->ob_outlet = o; | ||
1274 | return; | ||
1275 | } | ||
1276 | } | ||
1277 | |||
1278 | /* routines for DSP sorting, which are used in d_ugen.c and g_canvas.c */ | ||
1279 | /* LATER try to consolidate all the slightly different routines. */ | ||
1280 | |||
1281 | int obj_nsiginlets(t_object *x) | ||
1282 | { | ||
1283 | int n; | ||
1284 | t_inlet *i; | ||
1285 | for (i = x->ob_inlet, n = 0; i; i = i->i_next) | ||
1286 | if (i->i_symfrom == &s_signal) n++; | ||
1287 | if (x->ob_pd->c_firstin && x->ob_pd->c_floatsignalin) n++; | ||
1288 | return (n); | ||
1289 | } | ||
1290 | |||
1291 | /* get the index, among signal inlets, of the mth inlet overall */ | ||
1292 | int obj_siginletindex(t_object *x, int m) | ||
1293 | { | ||
1294 | int n = 0; | ||
1295 | t_inlet *i; | ||
1296 | if (x->ob_pd->c_firstin && x->ob_pd->c_floatsignalin) | ||
1297 | { | ||
1298 | if (!m--) return (0); | ||
1299 | n++; | ||
1300 | } | ||
1301 | for (i = x->ob_inlet; i; i = i->i_next, m--) | ||
1302 | if (i->i_symfrom == &s_signal) | ||
1303 | { | ||
1304 | if (m == 0) return (n); | ||
1305 | n++; | ||
1306 | } | ||
1307 | return (-1); | ||
1308 | } | ||
1309 | |||
1310 | int obj_issignalinlet(t_object *x, int m) | ||
1311 | { | ||
1312 | t_inlet *i; | ||
1313 | if (x->ob_pd->c_firstin) | ||
1314 | { | ||
1315 | if (!m) | ||
1316 | return (x->ob_pd->c_firstin && x->ob_pd->c_floatsignalin); | ||
1317 | else m--; | ||
1318 | } | ||
1319 | for (i = x->ob_inlet; i && m; i = i->i_next, m--) | ||
1320 | ; | ||
1321 | return (i && (i->i_symfrom == &s_signal)); | ||
1322 | } | ||
1323 | |||
1324 | int obj_nsigoutlets(t_object *x) | ||
1325 | { | ||
1326 | int n; | ||
1327 | t_outlet *o; | ||
1328 | for (o = x->ob_outlet, n = 0; o; o = o->o_next) | ||
1329 | if (o->o_sym == &s_signal) n++; | ||
1330 | return (n); | ||
1331 | } | ||
1332 | |||
1333 | int obj_sigoutletindex(t_object *x, int m) | ||
1334 | { | ||
1335 | int n; | ||
1336 | t_outlet *o2; | ||
1337 | for (o2 = x->ob_outlet, n = 0; o2; o2 = o2->o_next, m--) | ||
1338 | if (o2->o_sym == &s_signal) | ||
1339 | { | ||
1340 | if (m == 0) return (n); | ||
1341 | n++; | ||
1342 | } | ||
1343 | return (-1); | ||
1344 | } | ||
1345 | |||
1346 | int obj_issignaloutlet(t_object *x, int m) | ||
1347 | { | ||
1348 | int n; | ||
1349 | t_outlet *o2; | ||
1350 | for (o2 = x->ob_outlet, n = 0; o2 && m--; o2 = o2->o_next); | ||
1351 | return (o2 && (o2->o_sym == &s_signal)); | ||
1352 | } | ||
1353 | |||
1354 | t_sample *obj_findsignalscalar(t_object *x, int m) | ||
1355 | { | ||
1356 | int n = 0; | ||
1357 | t_inlet *i; | ||
1358 | if (x->ob_pd->c_firstin && x->ob_pd->c_floatsignalin) | ||
1359 | { | ||
1360 | if (!m--) | ||
1361 | return (x->ob_pd->c_floatsignalin > 0 ? | ||
1362 | (t_sample *)(((char *)x) + x->ob_pd->c_floatsignalin) : 0); | ||
1363 | n++; | ||
1364 | } | ||
1365 | for (i = x->ob_inlet; i; i = i->i_next, m--) | ||
1366 | if (i->i_symfrom == &s_signal) | ||
1367 | { | ||
1368 | if (m == 0) | ||
1369 | return (&i->i_un.iu_floatsignalvalue); | ||
1370 | n++; | ||
1371 | } | ||
1372 | return (0); | ||
1373 | } | ||
1374 | |||
1375 | /* and these are only used in g_io.c... */ | ||
1376 | |||
1377 | int inlet_getsignalindex(t_inlet *x) | ||
1378 | { | ||
1379 | int n = 0; | ||
1380 | t_inlet *i; | ||
1381 | for (i = x->i_owner->ob_inlet, n = 0; i && i != x; i = i->i_next) | ||
1382 | if (i->i_symfrom == &s_signal) n++; | ||
1383 | return (n); | ||
1384 | } | ||
1385 | |||
1386 | int outlet_getsignalindex(t_outlet *x) | ||
1387 | { | ||
1388 | int n = 0; | ||
1389 | t_outlet *o; | ||
1390 | for (o = x->o_owner->ob_outlet, n = 0; o && o != x; o = o->o_next) | ||
1391 | if (o->o_sym == &s_signal) n++; | ||
1392 | return (n); | ||
1393 | } | ||
1394 | |||