Domanda

I'm writing a method to output to several output streams at once, the way I got it set up right now is that I have a LogController, LogFile and LogConsole, the latter two are implementations of the Log interface.

What I'm trying to do right now adding a method to the LogController that attaches any implementation of the Log interface.

How I want to do this is as follows: in the LogController I have an associative array, in which I store pointers to Log objects. When the writeOut method of the LogController is called, I want it to then run over the elements of the array and call their writeOut methods too. The latter I can do, but the previous is proving to be difficult.

Mage/Utility/LogController.d

module Mage.Utility.LogController;

import std.stdio;

interface Log {
    public void writeOut(string s);
}

class LogController {
    private Log*[string] m_Logs;

    public this() {

    }

    public void attach(string name, ref Log l) {
        foreach (string key; m_Logs.keys) {
            if (name is key) return;
        }

        m_Logs[name] = &l;
    }

    public void writeOut(string s) {
        foreach (Log* log; m_Logs) {
            log.writeOut(s);
        }
    }
}

Mage/Utility/LogFile.d

module Mage.Utility.LogFile;

import std.stdio;
import std.datetime;

import Mage.Utility.LogController;

class LogFile : Log {
    private File fp;
    private string path;

    public this(string path) {
        this.fp = File(path, "a+");
        this.path = path;
    }

    public void writeOut(string s) {
        this.fp.writefln("[%s] %s", this.timestamp(), s);
    }

    private string timestamp() {
        return Clock.currTime().toISOExtString();
    }
}

I've already tried multiple things with the attach functions, and none of them. The build fails with the following error:

Mage\Root.d(0,0): Error: function Mage.Utility.LogController.LogController.attach (string name, ref Log l) is not callable using argument types (string, LogFile)

This is the incriminating function:

public void initialise(string logfile = DEFAULT_LOG_FILENAME) {
    m_Log = new LogController();

    LogFile lf = new LogFile(logfile);
    m_Log.attach("Log File", lf);
}

Can anyone tell me where I'm going wrong here? I'm stumped and I haven't been able to find the answer anywhere. I've tried a multitude of different solutions and none of them work.

È stato utile?

Soluzione

Classes and interfaces in D are reference types, so Log* is redundant - remove the *. Similarly, there is no need to use ref in ref Log l - that's like taking a pointer by reference in C++.

This is the cause of the error message you posted - variables passed by reference must match in type exactly. Removing the ref should solve the error.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top