scide: DocManager - report warnings via the status bar
[supercollider.git] / editors / sc-ide / primitives / sc_ipc_client.cpp
blob8773c44f8992d36b67e0da68278c0a0829422771
1 /*
2 * SuperCollider Qt IDE
3 * Copyright (c) 2012 Jakob Leben & Tim Blechmann
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 <QtNetwork/QLocalSocket>
23 #include <cstdlib>
25 #include <yaml-cpp/emitter.h>
27 #include "PyrPrimitive.h"
28 #include "SCBase.h"
29 #include "GC.h"
30 #include "PyrKernel.h"
31 #include "PyrSymbol.h"
33 class SCIpcClient
35 public:
36 QLocalSocket * mSocket;
37 SCIpcClient( const char * ideName ):
38 mSocket(NULL)
40 mSocket = new QLocalSocket();
41 mSocket->connectToServer(QString(ideName));
44 void send(const char * data, size_t length)
46 mSocket->write(data, length);
49 ~SCIpcClient()
51 mSocket->disconnectFromServer();
55 static SCIpcClient * gIpcClient = NULL;
58 int ScIDE_Connect(struct VMGlobals *g, int numArgsPushed)
60 if (gIpcClient) {
61 error("ScIDE already connected\n");
62 return errFailed;
65 PyrSlot * ideNameSlot = g->sp;
67 char ideName[1024];
68 int status = slotStrVal(ideNameSlot, ideName, 1024);
69 if (status != errNone)
70 return errWrongType;
72 gIpcClient = new SCIpcClient(ideName);
74 return errNone;
77 int ScIDE_Connected(struct VMGlobals *g, int numArgsPushed)
79 PyrSlot * returnSlot = g->sp - numArgsPushed + 1;
81 SetBool(returnSlot, gIpcClient != 0);
83 return errNone;
86 struct YAMLSerializer
88 YAML::Emitter emitter;
90 public:
91 explicit YAMLSerializer (PyrSlot * slot)
93 serialize(slot);
96 const char * data ()
98 return emitter.c_str();
101 size_t size()
103 return emitter.size();
106 private:
107 void serialize(PyrSlot * slot)
109 if (IsFloat(slot)) {
110 emitter << slotRawFloat(slot);
111 return;
114 switch (GetTag(slot)) {
115 case tagNil:
116 emitter << YAML::Null;
117 return;
119 case tagInt:
120 emitter << slotRawInt(slot);
121 return;
123 case tagFalse:
124 emitter << false;
125 return;
127 case tagTrue:
128 emitter << true;
129 return;
131 case tagObj:
132 serialize(slotRawObject(slot));
133 return;
135 case tagSym:
136 emitter << YAML::DoubleQuoted << slotRawSymbol(slot)->name;
137 return;
139 default:
140 printf ("type: %d\n", GetTag(slot));
141 throw std::runtime_error("YAMLSerializer: not implementation for this type");
145 void serialize(PyrObject * object)
147 if (isKindOf(object, class_string)) {
148 PyrObjectHdr * hdr = static_cast<PyrObjectHdr*>(object);
149 PyrString * str = static_cast<PyrString*>(hdr);
151 size_t len = str->size;
152 char * cstr = new char[len + 10];
153 memcpy(cstr, str->s, len);
154 cstr[len] = 0; // zero-terminate
155 emitter << YAML::DoubleQuoted << cstr;
156 delete[] cstr;
157 return;
160 if (isKindOf(object, class_arrayed_collection)) {
161 emitter << YAML::BeginSeq;
162 for (size_t i = 0; i != object->size; ++i)
163 serialize(object->slots + i);
165 emitter << YAML::EndSeq;
166 return;
168 throw std::runtime_error("YAMLSerializer: not implementation for this type");
172 int ScIDE_Send(struct VMGlobals *g, int numArgsPushed)
174 if (!gIpcClient) {
175 error("ScIDE not connected\n");
176 return errFailed;
179 PyrSlot * idSlot = g->sp - 1;
180 char id[255];
181 if (slotStrVal( idSlot, id, 255 ))
182 return errWrongType;
184 PyrSlot * argSlot = g->sp;
186 try {
187 YAMLSerializer serializer(argSlot);
189 QDataStream stream(gIpcClient->mSocket);
190 stream.setVersion(QDataStream::Qt_4_6);
191 stream << QString(id);
192 stream << QString::fromUtf8(serializer.data());
193 } catch (std::exception const & e) {
194 postfl("Exception during ScIDE_Send: %s\n", e.what());
195 return errFailed;
198 return errNone;
202 void initScIDEPrimitives()
204 int base = nextPrimitiveIndex();
205 int index = 0;
206 definePrimitive(base, index++, "_ScIDE_Connect", ScIDE_Connect, 2, 0);
207 definePrimitive(base, index++, "_ScIDE_Connected", ScIDE_Connected, 1, 0);
208 definePrimitive(base, index++, "_ScIDE_Send", ScIDE_Send, 3, 0);