diff --git a/.gitignore b/.gitignore index 1774c281..150f1194 100755 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ bin/ lib/ # Because apparently nobody has any self control *.orig + +tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/x64/Debug/ +tools/LiveTexturing/mayaPluginRTT/x64/Debug/ +*.suo diff --git a/tools/LiveTexturing/LiveTexturing/main.js b/tools/LiveTexturing/LiveTexturing/main.js new file mode 100644 index 00000000..e9177937 --- /dev/null +++ b/tools/LiveTexturing/LiveTexturing/main.js @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +(function () { + "use strict"; + var start = 0; + var zmq = require('zmq'); + var publisher = zmq.socket('pub'); + + publisher.bind('tcp://*:5555', function (err) { + if (err) { + console.log(err); + } + else { + console.log("5555"); + } + }); + + + + process.on('SIGINT', function () { + publisher.close(); + }); + + + var PLUGIN_ID = require("./package.json").name, + MENU_ID = "TeamFisk plugins", + MENU_LABEL = "$$$/JavaScripts/Generator/TeamFisk plugins/Menu=Live Texturing RAMDisk"; + + var _generator = null; + + // Initialize script here + function init(generator, config) { + _generator = generator; + _generator.addMenuItem(MENU_ID, MENU_LABEL, true, false) + .then( + function () { + console.log("Menu created", MENU_ID); + }, function () { + console.error("Menu creation failed", MENU_ID); + } + ); + + _generator.onPhotoshopEvent("imageChanged", handleImageChanged); + } + + var lastSent = 0; + function handleImageChanged(document) { + + var start = new Date().getTime(); + if (start - lastSent > 200) { + _generator.getDocumentInfo(document.id).then( + function (document) { + // console.log(new Date().getTime() / 1000); + // console.log(stringify(document.timeStamp)); + + //lastSent = document.timeStamp + // console.log(stringify(document)); + //console.log("Received complete document:", stringify(document)); + //var str = 'var options = new PNGSaveOptions(); app.activeDocument.saveAs (new File("D:/HejHej.png"),options, false);'; + var str = 'app.activeDocument.save()'; + _generator.evaluateJSXString(str).done(); + + var size = (4 + document.file.length + 1); + var message = new Buffer(size); + + var offset = 0; + + //console.log("document.file.length: " + document.file.length); + //console.log("document.fileName: " + document.file); + + message.writeInt32LE(document.file.length + 1, offset); + + offset += 4; + + var fileName = document.file.replace(/\\/g, "/"); + message.write(fileName, offset, fileName.length, 'utf8'); + offset += fileName.length; + message.writeUInt8(0, offset); //Null byte + offset += 1; + + publisher.send(message); + + var asd = new Date().getTime(); + var time = asd - start; + console.log(time); + lastSent = new Date().getTime(); + console.log("LastSent: " + lastSent); + }); + } + } + + function stringify(object) { + try { + return JSON.stringify(object, null, " "); + } catch (e) { + console.error(e); + } + return String(object); + } + + //Declare entery function in the script + exports.init = init; +}()); \ No newline at end of file diff --git a/tools/LiveTexturing/LiveTexturing/package.json b/tools/LiveTexturing/LiveTexturing/package.json new file mode 100644 index 00000000..dec32236 --- /dev/null +++ b/tools/LiveTexturing/LiveTexturing/package.json @@ -0,0 +1,15 @@ +{ + "name": "Live Textureing RAMDisk", + "version": "1.0.0", + "description": "Send image from Photoshop", + "main": "main.js", + "generator-core-version": "~3", + "license": "Public Domain", + "readmeFilename": "", + "scripts": { + }, + "dependencies": { + }, + "devDependencies": { + } +} diff --git a/tools/LiveTexturing/mayaPluginRTT/.vs/config/applicationhost.config b/tools/LiveTexturing/mayaPluginRTT/.vs/config/applicationhost.config new file mode 100644 index 00000000..c2abfb48 --- /dev/null +++ b/tools/LiveTexturing/mayaPluginRTT/.vs/config/applicationhost.config @@ -0,0 +1,1030 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.opensdf b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.opensdf new file mode 100644 index 00000000..31dea47b Binary files /dev/null and b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.opensdf differ diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.sdf b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.sdf new file mode 100644 index 00000000..92ccd791 Binary files /dev/null and b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.sdf differ diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.sln b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.sln new file mode 100644 index 00000000..1e3c9af8 --- /dev/null +++ b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mayaPluginRTT", "mayaPluginRTT\mayaPluginRTT.vcxproj", "{C26D6DAB-3247-4782-94AC-738BDB20CFD0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C26D6DAB-3247-4782-94AC-738BDB20CFD0}.Debug|x64.ActiveCfg = Debug|x64 + {C26D6DAB-3247-4782-94AC-738BDB20CFD0}.Debug|x64.Build.0 = Debug|x64 + {C26D6DAB-3247-4782-94AC-738BDB20CFD0}.Debug|x86.ActiveCfg = Debug|Win32 + {C26D6DAB-3247-4782-94AC-738BDB20CFD0}.Debug|x86.Build.0 = Debug|Win32 + {C26D6DAB-3247-4782-94AC-738BDB20CFD0}.Release|x64.ActiveCfg = Release|x64 + {C26D6DAB-3247-4782-94AC-738BDB20CFD0}.Release|x64.Build.0 = Release|x64 + {C26D6DAB-3247-4782-94AC-738BDB20CFD0}.Release|x86.ActiveCfg = Release|Win32 + {C26D6DAB-3247-4782-94AC-738BDB20CFD0}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/libzmq-v120-mt-4_0_4.lib b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/libzmq-v120-mt-4_0_4.lib new file mode 100644 index 00000000..b2f765ca Binary files /dev/null and b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/libzmq-v120-mt-4_0_4.lib differ diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/main.cpp b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/main.cpp new file mode 100644 index 00000000..21ceef7a --- /dev/null +++ b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/main.cpp @@ -0,0 +1,427 @@ +// UD1414_Plugin.cpp : Defines the exported functions for the DLL application. +#include "zmq.hpp" +#include "maya_includes.h" +#include +#include +#include +#include +#include + +#pragma comment(lib, "libzmq-v120-mt-4_0_4.lib") + +using namespace std; + +MCallbackIdArray IDArray; +map > textureObject; +//map compareObject; +vector compareObject_key; +vector compareObject_value; +struct message { + int docNameLength; + //int numPixels; + //int startX; + //int startY; + //int canvasY; + //int canvasX; + //int rowLength; + char* docName; + //unsigned char* pixels; +}; + +typedef struct +{ + bool shutDown = false; + bool hasShutdown = false; +} ThreadVars; + +ThreadVars threadVars; +vector images; + +map docName_map; +list toUpdate; +MThreadRetVal ThreadFunction(void* data) +{ + zmq::context_t context(1); + zmq::socket_t subscriber(context, ZMQ_SUB); + + std::cout << "Connecting to hello world server..." << std::endl; + subscriber.connect("tcp://localhost:5555"); + subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0); + + zmq::message_t msg; + while (!threadVars.shutDown) + { + if (subscriber.recv(&msg, ZMQ_DONTWAIT)) + { + MObject outColorObject; + MPlug outColorPlug; + + size_t tet = msg.size(); + message PSData; + PSData.docNameLength = ((message*)msg.data())->docNameLength; + //PSData.numPixels = ((message*)msg.data())->numPixels; + //PSData.startX = ((message*)msg.data())->startX; + //PSData.startY = ((message*)msg.data())->startY; + //PSData.canvasY = ((message*)msg.data())->canvasY; + //PSData.canvasX = ((message*)msg.data())->canvasX; + //PSData.rowLength = ((message*)msg.data())->rowLength; + PSData.docName = (char*)msg.data() + sizeof(message) - sizeof(char*) - 4; + //PSData.pixels = (unsigned char*)msg.data() + sizeof(message) - sizeof(char*) * 2 + 8 + PSData.docNameLength; + + MGlobal::displayInfo(MString() + "docName: " + PSData.docName); + MGlobal::displayInfo(MString() + "docNameLength: " + PSData.docNameLength); + + if (textureObject.find(PSData.docName) != textureObject.end()) + { + toUpdate.push_back(PSData.docName); + //toUpdate.unique(); + /* vector& textureNode = textureObject[PSData.docName]; + vector::iterator it; + for (it = textureNode.begin(); it != textureNode.end(); it++) + { + MFnDependencyNode depNode(*it); + MPlug plug = depNode.findPlug("outColor"); + MGlobal::displayInfo(MString() + "ANKA: " + plug.name()); + plug.setMObject(plug.asMObject()); + }*/ + } + + //std::map::iterator it; + //it = docName_map.find(PSData.docName); + //if (! (it != docName_map.end())) + //{ + // MStatus res = MS::kSuccess; + // MString file; + // MString place2dTexture; + + // do + // { + // res = MGlobal::executeCommand(MString() + "shadingNode - asUtility place2dTexture;", place2dTexture); + // } while (res != MS::kSuccess); + + // do + // { + // res = MGlobal::executeCommand(MString() + "shadingNode - asTexture - isColorManaged file;", file); + // } while (res != MS::kSuccess); + + // MGlobal::displayInfo(MString() + "ASDASDASD: " + file); + // MGlobal::displayInfo(MString() + "ASDASDASD: " + place2dTexture); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".coverage " + file + ".coverage;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".translateFrame " + file + ".translateFrame;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".rotateFrame " + file + ".rotateFrame;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".mirrorU " + file + ".mirrorU;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".mirrorV " + file + ".mirrorV;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".stagger " + file + ".stagger;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".wrapU " + file + ".wrapU;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".wrapV " + file + ".wrapV;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".repeatUV " + file + ".repeatUV;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".offset " + file + ".offset;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".rotateUV " + file + ".rotateUV;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".noiseUV " + file + ".noiseUV;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".vertexUvOne " + file + ".vertexUvOne;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".vertexUvTwo " + file + ".vertexUvTwo;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".vertexUvThree " + file + ".vertexUvThree;"); + // MGlobal::executeCommand("connectAttr - f " + place2dTexture + ".vertexCameraOne " + file + ".vertexCameraOne;"); + // MGlobal::executeCommand("connectAttr " + place2dTexture + ".outUvFilterSize " + file + ".uvFilterSize;"); + // MGlobal::executeCommand("connectAttr " + place2dTexture + ".outUV " + file + ".uv;"); + // MSelectionList thisFile; + // MObject thisFileObject; + + // for (map >::iterator it = textureObject.begin(); it != textureObject.end(); ++it) + // { + // //MGlobal::displayInfo(MString() + "SECOND: " + it->second[0].apiTypeStr()); + // //MFnDependencyNode tmp_DN(it->second[0]); + // //MPlug tmpPlug = tmp_DN.findPlug("outColor"); + // //tmpPlug.setMObject(tmpPlug.asMObject()); + // //MGlobal::displayInfo(MString() + "tmp_DN: " + tmp_DN.name()); + // } + + + + // MGlobal::getSelectionListByName(file, thisFile); + // thisFile.getDependNode(0, thisFileObject); + + // docName_map[PSData.docName] = thisFileObject; + // MFnDependencyNode textureNode(thisFileObject); + // MImage image; + // image.readFromTextureNode(thisFileObject); + // + // unsigned int w, h; + // image.getSize(w, h); + // /*MGlobal::displayInfo(MString() + w + " " + h); + // for (unsigned int i = 0; i < w * h * 4; i++) + // { + // MGlobal::displayInfo(MString() + "Pix: " + imagePixels[i]); + // }*/ + // //image.setPixels(PSData.pixels, PSData.canvasX, PSData.canvasY); + // image.setRGBA(true); + // image.convertPixelFormat(MImage::MPixelType::kByte); + // unsigned char* imagePixels = image.pixels(); + + // MPlug color = textureNode.findPlug("uvCoord"); + // //color.setMObject(color.asMObject()); + // + // //unsigned int w, h; + // image.getSize(w, h); + // MGlobal::displayInfo(MString() + w + " " + h); + // for (unsigned int i = 0; i < w * h * 4; i++) + // { + // MGlobal::displayInfo(MString() + "Pix: " + imagePixels[i]); + // } + // MGlobal::displayInfo("999999999999"); + + // //image.writeToFile("C:/Users/kamisama/Desktop/3.png", "png"); + + // color.setMObject(color.asMObject()); + //} + //else + //{ + // MObject& thisFileObject = docName_map[PSData.docName]; + // MFnDependencyNode textureNode(thisFileObject); + // + // MImage image; + // image.readFromTextureNode(thisFileObject); + // unsigned char* imagePixels = image.pixels(); + + // unsigned int w, h; + // image.getSize(w, h); + // MGlobal::displayInfo("Before"); + // MGlobal::displayInfo(MString() + w + " " + h); + // for (unsigned int i = 0; i < w * h * 4; i++) + // { + // //MGlobal::displayInfo(MString() + "Pix: " + imagePixels[i]); + // } + // //image.setPixels(PSData.pixels, PSData.canvasX, PSData.canvasY); + // //memcpy(image.pixels(), PSData.pixels, w * h * 4); + // //MPlug color = textureNode.findPlug("outColor"); + + // image.getSize(w, h); + // MGlobal::displayInfo("After"); + // MGlobal::displayInfo(MString() + w + " " + h); + // for (unsigned int i = 0; i < w * h * 4; i++) + // { + // //MGlobal::displayInfo(MString() + "Pix: " + imagePixels[i]); + // } + // + // MPlug color = textureNode.findPlug("uvCoord"); + // color.setMObject(color.asMObject()); + //} + //MItDependencyNodes it(MFn::kFileTexture); + //for (; !it.isDone(); it.next()) + //{ + // MFnDependencyNode texture_node(it.thisNode()); + // globalShitPlug = texture_node.findPlug("outColor"); + // globalShit = globalShitPlug.asMObject(); + // MGlobal::displayInfo(MString() + "Plug name: " + globalShitPlug.name()); + // MImage test_Mimage; + // MGlobal::displayInfo(MString() + "hej"); + // test_Mimage.create(1, 1, 4, MImage::kByte); + // //test_Mimage.readFromTextureNode(globalShit); + // MGlobal::displayInfo(MString() + "hej igen"); + // unsigned char* test_pixels; + // test_pixels = test_Mimage.pixels(); + + // unsigned int width, height; + // test_Mimage.getSize(width, height); + // MGlobal::displayInfo(MString() + "WIDTH: " + width); + // MGlobal::displayInfo(MString() + "HEIGHT: " + height); + // for (unsigned int i = 0; i < width * height * 4; i++) + // { + // test_pixels[i] = imageData->pixels[i]; + // } + + // globalShitPlug.setMObject(globalShit); + + // break; + //} + } + } + + threadVars.hasShutdown = true; + return 0; +} + +void textureChanged(MNodeMessage::AttributeMessage msg, MPlug &plug, MPlug &otherPlug, void *clientData) +{ + //MGlobal::displayInfo(MString() + "Hello!!!!!!!!!!!! " + otherPlug.name()); + //MGlobal::displayInfo(MString() + "Hello! :DDDDDDD " + otherPlug.asString()); + string plugName(plug.name().asChar()); + if (plugName.find("fileTextureName") != string::npos) + { + if (msg & MNodeMessage::AttributeMessage::kAttributeSet) + { + //MGlobal::displayInfo("Hello from file name! :P"); + + map >::iterator it; + vector::iterator its; + vector::iterator itVec_string; + bool newName = false; + bool nameIsBiggerThenZero = false; + int index = 0; + for (its = compareObject_key.begin(); its != compareObject_key.end(); its++) + { + //MGlobal::displayInfo("Cool"); + if (*its == plug.node()) + { + if (compareObject_value[index].compare(plug.asString().asChar()) != 0) + { + //MGlobal::displayInfo("Cool 1"); + newName = true; + if (compareObject_value[index].length() > 0) + //MGlobal::displayInfo("Cool 2"); + nameIsBiggerThenZero = true; + break; + } + } + index++; + } + if (its == compareObject_key.end()) + { + newName = true; + } + + if (newName == true) + { + MGlobal::displayInfo("New Name"); + if (nameIsBiggerThenZero) + { + vector::iterator iii; + vector& objectVector = textureObject[compareObject_value[index]]; + index = 0; + for (iii = objectVector.begin(); iii != objectVector.end(); iii++) + { + //MGlobal::displayInfo(MString() + "INSIDE THE FOR LOOP!!!!!! III " + (*iii).apiTypeStr()); + if ((*iii) == plug.node()) + { + MGlobal::displayInfo("iii == plug.node()"); + break; + } + index++; + } + //MGlobal::displayInfo("erase"); + + objectVector.erase(objectVector.begin() + index); + textureObject[plug.asString().asChar()].push_back(plug.node()); + //MGlobal::displayInfo(MString() + "index: " + index + " " + objectVector.size()); + } + + index = 0; + for (its = compareObject_key.begin(); its != compareObject_key.end(); its++) + { + if (*its == plug.node()) + { + MGlobal::displayInfo("its->first == plug.node()"); + compareObject_value[index] = plug.asString().asChar(); + break; + } + index++; + } + if (its == compareObject_key.end()) + { + //MGlobal::displayInfo("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + compareObject_key.push_back(plug.node()); + compareObject_value.push_back(plug.asString().asChar()); + textureObject[plug.asString().asChar()].push_back(plug.node()); + } + // //compareObject[plug.node()] = plug.asString().asChar(); + + } + + //MGlobal::displayInfo("Here"); + for (its = compareObject_key.begin(); its != compareObject_key.end(); its++) + { + //MGlobal::displayInfo(MString() + "compareObject_key: " + its->apiTypeStr()); + } + + for (itVec_string = compareObject_value.begin(); itVec_string != compareObject_value.end(); itVec_string++) + { + //MGlobal::displayInfo(MString() + "compareObject_value: " + (*itVec_string).c_str()); + } + + MGlobal::displayInfo("--- textureObject ---"); + + for (it = textureObject.begin(); it != textureObject.end(); it++) + { + MGlobal::displayInfo(MString() + "filename: " + it->first.c_str()); + MGlobal::displayInfo(MString() + "nr of nodes: " + it->second.size()); + } + + } + } +} + +void nodeCreated(MObject& node, void *clientData) +{ + if (node.hasFn(MFn::kFileTexture)) + { + MGlobal::displayInfo("FileTextureAdded"); + MNodeMessage::addAttributeChangedCallback(node, textureChanged); + } +} + +void timer(float elapsedTime, float lastTime, void *clientData) +{ + int size = toUpdate.size(); + while(size) + { + vector& textureNode = textureObject[toUpdate.front()]; + vector::iterator it; + for (it = textureNode.begin(); it != textureNode.end(); it++) + { + MFnDependencyNode depNode(*it); + MPlug plug = depNode.findPlug("outColor"); + MGlobal::displayInfo(MString() + "ANKA: " + plug.name()); + plug.setMObject(plug.asMObject()); + } + toUpdate.pop_front(); + size = toUpdate.size(); + } +} + +EXPORT MStatus initializePlugin(MObject obj) +{ + MStatus res = MS::kSuccess; + + threadVars.shutDown = false; + threadVars.hasShutdown = false; + MFnPlugin myPlugin(obj, "Maya plugin", "1.0", "Any", &res); + if (MFAIL(res)) { + CHECK_MSTATUS(res); + } + IDArray.append(MDGMessage::addNodeAddedCallback(nodeCreated)); + IDArray.append(MTimerMessage::addTimerCallback(0.2, timer)); + + res = MThreadAsync::init(); + if (res == MStatus::kSuccess) + { + res = MThreadAsync::createTask(ThreadFunction, nullptr, nullptr, NULL); + + if (res != MStatus::kSuccess) + { + threadVars.hasShutdown = true; + return MStatus::kFailure; + } + } + + MGlobal::displayInfo("Maya plugin loaded!"); + return res; +} + + +EXPORT MStatus uninitializePlugin(MObject obj) +{ + MFnPlugin plugin(obj); + + threadVars.shutDown = true; + //Wait for thread to shutdown befor releasing it + while (!threadVars.hasShutdown) + { + Sleep(1); + } + MThreadAsync::release(); + MMessage::removeCallbacks(IDArray); + + MGlobal::displayInfo("Maya plugin unloaded!"); + + return MS::kSuccess; +} \ No newline at end of file diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj new file mode 100644 index 00000000..88df7e84 --- /dev/null +++ b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {C26D6DAB-3247-4782-94AC-738BDB20CFD0} + Win32Proj + mayaPluginRTT + 8.1 + + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + .mll + C:\Program Files\ZeroMQ 4.0.4\include;$(IncludePath) + $(LibraryPath) + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MAYAPLUGINRTT_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;MAYAPLUGINRTT_EXPORTS;%(PreprocessorDefinitions) + C:\Program Files\Autodesk\Maya2016\include;%(AdditionalIncludeDirectories) + + + Windows + true + C:\Program Files\Autodesk\Maya2016\lib;%(AdditionalLibraryDirectories) + libzmq-v120-mt-4_0_4.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MAYAPLUGINRTT_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;MAYAPLUGINRTT_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj.filters b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj.filters new file mode 100644 index 00000000..e4528f22 --- /dev/null +++ b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj.user b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/mayaPluginRTT.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/maya_includes.h b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/maya_includes.h new file mode 100644 index 00000000..c9612783 --- /dev/null +++ b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/maya_includes.h @@ -0,0 +1,71 @@ +#pragma once + +// some definitions for the DLL to play nice with Maya +#define NT_PLUGIN +#define REQUIRE_IOSTREAM +#define EXPORT __declspec(dllexport) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Wrappers +#include + +// Commands +#include + +// Libraries to link from Maya +// This can be also done in the properties setting for the project. +#pragma comment(lib,"Foundation.lib") +#pragma comment(lib,"OpenMaya.lib") +#pragma comment(lib,"OpenMayaUI.lib") \ No newline at end of file diff --git a/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/zmq.hpp b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/zmq.hpp new file mode 100644 index 00000000..c1353abe --- /dev/null +++ b/tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/zmq.hpp @@ -0,0 +1,765 @@ +/* + Copyright (c) 2009-2011 250bpm s.r.o. + Copyright (c) 2011 Botond Ballo + Copyright (c) 2007-2009 iMatix Corporation + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef __ZMQ_HPP_INCLUDED__ +#define __ZMQ_HPP_INCLUDED__ + +#if __cplusplus >= 201103L +#define ZMQ_CPP11 +#define ZMQ_NOTHROW noexcept +#define ZMQ_EXPLICIT explicit +#else + #define ZMQ_CPP03 + #define ZMQ_NOTHROW + #define ZMQ_EXPLICIT +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef ZMQ_CPP11 +#include +#include +#endif + +// Detect whether the compiler supports C++11 rvalue references. +#if (defined(__GNUC__) && (__GNUC__ > 4 || \ + (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && \ + defined(__GXX_EXPERIMENTAL_CXX0X__)) + #define ZMQ_HAS_RVALUE_REFS + #define ZMQ_DELETED_FUNCTION = delete +#elif defined(__clang__) + #if __has_feature(cxx_rvalue_references) + #define ZMQ_HAS_RVALUE_REFS + #endif + + #if __has_feature(cxx_deleted_functions) + #define ZMQ_DELETED_FUNCTION = delete + #else + #define ZMQ_DELETED_FUNCTION + #endif +#elif defined(_MSC_VER) && (_MSC_VER >= 1600) + #define ZMQ_HAS_RVALUE_REFS + #define ZMQ_DELETED_FUNCTION +#else + #define ZMQ_DELETED_FUNCTION +#endif + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 3, 0) +#define ZMQ_NEW_MONITOR_EVENT_LAYOUT +#endif + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) +#define ZMQ_HAS_PROXY_STEERABLE +/* Socket event data */ +typedef struct { + uint16_t event; // id of the event as bitfield + int32_t value ; // value is either error code, fd or reconnect interval +} zmq_event_t; +#endif + +// Avoid using deprecated message receive function when possible +#if ZMQ_VERSION < ZMQ_MAKE_VERSION(3, 2, 0) +# define zmq_msg_recv(msg, socket, flags) zmq_recvmsg(socket, msg, flags) +#endif + + +// In order to prevent unused variable warnings when building in non-debug +// mode use this macro to make assertions. +#ifndef NDEBUG +# define ZMQ_ASSERT(expression) assert(expression) +#else +# define ZMQ_ASSERT(expression) (void)(expression) +#endif + +namespace zmq +{ + + typedef zmq_free_fn free_fn; + typedef zmq_pollitem_t pollitem_t; + + class error_t : public std::exception + { + public: + + error_t () : errnum (zmq_errno ()) {} + + virtual const char *what () const throw () + { + return zmq_strerror (errnum); + } + + int num () const + { + return errnum; + } + + private: + + int errnum; + }; + + inline int poll (zmq_pollitem_t const* items_, int nitems_, long timeout_ = -1) + { + int rc = zmq_poll (const_cast(items_), nitems_, timeout_); + if (rc < 0) + throw error_t (); + return rc; + } + + inline int poll(zmq_pollitem_t const* items, size_t nitems) + { + return poll(items, static_cast(nitems), -1); + } + + #ifdef ZMQ_CPP11 + inline int poll(zmq_pollitem_t const* items, size_t nitems, std::chrono::milliseconds timeout) + { + return poll(items, nitems, timeout.count() ); + } + + inline int poll(std::vector const& items, std::chrono::milliseconds timeout) + { + return poll(items.data(), items.size(), timeout.count() ); + } + + inline int poll(std::vector const& items, long timeout_ = -1) + { + return poll(items.data(), static_cast(items.size()), timeout_); + } + #endif + + + + inline void proxy (void *frontend, void *backend, void *capture) + { + int rc = zmq_proxy (frontend, backend, capture); + if (rc != 0) + throw error_t (); + } + +#ifdef ZMQ_HAS_PROXY_STEERABLE + inline void proxy_steerable (void *frontend, void *backend, void *capture, void *control) + { + int rc = zmq_proxy_steerable (frontend, backend, capture, control); + if (rc != 0) + throw error_t (); + } +#endif + + inline void version (int *major_, int *minor_, int *patch_) + { + zmq_version (major_, minor_, patch_); + } + + #ifdef ZMQ_CPP11 + inline std::tuple version() + { + std::tuple v; + zmq_version(&std::get<0>(v), &std::get<1>(v), &std::get<2>(v) ); + return v; + } + #endif + + class message_t + { + friend class socket_t; + + public: + + inline message_t () + { + int rc = zmq_msg_init (&msg); + if (rc != 0) + throw error_t (); + } + + inline explicit message_t (size_t size_) + { + int rc = zmq_msg_init_size (&msg, size_); + if (rc != 0) + throw error_t (); + } + + template message_t(I first, I last): + msg() + { + typedef typename std::iterator_traits::difference_type size_type; + typedef typename std::iterator_traits::pointer pointer_t; + + size_type const size_ = std::distance(first, last); + int const rc = zmq_msg_init_size (&msg, size_); + if (rc != 0) + throw error_t (); + std::copy(first, last, static_cast(zmq_msg_data (&msg)) ); + } + + inline message_t (void *data_, size_t size_, free_fn *ffn_, + void *hint_ = NULL) + { + int rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_); + if (rc != 0) + throw error_t (); + } + +#ifdef ZMQ_HAS_RVALUE_REFS + inline message_t (message_t &&rhs): msg (rhs.msg) + { + int rc = zmq_msg_init (&rhs.msg); + if (rc != 0) + throw error_t (); + } + + inline message_t &operator = (message_t &&rhs) ZMQ_NOTHROW + { + std::swap (msg, rhs.msg); + return *this; + } +#endif + + inline ~message_t () ZMQ_NOTHROW + { + int rc = zmq_msg_close (&msg); + ZMQ_ASSERT (rc == 0); + } + + inline void rebuild () + { + int rc = zmq_msg_close (&msg); + if (rc != 0) + throw error_t (); + rc = zmq_msg_init (&msg); + if (rc != 0) + throw error_t (); + } + + inline void rebuild (size_t size_) + { + int rc = zmq_msg_close (&msg); + if (rc != 0) + throw error_t (); + rc = zmq_msg_init_size (&msg, size_); + if (rc != 0) + throw error_t (); + } + + inline void rebuild (void *data_, size_t size_, free_fn *ffn_, + void *hint_ = NULL) + { + int rc = zmq_msg_close (&msg); + if (rc != 0) + throw error_t (); + rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_); + if (rc != 0) + throw error_t (); + } + + inline void move (message_t const *msg_) + { + int rc = zmq_msg_move (&msg, const_cast(&(msg_->msg))); + if (rc != 0) + throw error_t (); + } + + inline void copy (message_t const *msg_) + { + int rc = zmq_msg_copy (&msg, const_cast(&(msg_->msg))); + if (rc != 0) + throw error_t (); + } + + inline bool more () const ZMQ_NOTHROW + { + int rc = zmq_msg_more (const_cast(&msg) ); + return rc != 0; + } + + inline void *data () ZMQ_NOTHROW + { + return zmq_msg_data (&msg); + } + + inline const void* data () const ZMQ_NOTHROW + { + return zmq_msg_data (const_cast(&msg)); + } + + inline size_t size () const ZMQ_NOTHROW + { + return zmq_msg_size (const_cast(&msg)); + } + + template T* data() ZMQ_NOTHROW + { + return static_cast( data() ); + } + + template T const* data() const ZMQ_NOTHROW + { + return static_cast( data() ); + } + + + private: + // The underlying message + zmq_msg_t msg; + + // Disable implicit message copying, so that users won't use shared + // messages (less efficient) without being aware of the fact. + message_t (const message_t&) ZMQ_DELETED_FUNCTION; + void operator = (const message_t&) ZMQ_DELETED_FUNCTION; + }; + + class context_t + { + friend class socket_t; + + public: + inline context_t () + { + ptr = zmq_ctx_new (); + if (ptr == NULL) + throw error_t (); + } + + + inline explicit context_t (int io_threads_, int max_sockets_ = ZMQ_MAX_SOCKETS_DFLT) + { + ptr = zmq_ctx_new (); + if (ptr == NULL) + throw error_t (); + + int rc = zmq_ctx_set (ptr, ZMQ_IO_THREADS, io_threads_); + ZMQ_ASSERT (rc == 0); + + rc = zmq_ctx_set (ptr, ZMQ_MAX_SOCKETS, max_sockets_); + ZMQ_ASSERT (rc == 0); + } + +#ifdef ZMQ_HAS_RVALUE_REFS + inline context_t (context_t &&rhs) ZMQ_NOTHROW : ptr (rhs.ptr) + { + rhs.ptr = NULL; + } + inline context_t &operator = (context_t &&rhs) ZMQ_NOTHROW + { + std::swap (ptr, rhs.ptr); + return *this; + } +#endif + + inline ~context_t () ZMQ_NOTHROW + { + int rc = zmq_ctx_destroy (ptr); + ZMQ_ASSERT (rc == 0); + } + + inline void close() ZMQ_NOTHROW + { + int rc = zmq_ctx_shutdown (ptr); + ZMQ_ASSERT (rc == 0); + } + + // Be careful with this, it's probably only useful for + // using the C api together with an existing C++ api. + // Normally you should never need to use this. + inline ZMQ_EXPLICIT operator void* () ZMQ_NOTHROW + { + return ptr; + } + + inline ZMQ_EXPLICIT operator void const* () const ZMQ_NOTHROW + { + return ptr; + } + private: + + void *ptr; + + context_t (const context_t&) ZMQ_DELETED_FUNCTION; + void operator = (const context_t&) ZMQ_DELETED_FUNCTION; + }; + + #ifdef ZMQ_CPP11 + enum class socket_type: int + { + req = ZMQ_REQ, + rep = ZMQ_REP, + dealer = ZMQ_DEALER, + router = ZMQ_ROUTER, + pub = ZMQ_PUB, + sub = ZMQ_SUB, + xpub = ZMQ_XPUB, + xsub = ZMQ_XSUB, + push = ZMQ_PUSH, + pull = ZMQ_PULL, +#if ZMQ_VERSION_MAJOR < 4 + pair = ZMQ_PAIR +#else + pair = ZMQ_PAIR, + stream = ZMQ_STREAM +#endif + }; + #endif + + class socket_t + { + friend class monitor_t; + public: + inline socket_t(context_t& context_, int type_) + { + init(context_, type_); + } + + #ifdef ZMQ_CPP11 + inline socket_t(context_t& context_, socket_type type_) + { + init(context_, static_cast(type_)); + } + #endif + +#ifdef ZMQ_HAS_RVALUE_REFS + inline socket_t(socket_t&& rhs) ZMQ_NOTHROW : ptr(rhs.ptr) + { + rhs.ptr = NULL; + } + inline socket_t& operator=(socket_t&& rhs) ZMQ_NOTHROW + { + std::swap(ptr, rhs.ptr); + return *this; + } +#endif + + inline ~socket_t () ZMQ_NOTHROW + { + close(); + } + + inline ZMQ_EXPLICIT operator void* () ZMQ_NOTHROW + { + return ptr; + } + + inline ZMQ_EXPLICIT operator void const* () const ZMQ_NOTHROW + { + return ptr; + } + + inline void close() ZMQ_NOTHROW + { + if(ptr == NULL) + // already closed + return ; + int rc = zmq_close (ptr); + ZMQ_ASSERT (rc == 0); + ptr = 0 ; + } + + template void setsockopt(int option_, T const& optval) + { + setsockopt(option_, &optval, sizeof(T) ); + } + + inline void setsockopt (int option_, const void *optval_, + size_t optvallen_) + { + int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_); + if (rc != 0) + throw error_t (); + } + + inline void getsockopt (int option_, void *optval_, + size_t *optvallen_) const + { + int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_); + if (rc != 0) + throw error_t (); + } + + template T getsockopt(int option_) const + { + T optval; + size_t optlen = sizeof(T); + getsockopt(option_, &optval, &optlen ); + return optval; + } + + inline void bind(std::string const& addr) + { + bind(addr.c_str()); + } + + inline void bind (const char *addr_) + { + int rc = zmq_bind (ptr, addr_); + if (rc != 0) + throw error_t (); + } + + inline void unbind(std::string const& addr) + { + unbind(addr.c_str()); + } + + inline void unbind (const char *addr_) + { + int rc = zmq_unbind (ptr, addr_); + if (rc != 0) + throw error_t (); + } + + inline void connect(std::string const& addr) + { + connect(addr.c_str()); + } + + inline void connect (const char *addr_) + { + int rc = zmq_connect (ptr, addr_); + if (rc != 0) + throw error_t (); + } + + inline void disconnect(std::string const& addr) + { + disconnect(addr.c_str()); + } + + inline void disconnect (const char *addr_) + { + int rc = zmq_disconnect (ptr, addr_); + if (rc != 0) + throw error_t (); + } + + inline bool connected() const ZMQ_NOTHROW + { + return(ptr != NULL); + } + + inline size_t send (const void *buf_, size_t len_, int flags_ = 0) + { + int nbytes = zmq_send (ptr, buf_, len_, flags_); + if (nbytes >= 0) + return (size_t) nbytes; + if (zmq_errno () == EAGAIN) + return 0; + throw error_t (); + } + + inline bool send (message_t &msg_, int flags_ = 0) + { + int nbytes = zmq_msg_send (&(msg_.msg), ptr, flags_); + if (nbytes >= 0) + return true; + if (zmq_errno () == EAGAIN) + return false; + throw error_t (); + } + + template bool send(I first, I last, int flags_=0) + { + zmq::message_t msg(first, last); + return send(msg, flags_); + } + +#ifdef ZMQ_HAS_RVALUE_REFS + inline bool send (message_t &&msg_, int flags_ = 0) + { + return send(msg_, flags_); + } +#endif + + inline size_t recv (void *buf_, size_t len_, int flags_ = 0) + { + int nbytes = zmq_recv (ptr, buf_, len_, flags_); + if (nbytes >= 0) + return (size_t) nbytes; + if (zmq_errno () == EAGAIN) + return 0; + throw error_t (); + } + + inline bool recv (message_t *msg_, int flags_ = 0) + { + int nbytes = zmq_msg_recv (&(msg_->msg), ptr, flags_); + if (nbytes >= 0) + return true; + if (zmq_errno () == EAGAIN) + return false; + throw error_t (); + } + + private: + inline void init(context_t& context_, int type_) + { + ctxptr = context_.ptr; + ptr = zmq_socket (context_.ptr, type_ ); + if (ptr == NULL) + throw error_t (); + } + + void *ptr; + void *ctxptr; + + socket_t (const socket_t&) ZMQ_DELETED_FUNCTION; + void operator = (const socket_t&) ZMQ_DELETED_FUNCTION; + }; + + class monitor_t + { + public: + monitor_t() : socketPtr(NULL) {} + virtual ~monitor_t() {} + + void monitor(socket_t &socket, std::string const& addr, int events = ZMQ_EVENT_ALL) + { + monitor(socket, addr.c_str(), events); + } + + void monitor(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL) + { + int rc = zmq_socket_monitor(socket.ptr, addr_, events); + if (rc != 0) + throw error_t (); + + socketPtr = socket.ptr; + void *s = zmq_socket (socket.ctxptr, ZMQ_PAIR); + assert (s); + + rc = zmq_connect (s, addr_); + assert (rc == 0); + + on_monitor_started(); + + while (true) { + zmq_msg_t eventMsg; + zmq_msg_init (&eventMsg); + rc = zmq_msg_recv (&eventMsg, s, 0); + if (rc == -1 && zmq_errno() == ETERM) + break; + assert (rc != -1); +#if ZMQ_VERSION_MAJOR >= 4 + const char* data = static_cast(zmq_msg_data(&eventMsg)); + zmq_event_t msgEvent; + memcpy(&msgEvent.event, data, sizeof(uint16_t)); data += sizeof(uint16_t); + memcpy(&msgEvent.value, data, sizeof(int32_t)); + zmq_event_t* event = &msgEvent; +#else + zmq_event_t* event = static_cast(zmq_msg_data(&eventMsg)); +#endif + +#ifdef ZMQ_NEW_MONITOR_EVENT_LAYOUT + zmq_msg_t addrMsg; + zmq_msg_init (&addrMsg); + rc = zmq_msg_recv (&addrMsg, s, 0); + if (rc == -1 && zmq_errno() == ETERM) + break; + assert (rc != -1); + const char* str = static_cast(zmq_msg_data (&addrMsg)); + std::string address(str, str + zmq_msg_size(&addrMsg)); + zmq_msg_close (&addrMsg); +#else + // Bit of a hack, but all events in the zmq_event_t union have the same layout so this will work for all event types. + std::string address = event->data.connected.addr; +#endif + +#ifdef ZMQ_EVENT_MONITOR_STOPPED + if (event->event == ZMQ_EVENT_MONITOR_STOPPED) + break; +#endif + + switch (event->event) { + case ZMQ_EVENT_CONNECTED: + on_event_connected(*event, address.c_str()); + break; + case ZMQ_EVENT_CONNECT_DELAYED: + on_event_connect_delayed(*event, address.c_str()); + break; + case ZMQ_EVENT_CONNECT_RETRIED: + on_event_connect_retried(*event, address.c_str()); + break; + case ZMQ_EVENT_LISTENING: + on_event_listening(*event, address.c_str()); + break; + case ZMQ_EVENT_BIND_FAILED: + on_event_bind_failed(*event, address.c_str()); + break; + case ZMQ_EVENT_ACCEPTED: + on_event_accepted(*event, address.c_str()); + break; + case ZMQ_EVENT_ACCEPT_FAILED: + on_event_accept_failed(*event, address.c_str()); + break; + case ZMQ_EVENT_CLOSED: + on_event_closed(*event, address.c_str()); + break; + case ZMQ_EVENT_CLOSE_FAILED: + on_event_close_failed(*event, address.c_str()); + break; + case ZMQ_EVENT_DISCONNECTED: + on_event_disconnected(*event, address.c_str()); + break; + default: + on_event_unknown(*event, address.c_str()); + break; + } + zmq_msg_close (&eventMsg); + } + zmq_close (s); + socketPtr = NULL; + } + +#ifdef ZMQ_EVENT_MONITOR_STOPPED + void abort() + { + if (socketPtr) + zmq_socket_monitor(socketPtr, NULL, 0); + } +#endif + virtual void on_monitor_started() {} + virtual void on_event_connected(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_connect_delayed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_connect_retried(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_listening(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_bind_failed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_accepted(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_accept_failed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_closed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_close_failed(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_disconnected(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + virtual void on_event_unknown(const zmq_event_t &event_, const char* addr_) { (void)event_; (void)addr_; } + private: + void* socketPtr; + }; +} + +#endif