Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / server / scsynth / SC_UnitDef.cpp
blob6e0ab7f5ec47b1a68a6b8844c4aa8136542649db
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <stdlib.h>
23 #include "SC_Endian.h" // first to avoid win32 IN clash
25 #include "SC_Graph.h"
26 #include "SC_InterfaceTable.h"
27 #include "SC_Lib_Cintf.h"
28 #include "SC_Prototypes.h"
29 #include "SC_Str4.h"
30 #include "SC_Unit.h"
31 #include "SC_UnitDef.h"
32 #include "SC_World.h"
33 #include "sc_msg_iter.h"
36 bool UnitDef_Create(const char *inName, size_t inAllocSize, UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags)
38 if (strlen(inName) >= kSCNameByteLen) return false;
40 UnitDef *unitDef = (UnitDef*)malloc(sizeof(UnitDef));
41 if (!unitDef) return false;
43 str4cpy(unitDef->mUnitDefName, inName);
44 unitDef->mHash = Hash(unitDef->mUnitDefName);
46 unitDef->mAllocSize = inAllocSize;
47 unitDef->mUnitCtorFunc = inCtor;
48 unitDef->mUnitDtorFunc = inDtor;
50 unitDef->mCmds = 0;
51 unitDef->mFlags = inFlags;
53 if (!AddUnitDef(unitDef)) {
54 free(unitDef);
55 return false;
57 return true;
62 bool UnitDef_AddCmd(const char *inUnitDefName, const char *inCmdName, UnitCmdFunc inFunc)
64 if (strlen(inUnitDefName) >= kSCNameByteLen) return false;
65 int32 unitDefName[kSCNameLen];
66 memset(unitDefName, 0, kSCNameByteLen);
67 strcpy((char*)unitDefName, inUnitDefName);
69 if (strlen(inCmdName) >= kSCNameByteLen) return false;
71 UnitDef* unitDef = GetUnitDef(unitDefName);
72 if (!unitDef) return false;
74 if (!unitDef->mCmds)
75 unitDef->mCmds = new HashTable<UnitCmd, Malloc>(&gMalloc, 4, true);
77 UnitCmd *cmd = new UnitCmd();
78 memset(cmd->mCmdName, 0, kSCNameByteLen);
79 strcpy((char*)cmd->mCmdName, inCmdName);
81 cmd->mFunc = inFunc;
82 cmd->mHash = Hash(cmd->mCmdName);
83 unitDef->mCmds->Add(cmd);
85 return true;
88 bool PlugIn_DefineCmd(const char *inCmdName, PlugInCmdFunc inFunc, void *inUserData)
90 if (strlen(inCmdName) >= kSCNameByteLen) return false;
92 PlugInCmd *cmd = new PlugInCmd();
93 memset(cmd->mCmdName, 0, kSCNameByteLen);
94 strcpy((char*)cmd->mCmdName, inCmdName);
96 cmd->mFunc = inFunc;
97 cmd->mHash = Hash(cmd->mCmdName);
98 cmd->mUserData = inUserData;
99 AddPlugInCmd(cmd);
101 return true;
104 int Unit_DoCmd(World *inWorld, int inSize, char *inData)
106 sc_msg_iter msg(inSize, inData);
107 int nodeID = msg.geti();
108 Graph* graph = World_GetGraph(inWorld, nodeID);
109 if (!graph) return kSCErr_NodeNotFound;
111 uint32 unitID = msg.geti();
112 if (unitID >= graph->mNumUnits) return kSCErr_IndexOutOfRange;
114 Unit *unit = graph->mUnits[unitID];
116 UnitDef* unitDef = unit->mUnitDef;
118 int32 *cmdName = msg.gets4();
119 if (!cmdName) return kSCErr_Failed;
121 if (!unitDef->mCmds) return kSCErr_Failed;
122 UnitCmd *cmd = unitDef->mCmds->Get(cmdName);
123 if (!cmd) return kSCErr_Failed;
125 (cmd->mFunc)(unit, &msg);
127 return kSCErr_None;
130 int PlugIn_DoCmd(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
132 sc_msg_iter msg(inSize, inData);
134 int32 *cmdName = msg.gets4();
135 if (!cmdName) return kSCErr_Failed;
137 PlugInCmd *cmd = GetPlugInCmd(cmdName);
138 if (!cmd) return kSCErr_Failed;
140 (cmd->mFunc)(inWorld, cmd->mUserData, &msg, (void*)inReply);
142 return kSCErr_None;