void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOperationOutput *output)
{
	/* cache connected sockets, so we can safely remove links first before replacing them */
	OpInputs targets = cache_output_links(output);
	if (targets.empty())
		return;
	
	WriteBufferOperation *writeOperation = NULL;
	for (OpInputs::const_iterator it = targets.begin(); it != targets.end(); ++it) {
		NodeOperationInput *target = *it;
		
		/* try to find existing write buffer operation */
		if (target->getOperation().isWriteBufferOperation()) {
			BLI_assert(writeOperation == NULL); /* there should only be one write op connected */
			writeOperation = (WriteBufferOperation *)(&target->getOperation());
		}
		else {
			/* remove all links to other nodes */
			removeInputLink(target);
		}
	}
	
	/* if no write buffer operation exists yet, create a new one */
	if (!writeOperation) {
		writeOperation = new WriteBufferOperation(operation->getOutputSocket()->getDataType());
		writeOperation->setbNodeTree(m_context->getbNodeTree());
		addOperation(writeOperation);
		
		addLink(output, writeOperation->getInputSocket(0));
	}
	
	writeOperation->readResolutionFromInputSocket();
	
	/* add readbuffer op for every former connected input */
	for (OpInputs::const_iterator it = targets.begin(); it != targets.end(); ++it) {
		NodeOperationInput *target = *it;
		if (&target->getOperation() == writeOperation)
			continue; /* skip existing write op links */
		
		ReadBufferOperation *readoperation = new ReadBufferOperation(operation->getOutputSocket()->getDataType());
		readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
		addOperation(readoperation);
		
		addLink(readoperation->getOutputSocket(), target);
	
		readoperation->readResolutionFromWriteBuffer();
	}
}
void NodeOperationBuilder::add_input_buffers(NodeOperation * /*operation*/,
                                             NodeOperationInput *input)
{
	if (!input->isConnected())
		return;
	
	NodeOperationOutput *output = input->getLink();
	if (output->getOperation().isReadBufferOperation()) {
		/* input is already buffered, no need to add another */
		return;
	}
	
	/* this link will be replaced below */
	removeInputLink(input);
	
	/* check of other end already has write operation, otherwise add a new one */
	WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output);
	if (!writeoperation) {
		writeoperation = new WriteBufferOperation(output->getDataType());
		writeoperation->setbNodeTree(m_context->getbNodeTree());
		addOperation(writeoperation);
		
		addLink(output, writeoperation->getInputSocket(0));
		
		writeoperation->readResolutionFromInputSocket();
	}
	
	/* add readbuffer op for the input */
	ReadBufferOperation *readoperation = new ReadBufferOperation(output->getDataType());
	readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
	this->addOperation(readoperation);
	
	addLink(readoperation->getOutputSocket(), input);
	
	readoperation->readResolutionFromWriteBuffer();
}